aboutsummaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-15 09:40:05 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-15 09:40:05 -0700
commit2ed0e21b30b53d3a94e204196e523e6c8f732b56 (patch)
treede2635426477d86338a9469ce09ba0626052288f /drivers/net
parent0fa213310cd8fa7a51071cdcf130e26fa56e9549 (diff)
parent9cbc1cb8cd46ce1f7645b9de249b2ce8460129bb (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1244 commits) pkt_sched: Rename PSCHED_US2NS and PSCHED_NS2US ipv4: Fix fib_trie rebalancing Bluetooth: Fix issue with uninitialized nsh.type in DTL-1 driver Bluetooth: Fix Kconfig issue with RFKILL integration PIM-SM: namespace changes ipv4: update ARPD help text net: use a deferred timer in rt_check_expire ieee802154: fix kconfig bool/tristate muckup bonding: initialization rework bonding: use is_zero_ether_addr bonding: network device names are case sensative bonding: elminate bad refcount code bonding: fix style issues bonding: fix destructor bonding: remove bonding read/write semaphore bonding: initialize before registration bonding: bond_create always called with default parameters x_tables: Convert printk to pr_err netfilter: conntrack: optional reliable conntrack event delivery list_nulls: add hlist_nulls_add_head and hlist_nulls_del ...
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/3c501.c65
-rw-r--r--drivers/net/3c503.c36
-rw-r--r--drivers/net/3c505.c217
-rw-r--r--drivers/net/3c507.c55
-rw-r--r--drivers/net/3c509.c76
-rw-r--r--drivers/net/3c515.c126
-rw-r--r--drivers/net/3c523.c91
-rw-r--r--drivers/net/3c527.c48
-rw-r--r--drivers/net/3c59x.c216
-rw-r--r--drivers/net/7990.c2
-rw-r--r--drivers/net/8139cp.c34
-rw-r--r--drivers/net/8139too.c210
-rw-r--r--drivers/net/82596.c14
-rw-r--r--drivers/net/8390.c10
-rw-r--r--drivers/net/8390p.c19
-rw-r--r--drivers/net/Kconfig57
-rw-r--r--drivers/net/Makefile6
-rw-r--r--drivers/net/a2065.c2
-rw-r--r--drivers/net/acenic.c1
-rw-r--r--drivers/net/appletalk/ipddp.c43
-rw-r--r--drivers/net/arm/at91_ether.c2
-rw-r--r--drivers/net/arm/ep93xx_eth.c4
-rw-r--r--drivers/net/arm/ether3.c2
-rw-r--r--drivers/net/arm/ixp4xx_eth.c8
-rw-r--r--drivers/net/atl1c/atl1c_ethtool.c2
-rw-r--r--drivers/net/atl1c/atl1c_main.c73
-rw-r--r--drivers/net/atl1e/atl1e.h1
-rw-r--r--drivers/net/atl1e/atl1e_main.c15
-rw-r--r--drivers/net/atlx/atl1.c10
-rw-r--r--drivers/net/au1000_eth.c2
-rw-r--r--drivers/net/b44.c4
-rw-r--r--drivers/net/b44.h1
-rw-r--r--drivers/net/benet/be_main.c159
-rw-r--r--drivers/net/bfin_mac.c235
-rw-r--r--drivers/net/bmac.c16
-rw-r--r--drivers/net/bnx2.c44
-rw-r--r--drivers/net/bnx2.h2
-rw-r--r--drivers/net/bnx2x.h15
-rw-r--r--drivers/net/bnx2x_fw_file_hdr.h37
-rw-r--r--drivers/net/bnx2x_init.h605
-rw-r--r--drivers/net/bnx2x_init_ops.h442
-rw-r--r--drivers/net/bnx2x_init_values.h16322
-rw-r--r--drivers/net/bnx2x_main.c359
-rw-r--r--drivers/net/bonding/bond_3ad.c5
-rw-r--r--drivers/net/bonding/bond_3ad.h4
-rw-r--r--drivers/net/bonding/bond_main.c826
-rw-r--r--drivers/net/bonding/bond_sysfs.c463
-rw-r--r--drivers/net/bonding/bonding.h10
-rw-r--r--drivers/net/can/Kconfig62
-rw-r--r--drivers/net/can/Makefile7
-rw-r--r--drivers/net/can/dev.c657
-rw-r--r--drivers/net/can/sja1000/Makefile11
-rw-r--r--drivers/net/can/sja1000/ems_pci.c320
-rw-r--r--drivers/net/can/sja1000/kvaser_pci.c412
-rw-r--r--drivers/net/can/sja1000/sja1000.c637
-rw-r--r--drivers/net/can/sja1000/sja1000.h181
-rw-r--r--drivers/net/can/sja1000/sja1000_of_platform.c235
-rw-r--r--drivers/net/can/sja1000/sja1000_platform.c165
-rw-r--r--drivers/net/cassini.c2
-rw-r--r--drivers/net/chelsio/common.h2
-rw-r--r--drivers/net/chelsio/cphy.h51
-rw-r--r--drivers/net/chelsio/cxgb2.c36
-rw-r--r--drivers/net/chelsio/mv88e1xxx.c5
-rw-r--r--drivers/net/chelsio/mv88x201x.c50
-rw-r--r--drivers/net/chelsio/my3126.c14
-rw-r--r--drivers/net/chelsio/sge.c5
-rw-r--r--drivers/net/chelsio/subr.c46
-rw-r--r--drivers/net/cpmac.c33
-rw-r--r--drivers/net/cs89x0.c2
-rw-r--r--drivers/net/cxgb3/Makefile2
-rw-r--r--drivers/net/cxgb3/adapter.h4
-rw-r--r--drivers/net/cxgb3/ael1002.c958
-rw-r--r--drivers/net/cxgb3/aq100x.c355
-rw-r--r--drivers/net/cxgb3/common.h67
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c152
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.c27
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.h3
-rw-r--r--drivers/net/cxgb3/sge.c71
-rw-r--r--drivers/net/cxgb3/t3_hw.c89
-rw-r--r--drivers/net/cxgb3/version.h4
-rw-r--r--drivers/net/cxgb3/vsc8211.c70
-rw-r--r--drivers/net/davinci_emac.c2830
-rw-r--r--drivers/net/de600.c25
-rw-r--r--drivers/net/de620.c63
-rw-r--r--drivers/net/declance.c5
-rw-r--r--drivers/net/defxx.c2
-rw-r--r--drivers/net/depca.c8
-rw-r--r--drivers/net/dl2k.c8
-rw-r--r--drivers/net/dm9000.c32
-rw-r--r--drivers/net/e100.c201
-rw-r--r--drivers/net/e1000/e1000_main.c44
-rw-r--r--drivers/net/e1000e/82571.c99
-rw-r--r--drivers/net/e1000e/defines.h25
-rw-r--r--drivers/net/e1000e/e1000.h61
-rw-r--r--drivers/net/e1000e/es2lan.c3
-rw-r--r--drivers/net/e1000e/ethtool.c46
-rw-r--r--drivers/net/e1000e/hw.h20
-rw-r--r--drivers/net/e1000e/ich8lan.c448
-rw-r--r--drivers/net/e1000e/lib.c38
-rw-r--r--drivers/net/e1000e/netdev.c280
-rw-r--r--drivers/net/e1000e/param.c2
-rw-r--r--drivers/net/e1000e/phy.c699
-rw-r--r--drivers/net/ehea/ehea_main.c8
-rw-r--r--drivers/net/enic/enic_main.c2
-rw-r--r--drivers/net/eql.c1
-rw-r--r--drivers/net/ethoc.c6
-rw-r--r--drivers/net/ewrk3.c2
-rw-r--r--drivers/net/fec.c901
-rw-r--r--drivers/net/fec.h127
-rw-r--r--drivers/net/fec_mpc52xx.c180
-rw-r--r--drivers/net/fec_mpc52xx_phy.c26
-rw-r--r--drivers/net/forcedeth.c240
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c108
-rw-r--r--drivers/net/fs_enet/fs_enet.h5
-rw-r--r--drivers/net/fs_enet/mac-fec.c34
-rw-r--r--drivers/net/fs_enet/mii-bitbang.c29
-rw-r--r--drivers/net/fs_enet/mii-fec.c32
-rw-r--r--drivers/net/fsl_pq_mdio.c59
-rw-r--r--drivers/net/gianfar.c112
-rw-r--r--drivers/net/gianfar.h4
-rw-r--r--drivers/net/hamachi.c5
-rw-r--r--drivers/net/hamradio/baycom_epp.c2
-rw-r--r--drivers/net/hamradio/bpqether.c4
-rw-r--r--drivers/net/hamradio/hdlcdrv.c2
-rw-r--r--drivers/net/hamradio/mkiss.c4
-rw-r--r--drivers/net/hp100.c4
-rw-r--r--drivers/net/hplance.c21
-rw-r--r--drivers/net/ibm_newemac/core.c2
-rw-r--r--drivers/net/ibmlana.c5
-rw-r--r--drivers/net/ibmveth.c40
-rw-r--r--drivers/net/ifb.c1
-rw-r--r--drivers/net/igb/e1000_82575.h1
-rw-r--r--drivers/net/igb/e1000_defines.h3
-rw-r--r--drivers/net/igb/e1000_mbx.c8
-rw-r--r--drivers/net/igb/e1000_phy.h2
-rw-r--r--drivers/net/igb/e1000_regs.h1
-rw-r--r--drivers/net/igb/igb.h15
-rw-r--r--drivers/net/igb/igb_ethtool.c37
-rw-r--r--drivers/net/igb/igb_main.c148
-rw-r--r--drivers/net/igbvf/ethtool.c36
-rw-r--r--drivers/net/igbvf/igbvf.h6
-rw-r--r--drivers/net/igbvf/netdev.c23
-rw-r--r--drivers/net/ioc3-eth.c2
-rw-r--r--drivers/net/irda/Kconfig45
-rw-r--r--drivers/net/irda/Makefile1
-rw-r--r--drivers/net/irda/au1k_ir.c22
-rw-r--r--drivers/net/irda/bfin_sir.c820
-rw-r--r--drivers/net/irda/bfin_sir.h148
-rw-r--r--drivers/net/irda/donauboe.c8
-rw-r--r--drivers/net/irda/irda-usb.c44
-rw-r--r--drivers/net/irda/kingsun-sir.c5
-rw-r--r--drivers/net/irda/ks959-sir.c5
-rw-r--r--drivers/net/irda/ksdazzle-sir.c5
-rw-r--r--drivers/net/irda/mcs7780.c6
-rw-r--r--drivers/net/irda/pxaficp_ir.c16
-rw-r--r--drivers/net/irda/sa1100_ir.c18
-rw-r--r--drivers/net/irda/sir_dev.c2
-rw-r--r--drivers/net/irda/smsc-ircc2.c2
-rw-r--r--drivers/net/iseries_veth.c17
-rw-r--r--drivers/net/ixgb/ixgb_hw.c20
-rw-r--r--drivers/net/ixgb/ixgb_hw.h14
-rw-r--r--drivers/net/ixgb/ixgb_main.c20
-rw-r--r--drivers/net/ixgb/ixgb_osdep.h2
-rw-r--r--drivers/net/ixgbe/Makefile2
-rw-r--r--drivers/net/ixgbe/ixgbe.h161
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c330
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c1489
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c316
-rw-r--r--drivers/net/ixgbe/ixgbe_common.h8
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82598.c4
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.c2
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_nl.c119
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c961
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.c556
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.h67
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c1708
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.c166
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.h5
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h333
-rw-r--r--drivers/net/ixp2000/ixpdev.c19
-rw-r--r--drivers/net/jazzsonic.c19
-rw-r--r--drivers/net/jme.c1
-rw-r--r--drivers/net/korina.c39
-rw-r--r--drivers/net/ks8842.c732
-rw-r--r--drivers/net/lasi_82596.c6
-rw-r--r--drivers/net/lib82596.c23
-rw-r--r--drivers/net/lib8390.c2
-rw-r--r--drivers/net/ll_temac.h374
-rw-r--r--drivers/net/ll_temac_main.c969
-rw-r--r--drivers/net/ll_temac_mdio.c120
-rw-r--r--drivers/net/loopback.c22
-rw-r--r--drivers/net/mac8390.c19
-rw-r--r--drivers/net/mac89x0.c4
-rw-r--r--drivers/net/macb.c20
-rw-r--r--drivers/net/mace.c18
-rw-r--r--drivers/net/macmace.c18
-rw-r--r--drivers/net/macvlan.c35
-rw-r--r--drivers/net/mdio.c431
-rw-r--r--drivers/net/meth.c28
-rw-r--r--drivers/net/mii.c91
-rw-r--r--drivers/net/mipsnet.c15
-rw-r--r--drivers/net/mlx4/Makefile2
-rw-r--r--drivers/net/mlx4/en_cq.c3
-rw-r--r--drivers/net/mlx4/en_ethtool.c (renamed from drivers/net/mlx4/en_params.c)67
-rw-r--r--drivers/net/mlx4/en_main.c68
-rw-r--r--drivers/net/mlx4/en_netdev.c199
-rw-r--r--drivers/net/mlx4/en_rx.c139
-rw-r--r--drivers/net/mlx4/en_tx.c112
-rw-r--r--drivers/net/mlx4/eq.c4
-rw-r--r--drivers/net/mlx4/mlx4_en.h49
-rw-r--r--drivers/net/mlx4/mr.c7
-rw-r--r--drivers/net/mv643xx_eth.c98
-rw-r--r--drivers/net/mvme147.c17
-rw-r--r--drivers/net/myri10ge/myri10ge.c70
-rw-r--r--drivers/net/myri_sbus.c2
-rw-r--r--drivers/net/ne2k-pci.c2
-rw-r--r--drivers/net/ne3210.c4
-rw-r--r--drivers/net/netx-eth.c17
-rw-r--r--drivers/net/netxen/netxen_nic.h624
-rw-r--r--drivers/net/netxen/netxen_nic_ctx.c241
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c106
-rw-r--r--drivers/net/netxen/netxen_nic_hdr.h8
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c737
-rw-r--r--drivers/net/netxen/netxen_nic_hw.h76
-rw-r--r--drivers/net/netxen/netxen_nic_init.c541
-rw-r--r--drivers/net/netxen/netxen_nic_main.c411
-rw-r--r--drivers/net/netxen/netxen_nic_niu.c341
-rw-r--r--drivers/net/netxen/netxen_nic_phan_reg.h27
-rw-r--r--drivers/net/ni65.c2
-rw-r--r--drivers/net/niu.c66
-rw-r--r--drivers/net/ns83820.c10
-rw-r--r--drivers/net/pasemi_mac.c58
-rw-r--r--drivers/net/pasemi_mac.h1
-rw-r--r--drivers/net/pci-skeleton.c19
-rw-r--r--drivers/net/pcmcia/3c574_cs.c2
-rw-r--r--drivers/net/pcmcia/3c589_cs.c4
-rw-r--r--drivers/net/pcmcia/axnet_cs.c2
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c2
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c2
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c2
-rw-r--r--drivers/net/pcnet32.c5
-rw-r--r--drivers/net/phy/marvell.c1
-rw-r--r--drivers/net/phy/mdio_bus.c29
-rw-r--r--drivers/net/phy/phy_device.c163
-rw-r--r--drivers/net/plip.c6
-rw-r--r--drivers/net/ppp_generic.c1
-rw-r--r--drivers/net/pppol2tp.c14
-rw-r--r--drivers/net/qla3xxx.c1
-rw-r--r--drivers/net/qlge/qlge.h31
-rw-r--r--drivers/net/qlge/qlge_ethtool.c6
-rw-r--r--drivers/net/qlge/qlge_main.c134
-rw-r--r--drivers/net/qlge/qlge_mpi.c58
-rw-r--r--drivers/net/r6040.c18
-rw-r--r--drivers/net/r8169.c218
-rw-r--r--drivers/net/rionet.c14
-rw-r--r--drivers/net/rrunner.c2
-rw-r--r--drivers/net/s2io-regs.h5
-rw-r--r--drivers/net/s2io.c44
-rw-r--r--drivers/net/s2io.h9
-rw-r--r--drivers/net/sb1250-mac.c37
-rw-r--r--drivers/net/sfc/Kconfig2
-rw-r--r--drivers/net/sfc/boards.c2
-rw-r--r--drivers/net/sfc/efx.c29
-rw-r--r--drivers/net/sfc/ethtool.c19
-rw-r--r--drivers/net/sfc/falcon.c137
-rw-r--r--drivers/net/sfc/falcon_hwdefs.h3
-rw-r--r--drivers/net/sfc/falcon_xmac.c2
-rw-r--r--drivers/net/sfc/mdio_10g.c385
-rw-r--r--drivers/net/sfc/mdio_10g.h282
-rw-r--r--drivers/net/sfc/net_driver.h34
-rw-r--r--drivers/net/sfc/rx.c26
-rw-r--r--drivers/net/sfc/selftest.c22
-rw-r--r--drivers/net/sfc/selftest.h2
-rw-r--r--drivers/net/sfc/sfe4001.c3
-rw-r--r--drivers/net/sfc/tenxpress.c251
-rw-r--r--drivers/net/sfc/tx.c7
-rw-r--r--drivers/net/sfc/xenpack.h62
-rw-r--r--drivers/net/sfc/xfp_phy.c55
-rw-r--r--drivers/net/sgiseeq.c18
-rw-r--r--drivers/net/sh_eth.c499
-rw-r--r--drivers/net/sh_eth.h278
-rw-r--r--drivers/net/sis190.c59
-rw-r--r--drivers/net/sis900.c2
-rw-r--r--drivers/net/skfp/skfddi.c158
-rw-r--r--drivers/net/skge.c2
-rw-r--r--drivers/net/sky2.c1
-rw-r--r--drivers/net/smc-mca.c4
-rw-r--r--drivers/net/smc911x.c23
-rw-r--r--drivers/net/smc9194.c2
-rw-r--r--drivers/net/smsc911x.c63
-rw-r--r--drivers/net/sonic.c2
-rw-r--r--drivers/net/starfire.c2
-rw-r--r--drivers/net/sun3_82586.c2
-rw-r--r--drivers/net/sun3lance.c21
-rw-r--r--drivers/net/sundance.c53
-rw-r--r--drivers/net/sunhme.c2
-rw-r--r--drivers/net/tc35815.c13
-rw-r--r--drivers/net/tehuti.c14
-rw-r--r--drivers/net/tg3.c107
-rw-r--r--drivers/net/tg3.h6
-rw-r--r--drivers/net/tlan.c2
-rw-r--r--drivers/net/tokenring/3c359.c2
-rw-r--r--drivers/net/tokenring/lanstreamer.c2
-rw-r--r--drivers/net/tokenring/olympic.c2
-rw-r--r--drivers/net/tokenring/smctr.c2
-rw-r--r--drivers/net/tokenring/tms380tr.c2
-rw-r--r--drivers/net/tulip/Kconfig12
-rw-r--r--drivers/net/tulip/de2104x.c15
-rw-r--r--drivers/net/tulip/de4x5.c12
-rw-r--r--drivers/net/tulip/dmfe.c2
-rw-r--r--drivers/net/tulip/uli526x.c2
-rw-r--r--drivers/net/tulip/winbond-840.c3
-rw-r--r--drivers/net/tun.c110
-rw-r--r--drivers/net/ucc_geth.c187
-rw-r--r--drivers/net/ucc_geth.h31
-rw-r--r--drivers/net/usb/Kconfig8
-rw-r--r--drivers/net/usb/Makefile1
-rw-r--r--drivers/net/usb/cdc_ether.c33
-rw-r--r--drivers/net/usb/dm9601.c12
-rw-r--r--drivers/net/usb/hso.c53
-rw-r--r--drivers/net/usb/int51x1.c253
-rw-r--r--drivers/net/usb/kaweth.c33
-rw-r--r--drivers/net/usb/rtl8150.c9
-rw-r--r--drivers/net/usb/smsc95xx.c4
-rw-r--r--drivers/net/usb/usbnet.c37
-rw-r--r--drivers/net/veth.c2
-rw-r--r--drivers/net/via-rhine.c58
-rw-r--r--drivers/net/via-velocity.c22
-rw-r--r--drivers/net/via-velocity.h1
-rw-r--r--drivers/net/virtio_net.c24
-rw-r--r--drivers/net/vxge/vxge-config.c12
-rw-r--r--drivers/net/vxge/vxge-main.c6
-rw-r--r--drivers/net/vxge/vxge-traffic.c4
-rw-r--r--drivers/net/wan/cycx_x25.c6
-rw-r--r--drivers/net/wan/dlci.c6
-rw-r--r--drivers/net/wan/hdlc_fr.c1
-rw-r--r--drivers/net/wan/ixp4xx_hss.c4
-rw-r--r--drivers/net/wan/pc300_drv.c20
-rw-r--r--drivers/net/wan/sbni.c2
-rw-r--r--drivers/net/wan/wanxl.c2
-rw-r--r--drivers/net/wimax/i2400m/control.c124
-rw-r--r--drivers/net/wimax/i2400m/driver.c45
-rw-r--r--drivers/net/wimax/i2400m/fw.c58
-rw-r--r--drivers/net/wimax/i2400m/i2400m-sdio.h9
-rw-r--r--drivers/net/wimax/i2400m/i2400m.h48
-rw-r--r--drivers/net/wimax/i2400m/netdev.c4
-rw-r--r--drivers/net/wimax/i2400m/op-rfkill.c4
-rw-r--r--drivers/net/wimax/i2400m/rx.c10
-rw-r--r--drivers/net/wimax/i2400m/sdio-fw.c109
-rw-r--r--drivers/net/wimax/i2400m/sdio-rx.c47
-rw-r--r--drivers/net/wimax/i2400m/sdio.c68
-rw-r--r--drivers/net/wimax/i2400m/tx.c75
-rw-r--r--drivers/net/wimax/i2400m/usb.c5
-rw-r--r--drivers/net/wireless/Kconfig20
-rw-r--r--drivers/net/wireless/Makefile8
-rw-r--r--drivers/net/wireless/adm8211.c14
-rw-r--r--drivers/net/wireless/airo.c9
-rw-r--r--drivers/net/wireless/arlan-main.c2
-rw-r--r--drivers/net/wireless/at76c50x-usb.c19
-rw-r--r--drivers/net/wireless/ath/Kconfig8
-rw-r--r--drivers/net/wireless/ath/Makefile6
-rw-r--r--drivers/net/wireless/ath/ar9170/Kconfig (renamed from drivers/net/wireless/ar9170/Kconfig)1
-rw-r--r--drivers/net/wireless/ath/ar9170/Makefile (renamed from drivers/net/wireless/ar9170/Makefile)0
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h (renamed from drivers/net/wireless/ar9170/ar9170.h)76
-rw-r--r--drivers/net/wireless/ath/ar9170/cmd.c (renamed from drivers/net/wireless/ar9170/cmd.c)0
-rw-r--r--drivers/net/wireless/ath/ar9170/cmd.h (renamed from drivers/net/wireless/ar9170/cmd.h)0
-rw-r--r--drivers/net/wireless/ath/ar9170/eeprom.h (renamed from drivers/net/wireless/ar9170/eeprom.h)0
-rw-r--r--drivers/net/wireless/ath/ar9170/hw.h (renamed from drivers/net/wireless/ar9170/hw.h)23
-rw-r--r--drivers/net/wireless/ath/ar9170/led.c (renamed from drivers/net/wireless/ar9170/led.c)17
-rw-r--r--drivers/net/wireless/ath/ar9170/mac.c (renamed from drivers/net/wireless/ar9170/mac.c)86
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c (renamed from drivers/net/wireless/ar9170/main.c)1411
-rw-r--r--drivers/net/wireless/ath/ar9170/phy.c (renamed from drivers/net/wireless/ar9170/phy.c)6
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c (renamed from drivers/net/wireless/ar9170/usb.c)195
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.h (renamed from drivers/net/wireless/ar9170/usb.h)11
-rw-r--r--drivers/net/wireless/ath/ath5k/Kconfig (renamed from drivers/net/wireless/ath5k/Kconfig)1
-rw-r--r--drivers/net/wireless/ath/ath5k/Makefile (renamed from drivers/net/wireless/ath5k/Makefile)1
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h (renamed from drivers/net/wireless/ath5k/ath5k.h)46
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c (renamed from drivers/net/wireless/ath5k/attach.c)1
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c (renamed from drivers/net/wireless/ath5k/base.c)347
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h (renamed from drivers/net/wireless/ath5k/base.h)13
-rw-r--r--drivers/net/wireless/ath/ath5k/caps.c (renamed from drivers/net/wireless/ath5k/caps.c)0
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c (renamed from drivers/net/wireless/ath5k/debug.c)0
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h (renamed from drivers/net/wireless/ath5k/debug.h)0
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.c (renamed from drivers/net/wireless/ath5k/desc.c)0
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.h (renamed from drivers/net/wireless/ath5k/desc.h)0
-rw-r--r--drivers/net/wireless/ath/ath5k/dma.c (renamed from drivers/net/wireless/ath5k/dma.c)2
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c (renamed from drivers/net/wireless/ath5k/eeprom.c)73
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h (renamed from drivers/net/wireless/ath5k/eeprom.h)46
-rw-r--r--drivers/net/wireless/ath/ath5k/gpio.c (renamed from drivers/net/wireless/ath5k/gpio.c)0
-rw-r--r--drivers/net/wireless/ath/ath5k/initvals.c (renamed from drivers/net/wireless/ath5k/initvals.c)8
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c (renamed from drivers/net/wireless/ath5k/led.c)10
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c (renamed from drivers/net/wireless/ath5k/pcu.c)10
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c (renamed from drivers/net/wireless/ath5k/phy.c)496
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c (renamed from drivers/net/wireless/ath5k/qcu.c)7
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h (renamed from drivers/net/wireless/ath5k/reg.h)9
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c (renamed from drivers/net/wireless/ath5k/reset.c)92
-rw-r--r--drivers/net/wireless/ath/ath5k/rfbuffer.h (renamed from drivers/net/wireless/ath5k/rfbuffer.h)0
-rw-r--r--drivers/net/wireless/ath/ath5k/rfgain.h (renamed from drivers/net/wireless/ath5k/rfgain.h)0
-rw-r--r--drivers/net/wireless/ath/ath5k/rfkill.c121
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig (renamed from drivers/net/wireless/ath9k/Kconfig)1
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile (renamed from drivers/net/wireless/ath9k/Makefile)1
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c (renamed from drivers/net/wireless/ath9k/ahb.c)0
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c (renamed from drivers/net/wireless/ath9k/ani.c)8
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h (renamed from drivers/net/wireless/ath9k/ani.h)0
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h (renamed from drivers/net/wireless/ath9k/ath9k.h)122
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c (renamed from drivers/net/wireless/ath9k/beacon.c)133
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c (renamed from drivers/net/wireless/ath9k/calib.c)129
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h (renamed from drivers/net/wireless/ath9k/calib.h)33
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c (renamed from drivers/net/wireless/ath9k/debug.c)158
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h (renamed from drivers/net/wireless/ath9k/debug.h)35
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c (renamed from drivers/net/wireless/ath9k/eeprom.c)75
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h (renamed from drivers/net/wireless/ath9k/eeprom.h)4
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c (renamed from drivers/net/wireless/ath9k/hw.c)269
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h (renamed from drivers/net/wireless/ath9k/hw.h)95
-rw-r--r--drivers/net/wireless/ath/ath9k/initvals.h (renamed from drivers/net/wireless/ath9k/initvals.h)0
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c (renamed from drivers/net/wireless/ath9k/mac.c)63
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h (renamed from drivers/net/wireless/ath9k/mac.h)0
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c (renamed from drivers/net/wireless/ath9k/main.c)780
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c (renamed from drivers/net/wireless/ath9k/pci.c)15
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.c (renamed from drivers/net/wireless/ath9k/phy.c)11
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h (renamed from drivers/net/wireless/ath9k/phy.h)5
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c (renamed from drivers/net/wireless/ath9k/rc.c)96
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h (renamed from drivers/net/wireless/ath9k/rc.h)4
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c (renamed from drivers/net/wireless/ath9k/recv.c)279
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h (renamed from drivers/net/wireless/ath9k/reg.h)0
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c (renamed from drivers/net/wireless/ath9k/virtual.c)0
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c (renamed from drivers/net/wireless/ath9k/xmit.c)87
-rw-r--r--drivers/net/wireless/ath/main.c22
-rw-r--r--drivers/net/wireless/ath/regd.c (renamed from drivers/net/wireless/ath9k/regd.c)276
-rw-r--r--drivers/net/wireless/ath/regd.h (renamed from drivers/net/wireless/ath9k/regd.h)40
-rw-r--r--drivers/net/wireless/ath/regd_common.h (renamed from drivers/net/wireless/ath9k/regd_common.h)0
-rw-r--r--drivers/net/wireless/atmel.c2
-rw-r--r--drivers/net/wireless/atmel_cs.c2
-rw-r--r--drivers/net/wireless/b43/Kconfig9
-rw-r--r--drivers/net/wireless/b43/Makefile2
-rw-r--r--drivers/net/wireless/b43/b43.h25
-rw-r--r--drivers/net/wireless/b43/dma.c2
-rw-r--r--drivers/net/wireless/b43/leds.c9
-rw-r--r--drivers/net/wireless/b43/main.c232
-rw-r--r--drivers/net/wireless/b43/main.h1
-rw-r--r--drivers/net/wireless/b43/phy_a.c4
-rw-r--r--drivers/net/wireless/b43/phy_common.c17
-rw-r--r--drivers/net/wireless/b43/phy_common.h6
-rw-r--r--drivers/net/wireless/b43/phy_g.c4
-rw-r--r--drivers/net/wireless/b43/phy_lp.c2
-rw-r--r--drivers/net/wireless/b43/phy_n.c2
-rw-r--r--drivers/net/wireless/b43/pio.c2
-rw-r--r--drivers/net/wireless/b43/rfkill.c171
-rw-r--r--drivers/net/wireless/b43/rfkill.h47
-rw-r--r--drivers/net/wireless/b43/xmit.c5
-rw-r--r--drivers/net/wireless/b43legacy/Kconfig10
-rw-r--r--drivers/net/wireless/b43legacy/Makefile2
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h15
-rw-r--r--drivers/net/wireless/b43legacy/leds.c10
-rw-r--r--drivers/net/wireless/b43legacy/main.c346
-rw-r--r--drivers/net/wireless/b43legacy/pio.c2
-rw-r--r--drivers/net/wireless/b43legacy/rfkill.c173
-rw-r--r--drivers/net/wireless/b43legacy/rfkill.h54
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c2
-rw-r--r--drivers/net/wireless/b43legacy/xmit.h4
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c2
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c8
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c57
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c4
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_tx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig5
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c66
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c412
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c95
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c175
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c593
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c1273
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c1189
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h107
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c193
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h69
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c153
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h253
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c233
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.c145
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.h48
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c70
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c214
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c1451
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Kconfig23
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Makefile5
-rw-r--r--drivers/net/wireless/iwmc3200wifi/bus.h57
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c409
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.h31
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c920
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.h419
-rw-r--r--drivers/net/wireless/iwmc3200wifi/debug.h124
-rw-r--r--drivers/net/wireless/iwmc3200wifi/debugfs.c453
-rw-r--r--drivers/net/wireless/iwmc3200wifi/eeprom.c187
-rw-r--r--drivers/net/wireless/iwmc3200wifi/eeprom.h114
-rw-r--r--drivers/net/wireless/iwmc3200wifi/fw.c388
-rw-r--r--drivers/net/wireless/iwmc3200wifi/fw.h100
-rw-r--r--drivers/net/wireless/iwmc3200wifi/hal.c464
-rw-r--r--drivers/net/wireless/iwmc3200wifi/hal.h236
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h346
-rw-r--r--drivers/net/wireless/iwmc3200wifi/lmac.h457
-rw-r--r--drivers/net/wireless/iwmc3200wifi/main.c680
-rw-r--r--drivers/net/wireless/iwmc3200wifi/netdev.c162
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c1431
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.h60
-rw-r--r--drivers/net/wireless/iwmc3200wifi/sdio.c516
-rw-r--r--drivers/net/wireless/iwmc3200wifi/sdio.h67
-rw-r--r--drivers/net/wireless/iwmc3200wifi/tx.c492
-rw-r--r--drivers/net/wireless/iwmc3200wifi/umac.h744
-rw-r--r--drivers/net/wireless/iwmc3200wifi/wext.c723
-rw-r--r--drivers/net/wireless/libertas/11d.c26
-rw-r--r--drivers/net/wireless/libertas/11d.h29
-rw-r--r--drivers/net/wireless/libertas/assoc.c758
-rw-r--r--drivers/net/wireless/libertas/assoc.h13
-rw-r--r--drivers/net/wireless/libertas/cmd.c42
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c17
-rw-r--r--drivers/net/wireless/libertas/debugfs.c8
-rw-r--r--drivers/net/wireless/libertas/defs.h21
-rw-r--r--drivers/net/wireless/libertas/dev.h9
-rw-r--r--drivers/net/wireless/libertas/host.h5
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h69
-rw-r--r--drivers/net/wireless/libertas/if_cs.c34
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c176
-rw-r--r--drivers/net/wireless/libertas/if_sdio.h10
-rw-r--r--drivers/net/wireless/libertas/if_spi.c139
-rw-r--r--drivers/net/wireless/libertas/if_usb.c3
-rw-r--r--drivers/net/wireless/libertas/main.c44
-rw-r--r--drivers/net/wireless/libertas/rx.c48
-rw-r--r--drivers/net/wireless/libertas/scan.c63
-rw-r--r--drivers/net/wireless/libertas/tx.c8
-rw-r--r--drivers/net/wireless/libertas/types.h152
-rw-r--r--drivers/net/wireless/libertas_tf/if_usb.c3
-rw-r--r--drivers/net/wireless/libertas_tf/main.c56
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c105
-rw-r--r--drivers/net/wireless/mwl8k.c20
-rw-r--r--drivers/net/wireless/p54/p54.h74
-rw-r--r--drivers/net/wireless/p54/p54common.c348
-rw-r--r--drivers/net/wireless/p54/p54spi.c175
-rw-r--r--drivers/net/wireless/p54/p54usb.c314
-rw-r--r--drivers/net/wireless/p54/p54usb.h16
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c8
-rw-r--r--drivers/net/wireless/ray_cs.c8
-rw-r--r--drivers/net/wireless/rndis_wlan.c1106
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig17
-rw-r--r--drivers/net/wireless/rt2x00/Makefile2
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c35
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c35
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c22
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c3078
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.h1945
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h57
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c9
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c89
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c134
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00ht.c69
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h65
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c88
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c16
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c48
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h53
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c38
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c34
-rw-r--r--drivers/net/wireless/rtl818x/Makefile2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c33
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187.h7
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c76
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_leds.c218
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_leds.h57
-rw-r--r--drivers/net/wireless/strip.c4
-rw-r--r--drivers/net/wireless/wavelan.c10
-rw-r--r--drivers/net/wireless/wavelan_cs.c5
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig11
-rw-r--r--drivers/net/wireless/wl12xx/Makefile4
-rw-r--r--drivers/net/wireless/wl12xx/acx.c689
-rw-r--r--drivers/net/wireless/wl12xx/acx.h1245
-rw-r--r--drivers/net/wireless/wl12xx/boot.c295
-rw-r--r--drivers/net/wireless/wl12xx/boot.h40
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c353
-rw-r--r--drivers/net/wireless/wl12xx/cmd.h265
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c508
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.h33
-rw-r--r--drivers/net/wireless/wl12xx/event.c127
-rw-r--r--drivers/net/wireless/wl12xx/event.h121
-rw-r--r--drivers/net/wireless/wl12xx/init.c200
-rw-r--r--drivers/net/wireless/wl12xx/init.h40
-rw-r--r--drivers/net/wireless/wl12xx/main.c1358
-rw-r--r--drivers/net/wireless/wl12xx/ps.c151
-rw-r--r--drivers/net/wireless/wl12xx/ps.h36
-rw-r--r--drivers/net/wireless/wl12xx/reg.h745
-rw-r--r--drivers/net/wireless/wl12xx/rx.c208
-rw-r--r--drivers/net/wireless/wl12xx/rx.h122
-rw-r--r--drivers/net/wireless/wl12xx/spi.c358
-rw-r--r--drivers/net/wireless/wl12xx/spi.h109
-rw-r--r--drivers/net/wireless/wl12xx/tx.c557
-rw-r--r--drivers/net/wireless/wl12xx/tx.h215
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.c709
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.h165
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h409
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx_80211.h156
-rw-r--r--drivers/net/wireless/wl3501_cs.c1
-rw-r--r--drivers/net/wireless/zd1201.c8
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c86
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h2
-rw-r--r--drivers/net/yellowfin.c3
623 files changed, 60702 insertions, 35143 deletions
diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c
index 1c5344aa57c..367bec63620 100644
--- a/drivers/net/3c501.c
+++ b/drivers/net/3c501.c
@@ -281,7 +281,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
autoirq = probe_irq_off(irq_mask);
if (autoirq == 0) {
- printk(KERN_WARNING "%s probe at %#x failed to detect IRQ line.\n",
+ pr_warning("%s probe at %#x failed to detect IRQ line.\n",
mname, ioaddr);
release_region(ioaddr, EL1_IO_EXTENT);
return -EAGAIN;
@@ -297,16 +297,16 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
if (autoirq)
dev->irq = autoirq;
- printk(KERN_INFO "%s: %s EtherLink at %#lx, using %sIRQ %d.\n",
+ pr_info("%s: %s EtherLink at %#lx, using %sIRQ %d.\n",
dev->name, mname, dev->base_addr,
autoirq ? "auto":"assigned ", dev->irq);
#ifdef CONFIG_IP_MULTICAST
- printk(KERN_WARNING "WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n");
+ pr_warning("WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n");
#endif
if (el_debug)
- printk(KERN_DEBUG "%s", version);
+ pr_debug("%s", version);
lp = netdev_priv(dev);
memset(lp, 0, sizeof(struct net_local));
@@ -343,7 +343,7 @@ static int el_open(struct net_device *dev)
unsigned long flags;
if (el_debug > 2)
- printk(KERN_DEBUG "%s: Doing el_open()...", dev->name);
+ pr_debug("%s: Doing el_open()...\n", dev->name);
retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev);
if (retval)
@@ -374,7 +374,7 @@ static void el_timeout(struct net_device *dev)
int ioaddr = dev->base_addr;
if (el_debug)
- printk(KERN_DEBUG "%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
+ pr_debug("%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
dev->name, inb(TX_STATUS),
inb(AX_STATUS), inb(RX_STATUS));
dev->stats.tx_errors++;
@@ -483,14 +483,13 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
lp->loading = 0;
dev->trans_start = jiffies;
if (el_debug > 2)
- printk(KERN_DEBUG " queued xmit.\n");
+ pr_debug(" queued xmit.\n");
dev_kfree_skb(skb);
return 0;
}
/* A receive upset our load, despite our best efforts */
if (el_debug > 2)
- printk(KERN_DEBUG "%s: burped during tx load.\n",
- dev->name);
+ pr_debug("%s: burped during tx load.\n", dev->name);
spin_lock_irqsave(&lp->lock, flags);
} while (1);
}
@@ -540,11 +539,10 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
*/
if (el_debug > 3)
- printk(KERN_DEBUG "%s: el_interrupt() aux=%#02x",
- dev->name, axsr);
+ pr_debug("%s: el_interrupt() aux=%#02x\n", dev->name, axsr);
if (lp->loading == 1 && !lp->txing)
- printk(KERN_WARNING "%s: Inconsistent state loading while not in tx\n",
+ pr_warning("%s: Inconsistent state loading while not in tx\n",
dev->name);
if (lp->txing) {
@@ -555,19 +553,17 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
int txsr = inb(TX_STATUS);
if (lp->loading == 1) {
- if (el_debug > 2) {
- printk(KERN_DEBUG "%s: Interrupt while loading [",
- dev->name);
- printk(" txsr=%02x gp=%04x rp=%04x]\n",
- txsr, inw(GP_LOW), inw(RX_LOW));
- }
+ if (el_debug > 2)
+ pr_debug("%s: Interrupt while loading [txsr=%02x gp=%04x rp=%04x]\n",
+ dev->name, txsr, inw(GP_LOW), inw(RX_LOW));
+
/* Force a reload */
lp->loading = 2;
spin_unlock(&lp->lock);
goto out;
}
if (el_debug > 6)
- printk(KERN_DEBUG " txsr=%02x gp=%04x rp=%04x",
+ pr_debug("%s: txsr=%02x gp=%04x rp=%04x\n", dev->name,
txsr, inw(GP_LOW), inw(RX_LOW));
if ((axsr & 0x80) && (txsr & TX_READY) == 0) {
@@ -576,7 +572,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
* on trying or reset immediately ?
*/
if (el_debug > 1)
- printk(KERN_DEBUG "%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x gp=%03x rp=%03x.\n",
+ pr_debug("%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x gp=%03x rp=%03x.\n",
dev->name, txsr, axsr,
inw(ioaddr + EL1_DATAPTR),
inw(ioaddr + EL1_RXPTR));
@@ -587,7 +583,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
* Timed out
*/
if (el_debug)
- printk(KERN_DEBUG "%s: Transmit failed 16 times, Ethernet jammed?\n", dev->name);
+ pr_debug("%s: Transmit failed 16 times, Ethernet jammed?\n", dev->name);
outb(AX_SYS, AX_CMD);
lp->txing = 0;
dev->stats.tx_aborted_errors++;
@@ -598,7 +594,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
*/
if (el_debug > 6)
- printk(KERN_DEBUG " retransmitting after a collision.\n");
+ pr_debug("%s: retransmitting after a collision.\n", dev->name);
/*
* Poor little chip can't reset its own start
* pointer
@@ -616,9 +612,8 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
*/
dev->stats.tx_packets++;
if (el_debug > 6)
- printk(KERN_DEBUG " Tx succeeded %s\n",
- (txsr & TX_RDY) ? "." :
- "but tx is busy!");
+ pr_debug("%s: Tx succeeded %s\n", dev->name,
+ (txsr & TX_RDY) ? "." : "but tx is busy!");
/*
* This is safe the interrupt is atomic WRT itself.
*/
@@ -633,7 +628,8 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
int rxsr = inb(RX_STATUS);
if (el_debug > 5)
- printk(KERN_DEBUG " rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS), inw(RX_LOW));
+ pr_debug("%s: rxsr=%02x txsr=%02x rp=%04x\n",
+ dev->name, rxsr, inb(TX_STATUS), inw(RX_LOW));
/*
* Just reading rx_status fixes most errors.
*/
@@ -643,7 +639,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
/* Handled to avoid board lock-up. */
dev->stats.rx_length_errors++;
if (el_debug > 5)
- printk(KERN_DEBUG " runt.\n");
+ pr_debug("%s: runt.\n", dev->name);
} else if (rxsr & RX_GOOD) {
/*
* Receive worked.
@@ -654,12 +650,10 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
* Nothing? Something is broken!
*/
if (el_debug > 2)
- printk(KERN_DEBUG "%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
+ pr_debug("%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
dev->name, rxsr);
el_reset(dev);
}
- if (el_debug > 3)
- printk(KERN_DEBUG ".\n");
}
/*
@@ -695,11 +689,11 @@ static void el_receive(struct net_device *dev)
pkt_len = inw(RX_LOW);
if (el_debug > 4)
- printk(KERN_DEBUG " el_receive %d.\n", pkt_len);
+ pr_debug(" el_receive %d.\n", pkt_len);
if (pkt_len < 60 || pkt_len > 1536) {
if (el_debug)
- printk(KERN_DEBUG "%s: bogus packet, length=%d\n",
+ pr_debug("%s: bogus packet, length=%d\n",
dev->name, pkt_len);
dev->stats.rx_over_errors++;
return;
@@ -718,8 +712,7 @@ static void el_receive(struct net_device *dev)
outw(0x00, GP_LOW);
if (skb == NULL) {
- printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n",
- dev->name);
+ pr_info("%s: Memory squeeze, dropping packet.\n", dev->name);
dev->stats.rx_dropped++;
return;
} else {
@@ -753,7 +746,7 @@ static void el_reset(struct net_device *dev)
int ioaddr = dev->base_addr;
if (el_debug > 2)
- printk(KERN_INFO "3c501 reset...");
+ pr_info("3c501 reset...\n");
outb(AX_RESET, AX_CMD); /* Reset the chip */
/* Aux control, irq and loopback enabled */
outb(AX_LOOP, AX_CMD);
@@ -787,7 +780,7 @@ static int el1_close(struct net_device *dev)
int ioaddr = dev->base_addr;
if (el_debug > 2)
- printk(KERN_INFO "%s: Shutting down Ethernet card at %#x.\n",
+ pr_info("%s: Shutting down Ethernet card at %#x.\n",
dev->name, ioaddr);
netif_stop_queue(dev);
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index 4f08bd99583..134638a9759 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -234,16 +234,16 @@ el2_probe1(struct net_device *dev, int ioaddr)
}
if (ei_debug && version_printed++ == 0)
- printk(version);
+ pr_debug("%s", version);
dev->base_addr = ioaddr;
- printk("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
+ pr_info("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
/* Retrieve and print the ethernet address. */
for (i = 0; i < 6; i++)
dev->dev_addr[i] = inb(ioaddr + i);
- printk("%pM", dev->dev_addr);
+ pr_cont("%pM", dev->dev_addr);
/* Map the 8390 back into the window. */
outb(ECNTRL_THIN, ioaddr + 0x406);
@@ -256,7 +256,8 @@ el2_probe1(struct net_device *dev, int ioaddr)
outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
/* Probe for, turn on and clear the board's shared memory. */
- if (ei_debug > 2) printk(" memory jumpers %2.2x ", membase_reg);
+ if (ei_debug > 2)
+ pr_cont(" memory jumpers %2.2x ", membase_reg);
outb(EGACFR_NORM, ioaddr + 0x405); /* Enable RAM */
/* This should be probed for (or set via an ioctl()) at run-time.
@@ -268,7 +269,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
#else
ei_status.interface_num = dev->mem_end & 0xf;
#endif
- printk(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");
+ pr_cont(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");
if ((membase_reg & 0xf0) == 0) {
dev->mem_start = 0;
@@ -292,7 +293,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
writel(test_val, mem_base + i);
if (readl(mem_base) != 0xba5eba5e
|| readl(mem_base + i) != test_val) {
- printk("3c503: memory failure or memory address conflict.\n");
+ pr_warning("3c503: memory failure or memory address conflict.\n");
dev->mem_start = 0;
ei_status.name = "3c503-PIO";
iounmap(mem_base);
@@ -344,7 +345,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
if (dev->irq == 2)
dev->irq = 9;
else if (dev->irq > 5 && dev->irq != 9) {
- printk("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
+ pr_warning("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
dev->irq);
dev->irq = 0;
}
@@ -359,7 +360,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
goto out1;
if (dev->mem_start)
- printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
+ pr_info("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
dev->name, ei_status.name, (wordlength+1)<<3,
dev->mem_start, dev->mem_end-1);
@@ -367,7 +368,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
{
ei_status.tx_start_page = EL2_MB1_START_PG;
ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
- printk("\n%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
+ pr_info("%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
dev->name, ei_status.name, (wordlength+1)<<3);
}
release_region(ioaddr + 0x400, 8);
@@ -435,15 +436,16 @@ static void
el2_reset_8390(struct net_device *dev)
{
if (ei_debug > 1) {
- printk("%s: Resetting the 3c503 board...", dev->name);
- printk("%#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
+ pr_debug("%s: Resetting the 3c503 board...", dev->name);
+ pr_cont(" %#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR));
}
outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL);
ei_status.txing = 0;
outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
el2_init_card(dev);
- if (ei_debug > 1) printk("done\n");
+ if (ei_debug > 1)
+ pr_cont("done\n");
}
/* Initialize the 3c503 GA registers after a reset. */
@@ -529,7 +531,7 @@ el2_block_output(struct net_device *dev, int count,
{
if(!boguscount--)
{
- printk("%s: FIFO blocked in el2_block_output.\n", dev->name);
+ pr_notice("%s: FIFO blocked in el2_block_output.\n", dev->name);
el2_reset_8390(dev);
goto blocked;
}
@@ -581,7 +583,7 @@ el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_pag
{
if(!boguscount--)
{
- printk("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
+ pr_notice("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
memset(hdr, 0x00, sizeof(struct e8390_pkt_hdr));
el2_reset_8390(dev);
goto blocked;
@@ -645,7 +647,7 @@ el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring
{
if(!boguscount--)
{
- printk("%s: FIFO blocked in el2_block_input.\n", dev->name);
+ pr_notice("%s: FIFO blocked in el2_block_input.\n", dev->name);
el2_reset_8390(dev);
goto blocked;
}
@@ -707,7 +709,7 @@ init_module(void)
for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
if (io[this_dev] == 0) {
if (this_dev != 0) break; /* only autoprobe 1st one */
- printk(KERN_NOTICE "3c503.c: Presently autoprobing (not recommended) for a single card.\n");
+ pr_notice("3c503.c: Presently autoprobing (not recommended) for a single card.\n");
}
dev = alloc_eip_netdev();
if (!dev)
@@ -720,7 +722,7 @@ init_module(void)
continue;
}
free_netdev(dev);
- printk(KERN_WARNING "3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
+ pr_warning("3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
break;
}
if (found)
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c
index 2de1c9cd7bd..f71b3540275 100644
--- a/drivers/net/3c505.c
+++ b/drivers/net/3c505.c
@@ -126,26 +126,25 @@
*
*********************************************************/
-static const char filename[] = __FILE__;
+#define filename __FILE__
-static const char timeout_msg[] = "*** timeout at %s:%s (line %d) ***\n";
+#define timeout_msg "*** timeout at %s:%s (line %d) ***\n"
#define TIMEOUT_MSG(lineno) \
- printk(timeout_msg, filename,__func__,(lineno))
+ pr_notice(timeout_msg, filename, __func__, (lineno))
-static const char invalid_pcb_msg[] =
-"*** invalid pcb length %d at %s:%s (line %d) ***\n";
+#define invalid_pcb_msg "*** invalid pcb length %d at %s:%s (line %d) ***\n"
#define INVALID_PCB_MSG(len) \
- printk(invalid_pcb_msg, (len),filename,__func__,__LINE__)
+ pr_notice(invalid_pcb_msg, (len), filename, __func__, __LINE__)
-static char search_msg[] __initdata = KERN_INFO "%s: Looking for 3c505 adapter at address %#x...";
+#define search_msg "%s: Looking for 3c505 adapter at address %#x..."
-static char stilllooking_msg[] __initdata = "still looking...";
+#define stilllooking_msg "still looking..."
-static char found_msg[] __initdata = "found.\n";
+#define found_msg "found.\n"
-static char notfound_msg[] __initdata = "not found (reason = %d)\n";
+#define notfound_msg "not found (reason = %d)\n"
-static char couldnot_msg[] __initdata = KERN_INFO "%s: 3c505 not found\n";
+#define couldnot_msg "%s: 3c505 not found\n"
/*********************************************************
*
@@ -284,7 +283,7 @@ static inline void adapter_reset(struct net_device *dev)
outb_control(orig_hcr, dev);
if (!start_receive(dev, &adapter->tx_pcb))
- printk(KERN_ERR "%s: start receive command failed \n", dev->name);
+ pr_err("%s: start receive command failed\n", dev->name);
}
/* Check to make sure that a DMA transfer hasn't timed out. This should
@@ -296,7 +295,9 @@ static inline void check_3c505_dma(struct net_device *dev)
elp_device *adapter = netdev_priv(dev);
if (adapter->dmaing && time_after(jiffies, adapter->current_dma.start_time + 10)) {
unsigned long flags, f;
- printk(KERN_ERR "%s: DMA %s timed out, %d bytes left\n", dev->name, adapter->current_dma.direction ? "download" : "upload", get_dma_residue(dev->dma));
+ pr_err("%s: DMA %s timed out, %d bytes left\n", dev->name,
+ adapter->current_dma.direction ? "download" : "upload",
+ get_dma_residue(dev->dma));
spin_lock_irqsave(&adapter->lock, flags);
adapter->dmaing = 0;
adapter->busy = 0;
@@ -321,7 +322,7 @@ static inline bool send_pcb_slow(unsigned int base_addr, unsigned char byte)
if (inb_status(base_addr) & HCRE)
return false;
}
- printk(KERN_WARNING "3c505: send_pcb_slow timed out\n");
+ pr_warning("3c505: send_pcb_slow timed out\n");
return true;
}
@@ -333,7 +334,7 @@ static inline bool send_pcb_fast(unsigned int base_addr, unsigned char byte)
if (inb_status(base_addr) & HCRE)
return false;
}
- printk(KERN_WARNING "3c505: send_pcb_fast timed out\n");
+ pr_warning("3c505: send_pcb_fast timed out\n");
return true;
}
@@ -386,7 +387,7 @@ static bool send_pcb(struct net_device *dev, pcb_struct * pcb)
/* Avoid contention */
if (test_and_set_bit(1, &adapter->send_pcb_semaphore)) {
if (elp_debug >= 3) {
- printk(KERN_DEBUG "%s: send_pcb entered while threaded\n", dev->name);
+ pr_debug("%s: send_pcb entered while threaded\n", dev->name);
}
return false;
}
@@ -424,14 +425,15 @@ static bool send_pcb(struct net_device *dev, pcb_struct * pcb)
case ASF_PCB_NAK:
#ifdef ELP_DEBUG
- printk(KERN_DEBUG "%s: send_pcb got NAK\n", dev->name);
+ pr_debug("%s: send_pcb got NAK\n", dev->name);
#endif
goto abort;
}
}
if (elp_debug >= 1)
- printk(KERN_DEBUG "%s: timeout waiting for PCB acknowledge (status %02x)\n", dev->name, inb_status(dev->base_addr));
+ pr_debug("%s: timeout waiting for PCB acknowledge (status %02x)\n",
+ dev->name, inb_status(dev->base_addr));
goto abort;
sti_abort:
@@ -481,7 +483,7 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout));
if (time_after_eq(jiffies, timeout)) {
TIMEOUT_MSG(__LINE__);
- printk(KERN_INFO "%s: status %02x\n", dev->name, stat);
+ pr_info("%s: status %02x\n", dev->name, stat);
return false;
}
pcb->length = inb_command(dev->base_addr);
@@ -518,7 +520,7 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
/* safety check total length vs data length */
if (total_length != (pcb->length + 2)) {
if (elp_debug >= 2)
- printk(KERN_WARNING "%s: mangled PCB received\n", dev->name);
+ pr_warning("%s: mangled PCB received\n", dev->name);
set_hsf(dev, HSF_PCB_NAK);
return false;
}
@@ -527,7 +529,7 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
if (test_and_set_bit(0, (void *) &adapter->busy)) {
if (backlog_next(adapter->rx_backlog.in) == adapter->rx_backlog.out) {
set_hsf(dev, HSF_PCB_NAK);
- printk(KERN_WARNING "%s: PCB rejected, transfer in progress and backlog full\n", dev->name);
+ pr_warning("%s: PCB rejected, transfer in progress and backlog full\n", dev->name);
pcb->command = 0;
return true;
} else {
@@ -552,7 +554,7 @@ static bool start_receive(struct net_device *dev, pcb_struct * tx_pcb)
elp_device *adapter = netdev_priv(dev);
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: restarting receiver\n", dev->name);
+ pr_debug("%s: restarting receiver\n", dev->name);
tx_pcb->command = CMD_RECEIVE_PACKET;
tx_pcb->length = sizeof(struct Rcv_pkt);
tx_pcb->data.rcv_pkt.buf_seg
@@ -586,7 +588,7 @@ static void receive_packet(struct net_device *dev, int len)
skb = dev_alloc_skb(rlen + 2);
if (!skb) {
- printk(KERN_WARNING "%s: memory squeeze, dropping packet\n", dev->name);
+ pr_warning("%s: memory squeeze, dropping packet\n", dev->name);
target = adapter->dma_buffer;
adapter->current_dma.target = NULL;
/* FIXME: stats */
@@ -604,7 +606,8 @@ static void receive_packet(struct net_device *dev, int len)
/* if this happens, we die */
if (test_and_set_bit(0, (void *) &adapter->dmaing))
- printk(KERN_ERR "%s: rx blocked, DMA in progress, dir %d\n", dev->name, adapter->current_dma.direction);
+ pr_err("%s: rx blocked, DMA in progress, dir %d\n",
+ dev->name, adapter->current_dma.direction);
adapter->current_dma.direction = 0;
adapter->current_dma.length = rlen;
@@ -623,14 +626,14 @@ static void receive_packet(struct net_device *dev, int len)
release_dma_lock(flags);
if (elp_debug >= 3) {
- printk(KERN_DEBUG "%s: rx DMA transfer started\n", dev->name);
+ pr_debug("%s: rx DMA transfer started\n", dev->name);
}
if (adapter->rx_active)
adapter->rx_active--;
if (!adapter->busy)
- printk(KERN_WARNING "%s: receive_packet called, busy not set.\n", dev->name);
+ pr_warning("%s: receive_packet called, busy not set.\n", dev->name);
}
/******************************************************
@@ -655,12 +658,13 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
* has a DMA transfer finished?
*/
if (inb_status(dev->base_addr) & DONE) {
- if (!adapter->dmaing) {
- printk(KERN_WARNING "%s: phantom DMA completed\n", dev->name);
- }
- if (elp_debug >= 3) {
- printk(KERN_DEBUG "%s: %s DMA complete, status %02x\n", dev->name, adapter->current_dma.direction ? "tx" : "rx", inb_status(dev->base_addr));
- }
+ if (!adapter->dmaing)
+ pr_warning("%s: phantom DMA completed\n", dev->name);
+
+ if (elp_debug >= 3)
+ pr_debug("%s: %s DMA complete, status %02x\n", dev->name,
+ adapter->current_dma.direction ? "tx" : "rx",
+ inb_status(dev->base_addr));
outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
if (adapter->current_dma.direction) {
@@ -682,7 +686,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
int t = adapter->rx_backlog.length[adapter->rx_backlog.out];
adapter->rx_backlog.out = backlog_next(adapter->rx_backlog.out);
if (elp_debug >= 2)
- printk(KERN_DEBUG "%s: receiving backlogged packet (%d)\n", dev->name, t);
+ pr_debug("%s: receiving backlogged packet (%d)\n", dev->name, t);
receive_packet(dev, t);
} else {
adapter->busy = 0;
@@ -713,21 +717,23 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
len = adapter->irx_pcb.data.rcv_resp.pkt_len;
dlen = adapter->irx_pcb.data.rcv_resp.buf_len;
if (adapter->irx_pcb.data.rcv_resp.timeout != 0) {
- printk(KERN_ERR "%s: interrupt - packet not received correctly\n", dev->name);
+ pr_err("%s: interrupt - packet not received correctly\n", dev->name);
} else {
if (elp_debug >= 3) {
- printk(KERN_DEBUG "%s: interrupt - packet received of length %i (%i)\n", dev->name, len, dlen);
+ pr_debug("%s: interrupt - packet received of length %i (%i)\n",
+ dev->name, len, dlen);
}
if (adapter->irx_pcb.command == 0xff) {
if (elp_debug >= 2)
- printk(KERN_DEBUG "%s: adding packet to backlog (len = %d)\n", dev->name, dlen);
+ pr_debug("%s: adding packet to backlog (len = %d)\n",
+ dev->name, dlen);
adapter->rx_backlog.length[adapter->rx_backlog.in] = dlen;
adapter->rx_backlog.in = backlog_next(adapter->rx_backlog.in);
} else {
receive_packet(dev, dlen);
}
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: packet received\n", dev->name);
+ pr_debug("%s: packet received\n", dev->name);
}
break;
@@ -737,7 +743,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
case CMD_CONFIGURE_82586_RESPONSE:
adapter->got[CMD_CONFIGURE_82586] = 1;
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: interrupt - configure response received\n", dev->name);
+ pr_debug("%s: interrupt - configure response received\n", dev->name);
break;
/*
@@ -746,7 +752,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
case CMD_CONFIGURE_ADAPTER_RESPONSE:
adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1;
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: Adapter memory configuration %s.\n", dev->name,
+ pr_debug("%s: Adapter memory configuration %s.\n", dev->name,
adapter->irx_pcb.data.failed ? "failed" : "succeeded");
break;
@@ -756,7 +762,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
case CMD_LOAD_MULTICAST_RESPONSE:
adapter->got[CMD_LOAD_MULTICAST_LIST] = 1;
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: Multicast address list loading %s.\n", dev->name,
+ pr_debug("%s: Multicast address list loading %s.\n", dev->name,
adapter->irx_pcb.data.failed ? "failed" : "succeeded");
break;
@@ -766,7 +772,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
case CMD_SET_ADDRESS_RESPONSE:
adapter->got[CMD_SET_STATION_ADDRESS] = 1;
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: Ethernet address setting %s.\n", dev->name,
+ pr_debug("%s: Ethernet address setting %s.\n", dev->name,
adapter->irx_pcb.data.failed ? "failed" : "succeeded");
break;
@@ -783,7 +789,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
dev->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res;
adapter->got[CMD_NETWORK_STATISTICS] = 1;
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: interrupt - statistics response received\n", dev->name);
+ pr_debug("%s: interrupt - statistics response received\n", dev->name);
break;
/*
@@ -791,17 +797,17 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
*/
case CMD_TRANSMIT_PACKET_COMPLETE:
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: interrupt - packet sent\n", dev->name);
+ pr_debug("%s: interrupt - packet sent\n", dev->name);
if (!netif_running(dev))
break;
switch (adapter->irx_pcb.data.xmit_resp.c_stat) {
case 0xffff:
dev->stats.tx_aborted_errors++;
- printk(KERN_INFO "%s: transmit timed out, network cable problem?\n", dev->name);
+ pr_info("%s: transmit timed out, network cable problem?\n", dev->name);
break;
case 0xfffe:
dev->stats.tx_fifo_errors++;
- printk(KERN_INFO "%s: transmit timed out, FIFO underrun\n", dev->name);
+ pr_info("%s: transmit timed out, FIFO underrun\n", dev->name);
break;
}
netif_wake_queue(dev);
@@ -811,11 +817,12 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
* some unknown PCB
*/
default:
- printk(KERN_DEBUG "%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command);
+ pr_debug("%s: unknown PCB received - %2.2x\n",
+ dev->name, adapter->irx_pcb.command);
break;
}
} else {
- printk(KERN_WARNING "%s: failed to read PCB on interrupt\n", dev->name);
+ pr_warning("%s: failed to read PCB on interrupt\n", dev->name);
adapter_reset(dev);
}
}
@@ -844,13 +851,13 @@ static int elp_open(struct net_device *dev)
int retval;
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: request to open device\n", dev->name);
+ pr_debug("%s: request to open device\n", dev->name);
/*
* make sure we actually found the device
*/
if (adapter == NULL) {
- printk(KERN_ERR "%s: Opening a non-existent physical device\n", dev->name);
+ pr_err("%s: Opening a non-existent physical device\n", dev->name);
return -EAGAIN;
}
/*
@@ -880,17 +887,17 @@ static int elp_open(struct net_device *dev)
* install our interrupt service routine
*/
if ((retval = request_irq(dev->irq, &elp_interrupt, 0, dev->name, dev))) {
- printk(KERN_ERR "%s: could not allocate IRQ%d\n", dev->name, dev->irq);
+ pr_err("%s: could not allocate IRQ%d\n", dev->name, dev->irq);
return retval;
}
if ((retval = request_dma(dev->dma, dev->name))) {
free_irq(dev->irq, dev);
- printk(KERN_ERR "%s: could not allocate DMA%d channel\n", dev->name, dev->dma);
+ pr_err("%s: could not allocate DMA%d channel\n", dev->name, dev->dma);
return retval;
}
adapter->dma_buffer = (void *) dma_mem_alloc(DMA_BUFFER_SIZE);
if (!adapter->dma_buffer) {
- printk(KERN_ERR "%s: could not allocate DMA buffer\n", dev->name);
+ pr_err("%s: could not allocate DMA buffer\n", dev->name);
free_dma(dev->dma);
free_irq(dev->irq, dev);
return -ENOMEM;
@@ -906,7 +913,7 @@ static int elp_open(struct net_device *dev)
* configure adapter memory: we need 10 multicast addresses, default==0
*/
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: sending 3c505 memory configuration command\n", dev->name);
+ pr_debug("%s: sending 3c505 memory configuration command\n", dev->name);
adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY;
adapter->tx_pcb.data.memconf.cmd_q = 10;
adapter->tx_pcb.data.memconf.rcv_q = 20;
@@ -917,7 +924,7 @@ static int elp_open(struct net_device *dev)
adapter->tx_pcb.length = sizeof(struct Memconf);
adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0;
if (!send_pcb(dev, &adapter->tx_pcb))
- printk(KERN_ERR "%s: couldn't send memory configuration command\n", dev->name);
+ pr_err("%s: couldn't send memory configuration command\n", dev->name);
else {
unsigned long timeout = jiffies + TIMEOUT;
while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && time_before(jiffies, timeout));
@@ -930,13 +937,13 @@ static int elp_open(struct net_device *dev)
* configure adapter to receive broadcast messages and wait for response
*/
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: sending 82586 configure command\n", dev->name);
+ pr_debug("%s: sending 82586 configure command\n", dev->name);
adapter->tx_pcb.command = CMD_CONFIGURE_82586;
adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
adapter->tx_pcb.length = 2;
adapter->got[CMD_CONFIGURE_82586] = 0;
if (!send_pcb(dev, &adapter->tx_pcb))
- printk(KERN_ERR "%s: couldn't send 82586 configure command\n", dev->name);
+ pr_err("%s: couldn't send 82586 configure command\n", dev->name);
else {
unsigned long timeout = jiffies + TIMEOUT;
while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout));
@@ -952,7 +959,7 @@ static int elp_open(struct net_device *dev)
*/
prime_rx(dev);
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: %d receive PCBs active\n", dev->name, adapter->rx_active);
+ pr_debug("%s: %d receive PCBs active\n", dev->name, adapter->rx_active);
/*
* device is now officially open!
@@ -982,7 +989,7 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb)
if (test_and_set_bit(0, (void *) &adapter->busy)) {
if (elp_debug >= 2)
- printk(KERN_DEBUG "%s: transmit blocked\n", dev->name);
+ pr_debug("%s: transmit blocked\n", dev->name);
return false;
}
@@ -1004,7 +1011,7 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb)
}
/* if this happens, we die */
if (test_and_set_bit(0, (void *) &adapter->dmaing))
- printk(KERN_DEBUG "%s: tx: DMA %d in progress\n", dev->name, adapter->current_dma.direction);
+ pr_debug("%s: tx: DMA %d in progress\n", dev->name, adapter->current_dma.direction);
adapter->current_dma.direction = 1;
adapter->current_dma.start_time = jiffies;
@@ -1030,7 +1037,7 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb)
release_dma_lock(flags);
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: DMA transfer started\n", dev->name);
+ pr_debug("%s: DMA transfer started\n", dev->name);
return true;
}
@@ -1044,9 +1051,10 @@ static void elp_timeout(struct net_device *dev)
int stat;
stat = inb_status(dev->base_addr);
- printk(KERN_WARNING "%s: transmit timed out, lost %s?\n", dev->name, (stat & ACRF) ? "interrupt" : "command");
+ pr_warning("%s: transmit timed out, lost %s?\n", dev->name,
+ (stat & ACRF) ? "interrupt" : "command");
if (elp_debug >= 1)
- printk(KERN_DEBUG "%s: status %#02x\n", dev->name, stat);
+ pr_debug("%s: status %#02x\n", dev->name, stat);
dev->trans_start = jiffies;
dev->stats.tx_dropped++;
netif_wake_queue(dev);
@@ -1068,7 +1076,7 @@ static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
check_3c505_dma(dev);
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: request to send packet of length %d\n", dev->name, (int) skb->len);
+ pr_debug("%s: request to send packet of length %d\n", dev->name, (int) skb->len);
netif_stop_queue(dev);
@@ -1077,13 +1085,13 @@ static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
*/
if (!send_packet(dev, skb)) {
if (elp_debug >= 2) {
- printk(KERN_DEBUG "%s: failed to transmit packet\n", dev->name);
+ pr_debug("%s: failed to transmit packet\n", dev->name);
}
spin_unlock_irqrestore(&adapter->lock, flags);
- return 1;
+ return NETDEV_TX_BUSY;
}
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: packet of length %d sent\n", dev->name, (int) skb->len);
+ pr_debug("%s: packet of length %d sent\n", dev->name, (int) skb->len);
/*
* start the transmit timeout
@@ -1107,7 +1115,7 @@ static struct net_device_stats *elp_get_stats(struct net_device *dev)
elp_device *adapter = netdev_priv(dev);
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: request for stats\n", dev->name);
+ pr_debug("%s: request for stats\n", dev->name);
/* If the device is closed, just return the latest stats we have,
- we cannot ask from the adapter without interrupts */
@@ -1119,7 +1127,7 @@ static struct net_device_stats *elp_get_stats(struct net_device *dev)
adapter->tx_pcb.length = 0;
adapter->got[CMD_NETWORK_STATISTICS] = 0;
if (!send_pcb(dev, &adapter->tx_pcb))
- printk(KERN_ERR "%s: couldn't send get statistics command\n", dev->name);
+ pr_err("%s: couldn't send get statistics command\n", dev->name);
else {
unsigned long timeout = jiffies + TIMEOUT;
while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && time_before(jiffies, timeout));
@@ -1169,7 +1177,7 @@ static int elp_close(struct net_device *dev)
elp_device *adapter = netdev_priv(dev);
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: request to close device\n", dev->name);
+ pr_debug("%s: request to close device\n", dev->name);
netif_stop_queue(dev);
@@ -1213,7 +1221,7 @@ static void elp_set_mc_list(struct net_device *dev)
unsigned long flags;
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: request to set multicast list\n", dev->name);
+ pr_debug("%s: request to set multicast list\n", dev->name);
spin_lock_irqsave(&adapter->lock, flags);
@@ -1228,7 +1236,7 @@ static void elp_set_mc_list(struct net_device *dev)
}
adapter->got[CMD_LOAD_MULTICAST_LIST] = 0;
if (!send_pcb(dev, &adapter->tx_pcb))
- printk(KERN_ERR "%s: couldn't send set_multicast command\n", dev->name);
+ pr_err("%s: couldn't send set_multicast command\n", dev->name);
else {
unsigned long timeout = jiffies + TIMEOUT;
while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && time_before(jiffies, timeout));
@@ -1247,14 +1255,14 @@ static void elp_set_mc_list(struct net_device *dev)
* and wait for response
*/
if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: sending 82586 configure command\n", dev->name);
+ pr_debug("%s: sending 82586 configure command\n", dev->name);
adapter->tx_pcb.command = CMD_CONFIGURE_82586;
adapter->tx_pcb.length = 2;
adapter->got[CMD_CONFIGURE_82586] = 0;
if (!send_pcb(dev, &adapter->tx_pcb))
{
spin_unlock_irqrestore(&adapter->lock, flags);
- printk(KERN_ERR "%s: couldn't send 82586 configure command\n", dev->name);
+ pr_err("%s: couldn't send 82586 configure command\n", dev->name);
}
else {
unsigned long timeout = jiffies + TIMEOUT;
@@ -1283,17 +1291,17 @@ static int __init elp_sense(struct net_device *dev)
orig_HSR = inb_status(addr);
if (elp_debug > 0)
- printk(search_msg, name, addr);
+ pr_debug(search_msg, name, addr);
if (orig_HSR == 0xff) {
if (elp_debug > 0)
- printk(notfound_msg, 1);
+ pr_cont(notfound_msg, 1);
goto out;
}
/* Wait for a while; the adapter may still be booting up */
if (elp_debug > 0)
- printk(stilllooking_msg);
+ pr_cont(stilllooking_msg);
if (orig_HSR & DIR) {
/* If HCR.DIR is up, we pull it down. HSR.DIR should follow. */
@@ -1301,7 +1309,7 @@ static int __init elp_sense(struct net_device *dev)
msleep(300);
if (inb_status(addr) & DIR) {
if (elp_debug > 0)
- printk(notfound_msg, 2);
+ pr_cont(notfound_msg, 2);
goto out;
}
} else {
@@ -1310,7 +1318,7 @@ static int __init elp_sense(struct net_device *dev)
msleep(300);
if (!(inb_status(addr) & DIR)) {
if (elp_debug > 0)
- printk(notfound_msg, 3);
+ pr_cont(notfound_msg, 3);
goto out;
}
}
@@ -1318,7 +1326,7 @@ static int __init elp_sense(struct net_device *dev)
* It certainly looks like a 3c505.
*/
if (elp_debug > 0)
- printk(found_msg);
+ pr_cont(found_msg);
return 0;
out:
@@ -1349,7 +1357,7 @@ static int __init elp_autodetect(struct net_device *dev)
/* could not find an adapter */
if (elp_debug > 0)
- printk(couldnot_msg, dev->name);
+ pr_debug(couldnot_msg, dev->name);
return 0; /* Because of this, the layer above will return -ENODEV */
}
@@ -1424,16 +1432,16 @@ static int __init elplus_setup(struct net_device *dev)
/* Nope, it's ignoring the command register. This means that
* either it's still booting up, or it's died.
*/
- printk(KERN_ERR "%s: command register wouldn't drain, ", dev->name);
+ pr_err("%s: command register wouldn't drain, ", dev->name);
if ((inb_status(dev->base_addr) & 7) == 3) {
/* If the adapter status is 3, it *could* still be booting.
* Give it the benefit of the doubt for 10 seconds.
*/
- printk("assuming 3c505 still starting\n");
+ pr_cont("assuming 3c505 still starting\n");
timeout = jiffies + 10*HZ;
while (time_before(jiffies, timeout) && (inb_status(dev->base_addr) & 7));
if (inb_status(dev->base_addr) & 7) {
- printk(KERN_ERR "%s: 3c505 failed to start\n", dev->name);
+ pr_err("%s: 3c505 failed to start\n", dev->name);
} else {
okay = 1; /* It started */
}
@@ -1441,7 +1449,7 @@ static int __init elplus_setup(struct net_device *dev)
/* Otherwise, it must just be in a strange
* state. We probably need to kick it.
*/
- printk("3c505 is sulking\n");
+ pr_cont("3c505 is sulking\n");
}
}
for (tries = 0; tries < 5 && okay; tries++) {
@@ -1454,18 +1462,19 @@ static int __init elplus_setup(struct net_device *dev)
adapter->tx_pcb.length = 0;
cookie = probe_irq_on();
if (!send_pcb(dev, &adapter->tx_pcb)) {
- printk(KERN_ERR "%s: could not send first PCB\n", dev->name);
+ pr_err("%s: could not send first PCB\n", dev->name);
probe_irq_off(cookie);
continue;
}
if (!receive_pcb(dev, &adapter->rx_pcb)) {
- printk(KERN_ERR "%s: could not read first PCB\n", dev->name);
+ pr_err("%s: could not read first PCB\n", dev->name);
probe_irq_off(cookie);
continue;
}
if ((adapter->rx_pcb.command != CMD_ADDRESS_RESPONSE) ||
(adapter->rx_pcb.length != 6)) {
- printk(KERN_ERR "%s: first PCB wrong (%d, %d)\n", dev->name, adapter->rx_pcb.command, adapter->rx_pcb.length);
+ pr_err("%s: first PCB wrong (%d, %d)\n", dev->name,
+ adapter->rx_pcb.command, adapter->rx_pcb.length);
probe_irq_off(cookie);
continue;
}
@@ -1474,32 +1483,32 @@ static int __init elplus_setup(struct net_device *dev)
/* It's broken. Do a hard reset to re-initialise the board,
* and try again.
*/
- printk(KERN_INFO "%s: resetting adapter\n", dev->name);
+ pr_info("%s: resetting adapter\n", dev->name);
outb_control(adapter->hcr_val | FLSH | ATTN, dev);
outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev);
}
- printk(KERN_ERR "%s: failed to initialise 3c505\n", dev->name);
+ pr_err("%s: failed to initialise 3c505\n", dev->name);
goto out;
okay:
if (dev->irq) { /* Is there a preset IRQ? */
int rpt = probe_irq_off(cookie);
if (dev->irq != rpt) {
- printk(KERN_WARNING "%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt);
+ pr_warning("%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt);
}
/* if dev->irq == probe_irq_off(cookie), all is well */
} else /* No preset IRQ; just use what we can detect */
dev->irq = probe_irq_off(cookie);
switch (dev->irq) { /* Legal, sane? */
case 0:
- printk(KERN_ERR "%s: IRQ probe failed: check 3c505 jumpers.\n",
+ pr_err("%s: IRQ probe failed: check 3c505 jumpers.\n",
dev->name);
goto out;
case 1:
case 6:
case 8:
case 13:
- printk(KERN_ERR "%s: Impossible IRQ %d reported by probe_irq_off().\n",
+ pr_err("%s: Impossible IRQ %d reported by probe_irq_off().\n",
dev->name, dev->irq);
goto out;
}
@@ -1521,7 +1530,7 @@ static int __init elplus_setup(struct net_device *dev)
dev->dma = dev->mem_start & 7;
}
else {
- printk(KERN_WARNING "%s: warning, DMA channel not specified, using default\n", dev->name);
+ pr_warning("%s: warning, DMA channel not specified, using default\n", dev->name);
dev->dma = ELP_DMA;
}
}
@@ -1529,11 +1538,8 @@ static int __init elplus_setup(struct net_device *dev)
/*
* print remainder of startup message
*/
- printk(KERN_INFO "%s: 3c505 at %#lx, irq %d, dma %d, "
- "addr %pM, ",
- dev->name, dev->base_addr, dev->irq, dev->dma,
- dev->dev_addr);
-
+ pr_info("%s: 3c505 at %#lx, irq %d, dma %d, addr %pM, ",
+ dev->name, dev->base_addr, dev->irq, dev->dma, dev->dev_addr);
/*
* read more information from the adapter
*/
@@ -1544,9 +1550,10 @@ static int __init elplus_setup(struct net_device *dev)
!receive_pcb(dev, &adapter->rx_pcb) ||
(adapter->rx_pcb.command != CMD_ADAPTER_INFO_RESPONSE) ||
(adapter->rx_pcb.length != 10)) {
- printk("not responding to second PCB\n");
+ pr_cont("not responding to second PCB\n");
}
- printk("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers, adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz);
+ pr_cont("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers,
+ adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz);
/*
* reconfigure the adapter memory to better suit our purposes
@@ -1563,10 +1570,10 @@ static int __init elplus_setup(struct net_device *dev)
!receive_pcb(dev, &adapter->rx_pcb) ||
(adapter->rx_pcb.command != CMD_CONFIGURE_ADAPTER_RESPONSE) ||
(adapter->rx_pcb.length != 2)) {
- printk(KERN_ERR "%s: could not configure adapter memory\n", dev->name);
+ pr_err("%s: could not configure adapter memory\n", dev->name);
}
if (adapter->rx_pcb.data.configure) {
- printk(KERN_ERR "%s: adapter configuration failed\n", dev->name);
+ pr_err("%s: adapter configuration failed\n", dev->name);
}
dev->netdev_ops = &elp_netdev_ops;
@@ -1631,17 +1638,17 @@ int __init init_module(void)
dev->dma = dma[this_dev];
} else {
dev->dma = ELP_DMA;
- printk(KERN_WARNING "3c505.c: warning, using default DMA channel,\n");
+ pr_warning("3c505.c: warning, using default DMA channel,\n");
}
if (io[this_dev] == 0) {
if (this_dev) {
free_netdev(dev);
break;
}
- printk(KERN_NOTICE "3c505.c: module autoprobe not recommended, give io=xx.\n");
+ pr_notice("3c505.c: module autoprobe not recommended, give io=xx.\n");
}
if (elplus_setup(dev) != 0) {
- printk(KERN_WARNING "3c505.c: Failed to register card at 0x%x.\n", io[this_dev]);
+ pr_warning("3c505.c: Failed to register card at 0x%x.\n", io[this_dev]);
free_netdev(dev);
break;
}
diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c
index fbbaf826def..96b86659381 100644
--- a/drivers/net/3c507.c
+++ b/drivers/net/3c507.c
@@ -364,7 +364,7 @@ static const struct net_device_ops netdev_ops = {
static int __init el16_probe1(struct net_device *dev, int ioaddr)
{
- static unsigned char init_ID_done, version_printed;
+ static unsigned char init_ID_done;
int i, irq, irqval, retval;
struct net_local *lp;
@@ -391,10 +391,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
goto out;
}
- if (net_debug && version_printed++ == 0)
- printk(version);
-
- printk("%s: 3c507 at %#x,", dev->name, ioaddr);
+ pr_info("%s: 3c507 at %#x,", dev->name, ioaddr);
/* We should make a few more checks here, like the first three octets of
the S.A. for the manufacturer's code. */
@@ -403,7 +400,8 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
irqval = request_irq(irq, &el16_interrupt, 0, DRV_NAME, dev);
if (irqval) {
- printk(KERN_ERR "3c507: unable to get IRQ %d (irqval=%d).\n", irq, irqval);
+ pr_cont("\n");
+ pr_err("3c507: unable to get IRQ %d (irqval=%d).\n", irq, irqval);
retval = -EAGAIN;
goto out;
}
@@ -414,7 +412,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
outb(0x01, ioaddr + MISC_CTRL);
for (i = 0; i < 6; i++)
dev->dev_addr[i] = inb(ioaddr + i);
- printk(" %pM", dev->dev_addr);
+ pr_cont(" %pM", dev->dev_addr);
if (mem_start)
net_debug = mem_start & 7;
@@ -443,18 +441,18 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
dev->if_port = (inb(ioaddr + ROM_CONFIG) & 0x80) ? 1 : 0;
dev->irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
- printk(", IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->irq,
+ pr_cont(", IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->irq,
dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1);
if (net_debug)
- printk(version);
+ pr_debug("%s", version);
lp = netdev_priv(dev);
memset(lp, 0, sizeof(*lp));
spin_lock_init(&lp->lock);
lp->base = ioremap(dev->mem_start, RX_BUF_END);
if (!lp->base) {
- printk(KERN_ERR "3c507: unable to remap memory\n");
+ pr_err("3c507: unable to remap memory\n");
retval = -EAGAIN;
goto out1;
}
@@ -488,20 +486,20 @@ static void el16_tx_timeout (struct net_device *dev)
void __iomem *shmem = lp->base;
if (net_debug > 1)
- printk ("%s: transmit timed out, %s? ", dev->name,
+ pr_debug("%s: transmit timed out, %s? ", dev->name,
readw(shmem + iSCB_STATUS) & 0x8000 ? "IRQ conflict" :
"network cable problem");
/* Try to restart the adaptor. */
if (lp->last_restart == dev->stats.tx_packets) {
if (net_debug > 1)
- printk ("Resetting board.\n");
+ pr_cont("Resetting board.\n");
/* Completely reset the adaptor. */
init_82586_mem (dev);
lp->tx_pkts_in_ring = 0;
} else {
/* Issue the channel attention signal and hope it "gets better". */
if (net_debug > 1)
- printk ("Kicking board.\n");
+ pr_cont("Kicking board.\n");
writew(0xf000 | CUC_START | RX_START, shmem + iSCB_CMD);
outb (0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */
lp->last_restart = dev->stats.tx_packets;
@@ -553,7 +551,8 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
void __iomem *shmem;
if (dev == NULL) {
- printk ("net_interrupt(): irq %d for unknown device.\n", irq);
+ pr_err("%s: net_interrupt(): irq %d for unknown device.\n",
+ dev->name, irq);
return IRQ_NONE;
}
@@ -566,7 +565,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
status = readw(shmem+iSCB_STATUS);
if (net_debug > 4) {
- printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
+ pr_debug("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
}
/* Disable the 82586's input to the interrupt line. */
@@ -577,7 +576,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
unsigned short tx_status = readw(shmem+lp->tx_reap);
if (!(tx_status & 0x8000)) {
if (net_debug > 5)
- printk("Tx command incomplete (%#x).\n", lp->tx_reap);
+ pr_debug("Tx command incomplete (%#x).\n", lp->tx_reap);
break;
}
/* Tx unsuccessful or some interesting status bit set. */
@@ -591,7 +590,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
}
dev->stats.tx_packets++;
if (net_debug > 5)
- printk("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
+ pr_debug("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
lp->tx_reap += TX_BUF_SIZE;
if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE)
lp->tx_reap = TX_BUF_START;
@@ -606,7 +605,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
if (status & 0x4000) { /* Packet received. */
if (net_debug > 5)
- printk("Received packet, rx_head %04x.\n", lp->rx_head);
+ pr_debug("Received packet, rx_head %04x.\n", lp->rx_head);
el16_rx(dev);
}
@@ -615,7 +614,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
if ((status & 0x0700) != 0x0200 && netif_running(dev)) {
if (net_debug)
- printk("%s: Command unit stopped, status %04x, restarting.\n",
+ pr_debug("%s: Command unit stopped, status %04x, restarting.\n",
dev->name, status);
/* If this ever occurs we should really re-write the idle loop, reset
the Tx list, and do a complete restart of the command unit.
@@ -627,7 +626,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
/* The Rx unit is not ready, it must be hung. Restart the receiver by
initializing the rx buffers, and issuing an Rx start command. */
if (net_debug)
- printk("%s: Rx unit stopped, status %04x, restarting.\n",
+ pr_debug("%s: Rx unit stopped, status %04x, restarting.\n",
dev->name, status);
init_rx_bufs(dev);
writew(RX_BUF_START,shmem+iSCB_RFA);
@@ -753,9 +752,8 @@ static void init_82586_mem(struct net_device *dev)
int boguscnt = 50;
while (readw(shmem+iSCB_STATUS) == 0)
if (--boguscnt == 0) {
- printk("%s: i82586 initialization timed out with status %04x, "
- "cmd %04x.\n", dev->name,
- readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD));
+ pr_warning("%s: i82586 initialization timed out with status %04x, cmd %04x.\n",
+ dev->name, readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD));
break;
}
/* Issue channel-attn -- the 82586 won't start. */
@@ -765,7 +763,7 @@ static void init_82586_mem(struct net_device *dev)
/* Disable loopback and enable interrupts. */
outb(0x84, ioaddr + MISC_CTRL);
if (net_debug > 4)
- printk("%s: Initialized 82586, status %04x.\n", dev->name,
+ pr_debug("%s: Initialized 82586, status %04x.\n", dev->name,
readw(shmem+iSCB_STATUS));
return;
}
@@ -810,7 +808,7 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length
lp->tx_head = TX_BUF_START;
if (net_debug > 4) {
- printk("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n",
+ pr_debug("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n",
dev->name, ioaddr, length, tx_block, lp->tx_head);
}
@@ -838,7 +836,7 @@ static void el16_rx(struct net_device *dev)
if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
|| (pkt_len & 0xC000) != 0xC000) {
- printk(KERN_ERR "%s: Rx frame at %#x corrupted, "
+ pr_err("%s: Rx frame at %#x corrupted, "
"status %04x cmd %04x next %04x "
"data-buf @%04x %04x.\n",
dev->name, rx_head, frame_status, rfd_cmd,
@@ -858,8 +856,7 @@ static void el16_rx(struct net_device *dev)
pkt_len &= 0x3fff;
skb = dev_alloc_skb(pkt_len+2);
if (skb == NULL) {
- printk(KERN_ERR "%s: Memory squeeze, "
- "dropping packet.\n",
+ pr_err("%s: Memory squeeze, dropping packet.\n",
dev->name);
dev->stats.rx_dropped++;
break;
@@ -926,7 +923,7 @@ MODULE_PARM_DESC(irq, "(ignored)");
int __init init_module(void)
{
if (io == 0)
- printk("3c507: You should not use auto-probing with insmod!\n");
+ pr_notice("3c507: You should not use auto-probing with insmod!\n");
dev_3c507 = el16_probe(-1);
return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
}
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index 682aad89708..d2137efbd45 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -257,7 +257,7 @@ static int el3_isa_id_sequence(__be16 *phys_addr)
&& !memcmp(phys_addr, el3_devs[i]->dev_addr,
ETH_ALEN)) {
if (el3_debug > 3)
- printk(KERN_DEBUG "3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
+ pr_debug("3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
phys_addr[0] & 0xff, phys_addr[0] >> 8,
phys_addr[1] & 0xff, phys_addr[1] >> 8,
phys_addr[2] & 0xff, phys_addr[2] >> 8);
@@ -578,19 +578,18 @@ static int __devinit el3_common_init(struct net_device *dev)
err = register_netdev(dev);
if (err) {
- printk(KERN_ERR "Failed to register 3c5x9 at %#3.3lx, IRQ %d.\n",
+ pr_err("Failed to register 3c5x9 at %#3.3lx, IRQ %d.\n",
dev->base_addr, dev->irq);
release_region(dev->base_addr, EL3_IO_EXTENT);
return err;
}
- printk(KERN_INFO "%s: 3c5x9 found at %#3.3lx, %s port, "
- "address %pM, IRQ %d.\n",
+ pr_info("%s: 3c5x9 found at %#3.3lx, %s port, address %pM, IRQ %d.\n",
dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)],
dev->dev_addr, dev->irq);
if (el3_debug > 0)
- printk(KERN_INFO "%s", version);
+ pr_info("%s", version);
return 0;
}
@@ -629,8 +628,8 @@ static int __init el3_mca_probe(struct device *device)
irq = pos5 & 0x0f;
- printk(KERN_INFO "3c529: found %s at slot %d\n",
- el3_mca_adapter_names[mdev->index], slot + 1);
+ pr_info("3c529: found %s at slot %d\n",
+ el3_mca_adapter_names[mdev->index], slot + 1);
/* claim the slot */
strncpy(mdev->name, el3_mca_adapter_names[mdev->index],
@@ -642,7 +641,7 @@ static int __init el3_mca_probe(struct device *device)
irq = mca_device_transform_irq(mdev, irq);
ioaddr = mca_device_transform_ioport(mdev, ioaddr);
if (el3_debug > 2) {
- printk(KERN_DEBUG "3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port);
+ pr_debug("3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port);
}
EL3WINDOW(0);
for (i = 0; i < 3; i++)
@@ -657,11 +656,11 @@ static int __init el3_mca_probe(struct device *device)
netdev_boot_setup_check(dev);
el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_MCA);
- device->driver_data = dev;
+ dev_set_drvdata(device, dev);
err = el3_common_init(dev);
if (err) {
- device->driver_data = NULL;
+ dev_set_drvdata(device, NULL);
free_netdev(dev);
return -ENOMEM;
}
@@ -725,12 +724,12 @@ static int __init el3_eisa_probe (struct device *device)
/* This remove works for all device types.
*
- * The net dev must be stored in the driver_data field */
+ * The net dev must be stored in the driver data field */
static int __devexit el3_device_remove (struct device *device)
{
struct net_device *dev;
- dev = device->driver_data;
+ dev = dev_get_drvdata(device);
el3_common_remove (dev);
return 0;
@@ -765,7 +764,7 @@ static ushort id_read_eeprom(int index)
word = (word << 1) + (inb(id_port) & 0x01);
if (el3_debug > 3)
- printk(KERN_DEBUG " 3c509 EEPROM word %d %#4.4x.\n", index, word);
+ pr_debug(" 3c509 EEPROM word %d %#4.4x.\n", index, word);
return word;
}
@@ -787,13 +786,13 @@ el3_open(struct net_device *dev)
EL3WINDOW(0);
if (el3_debug > 3)
- printk(KERN_DEBUG "%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name,
+ pr_debug("%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name,
dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
el3_up(dev);
if (el3_debug > 3)
- printk(KERN_DEBUG "%s: Opened 3c509 IRQ %d status %4.4x.\n",
+ pr_debug("%s: Opened 3c509 IRQ %d status %4.4x.\n",
dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
return 0;
@@ -805,8 +804,7 @@ el3_tx_timeout (struct net_device *dev)
int ioaddr = dev->base_addr;
/* Transmitter timeout, serious problems. */
- printk(KERN_WARNING "%s: transmit timed out, Tx_status %2.2x status %4.4x "
- "Tx FIFO room %d.\n",
+ pr_warning("%s: transmit timed out, Tx_status %2.2x status %4.4x Tx FIFO room %d.\n",
dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
inw(ioaddr + TX_FREE));
dev->stats.tx_errors++;
@@ -830,7 +828,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->stats.tx_bytes += skb->len;
if (el3_debug > 4) {
- printk(KERN_DEBUG "%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
+ pr_debug("%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
dev->name, skb->len, inw(ioaddr + EL3_STATUS));
}
#if 0
@@ -839,7 +837,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
ushort status = inw(ioaddr + EL3_STATUS);
if (status & 0x0001 /* IRQ line active, missed one. */
&& inw(ioaddr + EL3_STATUS) & 1) { /* Make sure. */
- printk(KERN_DEBUG "%s: Missed interrupt, status then %04x now %04x"
+ pr_debug("%s: Missed interrupt, status then %04x now %04x"
" Tx %2.2x Rx %4.4x.\n", dev->name, status,
inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
inw(ioaddr + RX_STATUS));
@@ -913,7 +911,7 @@ el3_interrupt(int irq, void *dev_id)
if (el3_debug > 4) {
status = inw(ioaddr + EL3_STATUS);
- printk(KERN_DEBUG "%s: interrupt, status %4.4x.\n", dev->name, status);
+ pr_debug("%s: interrupt, status %4.4x.\n", dev->name, status);
}
while ((status = inw(ioaddr + EL3_STATUS)) &
@@ -924,7 +922,7 @@ el3_interrupt(int irq, void *dev_id)
if (status & TxAvailable) {
if (el3_debug > 5)
- printk(KERN_DEBUG " TX room bit was handled.\n");
+ pr_debug(" TX room bit was handled.\n");
/* There's room in the FIFO for a full-sized packet. */
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
netif_wake_queue (dev);
@@ -962,7 +960,7 @@ el3_interrupt(int irq, void *dev_id)
}
if (--i < 0) {
- printk(KERN_ERR "%s: Infinite loop in interrupt, status %4.4x.\n",
+ pr_err("%s: Infinite loop in interrupt, status %4.4x.\n",
dev->name, status);
/* Clear all interrupts. */
outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
@@ -973,7 +971,7 @@ el3_interrupt(int irq, void *dev_id)
}
if (el3_debug > 4) {
- printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n", dev->name,
+ pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name,
inw(ioaddr + EL3_STATUS));
}
spin_unlock(&lp->lock);
@@ -1021,7 +1019,7 @@ static void update_stats(struct net_device *dev)
int ioaddr = dev->base_addr;
if (el3_debug > 5)
- printk(" Updating the statistics.\n");
+ pr_debug(" Updating the statistics.\n");
/* Turn off statistics updates while reading. */
outw(StatsDisable, ioaddr + EL3_CMD);
/* Switch to the stats window, and read everything. */
@@ -1051,7 +1049,7 @@ el3_rx(struct net_device *dev)
short rx_status;
if (el3_debug > 5)
- printk(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
+ pr_debug(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {
if (rx_status & 0x4000) { /* Error, update stats. */
@@ -1073,7 +1071,7 @@ el3_rx(struct net_device *dev)
skb = dev_alloc_skb(pkt_len+5);
if (el3_debug > 4)
- printk("Receiving packet size %d status %4.4x.\n",
+ pr_debug("Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status);
if (skb != NULL) {
skb_reserve(skb, 2); /* Align IP on 16 byte */
@@ -1092,12 +1090,12 @@ el3_rx(struct net_device *dev)
outw(RxDiscard, ioaddr + EL3_CMD);
dev->stats.rx_dropped++;
if (el3_debug)
- printk("%s: Couldn't allocate a sk_buff of size %d.\n",
+ pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n",
dev->name, pkt_len);
}
inw(ioaddr + EL3_STATUS); /* Delay. */
while (inw(ioaddr + EL3_STATUS) & 0x1000)
- printk(KERN_DEBUG " Waiting for 3c509 to discard packet, status %x.\n",
+ pr_debug(" Waiting for 3c509 to discard packet, status %x.\n",
inw(ioaddr + EL3_STATUS) );
}
@@ -1118,7 +1116,7 @@ set_multicast_list(struct net_device *dev)
static int old;
if (old != dev->mc_count) {
old = dev->mc_count;
- printk("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
+ pr_debug("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
}
}
spin_lock_irqsave(&lp->lock, flags);
@@ -1141,7 +1139,7 @@ el3_close(struct net_device *dev)
struct el3_private *lp = netdev_priv(dev);
if (el3_debug > 2)
- printk("%s: Shutting down ethercard.\n", dev->name);
+ pr_debug("%s: Shutting down ethercard.\n", dev->name);
el3_down(dev);
@@ -1388,30 +1386,30 @@ el3_up(struct net_device *dev)
EL3WINDOW(4);
net_diag = inw(ioaddr + WN4_NETDIAG);
net_diag = (net_diag | FD_ENABLE); /* temporarily assume full-duplex will be set */
- printk("%s: ", dev->name);
+ pr_info("%s: ", dev->name);
switch (dev->if_port & 0x0c) {
case 12:
/* force full-duplex mode if 3c5x9b */
if (sw_info & 0x000f) {
- printk("Forcing 3c5x9b full-duplex mode");
+ pr_cont("Forcing 3c5x9b full-duplex mode");
break;
}
case 8:
/* set full-duplex mode based on eeprom config setting */
if ((sw_info & 0x000f) && (sw_info & 0x8000)) {
- printk("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)");
+ pr_cont("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)");
break;
}
default:
/* xcvr=(0 || 4) OR user has an old 3c5x9 non "B" model */
- printk("Setting 3c5x9/3c5x9B half-duplex mode");
+ pr_cont("Setting 3c5x9/3c5x9B half-duplex mode");
net_diag = (net_diag & ~FD_ENABLE); /* disable full duplex */
}
outw(net_diag, ioaddr + WN4_NETDIAG);
- printk(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info);
+ pr_cont(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info);
if (el3_debug > 3)
- printk("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag);
+ pr_debug("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag);
/* Enable link beat and jabber check. */
outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
}
@@ -1455,7 +1453,7 @@ el3_suspend(struct device *pdev, pm_message_t state)
struct el3_private *lp;
int ioaddr;
- dev = pdev->driver_data;
+ dev = dev_get_drvdata(pdev);
lp = netdev_priv(dev);
ioaddr = dev->base_addr;
@@ -1479,7 +1477,7 @@ el3_resume(struct device *pdev)
struct el3_private *lp;
int ioaddr;
- dev = pdev->driver_data;
+ dev = dev_get_drvdata(pdev);
lp = netdev_priv(dev);
ioaddr = dev->base_addr;
@@ -1539,7 +1537,7 @@ static int __init el3_init_module(void)
}
if (id_port >= 0x200) {
id_port = 0;
- printk(KERN_ERR "No I/O port available for 3c509 activation.\n");
+ pr_err("No I/O port available for 3c509 activation.\n");
} else {
ret = isa_register_driver(&el3_isa_driver, EL3_MAX_CARDS);
if (!ret)
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
index 167bf23066e..3e00fa8ea65 100644
--- a/drivers/net/3c515.c
+++ b/drivers/net/3c515.c
@@ -420,7 +420,7 @@ int init_module(void)
if (debug >= 0)
corkscrew_debug = debug;
if (corkscrew_debug)
- printk(version);
+ pr_debug("%s", version);
while (corkscrew_scan(-1))
found++;
return found ? 0 : -ENODEV;
@@ -437,7 +437,7 @@ struct net_device *tc515_probe(int unit)
if (corkscrew_debug > 0 && !printed) {
printed = 1;
- printk(version);
+ pr_debug("%s", version);
}
return dev;
@@ -516,7 +516,7 @@ static struct net_device *corkscrew_scan(int unit)
if (pnp_device_attach(idev) < 0)
continue;
if (pnp_activate_dev(idev) < 0) {
- printk("pnp activate failed (out of resources?)\n");
+ pr_warning("pnp activate failed (out of resources?)\n");
pnp_device_detach(idev);
continue;
}
@@ -531,9 +531,9 @@ static struct net_device *corkscrew_scan(int unit)
continue;
}
if(corkscrew_debug)
- printk ("ISAPNP reports %s at i/o 0x%x, irq %d\n",
+ pr_debug("ISAPNP reports %s at i/o 0x%x, irq %d\n",
(char*) corkscrew_isapnp_adapters[i].driver_data, ioaddr, irq);
- printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
+ pr_info("3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
/* irq = inw(ioaddr + 0x2002) & 15; */ /* Use the irq from isapnp */
SET_NETDEV_DEV(dev, &idev->dev);
@@ -552,7 +552,7 @@ no_pnp:
if (!check_device(ioaddr))
continue;
- printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
+ pr_info("3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
err = corkscrew_setup(dev, ioaddr, NULL, cards_found++);
if (!err)
@@ -625,7 +625,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
list_add(&vp->list, &root_corkscrew_dev);
#endif
- printk(KERN_INFO "%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
+ pr_info("%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
spin_lock_init(&vp->lock);
@@ -648,19 +648,19 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
}
checksum = (checksum ^ (checksum >> 8)) & 0xff;
if (checksum != 0x00)
- printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
- printk(" %pM", dev->dev_addr);
+ pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
+ pr_cont(" %pM", dev->dev_addr);
if (eeprom[16] == 0x11c7) { /* Corkscrew */
if (request_dma(dev->dma, "3c515")) {
- printk(", DMA %d allocation failed", dev->dma);
+ pr_cont(", DMA %d allocation failed", dev->dma);
dev->dma = 0;
} else
- printk(", DMA %d", dev->dma);
+ pr_cont(", DMA %d", dev->dma);
}
- printk(", IRQ %d\n", dev->irq);
+ pr_cont(", IRQ %d\n", dev->irq);
/* Tell them about an invalid IRQ. */
if (corkscrew_debug && (dev->irq <= 0 || dev->irq > 15))
- printk(KERN_WARNING " *** Warning: this IRQ is unlikely to work! ***\n");
+ pr_warning(" *** Warning: this IRQ is unlikely to work! ***\n");
{
char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" };
@@ -669,9 +669,9 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
vp->available_media = inw(ioaddr + Wn3_Options);
config = inl(ioaddr + Wn3_Config);
if (corkscrew_debug > 1)
- printk(KERN_INFO " Internal config register is %4.4x, transceivers %#x.\n",
+ pr_info(" Internal config register is %4.4x, transceivers %#x.\n",
config, inw(ioaddr + Wn3_Options));
- printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
+ pr_info(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
8 << config & Ram_size,
config & Ram_width ? "word" : "byte",
ram_split[(config & Ram_split) >> Ram_split_shift],
@@ -682,7 +682,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
dev->if_port = vp->default_media;
}
if (vp->media_override != 7) {
- printk(KERN_INFO " Media override to transceiver type %d (%s).\n",
+ pr_info(" Media override to transceiver type %d (%s).\n",
vp->media_override,
media_tbl[vp->media_override].name);
dev->if_port = vp->media_override;
@@ -718,7 +718,7 @@ static int corkscrew_open(struct net_device *dev)
if (vp->media_override != 7) {
if (corkscrew_debug > 1)
- printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
+ pr_info("%s: Media override to transceiver %d (%s).\n",
dev->name, vp->media_override,
media_tbl[vp->media_override].name);
dev->if_port = vp->media_override;
@@ -729,7 +729,7 @@ static int corkscrew_open(struct net_device *dev)
dev->if_port = media_tbl[dev->if_port].next;
if (corkscrew_debug > 1)
- printk("%s: Initial media type %s.\n",
+ pr_debug("%s: Initial media type %s.\n",
dev->name, media_tbl[dev->if_port].name);
init_timer(&vp->timer);
@@ -744,7 +744,7 @@ static int corkscrew_open(struct net_device *dev)
outl(config, ioaddr + Wn3_Config);
if (corkscrew_debug > 1) {
- printk("%s: corkscrew_open() InternalConfig %8.8x.\n",
+ pr_debug("%s: corkscrew_open() InternalConfig %8.8x.\n",
dev->name, config);
}
@@ -777,7 +777,7 @@ static int corkscrew_open(struct net_device *dev)
if (corkscrew_debug > 1) {
EL3WINDOW(4);
- printk("%s: corkscrew_open() irq %d media status %4.4x.\n",
+ pr_debug("%s: corkscrew_open() irq %d media status %4.4x.\n",
dev->name, dev->irq, inw(ioaddr + Wn4_Media));
}
@@ -814,8 +814,7 @@ static int corkscrew_open(struct net_device *dev)
if (vp->full_bus_master_rx) { /* Boomerang bus master. */
vp->cur_rx = vp->dirty_rx = 0;
if (corkscrew_debug > 2)
- printk("%s: Filling in the Rx ring.\n",
- dev->name);
+ pr_debug("%s: Filling in the Rx ring.\n", dev->name);
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb;
if (i < (RX_RING_SIZE - 1))
@@ -877,7 +876,7 @@ static void corkscrew_timer(unsigned long data)
int ok = 0;
if (corkscrew_debug > 1)
- printk("%s: Media selection timer tick happened, %s.\n",
+ pr_debug("%s: Media selection timer tick happened, %s.\n",
dev->name, media_tbl[dev->if_port].name);
spin_lock_irqsave(&vp->lock, flags);
@@ -894,12 +893,12 @@ static void corkscrew_timer(unsigned long data)
if (media_status & Media_LnkBeat) {
ok = 1;
if (corkscrew_debug > 1)
- printk("%s: Media %s has link beat, %x.\n",
+ pr_debug("%s: Media %s has link beat, %x.\n",
dev->name,
media_tbl[dev->if_port].name,
media_status);
} else if (corkscrew_debug > 1)
- printk("%s: Media %s is has no link beat, %x.\n",
+ pr_debug("%s: Media %s is has no link beat, %x.\n",
dev->name,
media_tbl[dev->if_port].name,
media_status);
@@ -907,7 +906,7 @@ static void corkscrew_timer(unsigned long data)
break;
default: /* Other media types handled by Tx timeouts. */
if (corkscrew_debug > 1)
- printk("%s: Media %s is has no indication, %x.\n",
+ pr_debug("%s: Media %s is has no indication, %x.\n",
dev->name,
media_tbl[dev->if_port].name,
media_status);
@@ -925,12 +924,12 @@ static void corkscrew_timer(unsigned long data)
if (dev->if_port == 8) { /* Go back to default. */
dev->if_port = vp->default_media;
if (corkscrew_debug > 1)
- printk("%s: Media selection failing, using default %s port.\n",
+ pr_debug("%s: Media selection failing, using default %s port.\n",
dev->name,
media_tbl[dev->if_port].name);
} else {
if (corkscrew_debug > 1)
- printk("%s: Media selection failed, now trying %s port.\n",
+ pr_debug("%s: Media selection failed, now trying %s port.\n",
dev->name,
media_tbl[dev->if_port].name);
vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
@@ -953,7 +952,7 @@ static void corkscrew_timer(unsigned long data)
spin_unlock_irqrestore(&vp->lock, flags);
if (corkscrew_debug > 1)
- printk("%s: Media selection timer finished, %s.\n",
+ pr_debug("%s: Media selection timer finished, %s.\n",
dev->name, media_tbl[dev->if_port].name);
#endif /* AUTOMEDIA */
@@ -966,23 +965,21 @@ static void corkscrew_timeout(struct net_device *dev)
struct corkscrew_private *vp = netdev_priv(dev);
int ioaddr = dev->base_addr;
- printk(KERN_WARNING
- "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
+ pr_warning("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
dev->name, inb(ioaddr + TxStatus),
inw(ioaddr + EL3_STATUS));
/* Slight code bloat to be user friendly. */
if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
- printk(KERN_WARNING
- "%s: Transmitter encountered 16 collisions -- network"
+ pr_warning("%s: Transmitter encountered 16 collisions --"
" network cable problem?\n", dev->name);
#ifndef final_version
- printk(" Flags; bus-master %d, full %d; dirty %d current %d.\n",
+ pr_debug(" Flags; bus-master %d, full %d; dirty %d current %d.\n",
vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx,
vp->cur_tx);
- printk(" Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
+ pr_debug(" Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
&vp->tx_ring[0]);
for (i = 0; i < TX_RING_SIZE; i++) {
- printk(" %d: %p length %8.8x status %8.8x\n", i,
+ pr_debug(" %d: %p length %8.8x status %8.8x\n", i,
&vp->tx_ring[i],
vp->tx_ring[i].length, vp->tx_ring[i].status);
}
@@ -1017,13 +1014,13 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
int i;
if (vp->tx_full) /* No room to transmit with */
- return 1;
+ return NETDEV_TX_BUSY;
if (vp->cur_tx != 0)
prev_entry = &vp->tx_ring[(vp->cur_tx - 1) % TX_RING_SIZE];
else
prev_entry = NULL;
if (corkscrew_debug > 3)
- printk("%s: Trying to send a packet, Tx index %d.\n",
+ pr_debug("%s: Trying to send a packet, Tx index %d.\n",
dev->name, vp->cur_tx);
/* vp->tx_full = 1; */
vp->tx_skbuff[entry] = skb;
@@ -1102,7 +1099,7 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) {
if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */
if (corkscrew_debug > 2)
- printk("%s: Tx error, status %2.2x.\n",
+ pr_debug("%s: Tx error, status %2.2x.\n",
dev->name, tx_status);
if (tx_status & 0x04)
dev->stats.tx_fifo_errors++;
@@ -1143,7 +1140,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
status = inw(ioaddr + EL3_STATUS);
if (corkscrew_debug > 4)
- printk("%s: interrupt, status %4.4x, timer %d.\n",
+ pr_debug("%s: interrupt, status %4.4x, timer %d.\n",
dev->name, status, latency);
if ((status & 0xE000) != 0xE000) {
static int donedidthis;
@@ -1151,7 +1148,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
Ignore a single early interrupt, but don't hang the machine for
other interrupt problems. */
if (donedidthis++ > 100) {
- printk(KERN_ERR "%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
+ pr_err("%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
dev->name, status, netif_running(dev));
free_irq(dev->irq, dev);
dev->irq = -1;
@@ -1160,14 +1157,14 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
do {
if (corkscrew_debug > 5)
- printk("%s: In interrupt loop, status %4.4x.\n",
+ pr_debug("%s: In interrupt loop, status %4.4x.\n",
dev->name, status);
if (status & RxComplete)
corkscrew_rx(dev);
if (status & TxAvailable) {
if (corkscrew_debug > 5)
- printk(" TX room bit was handled.\n");
+ pr_debug(" TX room bit was handled.\n");
/* There's room in the FIFO for a full-sized packet. */
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
netif_wake_queue(dev);
@@ -1212,19 +1209,20 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
if (status & StatsFull) { /* Empty statistics. */
static int DoneDidThat;
if (corkscrew_debug > 4)
- printk("%s: Updating stats.\n", dev->name);
+ pr_debug("%s: Updating stats.\n", dev->name);
update_stats(ioaddr, dev);
/* DEBUG HACK: Disable statistics as an interrupt source. */
/* This occurs when we have the wrong media type! */
if (DoneDidThat == 0 && inw(ioaddr + EL3_STATUS) & StatsFull) {
int win, reg;
- printk("%s: Updating stats failed, disabling stats as an"
- " interrupt source.\n", dev->name);
+ pr_notice("%s: Updating stats failed, disabling stats as an interrupt source.\n",
+ dev->name);
for (win = 0; win < 8; win++) {
EL3WINDOW(win);
- printk("\n Vortex window %d:", win);
+ pr_notice("Vortex window %d:", win);
for (reg = 0; reg < 16; reg++)
- printk(" %2.2x", inb(ioaddr + reg));
+ pr_cont(" %2.2x", inb(ioaddr + reg));
+ pr_cont("\n");
}
EL3WINDOW(7);
outw(SetIntrEnb | TxAvailable |
@@ -1246,9 +1244,8 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
}
if (--i < 0) {
- printk(KERN_ERR "%s: Too much work in interrupt, status %4.4x. "
- "Disabling functions (%4.4x).\n", dev->name,
- status, SetStatusEnb | ((~status) & 0x7FE));
+ pr_err("%s: Too much work in interrupt, status %4.4x. Disabling functions (%4.4x).\n",
+ dev->name, status, SetStatusEnb | ((~status) & 0x7FE));
/* Disable all pending interrupts. */
outw(SetStatusEnb | ((~status) & 0x7FE), ioaddr + EL3_CMD);
outw(AckIntr | 0x7FF, ioaddr + EL3_CMD);
@@ -1262,7 +1259,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
spin_unlock(&lp->lock);
if (corkscrew_debug > 4)
- printk("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
+ pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
return IRQ_HANDLED;
}
@@ -1273,13 +1270,13 @@ static int corkscrew_rx(struct net_device *dev)
short rx_status;
if (corkscrew_debug > 5)
- printk(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
+ pr_debug(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
if (rx_status & 0x4000) { /* Error, update stats. */
unsigned char rx_error = inb(ioaddr + RxErrors);
if (corkscrew_debug > 2)
- printk(" Rx error: status %2.2x.\n",
+ pr_debug(" Rx error: status %2.2x.\n",
rx_error);
dev->stats.rx_errors++;
if (rx_error & 0x01)
@@ -1299,7 +1296,7 @@ static int corkscrew_rx(struct net_device *dev)
skb = dev_alloc_skb(pkt_len + 5 + 2);
if (corkscrew_debug > 4)
- printk("Receiving packet size %d status %4.4x.\n",
+ pr_debug("Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status);
if (skb != NULL) {
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
@@ -1318,7 +1315,7 @@ static int corkscrew_rx(struct net_device *dev)
break;
continue;
} else if (corkscrew_debug)
- printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
+ pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
}
outw(RxDiscard, ioaddr + EL3_CMD);
dev->stats.rx_dropped++;
@@ -1338,13 +1335,13 @@ static int boomerang_rx(struct net_device *dev)
int rx_status;
if (corkscrew_debug > 5)
- printk(" In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
+ pr_debug(" In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
while ((rx_status = vp->rx_ring[entry].status) & RxDComplete) {
if (rx_status & RxDError) { /* Error, update stats. */
unsigned char rx_error = rx_status >> 16;
if (corkscrew_debug > 2)
- printk(" Rx error: status %2.2x.\n",
+ pr_debug(" Rx error: status %2.2x.\n",
rx_error);
dev->stats.rx_errors++;
if (rx_error & 0x01)
@@ -1364,7 +1361,7 @@ static int boomerang_rx(struct net_device *dev)
dev->stats.rx_bytes += pkt_len;
if (corkscrew_debug > 4)
- printk("Receiving packet size %d status %4.4x.\n",
+ pr_debug("Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status);
/* Check if the packet is long enough to just accept without
@@ -1385,7 +1382,7 @@ static int boomerang_rx(struct net_device *dev)
temp = skb_put(skb, pkt_len);
/* Remove this checking code for final release. */
if (isa_bus_to_virt(vp->rx_ring[entry].addr) != temp)
- printk("%s: Warning -- the skbuff addresses do not match"
+ pr_warning("%s: Warning -- the skbuff addresses do not match"
" in boomerang_rx: %p vs. %p / %p.\n",
dev->name,
isa_bus_to_virt(vp->
@@ -1427,12 +1424,11 @@ static int corkscrew_close(struct net_device *dev)
netif_stop_queue(dev);
if (corkscrew_debug > 1) {
- printk("%s: corkscrew_close() status %4.4x, Tx status %2.2x.\n",
+ pr_debug("%s: corkscrew_close() status %4.4x, Tx status %2.2x.\n",
dev->name, inw(ioaddr + EL3_STATUS),
inb(ioaddr + TxStatus));
- printk("%s: corkscrew close stats: rx_nocopy %d rx_copy %d"
- " tx_queued %d.\n", dev->name, rx_nocopy, rx_copy,
- queued_packet);
+ pr_debug("%s: corkscrew close stats: rx_nocopy %d rx_copy %d tx_queued %d.\n",
+ dev->name, rx_nocopy, rx_copy, queued_packet);
}
del_timer(&vp->timer);
@@ -1534,7 +1530,7 @@ static void set_rx_mode(struct net_device *dev)
if (dev->flags & IFF_PROMISC) {
if (corkscrew_debug > 3)
- printk("%s: Setting promiscuous mode.\n",
+ pr_debug("%s: Setting promiscuous mode.\n",
dev->name);
new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm;
} else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
index 8f734d74b51..cdd955c4014 100644
--- a/drivers/net/3c523.c
+++ b/drivers/net/3c523.c
@@ -176,7 +176,7 @@ sizeof(nop_cmd) = 8;
if(!p->scb->cmd) break; \
DELAY_16(); \
if(i == 1023) { \
- printk(KERN_WARNING "%s:%d: scb_cmd timed out .. resetting i82586\n",\
+ pr_warning("%s:%d: scb_cmd timed out .. resetting i82586\n",\
dev->name,__LINE__); \
elmc_id_reset586(); } } }
@@ -291,7 +291,7 @@ static int elmc_open(struct net_device *dev)
ret = request_irq(dev->irq, &elmc_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM,
dev->name, dev);
if (ret) {
- printk(KERN_ERR "%s: couldn't get irq %d\n", dev->name, dev->irq);
+ pr_err("%s: couldn't get irq %d\n", dev->name, dev->irq);
elmc_id_reset586();
return ret;
}
@@ -371,9 +371,9 @@ static void alloc586(struct net_device *dev)
DELAY(2);
- if (p->iscp->busy) {
- printk(KERN_ERR "%s: Init-Problems (alloc).\n", dev->name);
- }
+ if (p->iscp->busy)
+ pr_err("%s: Init-Problems (alloc).\n", dev->name);
+
memset((char *) p->scb, 0, sizeof(struct scb_struct));
}
@@ -470,7 +470,7 @@ static int __init do_elmc_probe(struct net_device *dev)
mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev);
/* if we get this far, adapter has been found - carry on */
- printk(KERN_INFO "%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
+ pr_info("%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
/* Now we extract configuration info from the card.
The 3c523 provides information in two of the POS registers, but
@@ -507,7 +507,7 @@ static int __init do_elmc_probe(struct net_device *dev)
memset(pr, 0, sizeof(struct priv));
pr->slot = slot;
- printk(KERN_INFO "%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
+ pr_info("%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
dev->base_addr);
/* Determine if we're using the on-board transceiver (i.e. coax) or
@@ -529,7 +529,7 @@ static int __init do_elmc_probe(struct net_device *dev)
size = 0x4000; /* check for 16K mem */
if (!check586(dev, dev->mem_start, size)) {
- printk(KERN_ERR "%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
+ pr_err("%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
dev->mem_start);
retval = -ENODEV;
goto err_out;
@@ -546,7 +546,7 @@ static int __init do_elmc_probe(struct net_device *dev)
pr->num_recv_buffs = NUM_RECV_BUFFS_16;
/* dump all the assorted information */
- printk(KERN_INFO "%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name,
+ pr_info("%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name,
dev->irq, dev->if_port ? "ex" : "in",
dev->mem_start, dev->mem_end - 1);
@@ -555,7 +555,7 @@ static int __init do_elmc_probe(struct net_device *dev)
for (i = 0; i < 6; i++)
dev->dev_addr[i] = inb(dev->base_addr + i);
- printk(KERN_INFO "%s: hardware address %pM\n",
+ pr_info("%s: hardware address %pM\n",
dev->name, dev->dev_addr);
dev->netdev_ops = &netdev_ops;
@@ -660,7 +660,7 @@ static int init586(struct net_device *dev)
}
if ((cfg_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_COMPL | STAT_OK)) {
- printk(KERN_WARNING "%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status);
+ pr_warning("%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status);
return 1;
}
/*
@@ -686,7 +686,8 @@ static int init586(struct net_device *dev)
}
if ((ias_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_OK | STAT_COMPL)) {
- printk(KERN_WARNING "%s (elmc): individual address setup command failed: %04x\n", dev->name, ias_cmd->cmd_status);
+ pr_warning("%s (elmc): individual address setup command failed: %04x\n",
+ dev->name, ias_cmd->cmd_status);
return 1;
}
/*
@@ -707,7 +708,7 @@ static int init586(struct net_device *dev)
s = jiffies;
while (!(tdr_cmd->cmd_status & STAT_COMPL)) {
if (time_after(jiffies, s + 30*HZ/100)) {
- printk(KERN_WARNING "%s: %d Problems while running the TDR.\n", dev->name, __LINE__);
+ pr_warning("%s: %d Problems while running the TDR.\n", dev->name, __LINE__);
result = 1;
break;
}
@@ -723,14 +724,14 @@ static int init586(struct net_device *dev)
if (result & TDR_LNK_OK) {
/* empty */
} else if (result & TDR_XCVR_PRB) {
- printk(KERN_WARNING "%s: TDR: Transceiver problem!\n", dev->name);
+ pr_warning("%s: TDR: Transceiver problem!\n", dev->name);
} else if (result & TDR_ET_OPN) {
- printk(KERN_WARNING "%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
+ pr_warning("%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
} else if (result & TDR_ET_SRT) {
if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
- printk(KERN_WARNING "%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
+ pr_warning("%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
} else {
- printk(KERN_WARNING "%s: TDR: Unknown status %04x\n", dev->name, result);
+ pr_warning("%s: TDR: Unknown status %04x\n", dev->name, result);
}
}
/*
@@ -774,11 +775,11 @@ static int init586(struct net_device *dev)
/* I don't understand this: do we really need memory after the init? */
int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
if (len <= 0) {
- printk(KERN_ERR "%s: Ooooops, no memory for MC-Setup!\n", dev->name);
+ pr_err("%s: Ooooops, no memory for MC-Setup!\n", dev->name);
} else {
if (len < num_addrs) {
num_addrs = len;
- printk(KERN_WARNING "%s: Sorry, can only apply %d MC-Address(es).\n",
+ pr_warning("%s: Sorry, can only apply %d MC-Address(es).\n",
dev->name, num_addrs);
}
mc_cmd = (struct mcsetup_cmd_struct *) ptr;
@@ -799,7 +800,7 @@ static int init586(struct net_device *dev)
break;
}
if (!(mc_cmd->cmd_status & STAT_COMPL)) {
- printk(KERN_WARNING "%s: Can't apply multicast-address-list.\n", dev->name);
+ pr_warning("%s: Can't apply multicast-address-list.\n", dev->name);
}
}
}
@@ -812,7 +813,7 @@ static int init586(struct net_device *dev)
p->xmit_buffs[i] = (struct tbd_struct *) ptr; /* TBD */
ptr = (char *) ptr + sizeof(struct tbd_struct);
if ((void *) ptr > (void *) p->iscp) {
- printk(KERN_ERR "%s: not enough shared-mem for your configuration!\n", dev->name);
+ pr_err("%s: not enough shared-mem for your configuration!\n", dev->name);
return 1;
}
memset((char *) (p->xmit_cmds[i]), 0, sizeof(struct transmit_cmd_struct));
@@ -936,7 +937,8 @@ elmc_interrupt(int irq, void *dev_id)
if (stat & STAT_CNA) {
/* CU went 'not ready' */
if (netif_running(dev)) {
- printk(KERN_WARNING "%s: oops! CU has left active state. stat: %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
+ pr_warning("%s: oops! CU has left active state. stat: %04x/%04x.\n",
+ dev->name, (int) stat, (int) p->scb->status);
}
}
#endif
@@ -951,7 +953,8 @@ elmc_interrupt(int irq, void *dev_id)
p->scb->cmd = RUC_RESUME;
elmc_attn586();
} else {
- printk(KERN_WARNING "%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
+ pr_warning("%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n",
+ dev->name, (int) stat, (int) p->scb->status);
elmc_rnr_int(dev);
}
}
@@ -995,11 +998,11 @@ static void elmc_rcv_int(struct net_device *dev)
dev->stats.rx_dropped++;
}
} else {
- printk(KERN_WARNING "%s: received oversized frame.\n", dev->name);
+ pr_warning("%s: received oversized frame.\n", dev->name);
dev->stats.rx_dropped++;
}
} else { /* frame !(ok), only with 'save-bad-frames' */
- printk(KERN_WARNING "%s: oops! rfd-error-status: %04x\n", dev->name, status);
+ pr_warning("%s: oops! rfd-error-status: %04x\n", dev->name, status);
dev->stats.rx_errors++;
}
p->rfd_top->status = 0;
@@ -1028,7 +1031,7 @@ static void elmc_rnr_int(struct net_device *dev)
alloc_rfa(dev, (char *) p->rfd_first);
startrecv586(dev); /* restart RU */
- printk(KERN_WARNING "%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status);
+ pr_warning("%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status);
}
@@ -1043,7 +1046,7 @@ static void elmc_xmt_int(struct net_device *dev)
status = p->xmit_cmds[p->xmit_last]->cmd_status;
if (!(status & STAT_COMPL)) {
- printk(KERN_WARNING "%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
+ pr_warning("%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
}
if (status & STAT_OK) {
dev->stats.tx_packets++;
@@ -1051,18 +1054,18 @@ static void elmc_xmt_int(struct net_device *dev)
} else {
dev->stats.tx_errors++;
if (status & TCMD_LATECOLL) {
- printk(KERN_WARNING "%s: late collision detected.\n", dev->name);
+ pr_warning("%s: late collision detected.\n", dev->name);
dev->stats.collisions++;
} else if (status & TCMD_NOCARRIER) {
dev->stats.tx_carrier_errors++;
- printk(KERN_WARNING "%s: no carrier detected.\n", dev->name);
+ pr_warning("%s: no carrier detected.\n", dev->name);
} else if (status & TCMD_LOSTCTS) {
- printk(KERN_WARNING "%s: loss of CTS detected.\n", dev->name);
+ pr_warning("%s: loss of CTS detected.\n", dev->name);
} else if (status & TCMD_UNDERRUN) {
dev->stats.tx_fifo_errors++;
- printk(KERN_WARNING "%s: DMA underrun detected.\n", dev->name);
+ pr_warning("%s: DMA underrun detected.\n", dev->name);
} else if (status & TCMD_MAXCOLL) {
- printk(KERN_WARNING "%s: Max. collisions exceeded.\n", dev->name);
+ pr_warning("%s: Max. collisions exceeded.\n", dev->name);
dev->stats.collisions += 16;
}
}
@@ -1099,10 +1102,11 @@ static void elmc_timeout(struct net_device *dev)
struct priv *p = netdev_priv(dev);
/* COMMAND-UNIT active? */
if (p->scb->status & CU_ACTIVE) {
-#ifdef DEBUG
- printk("%s: strange ... timeout with CU active?!?\n", dev->name);
- printk("%s: X0: %04x N0: %04x N1: %04x %d\n", dev->name, (int) p->xmit_cmds[0]->cmd_status, (int) p->nop_cmds[0]->cmd_status, (int) p->nop_cmds[1]->cmd_status, (int) p->nop_point);
-#endif
+ pr_debug("%s: strange ... timeout with CU active?!?\n", dev->name);
+ pr_debug("%s: X0: %04x N0: %04x N1: %04x %d\n", dev->name,
+ (int)p->xmit_cmds[0]->cmd_status,
+ (int)p->nop_cmds[0]->cmd_status,
+ (int)p->nop_cmds[1]->cmd_status, (int)p->nop_point);
p->scb->cmd = CUC_ABORT;
elmc_attn586();
WAIT_4_SCB_CMD();
@@ -1112,10 +1116,10 @@ static void elmc_timeout(struct net_device *dev)
WAIT_4_SCB_CMD();
netif_wake_queue(dev);
} else {
-#ifdef DEBUG
- printk("%s: xmitter timed out, try to restart! stat: %04x\n", dev->name, p->scb->status);
- printk("%s: command-stats: %04x %04x\n", dev->name, p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status);
-#endif
+ pr_debug("%s: xmitter timed out, try to restart! stat: %04x\n",
+ dev->name, p->scb->status);
+ pr_debug("%s: command-stats: %04x %04x\n", dev->name,
+ p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status);
elmc_close(dev);
elmc_open(dev);
}
@@ -1162,7 +1166,7 @@ static int elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
break;
}
if (i == 15) {
- printk(KERN_WARNING "%s: Can't start transmit-command.\n", dev->name);
+ pr_warning("%s: Can't start transmit-command.\n", dev->name);
}
}
#else
@@ -1287,11 +1291,12 @@ int __init init_module(void)
free_netdev(dev);
if (io[this_dev]==0)
break;
- printk(KERN_WARNING "3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
+ pr_warning("3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
}
if(found==0) {
- if(io[0]==0) printk(KERN_NOTICE "3c523.c: No 3c523 cards found\n");
+ if (io[0]==0)
+ pr_notice("3c523.c: No 3c523 cards found\n");
return -ENXIO;
} else return 0;
}
diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c
index b61073c42bf..aaa8a9f405d 100644
--- a/drivers/net/3c527.c
+++ b/drivers/net/3c527.c
@@ -125,8 +125,6 @@ static const char* cardname = DRV_NAME;
#define NET_DEBUG 2
#endif
-#undef DEBUG_IRQ
-
static unsigned int mc32_debug = NET_DEBUG;
/* The number of low I/O ports used by the ethercard. */
@@ -351,15 +349,15 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
/* Time to play MCA games */
if (mc32_debug && version_printed++ == 0)
- printk(KERN_DEBUG "%s", version);
+ pr_debug("%s", version);
- printk(KERN_INFO "%s: %s found in slot %d:", dev->name, cardname, slot);
+ pr_info("%s: %s found in slot %d: ", dev->name, cardname, slot);
POS = mca_read_stored_pos(slot, 2);
if(!(POS&1))
{
- printk(" disabled.\n");
+ pr_cont("disabled.\n");
return -ENODEV;
}
@@ -370,7 +368,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
POS = mca_read_stored_pos(slot, 4);
if(!(POS&1))
{
- printk("memory window disabled.\n");
+ pr_cont("memory window disabled.\n");
return -ENODEV;
}
@@ -379,7 +377,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
i=(POS>>4)&3;
if(i==3)
{
- printk("invalid memory window.\n");
+ pr_cont("invalid memory window.\n");
return -ENODEV;
}
@@ -392,11 +390,11 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
if(!request_region(dev->base_addr, MC32_IO_EXTENT, cardname))
{
- printk("io 0x%3lX, which is busy.\n", dev->base_addr);
+ pr_cont("io 0x%3lX, which is busy.\n", dev->base_addr);
return -EBUSY;
}
- printk("io 0x%3lX irq %d mem 0x%lX (%dK)\n",
+ pr_cont("io 0x%3lX irq %d mem 0x%lX (%dK)\n",
dev->base_addr, dev->irq, dev->mem_start, i/1024);
@@ -416,7 +414,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
dev->dev_addr[i] = mca_read_pos(slot,3);
}
- printk("%s: Address %pM", dev->name, dev->dev_addr);
+ pr_info("%s: Address %pM ", dev->name, dev->dev_addr);
mca_write_pos(slot, 6, 0);
mca_write_pos(slot, 7, 0);
@@ -424,9 +422,9 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
POS = mca_read_stored_pos(slot, 4);
if(POS&2)
- printk(" : BNC port selected.\n");
+ pr_cont(": BNC port selected.\n");
else
- printk(" : AUI port selected.\n");
+ pr_cont(": AUI port selected.\n");
POS=inb(dev->base_addr+HOST_CTRL);
POS|=HOST_CTRL_ATTN|HOST_CTRL_RESET;
@@ -447,7 +445,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
err = request_irq(dev->irq, &mc32_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DRV_NAME, dev);
if (err) {
release_region(dev->base_addr, MC32_IO_EXTENT);
- printk(KERN_ERR "%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
+ pr_err("%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
goto err_exit_ports;
}
@@ -463,7 +461,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
i++;
if(i == 1000)
{
- printk(KERN_ERR "%s: failed to boot adapter.\n", dev->name);
+ pr_err("%s: failed to boot adapter.\n", dev->name);
err = -ENODEV;
goto err_exit_irq;
}
@@ -475,10 +473,10 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
if(base>0)
{
if(base < 0x0C)
- printk(KERN_ERR "%s: %s%s.\n", dev->name, failures[base-1],
+ pr_err("%s: %s%s.\n", dev->name, failures[base-1],
base<0x0A?" test failure":"");
else
- printk(KERN_ERR "%s: unknown failure %d.\n", dev->name, base);
+ pr_err("%s: unknown failure %d.\n", dev->name, base);
err = -ENODEV;
goto err_exit_irq;
}
@@ -494,7 +492,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
udelay(50);
if(n>100)
{
- printk(KERN_ERR "%s: mailbox read fail (%d).\n", dev->name, i);
+ pr_err("%s: mailbox read fail (%d).\n", dev->name, i);
err = -ENODEV;
goto err_exit_irq;
}
@@ -527,7 +525,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
init_completion(&lp->execution_cmd);
init_completion(&lp->xceiver_cmd);
- printk("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
+ pr_info("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
dev->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base);
dev->netdev_ops = &netdev_ops;
@@ -939,7 +937,7 @@ static int mc32_open(struct net_device *dev)
*/
if(mc32_command(dev, 8, descnumbuffs, 4)) {
- printk("%s: %s rejected our buffer configuration!\n",
+ pr_info("%s: %s rejected our buffer configuration!\n",
dev->name, cardname);
mc32_close(dev);
return -ENOBUFS;
@@ -995,7 +993,7 @@ static int mc32_open(struct net_device *dev)
static void mc32_timeout(struct net_device *dev)
{
- printk(KERN_WARNING "%s: transmit timed out?\n", dev->name);
+ pr_warning("%s: transmit timed out?\n", dev->name);
/* Try to restart the adaptor. */
netif_wake_queue(dev);
}
@@ -1032,7 +1030,7 @@ static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
if(atomic_read(&lp->tx_count)==0) {
- return 1;
+ return NETDEV_TX_BUSY;
}
if (skb_padto(skb, ETH_ZLEN)) {
@@ -1335,11 +1333,9 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id)
{
status=inb(ioaddr+HOST_CMD);
-#ifdef DEBUG_IRQ
- printk("Status TX%d RX%d EX%d OV%d BC%d\n",
+ pr_debug("Status TX%d RX%d EX%d OV%d BC%d\n",
(status&7), (status>>3)&7, (status>>6)&1,
(status>>7)&1, boguscount);
-#endif
switch(status&7)
{
@@ -1354,7 +1350,7 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id)
complete(&lp->xceiver_cmd);
break;
default:
- printk("%s: strange tx ack %d\n", dev->name, status&7);
+ pr_notice("%s: strange tx ack %d\n", dev->name, status&7);
}
status>>=3;
switch(status&7)
@@ -1376,7 +1372,7 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id)
mc32_start_transceiver(dev);
break;
default:
- printk("%s: strange rx ack %d\n",
+ pr_notice("%s: strange rx ack %d\n",
dev->name, status&7);
}
status>>=3;
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index c5669840242..c34aee91250 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -828,14 +828,14 @@ static int vortex_resume(struct pci_dev *pdev)
pci_restore_state(pdev);
err = pci_enable_device(pdev);
if (err) {
- printk(KERN_WARNING "%s: Could not enable device \n",
+ pr_warning("%s: Could not enable device\n",
dev->name);
return err;
}
pci_set_master(pdev);
if (request_irq(dev->irq, vp->full_bus_master_rx ?
&boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev)) {
- printk(KERN_WARNING "%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
+ pr_warning("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
pci_disable_device(pdev);
return -EBUSY;
}
@@ -894,7 +894,7 @@ static int __devexit vortex_eisa_remove(struct device *device)
dev = eisa_get_drvdata(edev);
if (!dev) {
- printk("vortex_eisa_remove called for Compaq device!\n");
+ pr_err("vortex_eisa_remove called for Compaq device!\n");
BUG();
}
@@ -1051,7 +1051,7 @@ static int __devinit vortex_probe1(struct device *gendev,
struct eisa_device *edev = NULL;
if (!printed_version) {
- printk (version);
+ pr_info("%s", version);
printed_version = 1;
}
@@ -1068,7 +1068,7 @@ static int __devinit vortex_probe1(struct device *gendev,
dev = alloc_etherdev(sizeof(*vp));
retval = -ENOMEM;
if (!dev) {
- printk (KERN_ERR PFX "unable to allocate etherdev, aborting\n");
+ pr_err(PFX "unable to allocate etherdev, aborting\n");
goto out;
}
SET_NETDEV_DEV(dev, gendev);
@@ -1100,9 +1100,9 @@ static int __devinit vortex_probe1(struct device *gendev,
print_info = (vortex_debug > 1);
if (print_info)
- printk (KERN_INFO "See Documentation/networking/vortex.txt\n");
+ pr_info("See Documentation/networking/vortex.txt\n");
- printk(KERN_INFO "%s: 3Com %s %s at %p.\n",
+ pr_info("%s: 3Com %s %s at %p.\n",
print_name,
pdev ? "PCI" : "EISA",
vci->name,
@@ -1144,10 +1144,9 @@ static int __devinit vortex_probe1(struct device *gendev,
chip only. */
pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
if (pci_latency < new_latency) {
- printk(KERN_INFO "%s: Overriding PCI latency"
- " timer (CFLT) setting of %d, new value is %d.\n",
+ pr_info("%s: Overriding PCI latency timer (CFLT) setting of %d, new value is %d.\n",
print_name, pci_latency, new_latency);
- pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
}
}
}
@@ -1236,17 +1235,17 @@ static int __devinit vortex_probe1(struct device *gendev,
checksum = (checksum ^ (checksum >> 8)) & 0xff;
}
if ((checksum != 0x00) && !(vci->drv_flags & IS_TORNADO))
- printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
+ pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
for (i = 0; i < 3; i++)
((__be16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
if (print_info)
- printk(" %pM", dev->dev_addr);
+ pr_cont(" %pM", dev->dev_addr);
/* Unfortunately an all zero eeprom passes the checksum and this
gets found in the wild in failure cases. Crypto is hard 8) */
if (!is_valid_ether_addr(dev->dev_addr)) {
retval = -EINVAL;
- printk(KERN_ERR "*** EEPROM MAC address is invalid.\n");
+ pr_err("*** EEPROM MAC address is invalid.\n");
goto free_ring; /* With every pack */
}
EL3WINDOW(2);
@@ -1254,17 +1253,17 @@ static int __devinit vortex_probe1(struct device *gendev,
iowrite8(dev->dev_addr[i], ioaddr + i);
if (print_info)
- printk(", IRQ %d\n", dev->irq);
+ pr_cont(", IRQ %d\n", dev->irq);
/* Tell them about an invalid IRQ. */
if (dev->irq <= 0 || dev->irq >= nr_irqs)
- printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n",
+ pr_warning(" *** Warning: IRQ %d is unlikely to work! ***\n",
dev->irq);
EL3WINDOW(4);
step = (ioread8(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
if (print_info) {
- printk(KERN_INFO " product code %02x%02x rev %02x.%d date %02d-"
- "%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
+ pr_info(" product code %02x%02x rev %02x.%d date %02d-%02d-%02d\n",
+ eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
step, (eeprom[4]>>5) & 15, eeprom[4] & 31, eeprom[4]>>9);
}
@@ -1279,8 +1278,7 @@ static int __devinit vortex_probe1(struct device *gendev,
}
if (print_info) {
- printk(KERN_INFO "%s: CardBus functions mapped "
- "%16.16llx->%p\n",
+ pr_info("%s: CardBus functions mapped %16.16llx->%p\n",
print_name,
(unsigned long long)pci_resource_start(pdev, 2),
vp->cb_fn_base);
@@ -1307,7 +1305,7 @@ static int __devinit vortex_probe1(struct device *gendev,
if (vp->info1 & 0x8000) {
vp->full_duplex = 1;
if (print_info)
- printk(KERN_INFO "Full duplex capable\n");
+ pr_info("Full duplex capable\n");
}
{
@@ -1319,9 +1317,9 @@ static int __devinit vortex_probe1(struct device *gendev,
vp->available_media = 0x40;
config = ioread32(ioaddr + Wn3_Config);
if (print_info) {
- printk(KERN_DEBUG " Internal config register is %4.4x, "
- "transceivers %#x.\n", config, ioread16(ioaddr + Wn3_Options));
- printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
+ pr_debug(" Internal config register is %4.4x, transceivers %#x.\n",
+ config, ioread16(ioaddr + Wn3_Options));
+ pr_info(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
8 << RAM_SIZE(config),
RAM_WIDTH(config) ? "word" : "byte",
ram_split[RAM_SPLIT(config)],
@@ -1336,7 +1334,7 @@ static int __devinit vortex_probe1(struct device *gendev,
}
if (vp->media_override != 7) {
- printk(KERN_INFO "%s: Media override to transceiver type %d (%s).\n",
+ pr_info("%s: Media override to transceiver type %d (%s).\n",
print_name, vp->media_override,
media_tbl[vp->media_override].name);
dev->if_port = vp->media_override;
@@ -1369,8 +1367,8 @@ static int __devinit vortex_probe1(struct device *gendev,
if (mii_status && mii_status != 0xffff) {
vp->phys[phy_idx++] = phyx;
if (print_info) {
- printk(KERN_INFO " MII transceiver found at address %d,"
- " status %4x.\n", phyx, mii_status);
+ pr_info(" MII transceiver found at address %d, status %4x.\n",
+ phyx, mii_status);
}
if ((mii_status & 0x0040) == 0)
mii_preamble_required++;
@@ -1378,7 +1376,7 @@ static int __devinit vortex_probe1(struct device *gendev,
}
mii_preamble_required--;
if (phy_idx == 0) {
- printk(KERN_WARNING" ***WARNING*** No MII transceivers found!\n");
+ pr_warning(" ***WARNING*** No MII transceivers found!\n");
vp->phys[0] = 24;
} else {
vp->advertising = mdio_read(dev, vp->phys[0], MII_ADVERTISE);
@@ -1394,7 +1392,7 @@ static int __devinit vortex_probe1(struct device *gendev,
if (vp->capabilities & CapBusMaster) {
vp->full_bus_master_tx = 1;
if (print_info) {
- printk(KERN_INFO " Enabling bus-master transmits and %s receives.\n",
+ pr_info(" Enabling bus-master transmits and %s receives.\n",
(vp->info2 & 1) ? "early" : "whole-frame" );
}
vp->full_bus_master_rx = (vp->info2 & 1) ? 1 : 2;
@@ -1414,7 +1412,7 @@ static int __devinit vortex_probe1(struct device *gendev,
dev->netdev_ops = &vortex_netdev_ops;
if (print_info) {
- printk(KERN_INFO "%s: scatter/gather %sabled. h/w checksums %sabled\n",
+ pr_info("%s: scatter/gather %sabled. h/w checksums %sabled\n",
print_name,
(dev->features & NETIF_F_SG) ? "en":"dis",
(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
@@ -1442,7 +1440,7 @@ free_region:
if (vp->must_free_region)
release_region(dev->base_addr, vci->io_size);
free_netdev(dev);
- printk(KERN_ERR PFX "vortex_probe1 fails. Returns %d\n", retval);
+ pr_err(PFX "vortex_probe1 fails. Returns %d\n", retval);
out:
return retval;
}
@@ -1464,13 +1462,13 @@ issue_and_wait(struct net_device *dev, int cmd)
for (i = 0; i < 100000; i++) {
if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) {
if (vortex_debug > 1)
- printk(KERN_INFO "%s: command 0x%04x took %d usecs\n",
+ pr_info("%s: command 0x%04x took %d usecs\n",
dev->name, cmd, i * 10);
return;
}
udelay(10);
}
- printk(KERN_ERR "%s: command 0x%04x did not complete! Status=0x%x\n",
+ pr_err("%s: command 0x%04x did not complete! Status=0x%x\n",
dev->name, cmd, ioread16(ioaddr + EL3_STATUS));
}
@@ -1480,7 +1478,7 @@ vortex_set_duplex(struct net_device *dev)
struct vortex_private *vp = netdev_priv(dev);
void __iomem *ioaddr = vp->ioaddr;
- printk(KERN_INFO "%s: setting %s-duplex.\n",
+ pr_info("%s: setting %s-duplex.\n",
dev->name, (vp->full_duplex) ? "full" : "half");
EL3WINDOW(3);
@@ -1522,7 +1520,7 @@ vortex_up(struct net_device *dev)
pci_restore_state(VORTEX_PCI(vp));
err = pci_enable_device(VORTEX_PCI(vp));
if (err) {
- printk(KERN_WARNING "%s: Could not enable device \n",
+ pr_warning("%s: Could not enable device\n",
dev->name);
goto err_out;
}
@@ -1533,14 +1531,14 @@ vortex_up(struct net_device *dev)
config = ioread32(ioaddr + Wn3_Config);
if (vp->media_override != 7) {
- printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
+ pr_info("%s: Media override to transceiver %d (%s).\n",
dev->name, vp->media_override,
media_tbl[vp->media_override].name);
dev->if_port = vp->media_override;
} else if (vp->autoselect) {
if (vp->has_nway) {
if (vortex_debug > 1)
- printk(KERN_INFO "%s: using NWAY device table, not %d\n",
+ pr_info("%s: using NWAY device table, not %d\n",
dev->name, dev->if_port);
dev->if_port = XCVR_NWAY;
} else {
@@ -1549,13 +1547,13 @@ vortex_up(struct net_device *dev)
while (! (vp->available_media & media_tbl[dev->if_port].mask))
dev->if_port = media_tbl[dev->if_port].next;
if (vortex_debug > 1)
- printk(KERN_INFO "%s: first available media type: %s\n",
+ pr_info("%s: first available media type: %s\n",
dev->name, media_tbl[dev->if_port].name);
}
} else {
dev->if_port = vp->default_media;
if (vortex_debug > 1)
- printk(KERN_INFO "%s: using default media %s\n",
+ pr_info("%s: using default media %s\n",
dev->name, media_tbl[dev->if_port].name);
}
@@ -1570,13 +1568,13 @@ vortex_up(struct net_device *dev)
vp->rx_oom_timer.function = rx_oom_timer;
if (vortex_debug > 1)
- printk(KERN_DEBUG "%s: Initial media type %s.\n",
+ pr_debug("%s: Initial media type %s.\n",
dev->name, media_tbl[dev->if_port].name);
vp->full_duplex = vp->mii.force_media;
config = BFINS(config, dev->if_port, 20, 4);
if (vortex_debug > 6)
- printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config);
+ pr_debug("vortex_up(): writing 0x%x to InternalConfig\n", config);
iowrite32(config, ioaddr + Wn3_Config);
if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
@@ -1602,7 +1600,7 @@ vortex_up(struct net_device *dev)
if (vortex_debug > 1) {
EL3WINDOW(4);
- printk(KERN_DEBUG "%s: vortex_up() irq %d media status %4.4x.\n",
+ pr_debug("%s: vortex_up() irq %d media status %4.4x.\n",
dev->name, dev->irq, ioread16(ioaddr + Wn4_Media));
}
@@ -1704,13 +1702,13 @@ vortex_open(struct net_device *dev)
/* Use the now-standard shared IRQ implementation. */
if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ?
&boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev))) {
- printk(KERN_ERR "%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
+ pr_err("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
goto err;
}
if (vp->full_bus_master_rx) { /* Boomerang bus master. */
if (vortex_debug > 2)
- printk(KERN_DEBUG "%s: Filling in the Rx ring.\n", dev->name);
+ pr_debug("%s: Filling in the Rx ring.\n", dev->name);
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb;
vp->rx_ring[i].next = cpu_to_le32(vp->rx_ring_dma + sizeof(struct boom_rx_desc) * (i+1));
@@ -1728,7 +1726,7 @@ vortex_open(struct net_device *dev)
}
if (i != RX_RING_SIZE) {
int j;
- printk(KERN_EMERG "%s: no memory for rx ring\n", dev->name);
+ pr_emerg("%s: no memory for rx ring\n", dev->name);
for (j = 0; j < i; j++) {
if (vp->rx_skbuff[j]) {
dev_kfree_skb(vp->rx_skbuff[j]);
@@ -1750,7 +1748,7 @@ err_free_irq:
free_irq(dev->irq, dev);
err:
if (vortex_debug > 1)
- printk(KERN_ERR "%s: vortex_open() fails: returning %d\n", dev->name, retval);
+ pr_err("%s: vortex_open() fails: returning %d\n", dev->name, retval);
out:
return retval;
}
@@ -1766,9 +1764,9 @@ vortex_timer(unsigned long data)
int media_status, old_window;
if (vortex_debug > 2) {
- printk(KERN_DEBUG "%s: Media selection timer tick happened, %s.\n",
+ pr_debug("%s: Media selection timer tick happened, %s.\n",
dev->name, media_tbl[dev->if_port].name);
- printk(KERN_DEBUG "dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
+ pr_debug("dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
}
disable_irq_lockdep(dev->irq);
@@ -1781,12 +1779,12 @@ vortex_timer(unsigned long data)
netif_carrier_on(dev);
ok = 1;
if (vortex_debug > 1)
- printk(KERN_DEBUG "%s: Media %s has link beat, %x.\n",
+ pr_debug("%s: Media %s has link beat, %x.\n",
dev->name, media_tbl[dev->if_port].name, media_status);
} else {
netif_carrier_off(dev);
if (vortex_debug > 1) {
- printk(KERN_DEBUG "%s: Media %s has no link beat, %x.\n",
+ pr_debug("%s: Media %s has no link beat, %x.\n",
dev->name, media_tbl[dev->if_port].name, media_status);
}
}
@@ -1802,7 +1800,7 @@ vortex_timer(unsigned long data)
break;
default: /* Other media types handled by Tx timeouts. */
if (vortex_debug > 1)
- printk(KERN_DEBUG "%s: Media %s has no indication, %x.\n",
+ pr_debug("%s: Media %s has no indication, %x.\n",
dev->name, media_tbl[dev->if_port].name, media_status);
ok = 1;
}
@@ -1822,13 +1820,11 @@ vortex_timer(unsigned long data)
if (dev->if_port == XCVR_Default) { /* Go back to default. */
dev->if_port = vp->default_media;
if (vortex_debug > 1)
- printk(KERN_DEBUG "%s: Media selection failing, using default "
- "%s port.\n",
+ pr_debug("%s: Media selection failing, using default %s port.\n",
dev->name, media_tbl[dev->if_port].name);
} else {
if (vortex_debug > 1)
- printk(KERN_DEBUG "%s: Media selection failed, now trying "
- "%s port.\n",
+ pr_debug("%s: Media selection failed, now trying %s port.\n",
dev->name, media_tbl[dev->if_port].name);
next_tick = media_tbl[dev->if_port].wait;
}
@@ -1843,13 +1839,13 @@ vortex_timer(unsigned long data)
iowrite16(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
ioaddr + EL3_CMD);
if (vortex_debug > 1)
- printk(KERN_DEBUG "wrote 0x%08x to Wn3_Config\n", config);
+ pr_debug("wrote 0x%08x to Wn3_Config\n", config);
/* AKPM: FIXME: Should reset Rx & Tx here. P60 of 3c90xc.pdf */
}
leave_media_alone:
if (vortex_debug > 2)
- printk(KERN_DEBUG "%s: Media selection timer finished, %s.\n",
+ pr_debug("%s: Media selection timer finished, %s.\n",
dev->name, media_tbl[dev->if_port].name);
EL3WINDOW(old_window);
@@ -1865,21 +1861,21 @@ static void vortex_tx_timeout(struct net_device *dev)
struct vortex_private *vp = netdev_priv(dev);
void __iomem *ioaddr = vp->ioaddr;
- printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
+ pr_err("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
dev->name, ioread8(ioaddr + TxStatus),
ioread16(ioaddr + EL3_STATUS));
EL3WINDOW(4);
- printk(KERN_ERR " diagnostics: net %04x media %04x dma %08x fifo %04x\n",
+ pr_err(" diagnostics: net %04x media %04x dma %08x fifo %04x\n",
ioread16(ioaddr + Wn4_NetDiag),
ioread16(ioaddr + Wn4_Media),
ioread32(ioaddr + PktStatus),
ioread16(ioaddr + Wn4_FIFODiag));
/* Slight code bloat to be user friendly. */
if ((ioread8(ioaddr + TxStatus) & 0x88) == 0x88)
- printk(KERN_ERR "%s: Transmitter encountered 16 collisions --"
+ pr_err("%s: Transmitter encountered 16 collisions --"
" network cable problem?\n", dev->name);
if (ioread16(ioaddr + EL3_STATUS) & IntLatch) {
- printk(KERN_ERR "%s: Interrupt posted but not delivered --"
+ pr_err("%s: Interrupt posted but not delivered --"
" IRQ blocked by another device?\n", dev->name);
/* Bad idea here.. but we might as well handle a few events. */
{
@@ -1903,7 +1899,7 @@ static void vortex_tx_timeout(struct net_device *dev)
dev->stats.tx_errors++;
if (vp->full_bus_master_tx) {
- printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name);
+ pr_debug("%s: Resetting the Tx ring pointer.\n", dev->name);
if (vp->cur_tx - vp->dirty_tx > 0 && ioread32(ioaddr + DownListPtr) == 0)
iowrite32(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
ioaddr + DownListPtr);
@@ -1938,7 +1934,7 @@ vortex_error(struct net_device *dev, int status)
unsigned char tx_status = 0;
if (vortex_debug > 2) {
- printk(KERN_ERR "%s: vortex_error(), status=0x%x\n", dev->name, status);
+ pr_err("%s: vortex_error(), status=0x%x\n", dev->name, status);
}
if (status & TxComplete) { /* Really "TxError" for us. */
@@ -1946,10 +1942,10 @@ vortex_error(struct net_device *dev, int status)
/* Presumably a tx-timeout. We must merely re-enable. */
if (vortex_debug > 2
|| (tx_status != 0x88 && vortex_debug > 0)) {
- printk(KERN_ERR "%s: Transmit error, Tx status register %2.2x.\n",
+ pr_err("%s: Transmit error, Tx status register %2.2x.\n",
dev->name, tx_status);
if (tx_status == 0x82) {
- printk(KERN_ERR "Probably a duplex mismatch. See "
+ pr_err("Probably a duplex mismatch. See "
"Documentation/networking/vortex.txt\n");
}
dump_tx_ring(dev);
@@ -1975,13 +1971,13 @@ vortex_error(struct net_device *dev, int status)
if (status & StatsFull) { /* Empty statistics. */
static int DoneDidThat;
if (vortex_debug > 4)
- printk(KERN_DEBUG "%s: Updating stats.\n", dev->name);
+ pr_debug("%s: Updating stats.\n", dev->name);
update_stats(ioaddr, dev);
/* HACK: Disable statistics as an interrupt source. */
/* This occurs when we have the wrong media type! */
if (DoneDidThat == 0 &&
ioread16(ioaddr + EL3_STATUS) & StatsFull) {
- printk(KERN_WARNING "%s: Updating statistics failed, disabling "
+ pr_warning("%s: Updating statistics failed, disabling "
"stats as an interrupt source.\n", dev->name);
EL3WINDOW(5);
iowrite16(SetIntrEnb | (ioread16(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
@@ -1998,7 +1994,7 @@ vortex_error(struct net_device *dev, int status)
u16 fifo_diag;
EL3WINDOW(4);
fifo_diag = ioread16(ioaddr + Wn4_FIFODiag);
- printk(KERN_ERR "%s: Host error, FIFO diagnostic register %4.4x.\n",
+ pr_err("%s: Host error, FIFO diagnostic register %4.4x.\n",
dev->name, fifo_diag);
/* Adapter failure requires Tx/Rx reset and reinit. */
if (vp->full_bus_master_tx) {
@@ -2006,7 +2002,7 @@ vortex_error(struct net_device *dev, int status)
/* 0x80000000 PCI master abort. */
/* 0x40000000 PCI target abort. */
if (vortex_debug)
- printk(KERN_ERR "%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
+ pr_err("%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
/* In this case, blow the card away */
/* Must not enter D3 or we can't legally issue the reset! */
@@ -2075,7 +2071,7 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
while (--i > 0 && (tx_status = ioread8(ioaddr + TxStatus)) > 0) {
if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */
if (vortex_debug > 2)
- printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n",
+ pr_debug("%s: Tx error, status %2.2x.\n",
dev->name, tx_status);
if (tx_status & 0x04) dev->stats.tx_fifo_errors++;
if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
@@ -2101,17 +2097,17 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
unsigned long flags;
if (vortex_debug > 6) {
- printk(KERN_DEBUG "boomerang_start_xmit()\n");
- printk(KERN_DEBUG "%s: Trying to send a packet, Tx index %d.\n",
+ pr_debug("boomerang_start_xmit()\n");
+ pr_debug("%s: Trying to send a packet, Tx index %d.\n",
dev->name, vp->cur_tx);
}
if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) {
if (vortex_debug > 0)
- printk(KERN_WARNING "%s: BUG! Tx Ring full, refusing to send buffer.\n",
+ pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n",
dev->name);
netif_stop_queue(dev);
- return 1;
+ return NETDEV_TX_BUSY;
}
vp->tx_skbuff[entry] = skb;
@@ -2204,7 +2200,7 @@ vortex_interrupt(int irq, void *dev_id)
status = ioread16(ioaddr + EL3_STATUS);
if (vortex_debug > 6)
- printk("vortex_interrupt(). status=0x%4x\n", status);
+ pr_debug("vortex_interrupt(). status=0x%4x\n", status);
if ((status & IntLatch) == 0)
goto handler_exit; /* No interrupt: shared IRQs cause this */
@@ -2219,19 +2215,19 @@ vortex_interrupt(int irq, void *dev_id)
goto handler_exit;
if (vortex_debug > 4)
- printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
+ pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
dev->name, status, ioread8(ioaddr + Timer));
do {
if (vortex_debug > 5)
- printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
+ pr_debug("%s: In interrupt loop, status %4.4x.\n",
dev->name, status);
if (status & RxComplete)
vortex_rx(dev);
if (status & TxAvailable) {
if (vortex_debug > 5)
- printk(KERN_DEBUG " TX room bit was handled.\n");
+ pr_debug(" TX room bit was handled.\n");
/* There's room in the FIFO for a full-sized packet. */
iowrite16(AckIntr | TxAvailable, ioaddr + EL3_CMD);
netif_wake_queue (dev);
@@ -2263,8 +2259,8 @@ vortex_interrupt(int irq, void *dev_id)
}
if (--work_done < 0) {
- printk(KERN_WARNING "%s: Too much work in interrupt, status "
- "%4.4x.\n", dev->name, status);
+ pr_warning("%s: Too much work in interrupt, status %4.4x.\n",
+ dev->name, status);
/* Disable all pending interrupts. */
do {
vp->deferred |= status;
@@ -2281,7 +2277,7 @@ vortex_interrupt(int irq, void *dev_id)
} while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
if (vortex_debug > 4)
- printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
+ pr_debug("%s: exiting interrupt, status %4.4x.\n",
dev->name, status);
handler_exit:
spin_unlock(&vp->lock);
@@ -2313,14 +2309,14 @@ boomerang_interrupt(int irq, void *dev_id)
status = ioread16(ioaddr + EL3_STATUS);
if (vortex_debug > 6)
- printk(KERN_DEBUG "boomerang_interrupt. status=0x%4x\n", status);
+ pr_debug("boomerang_interrupt. status=0x%4x\n", status);
if ((status & IntLatch) == 0)
goto handler_exit; /* No interrupt: shared IRQs can cause this */
if (status == 0xffff) { /* h/w no longer present (hotplug)? */
if (vortex_debug > 1)
- printk(KERN_DEBUG "boomerang_interrupt(1): status = 0xffff\n");
+ pr_debug("boomerang_interrupt(1): status = 0xffff\n");
goto handler_exit;
}
@@ -2330,16 +2326,16 @@ boomerang_interrupt(int irq, void *dev_id)
}
if (vortex_debug > 4)
- printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
+ pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
dev->name, status, ioread8(ioaddr + Timer));
do {
if (vortex_debug > 5)
- printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
+ pr_debug("%s: In interrupt loop, status %4.4x.\n",
dev->name, status);
if (status & UpComplete) {
iowrite16(AckIntr | UpComplete, ioaddr + EL3_CMD);
if (vortex_debug > 5)
- printk(KERN_DEBUG "boomerang_interrupt->boomerang_rx\n");
+ pr_debug("boomerang_interrupt->boomerang_rx\n");
boomerang_rx(dev);
}
@@ -2374,7 +2370,7 @@ boomerang_interrupt(int irq, void *dev_id)
dev_kfree_skb_irq(skb);
vp->tx_skbuff[entry] = NULL;
} else {
- printk(KERN_DEBUG "boomerang_interrupt: no skb!\n");
+ pr_debug("boomerang_interrupt: no skb!\n");
}
/* dev->stats.tx_packets++; Counted below. */
dirty_tx++;
@@ -2382,7 +2378,7 @@ boomerang_interrupt(int irq, void *dev_id)
vp->dirty_tx = dirty_tx;
if (vp->cur_tx - dirty_tx <= TX_RING_SIZE - 1) {
if (vortex_debug > 6)
- printk(KERN_DEBUG "boomerang_interrupt: wake queue\n");
+ pr_debug("boomerang_interrupt: wake queue\n");
netif_wake_queue (dev);
}
}
@@ -2392,8 +2388,8 @@ boomerang_interrupt(int irq, void *dev_id)
vortex_error(dev, status);
if (--work_done < 0) {
- printk(KERN_WARNING "%s: Too much work in interrupt, status "
- "%4.4x.\n", dev->name, status);
+ pr_warning("%s: Too much work in interrupt, status %4.4x.\n",
+ dev->name, status);
/* Disable all pending interrupts. */
do {
vp->deferred |= status;
@@ -2413,7 +2409,7 @@ boomerang_interrupt(int irq, void *dev_id)
} while ((status = ioread16(ioaddr + EL3_STATUS)) & IntLatch);
if (vortex_debug > 4)
- printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
+ pr_debug("%s: exiting interrupt, status %4.4x.\n",
dev->name, status);
handler_exit:
spin_unlock(&vp->lock);
@@ -2428,13 +2424,13 @@ static int vortex_rx(struct net_device *dev)
short rx_status;
if (vortex_debug > 5)
- printk(KERN_DEBUG "vortex_rx(): status %4.4x, rx_status %4.4x.\n",
+ pr_debug("vortex_rx(): status %4.4x, rx_status %4.4x.\n",
ioread16(ioaddr+EL3_STATUS), ioread16(ioaddr+RxStatus));
while ((rx_status = ioread16(ioaddr + RxStatus)) > 0) {
if (rx_status & 0x4000) { /* Error, update stats. */
unsigned char rx_error = ioread8(ioaddr + RxErrors);
if (vortex_debug > 2)
- printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
+ pr_debug(" Rx error: status %2.2x.\n", rx_error);
dev->stats.rx_errors++;
if (rx_error & 0x01) dev->stats.rx_over_errors++;
if (rx_error & 0x02) dev->stats.rx_length_errors++;
@@ -2448,7 +2444,7 @@ static int vortex_rx(struct net_device *dev)
skb = dev_alloc_skb(pkt_len + 5);
if (vortex_debug > 4)
- printk(KERN_DEBUG "Receiving packet size %d status %4.4x.\n",
+ pr_debug("Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status);
if (skb != NULL) {
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
@@ -2478,8 +2474,8 @@ static int vortex_rx(struct net_device *dev)
break;
continue;
} else if (vortex_debug > 0)
- printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of "
- "size %d.\n", dev->name, pkt_len);
+ pr_notice("%s: No memory to allocate a sk_buff of size %d.\n",
+ dev->name, pkt_len);
dev->stats.rx_dropped++;
}
issue_and_wait(dev, RxDiscard);
@@ -2498,7 +2494,7 @@ boomerang_rx(struct net_device *dev)
int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx;
if (vortex_debug > 5)
- printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
+ pr_debug("boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){
if (--rx_work_limit < 0)
@@ -2506,7 +2502,7 @@ boomerang_rx(struct net_device *dev)
if (rx_status & RxDError) { /* Error, update stats. */
unsigned char rx_error = rx_status >> 16;
if (vortex_debug > 2)
- printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
+ pr_debug(" Rx error: status %2.2x.\n", rx_error);
dev->stats.rx_errors++;
if (rx_error & 0x01) dev->stats.rx_over_errors++;
if (rx_error & 0x02) dev->stats.rx_length_errors++;
@@ -2520,7 +2516,7 @@ boomerang_rx(struct net_device *dev)
dma_addr_t dma = le32_to_cpu(vp->rx_ring[entry].addr);
if (vortex_debug > 4)
- printk(KERN_DEBUG "Receiving packet size %d status %4.4x.\n",
+ pr_debug("Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status);
/* Check if the packet is long enough to just accept without
@@ -2566,7 +2562,7 @@ boomerang_rx(struct net_device *dev)
if (skb == NULL) {
static unsigned long last_jif;
if (time_after(jiffies, last_jif + 10 * HZ)) {
- printk(KERN_WARNING "%s: memory shortage\n", dev->name);
+ pr_warning("%s: memory shortage\n", dev->name);
last_jif = jiffies;
}
if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE)
@@ -2598,7 +2594,7 @@ rx_oom_timer(unsigned long arg)
if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE) /* This test is redundant, but makes me feel good */
boomerang_rx(dev);
if (vortex_debug > 1) {
- printk(KERN_DEBUG "%s: rx_oom_timer %s\n", dev->name,
+ pr_debug("%s: rx_oom_timer %s\n", dev->name,
((vp->cur_rx - vp->dirty_rx) != RX_RING_SIZE) ? "succeeded" : "retrying");
}
spin_unlock_irq(&vp->lock);
@@ -2655,9 +2651,9 @@ vortex_close(struct net_device *dev)
vortex_down(dev, 1);
if (vortex_debug > 1) {
- printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
+ pr_debug("%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
dev->name, ioread16(ioaddr + EL3_STATUS), ioread8(ioaddr + TxStatus));
- printk(KERN_DEBUG "%s: vortex close stats: rx_nocopy %d rx_copy %d"
+ pr_debug("%s: vortex close stats: rx_nocopy %d rx_copy %d"
" tx_queued %d Rx pre-checksummed %d.\n",
dev->name, vp->rx_nocopy, vp->rx_copy, vp->queued_packet, vp->rx_csumhits);
}
@@ -2666,8 +2662,7 @@ vortex_close(struct net_device *dev)
if (vp->rx_csumhits &&
(vp->drv_flags & HAS_HWCKSM) == 0 &&
(vp->card_idx >= MAX_UNITS || hw_checksums[vp->card_idx] == -1)) {
- printk(KERN_WARNING "%s supports hardware checksums, and we're "
- "not using them!\n", dev->name);
+ pr_warning("%s supports hardware checksums, and we're not using them!\n", dev->name);
}
#endif
@@ -2717,16 +2712,16 @@ dump_tx_ring(struct net_device *dev)
int i;
int stalled = ioread32(ioaddr + PktStatus) & 0x04; /* Possible racy. But it's only debug stuff */
- printk(KERN_ERR " Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
+ pr_err(" Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
vp->full_bus_master_tx,
vp->dirty_tx, vp->dirty_tx % TX_RING_SIZE,
vp->cur_tx, vp->cur_tx % TX_RING_SIZE);
- printk(KERN_ERR " Transmit list %8.8x vs. %p.\n",
+ pr_err(" Transmit list %8.8x vs. %p.\n",
ioread32(ioaddr + DownListPtr),
&vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
issue_and_wait(dev, DownStall);
for (i = 0; i < TX_RING_SIZE; i++) {
- printk(KERN_ERR " %d: @%p length %8.8x status %8.8x\n", i,
+ pr_err(" %d: @%p length %8.8x status %8.8x\n", i,
&vp->tx_ring[i],
#if DO_ZEROCOPY
le32_to_cpu(vp->tx_ring[i].frag[0].length),
@@ -2970,7 +2965,7 @@ static void set_rx_mode(struct net_device *dev)
if (dev->flags & IFF_PROMISC) {
if (vortex_debug > 3)
- printk(KERN_NOTICE "%s: Setting promiscuous mode.\n", dev->name);
+ pr_notice("%s: Setting promiscuous mode.\n", dev->name);
new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast|RxProm;
} else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast;
@@ -3145,8 +3140,7 @@ static void acpi_set_WOL(struct net_device *dev)
iowrite16(RxEnable, ioaddr + EL3_CMD);
if (pci_enable_wake(VORTEX_PCI(vp), PCI_D3hot, 1)) {
- printk(KERN_INFO "%s: WOL not supported.\n",
- pci_name(VORTEX_PCI(vp)));
+ pr_info("%s: WOL not supported.\n", pci_name(VORTEX_PCI(vp)));
vp->enable_wol = 0;
return;
@@ -3164,7 +3158,7 @@ static void __devexit vortex_remove_one(struct pci_dev *pdev)
struct vortex_private *vp;
if (!dev) {
- printk("vortex_remove_one called for Compaq device!\n");
+ pr_err("vortex_remove_one called for Compaq device!\n");
BUG();
}
diff --git a/drivers/net/7990.c b/drivers/net/7990.c
index 7a331acc34a..69f5b7d298a 100644
--- a/drivers/net/7990.c
+++ b/drivers/net/7990.c
@@ -541,7 +541,7 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
unsigned long flags;
if (!TX_BUFFS_AVAIL)
- return -1;
+ return NETDEV_TX_LOCKED;
netif_stop_queue (dev);
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 02330f3d5a5..50efde11ea6 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -471,8 +471,7 @@ static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail,
u32 status, u32 len)
{
if (netif_msg_rx_err (cp))
- printk (KERN_DEBUG
- "%s: rx err, slot %d status 0x%x len %d\n",
+ pr_debug("%s: rx err, slot %d status 0x%x len %d\n",
cp->dev->name, rx_tail, status, len);
cp->dev->stats.rx_errors++;
if (status & RxErrFrame)
@@ -547,7 +546,7 @@ rx_status_loop:
}
if (netif_msg_rx_status(cp))
- printk(KERN_DEBUG "%s: rx slot %d status 0x%x len %d\n",
+ pr_debug("%s: rx slot %d status 0x%x len %d\n",
dev->name, rx_tail, status, len);
buflen = cp->rx_buf_sz + NET_IP_ALIGN;
@@ -626,7 +625,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
return IRQ_NONE;
if (netif_msg_intr(cp))
- printk(KERN_DEBUG "%s: intr, status %04x cmd %02x cpcmd %04x\n",
+ pr_debug("%s: intr, status %04x cmd %02x cpcmd %04x\n",
dev->name, status, cpr8(Cmd), cpr16(CpCmd));
cpw16(IntrStatus, status & ~cp_rx_intr_mask);
@@ -658,7 +657,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
pci_read_config_word(cp->pdev, PCI_STATUS, &pci_status);
pci_write_config_word(cp->pdev, PCI_STATUS, pci_status);
- printk(KERN_ERR "%s: PCI bus error, status=%04x, PCI status=%04x\n",
+ pr_err("%s: PCI bus error, status=%04x, PCI status=%04x\n",
dev->name, status, pci_status);
/* TODO: reset hardware */
@@ -705,7 +704,7 @@ static void cp_tx (struct cp_private *cp)
if (status & LastFrag) {
if (status & (TxError | TxFIFOUnder)) {
if (netif_msg_tx_err(cp))
- printk(KERN_DEBUG "%s: tx err, status 0x%x\n",
+ pr_debug("%s: tx err, status 0x%x\n",
cp->dev->name, status);
cp->dev->stats.tx_errors++;
if (status & TxOWC)
@@ -722,7 +721,7 @@ static void cp_tx (struct cp_private *cp)
cp->dev->stats.tx_packets++;
cp->dev->stats.tx_bytes += skb->len;
if (netif_msg_tx_done(cp))
- printk(KERN_DEBUG "%s: tx done, slot %d\n", cp->dev->name, tx_tail);
+ pr_debug("%s: tx done, slot %d\n", cp->dev->name, tx_tail);
}
dev_kfree_skb_irq(skb);
}
@@ -755,9 +754,9 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) {
netif_stop_queue(dev);
spin_unlock_irqrestore(&cp->lock, intr_flags);
- printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
+ pr_err(PFX "%s: BUG! Tx Ring full when queue awake!\n",
dev->name);
- return 1;
+ return NETDEV_TX_BUSY;
}
#if CP_VLAN_TAG_USED
@@ -882,7 +881,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
}
cp->tx_head = entry;
if (netif_msg_tx_queued(cp))
- printk(KERN_DEBUG "%s: tx queued, slot %d, skblen %d\n",
+ pr_debug("%s: tx queued, slot %d, skblen %d\n",
dev->name, entry, skb->len);
if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1))
netif_stop_queue(dev);
@@ -996,7 +995,7 @@ static void cp_reset_hw (struct cp_private *cp)
schedule_timeout_uninterruptible(10);
}
- printk(KERN_ERR "%s: hardware reset timeout\n", cp->dev->name);
+ pr_err("%s: hardware reset timeout\n", cp->dev->name);
}
static inline void cp_start_hw (struct cp_private *cp)
@@ -1166,7 +1165,7 @@ static int cp_open (struct net_device *dev)
int rc;
if (netif_msg_ifup(cp))
- printk(KERN_DEBUG "%s: enabling interface\n", dev->name);
+ pr_debug("%s: enabling interface\n", dev->name);
rc = cp_alloc_rings(cp);
if (rc)
@@ -1201,7 +1200,7 @@ static int cp_close (struct net_device *dev)
napi_disable(&cp->napi);
if (netif_msg_ifdown(cp))
- printk(KERN_DEBUG "%s: disabling interface\n", dev->name);
+ pr_debug("%s: disabling interface\n", dev->name);
spin_lock_irqsave(&cp->lock, flags);
@@ -1224,7 +1223,7 @@ static void cp_tx_timeout(struct net_device *dev)
unsigned long flags;
int rc;
- printk(KERN_WARNING "%s: Transmit timeout, status %2x %4x %4x %4x\n",
+ pr_warning("%s: Transmit timeout, status %2x %4x %4x %4x\n",
dev->name, cpr8(Cmd), cpr16(CpCmd),
cpr16(IntrStatus), cpr16(IntrMask));
@@ -1873,7 +1872,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
#ifndef MODULE
static int version_printed;
if (version_printed++ == 0)
- printk("%s", version);
+ pr_info("%s", version);
#endif
if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
@@ -1995,8 +1994,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
goto err_out_iomap;
- printk (KERN_INFO "%s: RTL-8139C+ at 0x%lx, "
- "%pM, IRQ %d\n",
+ pr_info("%s: RTL-8139C+ at 0x%lx, %pM, IRQ %d\n",
dev->name,
dev->base_addr,
dev->dev_addr,
@@ -2113,7 +2111,7 @@ static struct pci_driver cp_driver = {
static int __init cp_init (void)
{
#ifdef MODULE
- printk("%s", version);
+ pr_info("%s", version);
#endif
return pci_register_driver(&cp_driver);
}
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 1fc45431a62..8ae72ec1445 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -126,19 +126,12 @@
#undef RTL8139_NDEBUG
-#if RTL8139_DEBUG
-/* note: prints function name for you */
-# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
-#else
-# define DPRINTK(fmt, args...)
-#endif
-
#ifdef RTL8139_NDEBUG
# define assert(expr) do {} while (0)
#else
# define assert(expr) \
if(unlikely(!(expr))) { \
- printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \
+ pr_err("Assertion failed! %s,%s,%s,line=%d\n", \
#expr, __FILE__, __func__, __LINE__); \
}
#endif
@@ -784,8 +777,8 @@ static __devinit struct net_device * rtl8139_init_board (struct pci_dev *pdev)
/* set this immediately, we need to know before
* we talk to the chip directly */
- DPRINTK("PIO region size == 0x%02X\n", pio_len);
- DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);
+ pr_debug("PIO region size == 0x%02lX\n", pio_len);
+ pr_debug("MMIO region size == 0x%02lX\n", mmio_len);
retry:
if (use_io) {
@@ -865,19 +858,17 @@ retry:
}
/* if unknown chip, assume array element #0, original RTL-8139 in this case */
- dev_printk (KERN_DEBUG, &pdev->dev,
- "unknown chip version, assuming RTL-8139\n");
- dev_printk (KERN_DEBUG, &pdev->dev,
- "TxConfig = 0x%lx\n", RTL_R32 (TxConfig));
+ dev_dbg(&pdev->dev, "unknown chip version, assuming RTL-8139\n");
+ dev_dbg(&pdev->dev, "TxConfig = 0x%lx\n", RTL_R32 (TxConfig));
tp->chipset = 0;
match:
- DPRINTK ("chipset id (%d) == index %d, '%s'\n",
+ pr_debug("chipset id (%d) == index %d, '%s'\n",
version, i, rtl_chip_info[i].name);
if (tp->chipset >= CH_8139B) {
u8 new_tmp8 = tmp8 = RTL_R8 (Config1);
- DPRINTK("PCI PM wakeup\n");
+ pr_debug("PCI PM wakeup\n");
if ((rtl_chip_info[tp->chipset].flags & HasLWake) &&
(tmp8 & LWAKE))
new_tmp8 &= ~LWAKE;
@@ -896,7 +887,7 @@ match:
}
}
} else {
- DPRINTK("Old chip wakeup\n");
+ pr_debug("Old chip wakeup\n");
tmp8 = RTL_R8 (Config1);
tmp8 &= ~(SLEEP | PWRDN);
RTL_W8 (Config1, tmp8);
@@ -949,7 +940,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
{
static int printed_version;
if (!printed_version++)
- printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
+ pr_info(RTL8139_DRIVER_NAME "\n");
}
#endif
@@ -965,7 +956,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
pdev->device == PCI_DEVICE_ID_REALTEK_8139 &&
pdev->subsystem_vendor == PCI_VENDOR_ID_ATHEROS &&
pdev->subsystem_device == PCI_DEVICE_ID_REALTEK_8139) {
- printk(KERN_INFO "8139too: OQO Model 2 detected. Forcing PIO\n");
+ pr_info("8139too: OQO Model 2 detected. Forcing PIO\n");
use_io = 1;
}
@@ -1018,21 +1009,20 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
tp->mii.reg_num_mask = 0x1f;
/* dev is fully set up and ready to use now */
- DPRINTK("about to register device named %s (%p)...\n", dev->name, dev);
+ pr_debug("about to register device named %s (%p)...\n", dev->name, dev);
i = register_netdev (dev);
if (i) goto err_out;
pci_set_drvdata (pdev, dev);
- printk (KERN_INFO "%s: %s at 0x%lx, "
- "%pM, IRQ %d\n",
+ pr_info("%s: %s at 0x%lx, %pM, IRQ %d\n",
dev->name,
board_info[ent->driver_data].name,
dev->base_addr,
dev->dev_addr,
dev->irq);
- printk (KERN_DEBUG "%s: Identified 8139 chip type '%s'\n",
+ pr_debug("%s: Identified 8139 chip type '%s'\n",
dev->name, rtl_chip_info[tp->chipset].name);
/* Find the connected MII xcvrs.
@@ -1046,14 +1036,12 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
if (mii_status != 0xffff && mii_status != 0x0000) {
u16 advertising = mdio_read(dev, phy, 4);
tp->phys[phy_idx++] = phy;
- printk(KERN_INFO "%s: MII transceiver %d status 0x%4.4x "
- "advertising %4.4x.\n",
+ pr_info("%s: MII transceiver %d status 0x%4.4x advertising %4.4x.\n",
dev->name, phy, mii_status, advertising);
}
}
if (phy_idx == 0) {
- printk(KERN_INFO "%s: No MII transceivers found! Assuming SYM "
- "transceiver.\n",
+ pr_info("%s: No MII transceivers found! Assuming SYM transceiver.\n",
dev->name);
tp->phys[0] = 32;
}
@@ -1073,13 +1061,13 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
if (board_idx < MAX_UNITS && full_duplex[board_idx] > 0)
tp->mii.full_duplex = full_duplex[board_idx];
if (tp->mii.full_duplex) {
- printk(KERN_INFO "%s: Media type forced to Full Duplex.\n", dev->name);
+ pr_info("%s: Media type forced to Full Duplex.\n", dev->name);
/* Changing the MII-advertised media because might prevent
re-connection. */
tp->mii.force_media = 1;
}
if (tp->default_port) {
- printk(KERN_INFO " Forcing %dMbps %s-duplex operation.\n",
+ pr_info(" Forcing %dMbps %s-duplex operation.\n",
(option & 0x20 ? 100 : 10),
(option & 0x10 ? "full" : "half"));
mdio_write(dev, tp->phys[0], 0,
@@ -1342,7 +1330,7 @@ static int rtl8139_open (struct net_device *dev)
netif_start_queue (dev);
if (netif_msg_ifup(tp))
- printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#llx IRQ %d"
+ pr_debug("%s: rtl8139_open() ioaddr %#llx IRQ %d"
" GP Pins %2.2x %s-duplex.\n", dev->name,
(unsigned long long)pci_resource_start (tp->pci_dev, 1),
dev->irq, RTL_R8 (MediaStatus),
@@ -1404,7 +1392,7 @@ static void rtl8139_hw_start (struct net_device *dev)
RTL_W8 (Config3, RTL_R8 (Config3) & ~Cfg3_Magic);
}
- DPRINTK("init buffer addresses\n");
+ pr_debug("init buffer addresses\n");
/* Lock Config[01234] and BMCR register writes */
RTL_W8 (Cfg9346, Cfg9346_Lock);
@@ -1566,14 +1554,13 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
tp->mii.full_duplex = duplex;
if (mii_lpa) {
- printk (KERN_INFO
- "%s: Setting %s-duplex based on MII #%d link"
+ pr_info("%s: Setting %s-duplex based on MII #%d link"
" partner ability of %4.4x.\n",
dev->name,
tp->mii.full_duplex ? "full" : "half",
tp->phys[0], mii_lpa);
} else {
- printk(KERN_INFO"%s: media is unconnected, link down, or incompatible connection\n",
+ pr_info("%s: media is unconnected, link down, or incompatible connection\n",
dev->name);
}
#if 0
@@ -1588,11 +1575,11 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
rtl8139_tune_twister (dev, tp);
- DPRINTK ("%s: Media selection tick, Link partner %4.4x.\n",
+ pr_debug("%s: Media selection tick, Link partner %4.4x.\n",
dev->name, RTL_R16 (NWayLPAR));
- DPRINTK ("%s: Other registers are IntMask %4.4x IntStatus %4.4x\n",
+ pr_debug("%s: Other registers are IntMask %4.4x IntStatus %4.4x\n",
dev->name, RTL_R16 (IntrMask), RTL_R16 (IntrStatus));
- DPRINTK ("%s: Chip config %2.2x %2.2x.\n",
+ pr_debug("%s: Chip config %2.2x %2.2x.\n",
dev->name, RTL_R8 (Config0),
RTL_R8 (Config1));
}
@@ -1652,14 +1639,14 @@ static void rtl8139_tx_timeout_task (struct work_struct *work)
int i;
u8 tmp8;
- printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x "
- "media %2.2x.\n", dev->name, RTL_R8 (ChipCmd),
+ pr_debug("%s: Transmit timeout, status %2.2x %4.4x %4.4x media %2.2x.\n",
+ dev->name, RTL_R8 (ChipCmd),
RTL_R16(IntrStatus), RTL_R16(IntrMask), RTL_R8(MediaStatus));
/* Emit info to figure out what went wrong. */
- printk (KERN_DEBUG "%s: Tx queue start entry %ld dirty entry %ld.\n",
+ pr_debug("%s: Tx queue start entry %ld dirty entry %ld.\n",
dev->name, tp->cur_tx, tp->dirty_tx);
for (i = 0; i < NUM_TX_DESC; i++)
- printk (KERN_DEBUG "%s: Tx descriptor %d is %8.8lx.%s\n",
+ pr_debug("%s: Tx descriptor %d is %8.8lx.%s\n",
dev->name, i, RTL_R32 (TxStatus0 + (i * 4)),
i == tp->dirty_tx % NUM_TX_DESC ?
" (queue head)" : "");
@@ -1741,7 +1728,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&tp->lock, flags);
if (netif_msg_tx_queued(tp))
- printk (KERN_DEBUG "%s: Queued Tx packet size %u to slot %d.\n",
+ pr_debug("%s: Queued Tx packet size %u to slot %d.\n",
dev->name, len, entry);
return 0;
@@ -1772,7 +1759,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
if (txstatus & (TxOutOfWindow | TxAborted)) {
/* There was an major error, log it. */
if (netif_msg_tx_err(tp))
- printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
+ pr_debug("%s: Transmit error, Tx status %8.8x.\n",
dev->name, txstatus);
dev->stats.tx_errors++;
if (txstatus & TxAborted) {
@@ -1803,7 +1790,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
#ifndef RTL8139_NDEBUG
if (tp->cur_tx - dirty_tx > NUM_TX_DESC) {
- printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
+ pr_err("%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
dev->name, dirty_tx, tp->cur_tx);
dirty_tx += NUM_TX_DESC;
}
@@ -1828,12 +1815,12 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
#endif
if (netif_msg_rx_err (tp))
- printk(KERN_DEBUG "%s: Ethernet frame had errors, status %8.8x.\n",
+ pr_debug("%s: Ethernet frame had errors, status %8.8x.\n",
dev->name, rx_status);
dev->stats.rx_errors++;
if (!(rx_status & RxStatusOK)) {
if (rx_status & RxTooLong) {
- DPRINTK ("%s: Oversized Ethernet frame, status %4.4x!\n",
+ pr_debug("%s: Oversized Ethernet frame, status %4.4x!\n",
dev->name, rx_status);
/* A.C.: The chip hangs here. */
}
@@ -1866,7 +1853,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
break;
}
if (tmp_work <= 0)
- printk (KERN_WARNING PFX "rx stop wait too long\n");
+ pr_warning(PFX "rx stop wait too long\n");
/* restart receive */
tmp_work = 200;
while (--tmp_work > 0) {
@@ -1877,7 +1864,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
break;
}
if (tmp_work <= 0)
- printk (KERN_WARNING PFX "tx/rx enable wait too long\n");
+ pr_warning(PFX "tx/rx enable wait too long\n");
/* and reinitialize all rx related registers */
RTL_W8_F (Cfg9346, Cfg9346_Unlock);
@@ -1888,7 +1875,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
RTL_W32 (RxConfig, tp->rx_config);
tp->cur_rx = 0;
- DPRINTK("init buffer addresses\n");
+ pr_debug("init buffer addresses\n");
/* Lock Config[01234] and BMCR register writes */
RTL_W8 (Cfg9346, Cfg9346_Lock);
@@ -1942,7 +1929,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
unsigned int cur_rx = tp->cur_rx;
unsigned int rx_size = 0;
- DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
+ pr_debug("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
" free to %4.4x, Cmd %2.2x.\n", dev->name, (u16)cur_rx,
RTL_R16 (RxBufAddr),
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
@@ -1962,17 +1949,17 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
pkt_size = rx_size - 4;
if (netif_msg_rx_status(tp))
- printk(KERN_DEBUG "%s: rtl8139_rx() status %4.4x, size %4.4x,"
+ pr_debug("%s: rtl8139_rx() status %4.4x, size %4.4x,"
" cur %4.4x.\n", dev->name, rx_status,
rx_size, cur_rx);
#if RTL8139_DEBUG > 2
{
int i;
- DPRINTK ("%s: Frame contents ", dev->name);
+ pr_debug("%s: Frame contents ", dev->name);
for (i = 0; i < 70; i++)
- printk (" %2.2x",
+ pr_cont(" %2.2x",
rx_ring[ring_offset + i]);
- printk (".\n");
+ pr_cont(".\n");
}
#endif
@@ -1984,12 +1971,12 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
if (!tp->fifo_copy_timeout)
tp->fifo_copy_timeout = jiffies + 2;
else if (time_after(jiffies, tp->fifo_copy_timeout)) {
- DPRINTK ("%s: hung FIFO. Reset.", dev->name);
+ pr_debug("%s: hung FIFO. Reset.", dev->name);
rx_size = 0;
goto no_early_rx;
}
if (netif_msg_intr(tp)) {
- printk(KERN_DEBUG "%s: fifo copy in progress.",
+ pr_debug("%s: fifo copy in progress.",
dev->name);
}
tp->xstats.early_rx++;
@@ -2033,8 +2020,7 @@ no_early_rx:
netif_receive_skb (skb);
} else {
if (net_ratelimit())
- printk (KERN_WARNING
- "%s: Memory squeeze, dropping packet.\n",
+ pr_warning("%s: Memory squeeze, dropping packet.\n",
dev->name);
dev->stats.rx_dropped++;
}
@@ -2049,12 +2035,10 @@ no_early_rx:
if (unlikely(!received || rx_size == 0xfff0))
rtl8139_isr_ack(tp);
-#if RTL8139_DEBUG > 1
- DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
+ pr_debug("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
" free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
RTL_R16 (RxBufAddr),
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
-#endif
tp->cur_rx = cur_rx;
@@ -2075,7 +2059,7 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
void __iomem *ioaddr,
int status, int link_changed)
{
- DPRINTK ("%s: Abnormal interrupt, status %8.8x.\n",
+ pr_debug("%s: Abnormal interrupt, status %8.8x.\n",
dev->name, status);
assert (dev != NULL);
@@ -2104,7 +2088,7 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
pci_write_config_word (tp->pci_dev, PCI_STATUS, pci_cmd_status);
- printk (KERN_ERR "%s: PCI Bus error %4.4x.\n",
+ pr_err("%s: PCI Bus error %4.4x.\n",
dev->name, pci_cmd_status);
}
}
@@ -2198,7 +2182,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
out:
spin_unlock (&tp->lock);
- DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
+ pr_debug("%s: exiting interrupt, intr_status=%#4.4x.\n",
dev->name, RTL_R16 (IntrStatus));
return IRQ_RETVAL(handled);
}
@@ -2249,7 +2233,7 @@ static int rtl8139_close (struct net_device *dev)
napi_disable(&tp->napi);
if (netif_msg_ifdown(tp))
- printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
+ pr_debug("%s: Shutting down ethercard, status was 0x%4.4x.\n",
dev->name, RTL_R16 (IntrStatus));
spin_lock_irqsave (&tp->lock, flags);
@@ -2292,11 +2276,11 @@ static int rtl8139_close (struct net_device *dev)
other threads or interrupts aren't messing with the 8139. */
static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
- struct rtl8139_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->mmio_addr;
+ struct rtl8139_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->mmio_addr;
- spin_lock_irq(&np->lock);
- if (rtl_chip_info[np->chipset].flags & HasLWake) {
+ spin_lock_irq(&tp->lock);
+ if (rtl_chip_info[tp->chipset].flags & HasLWake) {
u8 cfg3 = RTL_R8 (Config3);
u8 cfg5 = RTL_R8 (Config5);
@@ -2317,7 +2301,7 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
if (cfg5 & Cfg5_BWF)
wol->wolopts |= WAKE_BCAST;
}
- spin_unlock_irq(&np->lock);
+ spin_unlock_irq(&tp->lock);
}
@@ -2326,19 +2310,19 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
aren't messing with the 8139. */
static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
- struct rtl8139_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->mmio_addr;
+ struct rtl8139_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->mmio_addr;
u32 support;
u8 cfg3, cfg5;
- support = ((rtl_chip_info[np->chipset].flags & HasLWake)
+ support = ((rtl_chip_info[tp->chipset].flags & HasLWake)
? (WAKE_PHY | WAKE_MAGIC
| WAKE_UCAST | WAKE_MCAST | WAKE_BCAST)
: 0);
if (wol->wolopts & ~support)
return -EINVAL;
- spin_lock_irq(&np->lock);
+ spin_lock_irq(&tp->lock);
cfg3 = RTL_R8 (Config3) & ~(Cfg3_LinkUp | Cfg3_Magic);
if (wol->wolopts & WAKE_PHY)
cfg3 |= Cfg3_LinkUp;
@@ -2359,87 +2343,87 @@ static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
if (wol->wolopts & WAKE_BCAST)
cfg5 |= Cfg5_BWF;
RTL_W8 (Config5, cfg5); /* need not unlock via Cfg9346 */
- spin_unlock_irq(&np->lock);
+ spin_unlock_irq(&tp->lock);
return 0;
}
static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
- struct rtl8139_private *np = netdev_priv(dev);
+ struct rtl8139_private *tp = netdev_priv(dev);
strcpy(info->driver, DRV_NAME);
strcpy(info->version, DRV_VERSION);
- strcpy(info->bus_info, pci_name(np->pci_dev));
- info->regdump_len = np->regs_len;
+ strcpy(info->bus_info, pci_name(tp->pci_dev));
+ info->regdump_len = tp->regs_len;
}
static int rtl8139_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- struct rtl8139_private *np = netdev_priv(dev);
- spin_lock_irq(&np->lock);
- mii_ethtool_gset(&np->mii, cmd);
- spin_unlock_irq(&np->lock);
+ struct rtl8139_private *tp = netdev_priv(dev);
+ spin_lock_irq(&tp->lock);
+ mii_ethtool_gset(&tp->mii, cmd);
+ spin_unlock_irq(&tp->lock);
return 0;
}
static int rtl8139_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- struct rtl8139_private *np = netdev_priv(dev);
+ struct rtl8139_private *tp = netdev_priv(dev);
int rc;
- spin_lock_irq(&np->lock);
- rc = mii_ethtool_sset(&np->mii, cmd);
- spin_unlock_irq(&np->lock);
+ spin_lock_irq(&tp->lock);
+ rc = mii_ethtool_sset(&tp->mii, cmd);
+ spin_unlock_irq(&tp->lock);
return rc;
}
static int rtl8139_nway_reset(struct net_device *dev)
{
- struct rtl8139_private *np = netdev_priv(dev);
- return mii_nway_restart(&np->mii);
+ struct rtl8139_private *tp = netdev_priv(dev);
+ return mii_nway_restart(&tp->mii);
}
static u32 rtl8139_get_link(struct net_device *dev)
{
- struct rtl8139_private *np = netdev_priv(dev);
- return mii_link_ok(&np->mii);
+ struct rtl8139_private *tp = netdev_priv(dev);
+ return mii_link_ok(&tp->mii);
}
static u32 rtl8139_get_msglevel(struct net_device *dev)
{
- struct rtl8139_private *np = netdev_priv(dev);
- return np->msg_enable;
+ struct rtl8139_private *tp = netdev_priv(dev);
+ return tp->msg_enable;
}
static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
{
- struct rtl8139_private *np = netdev_priv(dev);
- np->msg_enable = datum;
+ struct rtl8139_private *tp = netdev_priv(dev);
+ tp->msg_enable = datum;
}
static int rtl8139_get_regs_len(struct net_device *dev)
{
- struct rtl8139_private *np;
+ struct rtl8139_private *tp;
/* TODO: we are too slack to do reg dumping for pio, for now */
if (use_io)
return 0;
- np = netdev_priv(dev);
- return np->regs_len;
+ tp = netdev_priv(dev);
+ return tp->regs_len;
}
static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
{
- struct rtl8139_private *np;
+ struct rtl8139_private *tp;
/* TODO: we are too slack to do reg dumping for pio, for now */
if (use_io)
return;
- np = netdev_priv(dev);
+ tp = netdev_priv(dev);
regs->version = RTL_REGS_VER;
- spin_lock_irq(&np->lock);
- memcpy_fromio(regbuf, np->mmio_addr, regs->len);
- spin_unlock_irq(&np->lock);
+ spin_lock_irq(&tp->lock);
+ memcpy_fromio(regbuf, tp->mmio_addr, regs->len);
+ spin_unlock_irq(&tp->lock);
}
static int rtl8139_get_sset_count(struct net_device *dev, int sset)
@@ -2454,12 +2438,12 @@ static int rtl8139_get_sset_count(struct net_device *dev, int sset)
static void rtl8139_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data)
{
- struct rtl8139_private *np = netdev_priv(dev);
+ struct rtl8139_private *tp = netdev_priv(dev);
- data[0] = np->xstats.early_rx;
- data[1] = np->xstats.tx_buf_mapped;
- data[2] = np->xstats.tx_timeouts;
- data[3] = np->xstats.rx_lost_in_ring;
+ data[0] = tp->xstats.early_rx;
+ data[1] = tp->xstats.tx_buf_mapped;
+ data[2] = tp->xstats.tx_timeouts;
+ data[3] = tp->xstats.rx_lost_in_ring;
}
static void rtl8139_get_strings(struct net_device *dev, u32 stringset, u8 *data)
@@ -2486,15 +2470,15 @@ static const struct ethtool_ops rtl8139_ethtool_ops = {
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- struct rtl8139_private *np = netdev_priv(dev);
+ struct rtl8139_private *tp = netdev_priv(dev);
int rc;
if (!netif_running(dev))
return -EINVAL;
- spin_lock_irq(&np->lock);
- rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
- spin_unlock_irq(&np->lock);
+ spin_lock_irq(&tp->lock);
+ rc = generic_mii_ioctl(&tp->mii, if_mii(rq), cmd, NULL);
+ spin_unlock_irq(&tp->lock);
return rc;
}
@@ -2527,7 +2511,7 @@ static void __set_rx_mode (struct net_device *dev)
int i, rx_mode;
u32 tmp;
- DPRINTK ("%s: rtl8139_set_rx_mode(%4.4x) done -- Rx config %8.8lx.\n",
+ pr_debug("%s: rtl8139_set_rx_mode(%4.4x) done -- Rx config %8.8lx.\n",
dev->name, dev->flags, RTL_R32 (RxConfig));
/* Note: do not reorder, GCC is clever about common statements. */
@@ -2643,7 +2627,7 @@ static int __init rtl8139_init_module (void)
* even if no 8139 board is found.
*/
#ifdef MODULE
- printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
+ pr_info(RTL8139_DRIVER_NAME "\n");
#endif
return pci_register_driver(&rtl8139_pci_driver);
diff --git a/drivers/net/82596.c b/drivers/net/82596.c
index cca94b9c08a..77547545509 100644
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -122,13 +122,13 @@ static char version[] __initdata =
#define ISCP_BUSY 0x00010000
#define MACH_IS_APRICOT 0
#else
-#define WSWAPrfd(x) ((struct i596_rfd *)(x))
-#define WSWAPrbd(x) ((struct i596_rbd *)(x))
-#define WSWAPiscp(x) ((struct i596_iscp *)(x))
-#define WSWAPscb(x) ((struct i596_scb *)(x))
-#define WSWAPcmd(x) ((struct i596_cmd *)(x))
-#define WSWAPtbd(x) ((struct i596_tbd *)(x))
-#define WSWAPchar(x) ((char *)(x))
+#define WSWAPrfd(x) ((struct i596_rfd *)((long)x))
+#define WSWAPrbd(x) ((struct i596_rbd *)((long)x))
+#define WSWAPiscp(x) ((struct i596_iscp *)((long)x))
+#define WSWAPscb(x) ((struct i596_scb *)((long)x))
+#define WSWAPcmd(x) ((struct i596_cmd *)((long)x))
+#define WSWAPtbd(x) ((struct i596_tbd *)((long)x))
+#define WSWAPchar(x) ((char *)((long)x))
#define ISCP_BUSY 0x0001
#define MACH_IS_APRICOT 1
#endif
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
index ec3e22e6306..21153dea8eb 100644
--- a/drivers/net/8390.c
+++ b/drivers/net/8390.c
@@ -74,14 +74,8 @@ EXPORT_SYMBOL(ei_netdev_ops);
struct net_device *__alloc_ei_netdev(int size)
{
struct net_device *dev = ____alloc_ei_netdev(size);
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
- if (dev) {
- dev->hard_start_xmit = ei_start_xmit;
- dev->get_stats = ei_get_stats;
- dev->set_multicast_list = ei_set_multicast_list;
- dev->tx_timeout = ei_tx_timeout;
- }
-#endif
+ if (dev)
+ dev->netdev_ops = &ei_netdev_ops;
return dev;
}
EXPORT_SYMBOL(__alloc_ei_netdev);
diff --git a/drivers/net/8390p.c b/drivers/net/8390p.c
index da863c91d1d..d225c291fd9 100644
--- a/drivers/net/8390p.c
+++ b/drivers/net/8390p.c
@@ -79,14 +79,8 @@ EXPORT_SYMBOL(eip_netdev_ops);
struct net_device *__alloc_eip_netdev(int size)
{
struct net_device *dev = ____alloc_ei_netdev(size);
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
- if (dev) {
- dev->hard_start_xmit = eip_start_xmit;
- dev->get_stats = eip_get_stats;
- dev->set_multicast_list = eip_set_multicast_list;
- dev->tx_timeout = eip_tx_timeout;
- }
-#endif
+ if (dev)
+ dev->netdev_ops = &eip_netdev_ops;
return dev;
}
EXPORT_SYMBOL(__alloc_eip_netdev);
@@ -97,16 +91,15 @@ void NS8390p_init(struct net_device *dev, int startp)
}
EXPORT_SYMBOL(NS8390p_init);
-#if defined(MODULE)
-
-int init_module(void)
+static int __init NS8390p_init_module(void)
{
return 0;
}
-void cleanup_module(void)
+static void __exit NS8390p_cleanup_module(void)
{
}
-#endif /* MODULE */
+module_init(NS8390p_init_module);
+module_exit(NS8390p_cleanup_module);
MODULE_LICENSE("GPL");
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 3111b6c7cbc..01f282cd098 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1,4 +1,3 @@
-
#
# Network device configuration
#
@@ -26,15 +25,6 @@ menuconfig NETDEVICES
# that for each of the symbols.
if NETDEVICES
-config COMPAT_NET_DEV_OPS
- default y
- bool "Enable older network device API compatibility"
- ---help---
- This option enables kernel compatibility with older network devices
- that do not use net_device_ops interface.
-
- If unsure, say Y.
-
config IFB
tristate "Intermediate Functional Block support"
depends on NET_CLS_ACT
@@ -526,15 +516,16 @@ config STNIC
config SH_ETH
tristate "Renesas SuperH Ethernet support"
depends on SUPERH && \
- (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7763 || \
- CPU_SUBTYPE_SH7619)
+ (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
+ CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
+ CPU_SUBTYPE_SH7724)
select CRC32
select MII
select MDIO_BITBANG
select PHYLIB
help
Renesas SuperH Ethernet device driver.
- This driver support SH7710, SH7712, SH7763 and SH7619.
+ This driver support SH7710, SH7712, SH7763, SH7619, and SH7724.
config SUNLANCE
tristate "Sun LANCE support"
@@ -927,6 +918,16 @@ config NET_NETX
To compile this driver as a module, choose M here. The module
will be called netx-eth.
+config TI_DAVINCI_EMAC
+ tristate "TI DaVinci EMAC Support"
+ depends on ARM && ARCH_DAVINCI
+ select PHYLIB
+ help
+ This driver supports TI's DaVinci Ethernet .
+
+ To compile this driver as a module, choose M here: the module
+ will be called davinci_emac_driver. This is recommended.
+
config DM9000
tristate "DM9000 support"
depends on ARM || BLACKFIN || MIPS
@@ -1000,7 +1001,7 @@ config SMC911X
config SMSC911X
tristate "SMSC LAN911x/LAN921x families embedded ethernet support"
- depends on ARM || SUPERH
+ depends on ARM || SUPERH || BLACKFIN
select CRC32
select MII
select PHYLIB
@@ -1722,6 +1723,11 @@ config TLAN
Please email feedback to <torben.mathiasen@compaq.com>.
+config KS8842
+ tristate "Micrel KSZ8842"
+ help
+ This platform driver is for Micrel KSZ8842 chip.
+
config VIA_RHINE
tristate "VIA Rhine support"
depends on NET_PCI && PCI
@@ -1858,8 +1864,8 @@ config 68360_ENET
the Motorola 68360 processor.
config FEC
- bool "FEC ethernet controller (of ColdFire CPUs)"
- depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27
+ bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
+ depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 || ARCH_MX35
help
Say Y here if you want to use the built-in 10/100 Fast ethernet
controller on some Motorola ColdFire and Freescale i.MX processors.
@@ -2362,7 +2368,7 @@ config UGETH_TX_ON_DEMAND
config MV643XX_ETH
tristate "Marvell Discovery (643XX) and Orion ethernet support"
- depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || PLAT_ORION
+ depends on MV64X60 || PPC32 || PLAT_ORION
select INET_LRO
select PHYLIB
help
@@ -2373,6 +2379,14 @@ config MV643XX_ETH
Some boards that use the Discovery chipset are the Momenco
Ocelot C and Jaguar ATX and Pegasos II.
+config XILINX_LL_TEMAC
+ tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
+ select PHYLIB
+ depends on PPC_DCR_NATIVE
+ help
+ This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
+ core used in Xilinx Spartan and Virtex FPGAs
+
config QLA3XXX
tristate "QLogic QLA3XXX Network Driver Support"
depends on PCI
@@ -2446,10 +2460,14 @@ menuconfig NETDEV_10000
if NETDEV_10000
+config MDIO
+ tristate
+
config CHELSIO_T1
tristate "Chelsio 10Gb Ethernet support"
depends on PCI
select CRC32
+ select MDIO
help
This driver supports Chelsio gigabit and 10-gigabit
Ethernet cards. More information about adapter features and
@@ -2482,6 +2500,7 @@ config CHELSIO_T3
tristate "Chelsio Communications T3 10Gb Ethernet support"
depends on CHELSIO_T3_DEPENDS
select FW_LOADER
+ select MDIO
help
This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
adapters.
@@ -2517,6 +2536,7 @@ config ENIC
config IXGBE
tristate "Intel(R) 10GbE PCI Express adapters support"
depends on PCI && INET
+ select MDIO
---help---
This driver supports Intel(R) 10GbE PCI Express family of
adapters. For more information on how to identify your adapter, go
@@ -2679,6 +2699,7 @@ config TEHUTI
config BNX2X
tristate "Broadcom NetXtremeII 10Gb support"
depends on PCI
+ select FW_LOADER
select ZLIB_INFLATE
select LIBCRC32C
help
@@ -2715,6 +2736,8 @@ source "drivers/net/wan/Kconfig"
source "drivers/atm/Kconfig"
+source "drivers/ieee802154/Kconfig"
+
source "drivers/s390/net/Kconfig"
config XEN_NETDEV_FRONTEND
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index db30ebd7b26..d366fb2b40e 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -2,6 +2,8 @@
# Makefile for the Linux network (ethercard) device drivers.
#
+obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o
+
obj-$(CONFIG_E1000) += e1000/
obj-$(CONFIG_E1000E) += e1000e/
obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
@@ -85,6 +87,7 @@ obj-$(CONFIG_TC35815) += tc35815.o
obj-$(CONFIG_SKGE) += skge.o
obj-$(CONFIG_SKY2) += sky2.o
obj-$(CONFIG_SKFP) += skfp/
+obj-$(CONFIG_KS8842) += ks8842.o
obj-$(CONFIG_VIA_RHINE) += via-rhine.o
obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
@@ -96,6 +99,7 @@ obj-$(CONFIG_SH_ETH) += sh_eth.o
#
obj-$(CONFIG_MII) += mii.o
+obj-$(CONFIG_MDIO) += mdio.o
obj-$(CONFIG_PHYLIB) += phy/
obj-$(CONFIG_SUNDANCE) += sundance.o
@@ -135,6 +139,8 @@ obj-$(CONFIG_AX88796) += ax88796.o
obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
+ll_temac-objs := ll_temac_main.o ll_temac_mdio.o
+obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o
obj-$(CONFIG_QLA3XXX) += qla3xxx.o
obj-$(CONFIG_QLGE) += qlge/
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c
index 02f64d57864..85a18175730 100644
--- a/drivers/net/a2065.c
+++ b/drivers/net/a2065.c
@@ -564,7 +564,7 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
if (!TX_BUFFS_AVAIL){
local_irq_restore(flags);
- return -1;
+ return NETDEV_TX_LOCKED;
}
#ifdef DEBUG_DRIVER
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 57bc7152785..08419ee1029 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -2573,7 +2573,6 @@ restart:
netif_wake_queue(dev);
}
- dev->trans_start = jiffies;
return NETDEV_TX_OK;
overflow:
diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c
index da64ba88d7f..78cea5e80b1 100644
--- a/drivers/net/appletalk/ipddp.c
+++ b/drivers/net/appletalk/ipddp.c
@@ -39,6 +39,7 @@
static const char version[] = KERN_INFO "ipddp.c:v0.01 8/28/97 Bradford W. Johnson <johns393@maroon.tc.umn.edu>\n";
static struct ipddp_route *ipddp_route_list;
+static DEFINE_SPINLOCK(ipddp_route_lock);
#ifdef CONFIG_IPDDP_ENCAP
static int ipddp_mode = IPDDP_ENCAP;
@@ -50,7 +51,7 @@ static int ipddp_mode = IPDDP_DECAP;
static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev);
static int ipddp_create(struct ipddp_route *new_rt);
static int ipddp_delete(struct ipddp_route *rt);
-static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt);
+static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt);
static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
static const struct net_device_ops ipddp_netdev_ops = {
@@ -71,6 +72,7 @@ static struct net_device * __init ipddp_init(void)
if (!dev)
return ERR_PTR(-ENOMEM);
+ dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
strcpy(dev->name, "ipddp%d");
if (version_printed++ == 0)
@@ -113,11 +115,13 @@ static struct net_device * __init ipddp_init(void)
*/
static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
{
- __be32 paddr = ((struct rtable*)skb->dst)->rt_gateway;
+ __be32 paddr = skb_rtable(skb)->rt_gateway;
struct ddpehdr *ddp;
struct ipddp_route *rt;
struct atalk_addr *our_addr;
+ spin_lock(&ipddp_route_lock);
+
/*
* Find appropriate route to use, based only on IP number.
*/
@@ -126,8 +130,10 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
if(rt->ip == paddr)
break;
}
- if(rt == NULL)
+ if(rt == NULL) {
+ spin_unlock(&ipddp_route_lock);
return 0;
+ }
our_addr = atalk_find_dev_addr(rt->dev);
@@ -173,6 +179,8 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
if(aarp_send_ddp(rt->dev, skb, &rt->at, NULL) < 0)
dev_kfree_skb(skb);
+ spin_unlock(&ipddp_route_lock);
+
return 0;
}
@@ -195,7 +203,9 @@ static int ipddp_create(struct ipddp_route *new_rt)
return -ENETUNREACH;
}
- if (ipddp_find_route(rt)) {
+ spin_lock_bh(&ipddp_route_lock);
+ if (__ipddp_find_route(rt)) {
+ spin_unlock_bh(&ipddp_route_lock);
kfree(rt);
return -EEXIST;
}
@@ -203,6 +213,8 @@ static int ipddp_create(struct ipddp_route *new_rt)
rt->next = ipddp_route_list;
ipddp_route_list = rt;
+ spin_unlock_bh(&ipddp_route_lock);
+
return 0;
}
@@ -215,6 +227,7 @@ static int ipddp_delete(struct ipddp_route *rt)
struct ipddp_route **r = &ipddp_route_list;
struct ipddp_route *tmp;
+ spin_lock_bh(&ipddp_route_lock);
while((tmp = *r) != NULL)
{
if(tmp->ip == rt->ip
@@ -222,19 +235,21 @@ static int ipddp_delete(struct ipddp_route *rt)
&& tmp->at.s_node == rt->at.s_node)
{
*r = tmp->next;
+ spin_unlock_bh(&ipddp_route_lock);
kfree(tmp);
return 0;
}
r = &tmp->next;
}
+ spin_unlock_bh(&ipddp_route_lock);
return (-ENOENT);
}
/*
* Find a routing entry, we only return a FULL match
*/
-static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt)
+static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt)
{
struct ipddp_route *f;
@@ -252,7 +267,7 @@ static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt)
static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct ipddp_route __user *rt = ifr->ifr_data;
- struct ipddp_route rcp;
+ struct ipddp_route rcp, rcp2, *rp;
if(!capable(CAP_NET_ADMIN))
return -EPERM;
@@ -266,9 +281,19 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return (ipddp_create(&rcp));
case SIOCFINDIPDDPRT:
- if(copy_to_user(rt, ipddp_find_route(&rcp), sizeof(struct ipddp_route)))
- return -EFAULT;
- return 0;
+ spin_lock_bh(&ipddp_route_lock);
+ rp = __ipddp_find_route(&rcp);
+ if (rp)
+ memcpy(&rcp2, rp, sizeof(rcp2));
+ spin_unlock_bh(&ipddp_route_lock);
+
+ if (rp) {
+ if (copy_to_user(rt, &rcp2,
+ sizeof(struct ipddp_route)))
+ return -EFAULT;
+ return 0;
+ } else
+ return -ENOENT;
case SIOCDELIPDDPRT:
return (ipddp_delete(&rcp));
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
index 7f4bc8ae546..2e7419a6119 100644
--- a/drivers/net/arm/at91_ether.c
+++ b/drivers/net/arm/at91_ether.c
@@ -829,7 +829,7 @@ static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies;
} else {
printk(KERN_ERR "at91_ether.c: at91ether_start_xmit() called, but device is busy!\n");
- return 1; /* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
+ return NETDEV_TX_BUSY; /* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
on this skb, he also reports -ENETDOWN and printk's, so either
we free and return(0) or don't free and return 1 */
}
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index b72b3d639f6..fbf4645417d 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -253,7 +253,7 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget)
skb = dev_alloc_skb(length + 2);
if (likely(skb != NULL)) {
skb_reserve(skb, 2);
- dma_sync_single(NULL, ep->descs->rdesc[entry].buf_addr,
+ dma_sync_single_for_cpu(NULL, ep->descs->rdesc[entry].buf_addr,
length, DMA_FROM_DEVICE);
skb_copy_to_linear_data(skb, ep->rx_buf[entry], length);
skb_put(skb, length);
@@ -331,7 +331,7 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
ep->descs->tdesc[entry].tdesc1 =
TDESC1_EOF | (entry << 16) | (skb->len & 0xfff);
skb_copy_and_csum_dev(skb, ep->tx_buf[entry]);
- dma_sync_single(NULL, ep->descs->tdesc[entry].buf_addr,
+ dma_sync_single_for_cpu(NULL, ep->descs->tdesc[entry].buf_addr,
skb->len, DMA_TO_DEVICE);
dev_kfree_skb(skb);
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c
index ec8a1ae1e88..455037134aa 100644
--- a/drivers/net/arm/ether3.c
+++ b/drivers/net/arm/ether3.c
@@ -526,7 +526,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
if (priv(dev)->tx_tail == next_ptr) {
local_irq_restore(flags);
- return 1; /* unable to queue */
+ return NETDEV_TX_BUSY; /* unable to queue */
}
dev->trans_start = jiffies;
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c
index b6d188115ca..6f42ad72891 100644
--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -562,8 +562,8 @@ static int eth_poll(struct napi_struct *napi, int budget)
dma_unmap_single(&dev->dev, desc->data - NET_IP_ALIGN,
RX_BUFF_SIZE, DMA_FROM_DEVICE);
#else
- dma_sync_single(&dev->dev, desc->data - NET_IP_ALIGN,
- RX_BUFF_SIZE, DMA_FROM_DEVICE);
+ dma_sync_single_for_cpu(&dev->dev, desc->data - NET_IP_ALIGN,
+ RX_BUFF_SIZE, DMA_FROM_DEVICE);
memcpy_swab32((u32 *)skb->data, (u32 *)port->rx_buff_tab[n],
ALIGN(NET_IP_ALIGN + desc->pkt_len, 4) / 4);
#endif
@@ -1151,7 +1151,7 @@ static int __devinit eth_init_one(struct platform_device *pdev)
struct net_device *dev;
struct eth_plat_info *plat = pdev->dev.platform_data;
u32 regs_phys;
- char phy_id[BUS_ID_SIZE];
+ char phy_id[MII_BUS_ID_SIZE + 3];
int err;
if (!(dev = alloc_etherdev(sizeof(struct port))))
@@ -1209,7 +1209,7 @@ static int __devinit eth_init_one(struct platform_device *pdev)
__raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control);
udelay(50);
- snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, "0", plat->phy);
+ snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy);
port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0,
PHY_INTERFACE_MODE_MII);
if ((err = IS_ERR(port->phydev)))
diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c
index 45c5b7332cd..e4afbd628c2 100644
--- a/drivers/net/atl1c/atl1c_ethtool.c
+++ b/drivers/net/atl1c/atl1c_ethtool.c
@@ -271,7 +271,7 @@ static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
struct atl1c_adapter *adapter = netdev_priv(netdev);
if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
- WAKE_MCAST | WAKE_BCAST | WAKE_MCAST))
+ WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
return -EOPNOTSUPP;
/* these settings will always override what we currently have */
adapter->wol = 0;
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
index 83a12125b94..cd547a205fb 100644
--- a/drivers/net/atl1c/atl1c_main.c
+++ b/drivers/net/atl1c/atl1c_main.c
@@ -164,6 +164,24 @@ static inline void atl1c_irq_reset(struct atl1c_adapter *adapter)
}
/*
+ * atl1c_wait_until_idle - wait up to AT_HW_MAX_IDLE_DELAY reads
+ * of the idle status register until the device is actually idle
+ */
+static u32 atl1c_wait_until_idle(struct atl1c_hw *hw)
+{
+ int timeout;
+ u32 data;
+
+ for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
+ AT_READ_REG(hw, REG_IDLE_STATUS, &data);
+ if ((data & IDLE_STATUS_MASK) == 0)
+ return 0;
+ msleep(1);
+ }
+ return data;
+}
+
+/*
* atl1c_phy_config - Timer Call-back
* @data: pointer to netdev cast into an unsigned long
*/
@@ -220,11 +238,11 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter)
/* link down */
if (netif_carrier_ok(netdev)) {
hw->hibernate = true;
- atl1c_set_aspm(hw, false);
if (atl1c_stop_mac(hw) != 0)
if (netif_msg_hw(adapter))
dev_warn(&pdev->dev,
"stop mac failed\n");
+ atl1c_set_aspm(hw, false);
}
netif_carrier_off(netdev);
} else {
@@ -240,10 +258,10 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter)
adapter->link_duplex != duplex) {
adapter->link_speed = speed;
adapter->link_duplex = duplex;
+ atl1c_set_aspm(hw, true);
atl1c_enable_tx_ctrl(hw);
atl1c_enable_rx_ctrl(hw);
atl1c_setup_mac_ctrl(adapter);
- atl1c_set_aspm(hw, true);
if (netif_msg_link(adapter))
dev_info(&pdev->dev,
"%s: %s NIC Link is Up<%d Mbps %s>\n",
@@ -1106,7 +1124,6 @@ static void atl1c_configure_dma(struct atl1c_adapter *adapter)
static int atl1c_stop_mac(struct atl1c_hw *hw)
{
u32 data;
- int timeout;
AT_READ_REG(hw, REG_RXQ_CTRL, &data);
data &= ~(RXQ1_CTRL_EN | RXQ2_CTRL_EN |
@@ -1117,25 +1134,13 @@ static int atl1c_stop_mac(struct atl1c_hw *hw)
data &= ~TXQ_CTRL_EN;
AT_WRITE_REG(hw, REG_TWSI_CTRL, data);
- for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
- AT_READ_REG(hw, REG_IDLE_STATUS, &data);
- if ((data & (IDLE_STATUS_RXQ_NO_IDLE |
- IDLE_STATUS_TXQ_NO_IDLE)) == 0)
- break;
- msleep(1);
- }
+ atl1c_wait_until_idle(hw);
AT_READ_REG(hw, REG_MAC_CTRL, &data);
data &= ~(MAC_CTRL_TX_EN | MAC_CTRL_RX_EN);
AT_WRITE_REG(hw, REG_MAC_CTRL, data);
- for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
- AT_READ_REG(hw, REG_IDLE_STATUS, &data);
- if ((data & IDLE_STATUS_MASK) == 0)
- return 0;
- msleep(1);
- }
- return data;
+ return (int)atl1c_wait_until_idle(hw);
}
static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw)
@@ -1178,8 +1183,6 @@ static int atl1c_reset_mac(struct atl1c_hw *hw)
{
struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
struct pci_dev *pdev = adapter->pdev;
- u32 idle_status_data = 0;
- int timeout = 0;
int ret;
AT_WRITE_REG(hw, REG_IMR, 0);
@@ -1198,15 +1201,10 @@ static int atl1c_reset_mac(struct atl1c_hw *hw)
AT_WRITE_FLUSH(hw);
msleep(10);
/* Wait at least 10ms for All module to be Idle */
- for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
- AT_READ_REG(hw, REG_IDLE_STATUS, &idle_status_data);
- if ((idle_status_data & IDLE_STATUS_MASK) == 0)
- break;
- msleep(1);
- }
- if (timeout >= AT_HW_MAX_IDLE_DELAY) {
+
+ if (atl1c_wait_until_idle(hw)) {
dev_err(&pdev->dev,
- "MAC state machine cann't be idle since"
+ "MAC state machine can't be idle since"
" disabled for 10ms second\n");
return -1;
}
@@ -1242,9 +1240,7 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup)
AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data);
- pm_ctrl_data &= PM_CTRL_SERDES_PD_EX_L1;
- pm_ctrl_data |= ~PM_CTRL_SERDES_BUDS_RX_L1_EN;
- pm_ctrl_data |= ~PM_CTRL_SERDES_L1_EN;
+ pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1;
pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
PM_CTRL_L1_ENTRY_TIMER_SHIFT);
@@ -1254,19 +1250,11 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup)
pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN;
pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1;
- if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT) {
- pm_ctrl_data |= AT_ASPM_L1_TIMER <<
- PM_CTRL_L1_ENTRY_TIMER_SHIFT;
- pm_ctrl_data |= PM_CTRL_ASPM_L1_EN;
- } else
- pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
-
- if (hw->ctrl_flags & ATL1C_ASPM_L0S_SUPPORT)
- pm_ctrl_data |= PM_CTRL_ASPM_L0S_EN;
- else
- pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
-
+ pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN;
+ pm_ctrl_data |= PM_CTRL_SERDES_L1_EN;
} else {
+ pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN;
+ pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN;
pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN;
@@ -2123,7 +2111,6 @@ static int atl1c_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
atl1c_tx_map(adapter, skb, tpd, type);
atl1c_tx_queue(adapter, skb, tpd, type);
- netdev->trans_start = jiffies;
spin_unlock_irqrestore(&adapter->tx_lock, flags);
return NETDEV_TX_OK;
}
diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h
index 2bf63b4368e..ba48220df16 100644
--- a/drivers/net/atl1e/atl1e.h
+++ b/drivers/net/atl1e/atl1e.h
@@ -429,7 +429,6 @@ struct atl1e_adapter {
struct mii_if_info mii; /* MII interface info */
struct atl1e_hw hw;
struct atl1e_hw_stats hw_stats;
- struct net_device_stats net_stats;
bool have_msi;
u32 wol;
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index 1342418fb20..9fc6d6d9060 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -1154,7 +1154,7 @@ static struct net_device_stats *atl1e_get_stats(struct net_device *netdev)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
struct atl1e_hw_stats *hw_stats = &adapter->hw_stats;
- struct net_device_stats *net_stats = &adapter->net_stats;
+ struct net_device_stats *net_stats = &netdev->stats;
net_stats->rx_packets = hw_stats->rx_ok;
net_stats->tx_packets = hw_stats->tx_ok;
@@ -1182,7 +1182,7 @@ static struct net_device_stats *atl1e_get_stats(struct net_device *netdev)
net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
net_stats->tx_window_errors = hw_stats->tx_late_col;
- return &adapter->net_stats;
+ return net_stats;
}
static void atl1e_update_hw_stats(struct atl1e_adapter *adapter)
@@ -1310,7 +1310,7 @@ static irqreturn_t atl1e_intr(int irq, void *data)
/* link event */
if (status & (ISR_GPHY | ISR_MANUAL)) {
- adapter->net_stats.tx_carrier_errors++;
+ netdev->stats.tx_carrier_errors++;
atl1e_link_chg_event(adapter);
break;
}
@@ -1602,7 +1602,7 @@ static u16 atl1e_cal_tdp_req(const struct sk_buff *skb)
}
if (skb_is_gso(skb)) {
- if (skb->protocol == ntohs(ETH_P_IP) ||
+ if (skb->protocol == htons(ETH_P_IP) ||
(skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6)) {
proto_hdr_len = skb_transport_offset(skb) +
tcp_hdrlen(skb);
@@ -1795,8 +1795,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc));
tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
- if (tx_buffer->skb)
- BUG();
+ BUG_ON(tx_buffer->skb);
tx_buffer->skb = NULL;
tx_buffer->length =
@@ -1879,7 +1878,7 @@ static int atl1e_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
TPD_VLAN_SHIFT;
}
- if (skb->protocol == ntohs(ETH_P_8021Q))
+ if (skb->protocol == htons(ETH_P_8021Q))
tpd->word3 |= 1 << TPD_VL_TAGGED_SHIFT;
if (skb_network_offset(skb) != ETH_HLEN)
@@ -1895,7 +1894,7 @@ static int atl1e_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
atl1e_tx_map(adapter, skb, tpd);
atl1e_tx_queue(adapter, tpd_req, tpd);
- netdev->trans_start = jiffies;
+ netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
spin_unlock_irqrestore(&adapter->tx_lock, flags);
return NETDEV_TX_OK;
}
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 4e817126e28..94d7325caf4 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -2213,8 +2213,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
nr_frags = skb_shinfo(skb)->nr_frags;
next_to_use = atomic_read(&tpd_ring->next_to_use);
buffer_info = &tpd_ring->buffer_info[next_to_use];
- if (unlikely(buffer_info->skb))
- BUG();
+ BUG_ON(buffer_info->skb);
/* put skb in last TPD */
buffer_info->skb = NULL;
@@ -2280,8 +2279,8 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
ATL1_MAX_TX_BUF_LEN;
for (i = 0; i < nseg; i++) {
buffer_info = &tpd_ring->buffer_info[next_to_use];
- if (unlikely(buffer_info->skb))
- BUG();
+ BUG_ON(buffer_info->skb);
+
buffer_info->skb = NULL;
buffer_info->length = (buf_len > ATL1_MAX_TX_BUF_LEN) ?
ATL1_MAX_TX_BUF_LEN : buf_len;
@@ -2383,7 +2382,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
mss = skb_shinfo(skb)->gso_size;
if (mss) {
- if (skb->protocol == ntohs(ETH_P_IP)) {
+ if (skb->protocol == htons(ETH_P_IP)) {
proto_hdr_len = (skb_transport_offset(skb) +
tcp_hdrlen(skb));
if (unlikely(proto_hdr_len > len)) {
@@ -2438,7 +2437,6 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
atl1_tx_queue(adapter, count, ptpd);
atl1_update_mailbox(adapter);
mmiowb();
- netdev->trans_start = jiffies;
return NETDEV_TX_OK;
}
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index d58c105fc77..d3c734f4d67 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -957,7 +957,7 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
/* We've wrapped around and the transmitter is still busy */
netif_stop_queue(dev);
aup->tx_full = 1;
- return 1;
+ return NETDEV_TX_BUSY;
}
else if (buff_stat & TX_T_DONE) {
update_tx_stats(dev, ptxd->status);
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index b70b81ec34c..36d4d377ec2 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -782,7 +782,7 @@ static int b44_rx(struct b44 *bp, int budget)
drop_it:
b44_recycle_rx(bp, cons, bp->rx_prod);
drop_it_no_recycle:
- bp->stats.rx_dropped++;
+ bp->dev->stats.rx_dropped++;
goto next_pkt;
}
@@ -1647,7 +1647,7 @@ static int b44_close(struct net_device *dev)
static struct net_device_stats *b44_get_stats(struct net_device *dev)
{
struct b44 *bp = netdev_priv(dev);
- struct net_device_stats *nstat = &bp->stats;
+ struct net_device_stats *nstat = &dev->stats;
struct b44_hw_stats *hwstat = &bp->hw_stats;
/* Convert HW stats into netdevice stats. */
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index d24158e7f30..e1905a49279 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -384,7 +384,6 @@ struct b44 {
struct timer_list timer;
- struct net_device_stats stats;
struct b44_hw_stats hw_stats;
struct ssb_device *sdev;
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 5c378b5e8e4..66bb56874d9 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -168,6 +168,7 @@ static void netdev_stats_update(struct be_adapter *adapter)
struct be_port_rxf_stats *port_stats =
&rxf_stats->port[adapter->port_num];
struct net_device_stats *dev_stats = &adapter->stats.net_stats;
+ struct be_erx_stats *erx_stats = &hw_stats->erx;
dev_stats->rx_packets = port_stats->rx_total_frames;
dev_stats->tx_packets = port_stats->tx_unicastframes +
@@ -181,29 +182,33 @@ static void netdev_stats_update(struct be_adapter *adapter)
dev_stats->rx_errors = port_stats->rx_crc_errors +
port_stats->rx_alignment_symbol_errors +
port_stats->rx_in_range_errors +
- port_stats->rx_out_range_errors + port_stats->rx_frame_too_long;
-
- /* packet transmit problems */
- dev_stats->tx_errors = 0;
-
- /* no space in linux buffers */
- dev_stats->rx_dropped = 0;
-
- /* no space available in linux */
- dev_stats->tx_dropped = 0;
-
- dev_stats->multicast = port_stats->tx_multicastframes;
- dev_stats->collisions = 0;
+ port_stats->rx_out_range_errors +
+ port_stats->rx_frame_too_long +
+ port_stats->rx_dropped_too_small +
+ port_stats->rx_dropped_too_short +
+ port_stats->rx_dropped_header_too_small +
+ port_stats->rx_dropped_tcp_length +
+ port_stats->rx_dropped_runt +
+ port_stats->rx_tcp_checksum_errs +
+ port_stats->rx_ip_checksum_errs +
+ port_stats->rx_udp_checksum_errs;
+
+ /* no space in linux buffers: best possible approximation */
+ dev_stats->rx_dropped = erx_stats->rx_drops_no_fragments[0];
/* detailed rx errors */
dev_stats->rx_length_errors = port_stats->rx_in_range_errors +
- port_stats->rx_out_range_errors + port_stats->rx_frame_too_long;
+ port_stats->rx_out_range_errors +
+ port_stats->rx_frame_too_long;
+
/* receive ring buffer overflow */
dev_stats->rx_over_errors = 0;
+
dev_stats->rx_crc_errors = port_stats->rx_crc_errors;
/* frame alignment errors */
dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors;
+
/* receiver fifo overrun */
/* drops_no_pbuf is no per i/f, it's per BE card */
dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow +
@@ -211,6 +216,16 @@ static void netdev_stats_update(struct be_adapter *adapter)
rxf_stats->rx_drops_no_pbuf;
/* receiver missed packetd */
dev_stats->rx_missed_errors = 0;
+
+ /* packet transmit problems */
+ dev_stats->tx_errors = 0;
+
+ /* no space available in linux */
+ dev_stats->tx_dropped = 0;
+
+ dev_stats->multicast = port_stats->tx_multicastframes;
+ dev_stats->collisions = 0;
+
/* detailed tx_errors */
dev_stats->tx_aborted_errors = 0;
dev_stats->tx_carrier_errors = 0;
@@ -337,13 +352,10 @@ static void be_tx_stats_update(struct be_adapter *adapter,
/* Determine number of WRB entries needed to xmit data in an skb */
static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy)
{
- int cnt = 0;
- while (skb) {
- if (skb->len > skb->data_len)
- cnt++;
- cnt += skb_shinfo(skb)->nr_frags;
- skb = skb_shinfo(skb)->frag_list;
- }
+ int cnt = (skb->len > skb->data_len);
+
+ cnt += skb_shinfo(skb)->nr_frags;
+
/* to account for hdr wrb */
cnt++;
if (cnt & 1) {
@@ -409,31 +421,28 @@ static int make_tx_wrbs(struct be_adapter *adapter,
hdr = queue_head_node(txq);
queue_head_inc(txq);
- while (skb) {
- if (skb->len > skb->data_len) {
- int len = skb->len - skb->data_len;
- busaddr = pci_map_single(pdev, skb->data, len,
- PCI_DMA_TODEVICE);
- wrb = queue_head_node(txq);
- wrb_fill(wrb, busaddr, len);
- be_dws_cpu_to_le(wrb, sizeof(*wrb));
- queue_head_inc(txq);
- copied += len;
- }
+ if (skb->len > skb->data_len) {
+ int len = skb->len - skb->data_len;
+ busaddr = pci_map_single(pdev, skb->data, len,
+ PCI_DMA_TODEVICE);
+ wrb = queue_head_node(txq);
+ wrb_fill(wrb, busaddr, len);
+ be_dws_cpu_to_le(wrb, sizeof(*wrb));
+ queue_head_inc(txq);
+ copied += len;
+ }
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- struct skb_frag_struct *frag =
- &skb_shinfo(skb)->frags[i];
- busaddr = pci_map_page(pdev, frag->page,
- frag->page_offset,
- frag->size, PCI_DMA_TODEVICE);
- wrb = queue_head_node(txq);
- wrb_fill(wrb, busaddr, frag->size);
- be_dws_cpu_to_le(wrb, sizeof(*wrb));
- queue_head_inc(txq);
- copied += frag->size;
- }
- skb = skb_shinfo(skb)->frag_list;
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ struct skb_frag_struct *frag =
+ &skb_shinfo(skb)->frags[i];
+ busaddr = pci_map_page(pdev, frag->page,
+ frag->page_offset,
+ frag->size, PCI_DMA_TODEVICE);
+ wrb = queue_head_node(txq);
+ wrb_fill(wrb, busaddr, frag->size);
+ be_dws_cpu_to_le(wrb, sizeof(*wrb));
+ queue_head_inc(txq);
+ copied += frag->size;
}
if (dummy_wrb) {
@@ -478,8 +487,6 @@ static int be_xmit(struct sk_buff *skb, struct net_device *netdev)
be_txq_notify(&adapter->ctrl, txq->id, wrb_cnt);
- netdev->trans_start = jiffies;
-
be_tx_stats_update(adapter, wrb_cnt, copied, stopped);
return NETDEV_TX_OK;
}
@@ -637,6 +644,22 @@ static void be_rx_stats_update(struct be_adapter *adapter,
stats->be_rx_bytes += pktsize;
}
+static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso)
+{
+ u8 l4_cksm, ip_version, ipcksm, tcpf = 0, udpf = 0, ipv6_chk;
+
+ l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp);
+ ipcksm = AMAP_GET_BITS(struct amap_eth_rx_compl, ipcksm, rxcp);
+ ip_version = AMAP_GET_BITS(struct amap_eth_rx_compl, ip_version, rxcp);
+ if (ip_version) {
+ tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp);
+ udpf = AMAP_GET_BITS(struct amap_eth_rx_compl, udpf, rxcp);
+ }
+ ipv6_chk = (ip_version && (tcpf || udpf));
+
+ return ((l4_cksm && ipv6_chk && ipcksm) && cso) ? false : true;
+}
+
static struct be_rx_page_info *
get_rx_page_info(struct be_adapter *adapter, u16 frag_idx)
{
@@ -720,7 +743,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
if (pktsize <= rx_frag_size) {
BUG_ON(num_rcvd != 1);
- return;
+ goto done;
}
/* More frags present for this completion */
@@ -742,6 +765,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
memset(page_info, 0, sizeof(*page_info));
}
+done:
be_rx_stats_update(adapter, pktsize, num_rcvd);
return;
}
@@ -752,9 +776,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
{
struct sk_buff *skb;
u32 vtp, vid;
- int l4_cksm;
- l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp);
vtp = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN);
@@ -769,10 +791,10 @@ static void be_rx_compl_process(struct be_adapter *adapter,
skb_fill_rx_data(adapter, skb, rxcp);
- if (l4_cksm && adapter->rx_csum)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
+ if (do_pkt_csum(rxcp, adapter->rx_csum))
skb->ip_summed = CHECKSUM_NONE;
+ else
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
skb->truesize = skb->len + sizeof(struct sk_buff);
skb->protocol = eth_type_trans(skb, adapter->netdev);
@@ -854,12 +876,19 @@ static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter)
be_dws_le_to_cpu(rxcp, sizeof(*rxcp));
- rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0;
-
queue_tail_inc(&adapter->rx_obj.cq);
return rxcp;
}
+/* To reset the valid bit, we need to reset the whole word as
+ * when walking the queue the valid entries are little-endian
+ * and invalid entries are host endian
+ */
+static inline void be_rx_compl_reset(struct be_eth_rx_compl *rxcp)
+{
+ rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0;
+}
+
static inline struct page *be_alloc_pages(u32 size)
{
gfp_t alloc_flags = GFP_ATOMIC;
@@ -991,6 +1020,7 @@ static void be_rx_q_clean(struct be_adapter *adapter)
/* First cleanup pending rx completions */
while ((rxcp = be_rx_compl_get(adapter)) != NULL) {
be_rx_compl_discard(adapter, rxcp);
+ be_rx_compl_reset(rxcp);
be_cq_notify(&adapter->ctrl, rx_cq->id, true, 1);
}
@@ -1026,8 +1056,13 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
struct be_queue_info *q;
q = &adapter->tx_obj.q;
- if (q->created)
+ if (q->created) {
be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_TXQ);
+
+ /* No more tx completions can be rcvd now; clean up if there
+ * are any pending completions or pending tx requests */
+ be_tx_q_clean(adapter);
+ }
be_queue_free(adapter, q);
q = &adapter->tx_obj.cq;
@@ -1035,10 +1070,6 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_CQ);
be_queue_free(adapter, q);
- /* No more tx completions can be rcvd now; clean up if there are
- * any pending completions or pending tx requests */
- be_tx_q_clean(adapter);
-
q = &adapter->tx_eq.q;
if (q->created)
be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_EQ);
@@ -1272,6 +1303,8 @@ int be_poll_rx(struct napi_struct *napi, int budget)
be_rx_compl_process_lro(adapter, rxcp);
else
be_rx_compl_process(adapter, rxcp);
+
+ be_rx_compl_reset(rxcp);
}
lro_flush_all(&adapter->rx_obj.lro_mgr);
@@ -1527,7 +1560,7 @@ static int be_close(struct net_device *netdev)
struct be_eq_obj *tx_eq = &adapter->tx_eq;
int vec;
- cancel_delayed_work(&adapter->work);
+ cancel_delayed_work_sync(&adapter->work);
netif_stop_queue(netdev);
netif_carrier_off(netdev);
@@ -1626,10 +1659,12 @@ static void be_netdev_init(struct net_device *netdev)
netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM |
- NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
+ NETIF_F_IPV6_CSUM;
netdev->flags |= IFF_MULTICAST;
+ adapter->rx_csum = true;
+
BE_SET_NETDEV_OPS(netdev, &be_netdev_ops);
SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index b4da1821332..c15fc281f79 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -194,13 +194,13 @@ static int desc_list_init(void)
struct dma_descriptor *b = &(r->desc_b);
/* allocate a new skb for next time receive */
- new_skb = dev_alloc_skb(PKT_BUF_SZ + 2);
+ new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN);
if (!new_skb) {
printk(KERN_NOTICE DRV_NAME
": init: low on mem - packet dropped\n");
goto init_error;
}
- skb_reserve(new_skb, 2);
+ skb_reserve(new_skb, NET_IP_ALIGN);
r->skb = new_skb;
/*
@@ -566,9 +566,9 @@ static void adjust_tx_list(void)
*/
if (current_tx_ptr->next->next == tx_list_head) {
while (tx_list_head->status.status_word == 0) {
- mdelay(1);
+ udelay(10);
if (tx_list_head->status.status_word != 0
- || !(bfin_read_DMA2_IRQ_STATUS() & 0x08)) {
+ || !(bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)) {
goto adjust_head;
}
if (timeout_cnt-- < 0) {
@@ -606,93 +606,41 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
u16 *data;
-
+ u32 data_align = (unsigned long)(skb->data) & 0x3;
current_tx_ptr->skb = skb;
- if (ANOMALY_05000285) {
- /*
- * TXDWA feature is not avaible to older revision < 0.3 silicon
- * of BF537
- *
- * Only if data buffer is ODD WORD alignment, we do not
- * need to memcpy
- */
- u32 data_align = (u32)(skb->data) & 0x3;
- if (data_align == 0x2) {
- /* move skb->data to current_tx_ptr payload */
- data = (u16 *)(skb->data) - 1;
- *data = (u16)(skb->len);
- current_tx_ptr->desc_a.start_addr = (u32)data;
- /* this is important! */
- blackfin_dcache_flush_range((u32)data,
- (u32)((u8 *)data + skb->len + 4));
- } else {
- *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
- memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
- skb->len);
- current_tx_ptr->desc_a.start_addr =
- (u32)current_tx_ptr->packet;
- if (current_tx_ptr->status.status_word != 0)
- current_tx_ptr->status.status_word = 0;
- blackfin_dcache_flush_range(
- (u32)current_tx_ptr->packet,
- (u32)(current_tx_ptr->packet + skb->len + 2));
- }
+ if (data_align == 0x2) {
+ /* move skb->data to current_tx_ptr payload */
+ data = (u16 *)(skb->data) - 1;
+ *data = (u16)(skb->len);
+ current_tx_ptr->desc_a.start_addr = (u32)data;
+ /* this is important! */
+ blackfin_dcache_flush_range((u32)data,
+ (u32)((u8 *)data + skb->len + 4));
} else {
- /*
- * TXDWA feature is avaible to revision < 0.3 silicon of
- * BF537 and always avaible to BF52x
- */
- u32 data_align = (u32)(skb->data) & 0x3;
- if (data_align == 0x0) {
- u16 sysctl = bfin_read_EMAC_SYSCTL();
- sysctl |= TXDWA;
- bfin_write_EMAC_SYSCTL(sysctl);
-
- /* move skb->data to current_tx_ptr payload */
- data = (u16 *)(skb->data) - 2;
- *data = (u16)(skb->len);
- current_tx_ptr->desc_a.start_addr = (u32)data;
- /* this is important! */
- blackfin_dcache_flush_range(
- (u32)data,
- (u32)((u8 *)data + skb->len + 4));
- } else if (data_align == 0x2) {
- u16 sysctl = bfin_read_EMAC_SYSCTL();
- sysctl &= ~TXDWA;
- bfin_write_EMAC_SYSCTL(sysctl);
-
- /* move skb->data to current_tx_ptr payload */
- data = (u16 *)(skb->data) - 1;
- *data = (u16)(skb->len);
- current_tx_ptr->desc_a.start_addr = (u32)data;
- /* this is important! */
- blackfin_dcache_flush_range(
- (u32)data,
- (u32)((u8 *)data + skb->len + 4));
- } else {
- u16 sysctl = bfin_read_EMAC_SYSCTL();
- sysctl &= ~TXDWA;
- bfin_write_EMAC_SYSCTL(sysctl);
-
- *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
- memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
- skb->len);
- current_tx_ptr->desc_a.start_addr =
- (u32)current_tx_ptr->packet;
- if (current_tx_ptr->status.status_word != 0)
- current_tx_ptr->status.status_word = 0;
- blackfin_dcache_flush_range(
- (u32)current_tx_ptr->packet,
- (u32)(current_tx_ptr->packet + skb->len + 2));
- }
+ *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
+ memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
+ skb->len);
+ current_tx_ptr->desc_a.start_addr =
+ (u32)current_tx_ptr->packet;
+ if (current_tx_ptr->status.status_word != 0)
+ current_tx_ptr->status.status_word = 0;
+ blackfin_dcache_flush_range(
+ (u32)current_tx_ptr->packet,
+ (u32)(current_tx_ptr->packet + skb->len + 2));
}
+ /* make sure the internal data buffers in the core are drained
+ * so that the DMA descriptors are completely written when the
+ * DMA engine goes to fetch them below
+ */
+ SSYNC();
+
/* enable this packet's dma */
current_tx_ptr->desc_a.config |= DMAEN;
/* tx dma is running, just return */
- if (bfin_read_DMA2_IRQ_STATUS() & 0x08)
+ if (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)
goto out;
/* tx dma is not running */
@@ -718,7 +666,7 @@ static void bfin_mac_rx(struct net_device *dev)
/* allocate a new skb for next time receive */
skb = current_rx_ptr->skb;
- new_skb = dev_alloc_skb(PKT_BUF_SZ + 2);
+ new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN);
if (!new_skb) {
printk(KERN_NOTICE DRV_NAME
": rx: low on mem - packet dropped\n");
@@ -726,7 +674,7 @@ static void bfin_mac_rx(struct net_device *dev)
goto out;
}
/* reserve 2 bytes for RXDWA padding */
- skb_reserve(new_skb, 2);
+ skb_reserve(new_skb, NET_IP_ALIGN);
current_rx_ptr->skb = new_skb;
current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2;
@@ -1022,7 +970,8 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
{
struct net_device *ndev;
struct bfin_mac_local *lp;
- int rc, i;
+ struct platform_device *pd;
+ int rc;
ndev = alloc_etherdev(sizeof(struct bfin_mac_local));
if (!ndev) {
@@ -1047,13 +996,6 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
goto out_err_probe_mac;
}
- /* set the GPIO pins to Ethernet mode */
- rc = peripheral_request_list(pin_req, DRV_NAME);
- if (rc) {
- dev_err(&pdev->dev, "Requesting peripherals failed!\n");
- rc = -EFAULT;
- goto out_err_setup_pin_mux;
- }
/*
* Is it valid? (Did bootloader initialize it?)
@@ -1069,26 +1011,14 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
setup_mac_addr(ndev->dev_addr);
- /* MDIO bus initial */
- lp->mii_bus = mdiobus_alloc();
- if (lp->mii_bus == NULL)
- goto out_err_mdiobus_alloc;
-
- lp->mii_bus->priv = ndev;
- lp->mii_bus->read = bfin_mdiobus_read;
- lp->mii_bus->write = bfin_mdiobus_write;
- lp->mii_bus->reset = bfin_mdiobus_reset;
- lp->mii_bus->name = "bfin_mac_mdio";
- snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "0");
- lp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
- for (i = 0; i < PHY_MAX_ADDR; ++i)
- lp->mii_bus->irq[i] = PHY_POLL;
-
- rc = mdiobus_register(lp->mii_bus);
- if (rc) {
- dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
- goto out_err_mdiobus_register;
+ if (!pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "Cannot get platform device bfin_mii_bus!\n");
+ rc = -ENODEV;
+ goto out_err_probe_mac;
}
+ pd = pdev->dev.platform_data;
+ lp->mii_bus = platform_get_drvdata(pd);
+ lp->mii_bus->priv = ndev;
rc = mii_probe(ndev);
if (rc) {
@@ -1107,7 +1037,7 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
/* now, enable interrupts */
/* register irq handler */
rc = request_irq(IRQ_MAC_RX, bfin_mac_interrupt,
- IRQF_DISABLED | IRQF_SHARED, "EMAC_RX", ndev);
+ IRQF_DISABLED, "EMAC_RX", ndev);
if (rc) {
dev_err(&pdev->dev, "Cannot request Blackfin MAC RX IRQ!\n");
rc = -EBUSY;
@@ -1130,11 +1060,8 @@ out_err_reg_ndev:
out_err_request_irq:
out_err_mii_probe:
mdiobus_unregister(lp->mii_bus);
-out_err_mdiobus_register:
mdiobus_free(lp->mii_bus);
-out_err_mdiobus_alloc:
peripheral_free_list(pin_req);
-out_err_setup_pin_mux:
out_err_probe_mac:
platform_set_drvdata(pdev, NULL);
free_netdev(ndev);
@@ -1149,8 +1076,7 @@ static int __devexit bfin_mac_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
- mdiobus_unregister(lp->mii_bus);
- mdiobus_free(lp->mii_bus);
+ lp->mii_bus->priv = NULL;
unregister_netdev(ndev);
@@ -1188,6 +1114,74 @@ static int bfin_mac_resume(struct platform_device *pdev)
#define bfin_mac_resume NULL
#endif /* CONFIG_PM */
+static int __devinit bfin_mii_bus_probe(struct platform_device *pdev)
+{
+ struct mii_bus *miibus;
+ int rc, i;
+
+ /*
+ * We are setting up a network card,
+ * so set the GPIO pins to Ethernet mode
+ */
+ rc = peripheral_request_list(pin_req, DRV_NAME);
+ if (rc) {
+ dev_err(&pdev->dev, "Requesting peripherals failed!\n");
+ return rc;
+ }
+
+ rc = -ENOMEM;
+ miibus = mdiobus_alloc();
+ if (miibus == NULL)
+ goto out_err_alloc;
+ miibus->read = bfin_mdiobus_read;
+ miibus->write = bfin_mdiobus_write;
+ miibus->reset = bfin_mdiobus_reset;
+
+ miibus->parent = &pdev->dev;
+ miibus->name = "bfin_mii_bus";
+ snprintf(miibus->id, MII_BUS_ID_SIZE, "0");
+ miibus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
+ if (miibus->irq == NULL)
+ goto out_err_alloc;
+ for (i = 0; i < PHY_MAX_ADDR; ++i)
+ miibus->irq[i] = PHY_POLL;
+
+ rc = mdiobus_register(miibus);
+ if (rc) {
+ dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
+ goto out_err_mdiobus_register;
+ }
+
+ platform_set_drvdata(pdev, miibus);
+ return 0;
+
+out_err_mdiobus_register:
+ mdiobus_free(miibus);
+out_err_alloc:
+ peripheral_free_list(pin_req);
+
+ return rc;
+}
+
+static int __devexit bfin_mii_bus_remove(struct platform_device *pdev)
+{
+ struct mii_bus *miibus = platform_get_drvdata(pdev);
+ platform_set_drvdata(pdev, NULL);
+ mdiobus_unregister(miibus);
+ mdiobus_free(miibus);
+ peripheral_free_list(pin_req);
+ return 0;
+}
+
+static struct platform_driver bfin_mii_bus_driver = {
+ .probe = bfin_mii_bus_probe,
+ .remove = __devexit_p(bfin_mii_bus_remove),
+ .driver = {
+ .name = "bfin_mii_bus",
+ .owner = THIS_MODULE,
+ },
+};
+
static struct platform_driver bfin_mac_driver = {
.probe = bfin_mac_probe,
.remove = __devexit_p(bfin_mac_remove),
@@ -1201,7 +1195,11 @@ static struct platform_driver bfin_mac_driver = {
static int __init bfin_mac_init(void)
{
- return platform_driver_register(&bfin_mac_driver);
+ int ret;
+ ret = platform_driver_register(&bfin_mii_bus_driver);
+ if (!ret)
+ return platform_driver_register(&bfin_mac_driver);
+ return -ENODEV;
}
module_init(bfin_mac_init);
@@ -1209,6 +1207,7 @@ module_init(bfin_mac_init);
static void __exit bfin_mac_cleanup(void)
{
platform_driver_unregister(&bfin_mac_driver);
+ platform_driver_unregister(&bfin_mii_bus_driver);
}
module_exit(bfin_mac_cleanup);
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 44d015f70d1..9578a3dfac0 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1247,6 +1247,16 @@ static const struct ethtool_ops bmac_ethtool_ops = {
.get_link = ethtool_op_get_link,
};
+static const struct net_device_ops bmac_netdev_ops = {
+ .ndo_open = bmac_open,
+ .ndo_stop = bmac_close,
+ .ndo_start_xmit = bmac_output,
+ .ndo_set_multicast_list = bmac_set_multicast,
+ .ndo_set_mac_address = bmac_set_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_id *match)
{
int j, rev, ret;
@@ -1308,12 +1318,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
bmac_enable_and_reset_chip(dev);
bmwrite(dev, INTDISABLE, DisableAll);
- dev->open = bmac_open;
- dev->stop = bmac_close;
+ dev->netdev_ops = &bmac_netdev_ops;
dev->ethtool_ops = &bmac_ethtool_ops;
- dev->hard_start_xmit = bmac_output;
- dev->set_multicast_list = bmac_set_multicast;
- dev->set_mac_address = bmac_set_address;
bmac_get_station_address(dev, addr);
if (bmac_verify_checksum(dev) != 0)
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 3f5fcb0156a..7e3738112c4 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -48,6 +48,7 @@
#include <linux/cache.h>
#include <linux/firmware.h>
#include <linux/log2.h>
+#include <linux/list.h>
#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
#define BCM_CNIC 1
@@ -703,8 +704,7 @@ bnx2_free_rx_mem(struct bnx2 *bp)
rxr->rx_desc_mapping[j]);
rxr->rx_desc_ring[j] = NULL;
}
- if (rxr->rx_buf_ring)
- vfree(rxr->rx_buf_ring);
+ vfree(rxr->rx_buf_ring);
rxr->rx_buf_ring = NULL;
for (j = 0; j < bp->rx_max_pg_ring; j++) {
@@ -714,8 +714,7 @@ bnx2_free_rx_mem(struct bnx2 *bp)
rxr->rx_pg_desc_mapping[j]);
rxr->rx_pg_desc_ring[j] = NULL;
}
- if (rxr->rx_pg_ring)
- vfree(rxr->rx_pg_ring);
+ vfree(rxr->rx_pg_ring);
rxr->rx_pg_ring = NULL;
}
}
@@ -2788,14 +2787,15 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
tx_buf = &txr->tx_buf_ring[sw_ring_cons];
skb = tx_buf->skb;
+ /* prefetch skb_end_pointer() to speedup skb_shinfo(skb) */
+ prefetch(&skb->end);
+
/* partial BD completions possible with TSO packets */
- if (skb_is_gso(skb)) {
+ if (tx_buf->is_gso) {
u16 last_idx, last_ring_idx;
- last_idx = sw_cons +
- skb_shinfo(skb)->nr_frags + 1;
- last_ring_idx = sw_ring_cons +
- skb_shinfo(skb)->nr_frags + 1;
+ last_idx = sw_cons + tx_buf->nr_frags + 1;
+ last_ring_idx = sw_ring_cons + tx_buf->nr_frags + 1;
if (unlikely(last_ring_idx >= MAX_TX_DESC_CNT)) {
last_idx++;
}
@@ -2807,7 +2807,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
skb_dma_unmap(&bp->pdev->dev, skb, DMA_TO_DEVICE);
tx_buf->skb = NULL;
- last = skb_shinfo(skb)->nr_frags;
+ last = tx_buf->nr_frags;
for (i = 0; i < last; i++) {
sw_cons = NEXT_TX_BD(sw_cons);
@@ -2820,7 +2820,8 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
if (tx_pkt == budget)
break;
- hw_cons = bnx2_get_hw_tx_cons(bnapi);
+ if (hw_cons == sw_cons)
+ hw_cons = bnx2_get_hw_tx_cons(bnapi);
}
txr->hw_tx_cons = hw_cons;
@@ -3492,7 +3493,7 @@ bnx2_set_rx_mode(struct net_device *dev)
{
struct bnx2 *bp = netdev_priv(dev);
u32 rx_mode, sort_mode;
- struct dev_addr_list *uc_ptr;
+ struct netdev_hw_addr *ha;
int i;
if (!netif_running(dev))
@@ -3551,21 +3552,19 @@ bnx2_set_rx_mode(struct net_device *dev)
sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN;
}
- uc_ptr = NULL;
if (dev->uc_count > BNX2_MAX_UNICAST_ADDRESSES) {
rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN |
BNX2_RPM_SORT_USER0_PROM_VLAN;
} else if (!(dev->flags & IFF_PROMISC)) {
- uc_ptr = dev->uc_list;
-
/* Add all entries into to the match filter list */
- for (i = 0; i < dev->uc_count; i++) {
- bnx2_set_mac_addr(bp, uc_ptr->da_addr,
+ i = 0;
+ list_for_each_entry(ha, &dev->uc_list, list) {
+ bnx2_set_mac_addr(bp, ha->addr,
i + BNX2_START_UNICAST_ADDRESS_INDEX);
sort_mode |= (1 <<
(i + BNX2_START_UNICAST_ADDRESS_INDEX));
- uc_ptr = uc_ptr->next;
+ i++;
}
}
@@ -5673,7 +5672,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
dev_kfree_skb(skb);
return -EIO;
}
- map = skb_shinfo(skb)->dma_maps[0];
+ map = skb_shinfo(skb)->dma_head;
REG_WR(bp, BNX2_HC_COMMAND,
bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
@@ -6353,7 +6352,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
sp = skb_shinfo(skb);
- mapping = sp->dma_maps[0];
+ mapping = sp->dma_head;
tx_buf = &txr->tx_buf_ring[ring_prod];
tx_buf->skb = skb;
@@ -6366,6 +6365,8 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbd->tx_bd_vlan_tag_flags = vlan_tag_flags | TX_BD_FLAGS_START;
last_frag = skb_shinfo(skb)->nr_frags;
+ tx_buf->nr_frags = last_frag;
+ tx_buf->is_gso = skb_is_gso(skb);
for (i = 0; i < last_frag; i++) {
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -6375,7 +6376,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbd = &txr->tx_desc_ring[ring_prod];
len = frag->size;
- mapping = sp->dma_maps[i + 1];
+ mapping = sp->dma_maps[i];
txbd->tx_bd_haddr_hi = (u64) mapping >> 32;
txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff;
@@ -6394,7 +6395,6 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
mmiowb();
txr->tx_prod = prod;
- dev->trans_start = jiffies;
if (unlikely(bnx2_tx_avail(bp, txr) <= MAX_SKB_FRAGS)) {
netif_tx_stop_queue(txq);
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index a1ff739bc9b..f1edfaa9e56 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -6556,6 +6556,8 @@ struct sw_pg {
struct sw_tx_bd {
struct sk_buff *skb;
+ unsigned short is_gso;
+ unsigned short nr_frags;
};
#define SW_RXBD_RING_SIZE (sizeof(struct sw_bd) * RX_DESC_CNT)
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index a329bee2555..8678457849f 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -965,6 +965,21 @@ struct bnx2x {
int gunzip_outlen;
#define FW_BUF_SIZE 0x8000
+ struct raw_op *init_ops;
+ /* Init blocks offsets inside init_ops */
+ u16 *init_ops_offsets;
+ /* Data blob - has 32 bit granularity */
+ u32 *init_data;
+ /* Zipped PRAM blobs - raw data */
+ const u8 *tsem_int_table_data;
+ const u8 *tsem_pram_data;
+ const u8 *usem_int_table_data;
+ const u8 *usem_pram_data;
+ const u8 *xsem_int_table_data;
+ const u8 *xsem_pram_data;
+ const u8 *csem_int_table_data;
+ const u8 *csem_pram_data;
+ const struct firmware *firmware;
};
diff --git a/drivers/net/bnx2x_fw_file_hdr.h b/drivers/net/bnx2x_fw_file_hdr.h
new file mode 100644
index 00000000000..3f5ee5d7cc2
--- /dev/null
+++ b/drivers/net/bnx2x_fw_file_hdr.h
@@ -0,0 +1,37 @@
+/* bnx2x_fw_file_hdr.h: FW binary file header structure.
+ *
+ * Copyright (c) 2007-2009 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ *
+ * Maintained by: Eilon Greenstein <eilong@broadcom.com>
+ * Written by: Vladislav Zolotarov <vladz@broadcom.com>
+ * Based on the original idea of John Wright <john.wright@hp.com>.
+ */
+
+#ifndef BNX2X_INIT_FILE_HDR_H
+#define BNX2X_INIT_FILE_HDR_H
+
+struct bnx2x_fw_file_section {
+ __be32 len;
+ __be32 offset;
+};
+
+struct bnx2x_fw_file_hdr {
+ struct bnx2x_fw_file_section init_ops;
+ struct bnx2x_fw_file_section init_ops_offsets;
+ struct bnx2x_fw_file_section init_data;
+ struct bnx2x_fw_file_section tsem_int_table_data;
+ struct bnx2x_fw_file_section tsem_pram_data;
+ struct bnx2x_fw_file_section usem_int_table_data;
+ struct bnx2x_fw_file_section usem_pram_data;
+ struct bnx2x_fw_file_section csem_int_table_data;
+ struct bnx2x_fw_file_section csem_pram_data;
+ struct bnx2x_fw_file_section xsem_int_table_data;
+ struct bnx2x_fw_file_section xsem_pram_data;
+ struct bnx2x_fw_file_section fw_version;
+};
+
+#endif /* BNX2X_INIT_FILE_HDR_H */
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
index 39ba2936c0c..3ba4d888068 100644
--- a/drivers/net/bnx2x_init.h
+++ b/drivers/net/bnx2x_init.h
@@ -1,4 +1,5 @@
/* bnx2x_init.h: Broadcom Everest network driver.
+ * Structures and macroes needed during the initialization.
*
* Copyright (c) 2007-2009 Broadcom Corporation
*
@@ -8,6 +9,7 @@
*
* Maintained by: Eilon Greenstein <eilong@broadcom.com>
* Written by: Eliezer Tamir
+ * Modified by: Vladislav Zolotarov <vladz@broadcom.com>
*/
#ifndef BNX2X_INIT_H
@@ -45,33 +47,71 @@
#define OP_WR_64 0x8 /* write 64 bit pattern */
#define OP_WB 0x9 /* copy a string using DMAE */
-/* Operation specific for E1 */
-#define OP_RD_E1 0xa /* read single register */
-#define OP_WR_E1 0xb /* write single register */
-#define OP_IW_E1 0xc /* write single register using mailbox */
-#define OP_SW_E1 0xd /* copy a string to the device */
-#define OP_SI_E1 0xe /* copy a string using mailbox */
-#define OP_ZR_E1 0xf /* clear memory */
-#define OP_ZP_E1 0x10 /* unzip then copy with DMAE */
-#define OP_WR_64_E1 0x11 /* write 64 bit pattern on E1 */
-#define OP_WB_E1 0x12 /* copy a string using DMAE */
-
-/* Operation specific for E1H */
-#define OP_RD_E1H 0x13 /* read single register */
-#define OP_WR_E1H 0x14 /* write single register */
-#define OP_IW_E1H 0x15 /* write single register using mailbox */
-#define OP_SW_E1H 0x16 /* copy a string to the device */
-#define OP_SI_E1H 0x17 /* copy a string using mailbox */
-#define OP_ZR_E1H 0x18 /* clear memory */
-#define OP_ZP_E1H 0x19 /* unzip then copy with DMAE */
-#define OP_WR_64_E1H 0x1a /* write 64 bit pattern on E1H */
-#define OP_WB_E1H 0x1b /* copy a string using DMAE */
-
/* FPGA and EMUL specific operations */
-#define OP_WR_EMUL_E1H 0x1c /* write single register on E1H Emul */
-#define OP_WR_EMUL 0x1d /* write single register on Emulation */
-#define OP_WR_FPGA 0x1e /* write single register on FPGA */
-#define OP_WR_ASIC 0x1f /* write single register on ASIC */
+#define OP_WR_EMUL 0xa /* write single register on Emulation */
+#define OP_WR_FPGA 0xb /* write single register on FPGA */
+#define OP_WR_ASIC 0xc /* write single register on ASIC */
+
+/* Init stages */
+#define COMMON_STAGE 0
+#define PORT0_STAGE 1
+#define PORT1_STAGE 2
+/* Never reorder FUNCx stages !!! */
+#define FUNC0_STAGE 3
+#define FUNC1_STAGE 4
+#define FUNC2_STAGE 5
+#define FUNC3_STAGE 6
+#define FUNC4_STAGE 7
+#define FUNC5_STAGE 8
+#define FUNC6_STAGE 9
+#define FUNC7_STAGE 10
+#define STAGE_IDX_MAX 11
+
+#define STAGE_START 0
+#define STAGE_END 1
+
+
+/* Indices of blocks */
+#define PRS_BLOCK 0
+#define SRCH_BLOCK 1
+#define TSDM_BLOCK 2
+#define TCM_BLOCK 3
+#define BRB1_BLOCK 4
+#define TSEM_BLOCK 5
+#define PXPCS_BLOCK 6
+#define EMAC0_BLOCK 7
+#define EMAC1_BLOCK 8
+#define DBU_BLOCK 9
+#define MISC_BLOCK 10
+#define DBG_BLOCK 11
+#define NIG_BLOCK 12
+#define MCP_BLOCK 13
+#define UPB_BLOCK 14
+#define CSDM_BLOCK 15
+#define USDM_BLOCK 16
+#define CCM_BLOCK 17
+#define UCM_BLOCK 18
+#define USEM_BLOCK 19
+#define CSEM_BLOCK 20
+#define XPB_BLOCK 21
+#define DQ_BLOCK 22
+#define TIMERS_BLOCK 23
+#define XSDM_BLOCK 24
+#define QM_BLOCK 25
+#define PBF_BLOCK 26
+#define XCM_BLOCK 27
+#define XSEM_BLOCK 28
+#define CDU_BLOCK 29
+#define DMAE_BLOCK 30
+#define PXP_BLOCK 31
+#define CFC_BLOCK 32
+#define HC_BLOCK 33
+#define PXP2_BLOCK 34
+#define MISC_AEU_BLOCK 35
+
+/* Returns the index of start or end of a specific block stage in ops array*/
+#define BLOCK_OPS_IDX(block, stage, end) \
+ (2*(((block)*STAGE_IDX_MAX) + (stage)) + (end))
struct raw_op {
@@ -118,292 +158,6 @@ union init_op {
struct raw_op raw;
};
-#include "bnx2x_init_values.h"
-
-static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
-static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len);
-
-static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
- u32 len)
-{
- int i;
-
- for (i = 0; i < len; i++) {
- REG_WR(bp, addr + i*4, data[i]);
- if (!(i % 10000)) {
- touch_softlockup_watchdog();
- cpu_relax();
- }
- }
-}
-
-static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
- u16 len)
-{
- int i;
-
- for (i = 0; i < len; i++) {
- REG_WR_IND(bp, addr + i*4, data[i]);
- if (!(i % 10000)) {
- touch_softlockup_watchdog();
- cpu_relax();
- }
- }
-}
-
-static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
-{
- int offset = 0;
-
- if (bp->dmae_ready) {
- while (len > DMAE_LEN32_WR_MAX) {
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
- addr + offset, DMAE_LEN32_WR_MAX);
- offset += DMAE_LEN32_WR_MAX * 4;
- len -= DMAE_LEN32_WR_MAX;
- }
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
- addr + offset, len);
- } else
- bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
-}
-
-static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
-{
- u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4));
- u32 buf_len32 = buf_len / 4;
- int i;
-
- memset(bp->gunzip_buf, fill, buf_len);
-
- for (i = 0; i < len; i += buf_len32) {
- u32 cur_len = min(buf_len32, len - i);
-
- bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
- }
-}
-
-static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
- u32 len64)
-{
- u32 buf_len32 = FW_BUF_SIZE / 4;
- u32 len = len64 * 2;
- u64 data64 = 0;
- int i;
-
- /* 64 bit value is in a blob: first low DWORD, then high DWORD */
- data64 = HILO_U64((*(data + 1)), (*data));
- len64 = min((u32)(FW_BUF_SIZE/8), len64);
- for (i = 0; i < len64; i++) {
- u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i;
-
- *pdata = data64;
- }
-
- for (i = 0; i < len; i += buf_len32) {
- u32 cur_len = min(buf_len32, len - i);
-
- bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
- }
-}
-
-/*********************************************************
- There are different blobs for each PRAM section.
- In addition, each blob write operation is divided into a few operations
- in order to decrease the amount of phys. contiguous buffer needed.
- Thus, when we select a blob the address may be with some offset
- from the beginning of PRAM section.
- The same holds for the INT_TABLE sections.
-**********************************************************/
-#define IF_IS_INT_TABLE_ADDR(base, addr) \
- if (((base) <= (addr)) && ((base) + 0x400 >= (addr)))
-
-#define IF_IS_PRAM_ADDR(base, addr) \
- if (((base) <= (addr)) && ((base) + 0x40000 >= (addr)))
-
-static const u32 *bnx2x_sel_blob(u32 addr, const u32 *data, int is_e1)
-{
- IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
- data = is_e1 ? tsem_int_table_data_e1 :
- tsem_int_table_data_e1h;
- else
- IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
- data = is_e1 ? csem_int_table_data_e1 :
- csem_int_table_data_e1h;
- else
- IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
- data = is_e1 ? usem_int_table_data_e1 :
- usem_int_table_data_e1h;
- else
- IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
- data = is_e1 ? xsem_int_table_data_e1 :
- xsem_int_table_data_e1h;
- else
- IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
- data = is_e1 ? tsem_pram_data_e1 : tsem_pram_data_e1h;
- else
- IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
- data = is_e1 ? csem_pram_data_e1 : csem_pram_data_e1h;
- else
- IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
- data = is_e1 ? usem_pram_data_e1 : usem_pram_data_e1h;
- else
- IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
- data = is_e1 ? xsem_pram_data_e1 : xsem_pram_data_e1h;
-
- return data;
-}
-
-static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
- u32 len, int gunzip, int is_e1, u32 blob_off)
-{
- int offset = 0;
-
- data = bnx2x_sel_blob(addr, data, is_e1) + blob_off;
-
- if (gunzip) {
- int rc;
-#ifdef __BIG_ENDIAN
- int i, size;
- u32 *temp;
-
- temp = kmalloc(len, GFP_KERNEL);
- size = (len / 4) + ((len % 4) ? 1 : 0);
- for (i = 0; i < size; i++)
- temp[i] = swab32(data[i]);
- data = temp;
-#endif
- rc = bnx2x_gunzip(bp, (u8 *)data, len);
- if (rc) {
- BNX2X_ERR("gunzip failed ! rc %d\n", rc);
-#ifdef __BIG_ENDIAN
- kfree(temp);
-#endif
- return;
- }
- len = bp->gunzip_outlen;
-#ifdef __BIG_ENDIAN
- kfree(temp);
- for (i = 0; i < len; i++)
- ((u32 *)bp->gunzip_buf)[i] =
- swab32(((u32 *)bp->gunzip_buf)[i]);
-#endif
- } else {
- if ((len * 4) > FW_BUF_SIZE) {
- BNX2X_ERR("LARGE DMAE OPERATION ! "
- "addr 0x%x len 0x%x\n", addr, len*4);
- return;
- }
- memcpy(bp->gunzip_buf, data, len * 4);
- }
-
- if (bp->dmae_ready) {
- while (len > DMAE_LEN32_WR_MAX) {
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
- addr + offset, DMAE_LEN32_WR_MAX);
- offset += DMAE_LEN32_WR_MAX * 4;
- len -= DMAE_LEN32_WR_MAX;
- }
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
- addr + offset, len);
- } else
- bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len);
-}
-
-static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end)
-{
- int is_e1 = CHIP_IS_E1(bp);
- int is_e1h = CHIP_IS_E1H(bp);
- int is_emul_e1h = (CHIP_REV_IS_EMUL(bp) && is_e1h);
- int hw_wr, i;
- union init_op *op;
- u32 op_type, addr, len;
- const u32 *data, *data_base;
-
- if (CHIP_REV_IS_FPGA(bp))
- hw_wr = OP_WR_FPGA;
- else if (CHIP_REV_IS_EMUL(bp))
- hw_wr = OP_WR_EMUL;
- else
- hw_wr = OP_WR_ASIC;
-
- if (is_e1)
- data_base = init_data_e1;
- else /* CHIP_IS_E1H(bp) */
- data_base = init_data_e1h;
-
- for (i = op_start; i < op_end; i++) {
-
- op = (union init_op *)&(init_ops[i]);
-
- op_type = op->str_wr.op;
- addr = op->str_wr.offset;
- len = op->str_wr.data_len;
- data = data_base + op->str_wr.data_off;
-
- /* careful! it must be in order */
- if (unlikely(op_type > OP_WB)) {
-
- /* If E1 only */
- if (op_type <= OP_WB_E1) {
- if (is_e1)
- op_type -= (OP_RD_E1 - OP_RD);
-
- /* If E1H only */
- } else if (op_type <= OP_WB_E1H) {
- if (is_e1h)
- op_type -= (OP_RD_E1H - OP_RD);
- }
-
- /* HW/EMUL specific */
- if (op_type == hw_wr)
- op_type = OP_WR;
-
- /* EMUL on E1H is special */
- if ((op_type == OP_WR_EMUL_E1H) && is_emul_e1h)
- op_type = OP_WR;
- }
-
- switch (op_type) {
- case OP_RD:
- REG_RD(bp, addr);
- break;
- case OP_WR:
- REG_WR(bp, addr, op->write.val);
- break;
- case OP_SW:
- bnx2x_init_str_wr(bp, addr, data, len);
- break;
- case OP_WB:
- bnx2x_init_wr_wb(bp, addr, data, len, 0, is_e1, 0);
- break;
- case OP_SI:
- bnx2x_init_ind_wr(bp, addr, data, len);
- break;
- case OP_ZR:
- bnx2x_init_fill(bp, addr, 0, op->zero.len);
- break;
- case OP_ZP:
- bnx2x_init_wr_wb(bp, addr, data, len, 1, is_e1,
- op->str_wr.data_off);
- break;
- case OP_WR_64:
- bnx2x_init_wr_64(bp, addr, data, len);
- break;
- default:
- /* happens whenever an op is of a diff HW */
-#if 0
- DP(NETIF_MSG_HW, "skipping init operation "
- "index %d[%d:%d]: type %d addr 0x%x "
- "len %d(0x%x)\n",
- i, op_start, op_end, op_type, addr, len, len);
-#endif
- break;
- }
- }
-}
-
-
/****************************************************************************
* PXP
****************************************************************************/
@@ -567,111 +321,6 @@ static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
PXP2_REG_RQ_BW_WR_UBOUND30}
};
-static void bnx2x_init_pxp(struct bnx2x *bp)
-{
- u16 devctl;
- int r_order, w_order;
- u32 val, i;
-
- pci_read_config_word(bp->pdev,
- bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
- DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
- w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
- if (bp->mrrs == -1)
- r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
- else {
- DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
- r_order = bp->mrrs;
- }
-
- if (r_order > MAX_RD_ORD) {
- DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n",
- r_order, MAX_RD_ORD);
- r_order = MAX_RD_ORD;
- }
- if (w_order > MAX_WR_ORD) {
- DP(NETIF_MSG_HW, "write order of %d order adjusted to %d\n",
- w_order, MAX_WR_ORD);
- w_order = MAX_WR_ORD;
- }
- if (CHIP_REV_IS_FPGA(bp)) {
- DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n");
- w_order = 0;
- }
- DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order);
-
- for (i = 0; i < NUM_RD_Q-1; i++) {
- REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l);
- REG_WR(bp, read_arb_addr[i].add,
- read_arb_data[i][r_order].add);
- REG_WR(bp, read_arb_addr[i].ubound,
- read_arb_data[i][r_order].ubound);
- }
-
- for (i = 0; i < NUM_WR_Q-1; i++) {
- if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) ||
- (write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) {
-
- REG_WR(bp, write_arb_addr[i].l,
- write_arb_data[i][w_order].l);
-
- REG_WR(bp, write_arb_addr[i].add,
- write_arb_data[i][w_order].add);
-
- REG_WR(bp, write_arb_addr[i].ubound,
- write_arb_data[i][w_order].ubound);
- } else {
-
- val = REG_RD(bp, write_arb_addr[i].l);
- REG_WR(bp, write_arb_addr[i].l,
- val | (write_arb_data[i][w_order].l << 10));
-
- val = REG_RD(bp, write_arb_addr[i].add);
- REG_WR(bp, write_arb_addr[i].add,
- val | (write_arb_data[i][w_order].add << 10));
-
- val = REG_RD(bp, write_arb_addr[i].ubound);
- REG_WR(bp, write_arb_addr[i].ubound,
- val | (write_arb_data[i][w_order].ubound << 7));
- }
- }
-
- val = write_arb_data[NUM_WR_Q-1][w_order].add;
- val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10;
- val += write_arb_data[NUM_WR_Q-1][w_order].l << 17;
- REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val);
-
- val = read_arb_data[NUM_RD_Q-1][r_order].add;
- val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10;
- val += read_arb_data[NUM_RD_Q-1][r_order].l << 17;
- REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
-
- REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
- REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order);
- REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
- REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
-
- if (r_order == MAX_RD_ORD)
- REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
-
- REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
-
- if (CHIP_IS_E1H(bp)) {
- val = ((w_order == 0) ? 2 : 3);
- REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
- REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
- REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val);
- REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val);
- REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val);
- REG_WR(bp, PXP2_REG_WR_QM_MPS, val);
- REG_WR(bp, PXP2_REG_WR_TM_MPS, val);
- REG_WR(bp, PXP2_REG_WR_SRC_MPS, val);
- REG_WR(bp, PXP2_REG_WR_DBG_MPS, val);
- REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
- REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
- }
-}
-
/****************************************************************************
* CDU
@@ -695,128 +344,12 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
(0x80 | ((_type) & 0xf << 3) | (CDU_CRC8(_cid, _region, _type) & 0x7))
#define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val) ((_val) & ~0x80)
-/*****************************************************************************
- * Description:
- * Calculates crc 8 on a word value: polynomial 0-1-2-8
- * Code was translated from Verilog.
- ****************************************************************************/
-static u8 calc_crc8(u32 data, u8 crc)
-{
- u8 D[32];
- u8 NewCRC[8];
- u8 C[8];
- u8 crc_res;
- u8 i;
-
- /* split the data into 31 bits */
- for (i = 0; i < 32; i++) {
- D[i] = data & 1;
- data = data >> 1;
- }
-
- /* split the crc into 8 bits */
- for (i = 0; i < 8; i++) {
- C[i] = crc & 1;
- crc = crc >> 1;
- }
-
- NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
- D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
- C[6] ^ C[7];
- NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
- D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
- D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6];
- NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
- D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
- C[0] ^ C[1] ^ C[4] ^ C[5];
- NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
- D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
- C[1] ^ C[2] ^ C[5] ^ C[6];
- NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
- D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
- C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
- NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
- D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
- C[3] ^ C[4] ^ C[7];
- NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
- D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
- C[5];
- NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
- D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
- C[6];
-
- crc_res = 0;
- for (i = 0; i < 8; i++)
- crc_res |= (NewCRC[i] << i);
-
- return crc_res;
-}
/* registers addresses are not in order
so these arrays help simplify the code */
-static const int cm_start[E1H_FUNC_MAX][9] = {
- {MISC_FUNC0_START, TCM_FUNC0_START, UCM_FUNC0_START, CCM_FUNC0_START,
- XCM_FUNC0_START, TSEM_FUNC0_START, USEM_FUNC0_START, CSEM_FUNC0_START,
- XSEM_FUNC0_START},
- {MISC_FUNC1_START, TCM_FUNC1_START, UCM_FUNC1_START, CCM_FUNC1_START,
- XCM_FUNC1_START, TSEM_FUNC1_START, USEM_FUNC1_START, CSEM_FUNC1_START,
- XSEM_FUNC1_START},
- {MISC_FUNC2_START, TCM_FUNC2_START, UCM_FUNC2_START, CCM_FUNC2_START,
- XCM_FUNC2_START, TSEM_FUNC2_START, USEM_FUNC2_START, CSEM_FUNC2_START,
- XSEM_FUNC2_START},
- {MISC_FUNC3_START, TCM_FUNC3_START, UCM_FUNC3_START, CCM_FUNC3_START,
- XCM_FUNC3_START, TSEM_FUNC3_START, USEM_FUNC3_START, CSEM_FUNC3_START,
- XSEM_FUNC3_START},
- {MISC_FUNC4_START, TCM_FUNC4_START, UCM_FUNC4_START, CCM_FUNC4_START,
- XCM_FUNC4_START, TSEM_FUNC4_START, USEM_FUNC4_START, CSEM_FUNC4_START,
- XSEM_FUNC4_START},
- {MISC_FUNC5_START, TCM_FUNC5_START, UCM_FUNC5_START, CCM_FUNC5_START,
- XCM_FUNC5_START, TSEM_FUNC5_START, USEM_FUNC5_START, CSEM_FUNC5_START,
- XSEM_FUNC5_START},
- {MISC_FUNC6_START, TCM_FUNC6_START, UCM_FUNC6_START, CCM_FUNC6_START,
- XCM_FUNC6_START, TSEM_FUNC6_START, USEM_FUNC6_START, CSEM_FUNC6_START,
- XSEM_FUNC6_START},
- {MISC_FUNC7_START, TCM_FUNC7_START, UCM_FUNC7_START, CCM_FUNC7_START,
- XCM_FUNC7_START, TSEM_FUNC7_START, USEM_FUNC7_START, CSEM_FUNC7_START,
- XSEM_FUNC7_START}
-};
-
-static const int cm_end[E1H_FUNC_MAX][9] = {
- {MISC_FUNC0_END, TCM_FUNC0_END, UCM_FUNC0_END, CCM_FUNC0_END,
- XCM_FUNC0_END, TSEM_FUNC0_END, USEM_FUNC0_END, CSEM_FUNC0_END,
- XSEM_FUNC0_END},
- {MISC_FUNC1_END, TCM_FUNC1_END, UCM_FUNC1_END, CCM_FUNC1_END,
- XCM_FUNC1_END, TSEM_FUNC1_END, USEM_FUNC1_END, CSEM_FUNC1_END,
- XSEM_FUNC1_END},
- {MISC_FUNC2_END, TCM_FUNC2_END, UCM_FUNC2_END, CCM_FUNC2_END,
- XCM_FUNC2_END, TSEM_FUNC2_END, USEM_FUNC2_END, CSEM_FUNC2_END,
- XSEM_FUNC2_END},
- {MISC_FUNC3_END, TCM_FUNC3_END, UCM_FUNC3_END, CCM_FUNC3_END,
- XCM_FUNC3_END, TSEM_FUNC3_END, USEM_FUNC3_END, CSEM_FUNC3_END,
- XSEM_FUNC3_END},
- {MISC_FUNC4_END, TCM_FUNC4_END, UCM_FUNC4_END, CCM_FUNC4_END,
- XCM_FUNC4_END, TSEM_FUNC4_END, USEM_FUNC4_END, CSEM_FUNC4_END,
- XSEM_FUNC4_END},
- {MISC_FUNC5_END, TCM_FUNC5_END, UCM_FUNC5_END, CCM_FUNC5_END,
- XCM_FUNC5_END, TSEM_FUNC5_END, USEM_FUNC5_END, CSEM_FUNC5_END,
- XSEM_FUNC5_END},
- {MISC_FUNC6_END, TCM_FUNC6_END, UCM_FUNC6_END, CCM_FUNC6_END,
- XCM_FUNC6_END, TSEM_FUNC6_END, USEM_FUNC6_END, CSEM_FUNC6_END,
- XSEM_FUNC6_END},
- {MISC_FUNC7_END, TCM_FUNC7_END, UCM_FUNC7_END, CCM_FUNC7_END,
- XCM_FUNC7_END, TSEM_FUNC7_END, USEM_FUNC7_END, CSEM_FUNC7_END,
- XSEM_FUNC7_END},
-};
-
-static const int hc_limits[E1H_FUNC_MAX][2] = {
- {HC_FUNC0_START, HC_FUNC0_END},
- {HC_FUNC1_START, HC_FUNC1_END},
- {HC_FUNC2_START, HC_FUNC2_END},
- {HC_FUNC3_START, HC_FUNC3_END},
- {HC_FUNC4_START, HC_FUNC4_END},
- {HC_FUNC5_START, HC_FUNC5_END},
- {HC_FUNC6_START, HC_FUNC6_END},
- {HC_FUNC7_START, HC_FUNC7_END}
+static const int cm_blocks[9] = {
+ MISC_BLOCK, TCM_BLOCK, UCM_BLOCK, CCM_BLOCK, XCM_BLOCK,
+ TSEM_BLOCK, USEM_BLOCK, CSEM_BLOCK, XSEM_BLOCK
};
#endif /* BNX2X_INIT_H */
diff --git a/drivers/net/bnx2x_init_ops.h b/drivers/net/bnx2x_init_ops.h
new file mode 100644
index 00000000000..32552b9366c
--- /dev/null
+++ b/drivers/net/bnx2x_init_ops.h
@@ -0,0 +1,442 @@
+/* bnx2x_init_ops.h: Broadcom Everest network driver.
+ * Static functions needed during the initialization.
+ * This file is "included" in bnx2x_main.c.
+ *
+ * Copyright (c) 2007-2009 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ *
+ * Maintained by: Eilon Greenstein <eilong@broadcom.com>
+ * Written by: Vladislav Zolotarov <vladz@broadcom.com>
+ */
+#ifndef BNX2X_INIT_OPS_H
+#define BNX2X_INIT_OPS_H
+
+static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
+static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len);
+
+static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
+ u32 len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ REG_WR(bp, addr + i*4, data[i]);
+ if (!(i % 10000)) {
+ touch_softlockup_watchdog();
+ cpu_relax();
+ }
+ }
+}
+
+static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
+ u16 len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ REG_WR_IND(bp, addr + i*4, data[i]);
+ if (!(i % 10000)) {
+ touch_softlockup_watchdog();
+ cpu_relax();
+ }
+ }
+}
+
+static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
+{
+ int offset = 0;
+
+ if (bp->dmae_ready) {
+ while (len > DMAE_LEN32_WR_MAX) {
+ bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+ addr + offset, DMAE_LEN32_WR_MAX);
+ offset += DMAE_LEN32_WR_MAX * 4;
+ len -= DMAE_LEN32_WR_MAX;
+ }
+ bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+ addr + offset, len);
+ } else
+ bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
+}
+
+static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
+{
+ u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4));
+ u32 buf_len32 = buf_len / 4;
+ int i;
+
+ memset(bp->gunzip_buf, fill, buf_len);
+
+ for (i = 0; i < len; i += buf_len32) {
+ u32 cur_len = min(buf_len32, len - i);
+
+ bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
+ }
+}
+
+static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
+ u32 len64)
+{
+ u32 buf_len32 = FW_BUF_SIZE / 4;
+ u32 len = len64 * 2;
+ u64 data64 = 0;
+ int i;
+
+ /* 64 bit value is in a blob: first low DWORD, then high DWORD */
+ data64 = HILO_U64((*(data + 1)), (*data));
+ len64 = min((u32)(FW_BUF_SIZE/8), len64);
+ for (i = 0; i < len64; i++) {
+ u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i;
+
+ *pdata = data64;
+ }
+
+ for (i = 0; i < len; i += buf_len32) {
+ u32 cur_len = min(buf_len32, len - i);
+
+ bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
+ }
+}
+
+/*********************************************************
+ There are different blobs for each PRAM section.
+ In addition, each blob write operation is divided into a few operations
+ in order to decrease the amount of phys. contiguous buffer needed.
+ Thus, when we select a blob the address may be with some offset
+ from the beginning of PRAM section.
+ The same holds for the INT_TABLE sections.
+**********************************************************/
+#define IF_IS_INT_TABLE_ADDR(base, addr) \
+ if (((base) <= (addr)) && ((base) + 0x400 >= (addr)))
+
+#define IF_IS_PRAM_ADDR(base, addr) \
+ if (((base) <= (addr)) && ((base) + 0x40000 >= (addr)))
+
+static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, const u8 *data)
+{
+ IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
+ data = bp->tsem_int_table_data;
+ else IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
+ data = bp->csem_int_table_data;
+ else IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
+ data = bp->usem_int_table_data;
+ else IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
+ data = bp->xsem_int_table_data;
+ else IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
+ data = bp->tsem_pram_data;
+ else IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
+ data = bp->csem_pram_data;
+ else IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
+ data = bp->usem_pram_data;
+ else IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
+ data = bp->xsem_pram_data;
+
+ return data;
+}
+
+static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len)
+{
+ int offset = 0;
+
+ if (bp->dmae_ready) {
+ while (len > DMAE_LEN32_WR_MAX) {
+ bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+ addr + offset, DMAE_LEN32_WR_MAX);
+ offset += DMAE_LEN32_WR_MAX * 4;
+ len -= DMAE_LEN32_WR_MAX;
+ }
+ bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+ addr + offset, len);
+ } else
+ bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len);
+}
+
+static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
+ u32 len)
+{
+ /* This is needed for NO_ZIP mode, currently supported
+ in little endian mode only */
+ data = (const u32*)bnx2x_sel_blob(bp, addr, (const u8*)data);
+
+ if ((len * 4) > FW_BUF_SIZE) {
+ BNX2X_ERR("LARGE DMAE OPERATION ! "
+ "addr 0x%x len 0x%x\n", addr, len*4);
+ return;
+ }
+ memcpy(bp->gunzip_buf, data, len * 4);
+
+ bnx2x_write_big_buf_wb(bp, addr, len);
+}
+
+static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr,
+ u32 len, u32 blob_off)
+{
+ int rc, i;
+ const u8 *data = NULL;
+
+ data = bnx2x_sel_blob(bp, addr, data) + 4*blob_off;
+
+ if (data == NULL) {
+ panic("Blob not found for addr 0x%x\n", addr);
+ return;
+ }
+
+ rc = bnx2x_gunzip(bp, data, len);
+ if (rc) {
+ BNX2X_ERR("gunzip failed ! addr 0x%x rc %d\n", addr, rc);
+ BNX2X_ERR("blob_offset=0x%x\n", blob_off);
+ return;
+ }
+
+ /* gunzip_outlen is in dwords */
+ len = bp->gunzip_outlen;
+ for (i = 0; i < len; i++)
+ ((u32 *)bp->gunzip_buf)[i] =
+ cpu_to_le32(((u32 *)bp->gunzip_buf)[i]);
+
+ bnx2x_write_big_buf_wb(bp, addr, len);
+}
+
+static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
+{
+ int hw_wr, i;
+ u16 op_start =
+ bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_START)];
+ u16 op_end =
+ bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_END)];
+ union init_op *op;
+ u32 op_type, addr, len;
+ const u32 *data, *data_base;
+
+ /* If empty block */
+ if (op_start == op_end)
+ return;
+
+ if (CHIP_REV_IS_FPGA(bp))
+ hw_wr = OP_WR_FPGA;
+ else if (CHIP_REV_IS_EMUL(bp))
+ hw_wr = OP_WR_EMUL;
+ else
+ hw_wr = OP_WR_ASIC;
+
+ data_base = bp->init_data;
+
+ for (i = op_start; i < op_end; i++) {
+
+ op = (union init_op *)&(bp->init_ops[i]);
+
+ op_type = op->str_wr.op;
+ addr = op->str_wr.offset;
+ len = op->str_wr.data_len;
+ data = data_base + op->str_wr.data_off;
+
+ /* HW/EMUL specific */
+ if (unlikely((op_type > OP_WB) && (op_type == hw_wr)))
+ op_type = OP_WR;
+
+ switch (op_type) {
+ case OP_RD:
+ REG_RD(bp, addr);
+ break;
+ case OP_WR:
+ REG_WR(bp, addr, op->write.val);
+ break;
+ case OP_SW:
+ bnx2x_init_str_wr(bp, addr, data, len);
+ break;
+ case OP_WB:
+ bnx2x_init_wr_wb(bp, addr, data, len);
+ break;
+ case OP_SI:
+ bnx2x_init_ind_wr(bp, addr, data, len);
+ break;
+ case OP_ZR:
+ bnx2x_init_fill(bp, addr, 0, op->zero.len);
+ break;
+ case OP_ZP:
+ bnx2x_init_wr_zp(bp, addr, len,
+ op->str_wr.data_off);
+ break;
+ case OP_WR_64:
+ bnx2x_init_wr_64(bp, addr, data, len);
+ break;
+ default:
+ /* happens whenever an op is of a diff HW */
+#if 0
+ DP(NETIF_MSG_HW, "skipping init operation "
+ "index %d[%d:%d]: type %d addr 0x%x "
+ "len %d(0x%x)\n",
+ i, op_start, op_end, op_type, addr, len, len);
+#endif
+ break;
+ }
+ }
+}
+
+/* PXP */
+static void bnx2x_init_pxp(struct bnx2x *bp)
+{
+ u16 devctl;
+ int r_order, w_order;
+ u32 val, i;
+
+ pci_read_config_word(bp->pdev,
+ bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
+ DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
+ w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
+ if (bp->mrrs == -1)
+ r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+ else {
+ DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
+ r_order = bp->mrrs;
+ }
+
+ if (r_order > MAX_RD_ORD) {
+ DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n",
+ r_order, MAX_RD_ORD);
+ r_order = MAX_RD_ORD;
+ }
+ if (w_order > MAX_WR_ORD) {
+ DP(NETIF_MSG_HW, "write order of %d order adjusted to %d\n",
+ w_order, MAX_WR_ORD);
+ w_order = MAX_WR_ORD;
+ }
+ if (CHIP_REV_IS_FPGA(bp)) {
+ DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n");
+ w_order = 0;
+ }
+ DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order);
+
+ for (i = 0; i < NUM_RD_Q-1; i++) {
+ REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l);
+ REG_WR(bp, read_arb_addr[i].add,
+ read_arb_data[i][r_order].add);
+ REG_WR(bp, read_arb_addr[i].ubound,
+ read_arb_data[i][r_order].ubound);
+ }
+
+ for (i = 0; i < NUM_WR_Q-1; i++) {
+ if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) ||
+ (write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) {
+
+ REG_WR(bp, write_arb_addr[i].l,
+ write_arb_data[i][w_order].l);
+
+ REG_WR(bp, write_arb_addr[i].add,
+ write_arb_data[i][w_order].add);
+
+ REG_WR(bp, write_arb_addr[i].ubound,
+ write_arb_data[i][w_order].ubound);
+ } else {
+
+ val = REG_RD(bp, write_arb_addr[i].l);
+ REG_WR(bp, write_arb_addr[i].l,
+ val | (write_arb_data[i][w_order].l << 10));
+
+ val = REG_RD(bp, write_arb_addr[i].add);
+ REG_WR(bp, write_arb_addr[i].add,
+ val | (write_arb_data[i][w_order].add << 10));
+
+ val = REG_RD(bp, write_arb_addr[i].ubound);
+ REG_WR(bp, write_arb_addr[i].ubound,
+ val | (write_arb_data[i][w_order].ubound << 7));
+ }
+ }
+
+ val = write_arb_data[NUM_WR_Q-1][w_order].add;
+ val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10;
+ val += write_arb_data[NUM_WR_Q-1][w_order].l << 17;
+ REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val);
+
+ val = read_arb_data[NUM_RD_Q-1][r_order].add;
+ val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10;
+ val += read_arb_data[NUM_RD_Q-1][r_order].l << 17;
+ REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
+
+ REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
+ REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order);
+ REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
+ REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
+
+ if (r_order == MAX_RD_ORD)
+ REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
+
+ REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
+
+ if (CHIP_IS_E1H(bp)) {
+ val = ((w_order == 0) ? 2 : 3);
+ REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_QM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_TM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_SRC_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_DBG_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
+ REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
+ }
+}
+
+/*****************************************************************************
+ * Description:
+ * Calculates crc 8 on a word value: polynomial 0-1-2-8
+ * Code was translated from Verilog.
+ ****************************************************************************/
+static u8 calc_crc8(u32 data, u8 crc)
+{
+ u8 D[32];
+ u8 NewCRC[8];
+ u8 C[8];
+ u8 crc_res;
+ u8 i;
+
+ /* split the data into 31 bits */
+ for (i = 0; i < 32; i++) {
+ D[i] = data & 1;
+ data = data >> 1;
+ }
+
+ /* split the crc into 8 bits */
+ for (i = 0; i < 8; i++) {
+ C[i] = crc & 1;
+ crc = crc >> 1;
+ }
+
+ NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
+ D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
+ C[6] ^ C[7];
+ NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
+ D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
+ D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6];
+ NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
+ D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
+ C[0] ^ C[1] ^ C[4] ^ C[5];
+ NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
+ D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
+ C[1] ^ C[2] ^ C[5] ^ C[6];
+ NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
+ D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
+ C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
+ NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
+ D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
+ C[3] ^ C[4] ^ C[7];
+ NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
+ D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
+ C[5];
+ NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
+ D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
+ C[6];
+
+ crc_res = 0;
+ for (i = 0; i < 8; i++)
+ crc_res |= (NewCRC[i] << i);
+
+ return crc_res;
+}
+
+#endif /* BNX2X_INIT_OPS_H */
diff --git a/drivers/net/bnx2x_init_values.h b/drivers/net/bnx2x_init_values.h
deleted file mode 100644
index 1f22c9ab66d..00000000000
--- a/drivers/net/bnx2x_init_values.h
+++ /dev/null
@@ -1,16322 +0,0 @@
-#ifndef __BNX2X_INIT_VALUES_H__
-#define __BNX2X_INIT_VALUES_H__
-
-/* bnx2x_init_values.h: Broadcom NX2 10G network driver.
- *
- * Copyright (c) 2007-2009 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, except as noted below.
- *
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2007-2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- *
- *
- * This array contains the list of operations needed to initialize the chip.
- *
- * For each block in the chip there are three init stages:
- * common - HW used by both ports,
- * port1 and port2 - initialization for a specific Ethernet port.
- * When a port is opened or closed, the management CPU tells the driver
- * whether to init/disable common HW in addition to the port HW.
- * This way the first port going up will first initializes the common HW,
- * and the last port going down also resets the common HW
- *
- * For each init stage/block there is a list of actions needed in a format:
- * {operation, register, data}
- * where:
- * OP_WR - write a value to the chip.
- * OP_RD - read a register (usually a clear on read register).
- * OP_SW - string write, write a section of consecutive addresses to the chip.
- * OP_SI - copy a string using indirect writes.
- * OP_ZR - clear a range of memory.
- * OP_ZP - unzip and copy using DMAE.
- * OP_WB - string copy using DMAE.
- *
- * The #defines mark the stages.
- *
- */
-
-static const struct raw_op init_ops[] = {
-#define PRS_COMMON_START 0
- {OP_WR, PRS_REG_INC_VALUE, 0xf},
- {OP_WR, PRS_REG_EVENT_ID_1, 0x45},
- {OP_WR, PRS_REG_EVENT_ID_2, 0x84},
- {OP_WR, PRS_REG_EVENT_ID_3, 0x6},
- {OP_WR, PRS_REG_NO_MATCH_EVENT_ID, 0x4},
- {OP_WR, PRS_REG_CM_HDR_TYPE_0, 0x0},
- {OP_WR, PRS_REG_CM_HDR_TYPE_1, 0x12170000},
- {OP_WR, PRS_REG_CM_HDR_TYPE_2, 0x22170000},
- {OP_WR, PRS_REG_CM_HDR_TYPE_3, 0x32170000},
- {OP_ZR, PRS_REG_CM_HDR_TYPE_4, 0x5},
- {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_1, 0x12150000},
- {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_2, 0x22150000},
- {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_3, 0x32150000},
- {OP_ZR, PRS_REG_CM_HDR_LOOPBACK_TYPE_4, 0x4},
- {OP_WR, PRS_REG_CM_NO_MATCH_HDR, 0x2100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_0, 0x100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_1, 0x10100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_2, 0x20100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_3, 0x30100000},
- {OP_ZR_E1, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x4},
- {OP_WR_E1H, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x40100000},
- {OP_ZR_E1H, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_5, 0x3},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_0, 0x100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_1, 0x12140000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_2, 0x22140000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_3, 0x32140000},
- {OP_ZR_E1, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x4},
- {OP_WR_E1H, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x42140000},
- {OP_ZR_E1H, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_5, 0x3},
- {OP_RD, PRS_REG_NUM_OF_PACKETS, 0x0},
- {OP_RD, PRS_REG_NUM_OF_CFC_FLUSH_MESSAGES, 0x0},
- {OP_RD, PRS_REG_NUM_OF_TRANSPARENT_FLUSH_MESSAGES, 0x0},
- {OP_RD, PRS_REG_NUM_OF_DEAD_CYCLES, 0x0},
- {OP_WR_E1H, PRS_REG_FCOE_TYPE, 0x8906},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_0, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_1, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_2, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_3, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_4, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_5, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_6, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_7, 0xff},
- {OP_WR, PRS_REG_PURE_REGIONS, 0x3e},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_0, 0x0},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_1, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_2, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_3, 0x3f},
- {OP_WR_E1, PRS_REG_PACKET_REGIONS_TYPE_4, 0x0},
- {OP_WR_E1H, PRS_REG_PACKET_REGIONS_TYPE_4, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_5, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_6, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_7, 0x3f},
-#define PRS_COMMON_END 52
-#define SRCH_COMMON_START 52
- {OP_WR_E1H, SRC_REG_E1HMF_ENABLE, 0x1},
-#define SRCH_COMMON_END 53
-#define TSDM_COMMON_START 53
- {OP_WR_E1, TSDM_REG_CFC_RSP_START_ADDR, 0x411},
- {OP_WR_E1H, TSDM_REG_CFC_RSP_START_ADDR, 0x211},
- {OP_WR_E1, TSDM_REG_CMP_COUNTER_START_ADDR, 0x400},
- {OP_WR_E1H, TSDM_REG_CMP_COUNTER_START_ADDR, 0x200},
- {OP_WR_E1, TSDM_REG_Q_COUNTER_START_ADDR, 0x404},
- {OP_WR_E1H, TSDM_REG_Q_COUNTER_START_ADDR, 0x204},
- {OP_WR_E1, TSDM_REG_PCK_END_MSG_START_ADDR, 0x419},
- {OP_WR_E1H, TSDM_REG_PCK_END_MSG_START_ADDR, 0x219},
- {OP_WR, TSDM_REG_CMP_COUNTER_MAX0, 0xffff},
- {OP_WR, TSDM_REG_CMP_COUNTER_MAX1, 0xffff},
- {OP_WR, TSDM_REG_CMP_COUNTER_MAX2, 0xffff},
- {OP_WR, TSDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_ZR_E1, TSDM_REG_AGG_INT_EVENT_0, 0x2},
- {OP_WR_E1H, TSDM_REG_AGG_INT_EVENT_0, 0x20},
- {OP_WR_E1H, TSDM_REG_AGG_INT_EVENT_1, 0x0},
- {OP_WR, TSDM_REG_AGG_INT_EVENT_2, 0x34},
- {OP_WR, TSDM_REG_AGG_INT_EVENT_3, 0x35},
- {OP_ZR_E1, TSDM_REG_AGG_INT_EVENT_4, 0x7c},
- {OP_ZR_E1H, TSDM_REG_AGG_INT_EVENT_4, 0x1c},
- {OP_WR_E1H, TSDM_REG_AGG_INT_T_0, 0x1},
- {OP_ZR_E1H, TSDM_REG_AGG_INT_T_1, 0x5f},
- {OP_WR, TSDM_REG_ENABLE_IN1, 0x7ffffff},
- {OP_WR, TSDM_REG_ENABLE_IN2, 0x3f},
- {OP_WR, TSDM_REG_ENABLE_OUT1, 0x7ffffff},
- {OP_WR, TSDM_REG_ENABLE_OUT2, 0xf},
- {OP_RD, TSDM_REG_NUM_OF_Q0_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q1_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q3_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q4_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q5_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q6_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q7_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q8_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q9_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q10_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q11_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR_E1, TSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
- {OP_WR_ASIC, TSDM_REG_TIMER_TICK, 0x3e8},
- {OP_WR_EMUL, TSDM_REG_TIMER_TICK, 0x1},
- {OP_WR_FPGA, TSDM_REG_TIMER_TICK, 0xa},
-#define TSDM_COMMON_END 96
-#define TCM_COMMON_START 96
- {OP_WR, TCM_REG_XX_MAX_LL_SZ, 0x20},
- {OP_WR, TCM_REG_XX_OVFL_EVNT_ID, 0x32},
- {OP_WR, TCM_REG_TQM_TCM_HDR_P, 0x2150020},
- {OP_WR, TCM_REG_TQM_TCM_HDR_S, 0x2150020},
- {OP_WR, TCM_REG_TM_TCM_HDR, 0x30},
- {OP_WR, TCM_REG_ERR_TCM_HDR, 0x8100000},
- {OP_WR, TCM_REG_ERR_EVNT_ID, 0x33},
- {OP_WR, TCM_REG_EXPR_EVNT_ID, 0x30},
- {OP_WR, TCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, TCM_REG_STORM_WEIGHT, 0x2},
- {OP_WR, TCM_REG_PRS_WEIGHT, 0x5},
- {OP_WR, TCM_REG_PBF_WEIGHT, 0x6},
- {OP_WR, TCM_REG_USEM_WEIGHT, 0x2},
- {OP_WR, TCM_REG_CSEM_WEIGHT, 0x2},
- {OP_WR, TCM_REG_CP_WEIGHT, 0x0},
- {OP_WR, TCM_REG_TSDM_WEIGHT, 0x5},
- {OP_WR, TCM_REG_TQM_P_WEIGHT, 0x2},
- {OP_WR, TCM_REG_TQM_S_WEIGHT, 0x2},
- {OP_WR, TCM_REG_TM_WEIGHT, 0x2},
- {OP_WR, TCM_REG_TCM_TQM_USE_Q, 0x1},
- {OP_WR, TCM_REG_GR_ARB_TYPE, 0x1},
- {OP_WR, TCM_REG_GR_LD0_PR, 0x1},
- {OP_WR, TCM_REG_GR_LD1_PR, 0x2},
- {OP_WR, TCM_REG_CFC_INIT_CRD, 0x1},
- {OP_WR, TCM_REG_FIC0_INIT_CRD, 0x40},
- {OP_WR, TCM_REG_FIC1_INIT_CRD, 0x40},
- {OP_WR, TCM_REG_TQM_INIT_CRD, 0x20},
- {OP_WR, TCM_REG_XX_INIT_CRD, 0x13},
- {OP_WR, TCM_REG_XX_MSG_NUM, 0x20},
- {OP_ZR, TCM_REG_XX_TABLE, 0xa},
- {OP_SW, TCM_REG_XX_DESCR_TABLE, 0x200000},
- {OP_WR, TCM_REG_N_SM_CTX_LD_0, 0x7},
- {OP_WR, TCM_REG_N_SM_CTX_LD_1, 0x7},
- {OP_WR, TCM_REG_N_SM_CTX_LD_2, 0x8},
- {OP_WR, TCM_REG_N_SM_CTX_LD_3, 0x8},
- {OP_ZR_E1, TCM_REG_N_SM_CTX_LD_4, 0x4},
- {OP_WR_E1H, TCM_REG_N_SM_CTX_LD_4, 0x1},
- {OP_ZR_E1H, TCM_REG_N_SM_CTX_LD_5, 0x3},
- {OP_WR, TCM_REG_TCM_REG0_SZ, 0x6},
- {OP_WR_E1, TCM_REG_PHYS_QNUM0_0, 0xd},
- {OP_WR_E1, TCM_REG_PHYS_QNUM0_1, 0x2d},
- {OP_WR_E1, TCM_REG_PHYS_QNUM1_0, 0x7},
- {OP_WR_E1, TCM_REG_PHYS_QNUM1_1, 0x27},
- {OP_WR_E1, TCM_REG_PHYS_QNUM2_0, 0x7},
- {OP_WR_E1, TCM_REG_PHYS_QNUM2_1, 0x27},
- {OP_WR_E1, TCM_REG_PHYS_QNUM3_0, 0x7},
- {OP_WR_E1, TCM_REG_PHYS_QNUM3_1, 0x27},
- {OP_WR, TCM_REG_TCM_STORM0_IFEN, 0x1},
- {OP_WR, TCM_REG_TCM_STORM1_IFEN, 0x1},
- {OP_WR, TCM_REG_TCM_TQM_IFEN, 0x1},
- {OP_WR, TCM_REG_STORM_TCM_IFEN, 0x1},
- {OP_WR, TCM_REG_TQM_TCM_IFEN, 0x1},
- {OP_WR, TCM_REG_TSDM_IFEN, 0x1},
- {OP_WR, TCM_REG_TM_TCM_IFEN, 0x1},
- {OP_WR, TCM_REG_PRS_IFEN, 0x1},
- {OP_WR, TCM_REG_PBF_IFEN, 0x1},
- {OP_WR, TCM_REG_USEM_IFEN, 0x1},
- {OP_WR, TCM_REG_CSEM_IFEN, 0x1},
- {OP_WR, TCM_REG_CDU_AG_WR_IFEN, 0x1},
- {OP_WR, TCM_REG_CDU_AG_RD_IFEN, 0x1},
- {OP_WR, TCM_REG_CDU_SM_WR_IFEN, 0x1},
- {OP_WR, TCM_REG_CDU_SM_RD_IFEN, 0x1},
- {OP_WR, TCM_REG_TCM_CFC_IFEN, 0x1},
-#define TCM_COMMON_END 159
-#define TCM_FUNC0_START 159
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0xd},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x7},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x7},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x7},
-#define TCM_FUNC0_END 163
-#define TCM_FUNC1_START 163
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x2d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x27},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x27},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x27},
-#define TCM_FUNC1_END 167
-#define TCM_FUNC2_START 167
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x1d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x17},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x17},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x17},
-#define TCM_FUNC2_END 171
-#define TCM_FUNC3_START 171
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x3d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x37},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x37},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x37},
-#define TCM_FUNC3_END 175
-#define TCM_FUNC4_START 175
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x4d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x47},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x47},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x47},
-#define TCM_FUNC4_END 179
-#define TCM_FUNC5_START 179
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x6d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x67},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x67},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x67},
-#define TCM_FUNC5_END 183
-#define TCM_FUNC6_START 183
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x5d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x57},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x57},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x57},
-#define TCM_FUNC6_END 187
-#define TCM_FUNC7_START 187
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x7d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x77},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x77},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x77},
-#define TCM_FUNC7_END 191
-#define BRB1_COMMON_START 191
- {OP_SW, BRB1_REG_LL_RAM, 0x2000020},
- {OP_WR, BRB1_REG_SOFT_RESET, 0x1},
- {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_4, 0x0},
- {OP_SW, BRB1_REG_FREE_LIST_PRS_CRDT, 0x30220},
- {OP_WR, BRB1_REG_SOFT_RESET, 0x0},
-#define BRB1_COMMON_END 196
-#define BRB1_PORT0_START 196
- {OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0xb8},
- {OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 0x114},
- {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_0, 0x0},
- {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_0, 0x0},
-#define BRB1_PORT0_END 200
-#define BRB1_PORT1_START 200
- {OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0xb8},
- {OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 0x114},
- {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_1, 0x0},
- {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_1, 0x0},
-#define BRB1_PORT1_END 204
-#define TSEM_COMMON_START 204
- {OP_RD, TSEM_REG_MSG_NUM_FIC0, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FIC1, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FOC0, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FOC1, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FOC2, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FOC3, 0x0},
- {OP_WR, TSEM_REG_ARB_ELEMENT0, 0x1},
- {OP_WR, TSEM_REG_ARB_ELEMENT1, 0x2},
- {OP_WR, TSEM_REG_ARB_ELEMENT2, 0x3},
- {OP_WR, TSEM_REG_ARB_ELEMENT3, 0x0},
- {OP_WR, TSEM_REG_ARB_ELEMENT4, 0x4},
- {OP_WR, TSEM_REG_ARB_CYCLE_SIZE, 0x1},
- {OP_WR, TSEM_REG_TS_0_AS, 0x0},
- {OP_WR, TSEM_REG_TS_1_AS, 0x1},
- {OP_WR, TSEM_REG_TS_2_AS, 0x4},
- {OP_WR, TSEM_REG_TS_3_AS, 0x0},
- {OP_WR, TSEM_REG_TS_4_AS, 0x1},
- {OP_WR, TSEM_REG_TS_5_AS, 0x3},
- {OP_WR, TSEM_REG_TS_6_AS, 0x0},
- {OP_WR, TSEM_REG_TS_7_AS, 0x1},
- {OP_WR, TSEM_REG_TS_8_AS, 0x4},
- {OP_WR, TSEM_REG_TS_9_AS, 0x0},
- {OP_WR, TSEM_REG_TS_10_AS, 0x1},
- {OP_WR, TSEM_REG_TS_11_AS, 0x3},
- {OP_WR, TSEM_REG_TS_12_AS, 0x0},
- {OP_WR, TSEM_REG_TS_13_AS, 0x1},
- {OP_WR, TSEM_REG_TS_14_AS, 0x4},
- {OP_WR, TSEM_REG_TS_15_AS, 0x0},
- {OP_WR, TSEM_REG_TS_16_AS, 0x4},
- {OP_WR, TSEM_REG_TS_17_AS, 0x3},
- {OP_ZR, TSEM_REG_TS_18_AS, 0x2},
- {OP_WR, TSEM_REG_ENABLE_IN, 0x3fff},
- {OP_WR, TSEM_REG_ENABLE_OUT, 0x3ff},
- {OP_WR, TSEM_REG_FIC0_DISABLE, 0x0},
- {OP_WR, TSEM_REG_FIC1_DISABLE, 0x0},
- {OP_WR, TSEM_REG_PAS_DISABLE, 0x0},
- {OP_WR, TSEM_REG_THREADS_LIST, 0xff},
- {OP_ZR, TSEM_REG_PASSIVE_BUFFER, 0x400},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x18000, 0x34},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x18040, 0x18},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x18080, 0xc},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x180c0, 0x20},
- {OP_WR_ASIC, TSEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
- {OP_WR_EMUL, TSEM_REG_FAST_MEMORY + 0x18300, 0x138},
- {OP_WR_FPGA, TSEM_REG_FAST_MEMORY + 0x18300, 0x1388},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2000, 0xb2},
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x11480, 0x1},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x23c8, 0xc1},
- {OP_WR_EMUL_E1H, TSEM_REG_FAST_MEMORY + 0x11480, 0x0},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x23c8 + 0x304, 0x10223},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x1000, 0x2b3},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x1000 + 0xacc, 0x10223},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa020, 0xc8},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1c18, 0x4},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa000, 0x2},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1c10, 0x2},
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x1ad0, 0x0},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x1ad8, 0x4},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3678, 0x6},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x810, 0x4},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3670, 0x2},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x40224},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x4cb0, 0x80228},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5008, 0x4},
- {OP_ZP_E1, TSEM_REG_INT_TABLE, 0x930000},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5018, 0x4},
- {OP_WR_64_E1, TSEM_REG_INT_TABLE + 0x360, 0x140230},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5028, 0x4},
- {OP_ZP_E1, TSEM_REG_PRAM, 0x324f0000},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5038, 0x4},
- {OP_ZP_E1, TSEM_REG_PRAM + 0x8000, 0x33250c94},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5048, 0x4},
- {OP_ZP_E1, TSEM_REG_PRAM + 0x10000, 0xe4d195e},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5058, 0x4},
- {OP_WR_64_E1, TSEM_REG_PRAM + 0x11e00, 0x5c400232},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5068, 0x4},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5078, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x62c0, 0x200224},
- {OP_ZP_E1H, TSEM_REG_INT_TABLE, 0x9b0000},
- {OP_WR_64_E1H, TSEM_REG_INT_TABLE + 0x398, 0xd0244},
- {OP_ZP_E1H, TSEM_REG_PRAM, 0x325e0000},
- {OP_ZP_E1H, TSEM_REG_PRAM + 0x8000, 0x35960c98},
- {OP_ZP_E1H, TSEM_REG_PRAM + 0x10000, 0x1aea19fe},
- {OP_WR_64_E1H, TSEM_REG_PRAM + 0x143d0, 0x57860246},
-#define TSEM_COMMON_END 297
-#define TSEM_PORT0_START 297
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x22c8, 0x20},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x2000, 0x16c},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x4000, 0x16c},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb000, 0x28},
- {OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b60, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb140, 0xc},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1400, 0xa},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32c0, 0x12},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1450, 0x6},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3350, 0x64},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8108, 0x2},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1500 + 0x8, 0x50234},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500 + 0x1c, 0x7},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1570, 0x12},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x9c0, 0x4c},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x820, 0xe},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x20239},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2908, 0x2},
-#define TSEM_PORT0_END 317
-#define TSEM_PORT1_START 317
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2348, 0x20},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x25b0, 0x16c},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x45b0, 0x16c},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb0a0, 0x28},
- {OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b64, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb170, 0xc},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1428, 0xa},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3308, 0x12},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1468, 0x6},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x34e0, 0x64},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8110, 0x2},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1538 + 0x8, 0x5023b},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538 + 0x1c, 0x7},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x15b8, 0x12},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0xaf0, 0x4c},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x858, 0xe},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb8, 0x20240},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2910, 0x2},
-#define TSEM_PORT1_END 337
-#define TSEM_FUNC0_START 337
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b60, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3000 + 0x8, 0x50248},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31c0, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5080, 0x12},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2},
-#define TSEM_FUNC0_END 345
-#define TSEM_FUNC1_START 345
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b64, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3038 + 0x8, 0x5024d},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31e0, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5010, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x50c8, 0x12},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2},
-#define TSEM_FUNC1_END 353
-#define TSEM_FUNC2_START 353
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b68, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3070 + 0x8, 0x50252},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3200, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5020, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5110, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4010, 0x20257},
-#define TSEM_FUNC2_END 361
-#define TSEM_FUNC3_START 361
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b6c, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x30a8 + 0x8, 0x50259},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3220, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5030, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5158, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4018, 0x2025e},
-#define TSEM_FUNC3_END 369
-#define TSEM_FUNC4_START 369
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b70, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x30e0 + 0x8, 0x50260},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3240, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5040, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51a0, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4020, 0x20265},
-#define TSEM_FUNC4_END 377
-#define TSEM_FUNC5_START 377
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b74, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3118 + 0x8, 0x50267},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3260, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5050, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51e8, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4028, 0x2026c},
-#define TSEM_FUNC5_END 385
-#define TSEM_FUNC6_START 385
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b78, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3150 + 0x8, 0x5026e},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3280, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5060, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5230, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4030, 0x20273},
-#define TSEM_FUNC6_END 393
-#define TSEM_FUNC7_START 393
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b7c, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3188 + 0x8, 0x50275},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188 + 0x1c, 0x7},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32a0, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5070, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5278, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4038, 0x2027a},
-#define TSEM_FUNC7_END 401
-#define MISC_COMMON_START 401
- {OP_WR_E1, MISC_REG_GRC_TIMEOUT_EN, 0x1},
- {OP_WR, MISC_REG_PLL_STORM_CTRL_1, 0x71d2911},
- {OP_WR, MISC_REG_PLL_STORM_CTRL_2, 0x0},
- {OP_WR, MISC_REG_PLL_STORM_CTRL_3, 0x9c0424},
- {OP_WR, MISC_REG_PLL_STORM_CTRL_4, 0x0},
- {OP_WR, MISC_REG_LCPLL_CTRL_1, 0x209},
- {OP_WR_E1, MISC_REG_SPIO, 0xff000000},
-#define MISC_COMMON_END 408
-#define MISC_FUNC0_START 408
- {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC0_END 409
-#define MISC_FUNC1_START 409
- {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC1_END 410
-#define MISC_FUNC2_START 410
- {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC2_END 411
-#define MISC_FUNC3_START 411
- {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC3_END 412
-#define MISC_FUNC4_START 412
- {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC4_END 413
-#define MISC_FUNC5_START 413
- {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC5_END 414
-#define MISC_FUNC6_START 414
- {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC6_END 415
-#define MISC_FUNC7_START 415
- {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC7_END 416
-#define NIG_COMMON_START 416
- {OP_WR, NIG_REG_PBF_LB_IN_EN, 0x1},
- {OP_WR, NIG_REG_PRS_REQ_IN_EN, 0x1},
- {OP_WR, NIG_REG_EGRESS_DEBUG_IN_EN, 0x1},
- {OP_WR, NIG_REG_BRB_LB_OUT_EN, 0x1},
- {OP_WR, NIG_REG_PRS_EOP_OUT_EN, 0x1},
-#define NIG_COMMON_END 421
-#define NIG_PORT0_START 421
- {OP_WR, NIG_REG_LLH0_CM_HEADER, 0x300000},
- {OP_WR, NIG_REG_LLH0_EVENT_ID, 0x28},
- {OP_WR, NIG_REG_LLH0_ERROR_MASK, 0x0},
- {OP_WR, NIG_REG_LLH0_XCM_MASK, 0x4},
- {OP_WR, NIG_REG_LLH0_BRB1_NOT_MCP, 0x1},
- {OP_WR, NIG_REG_STATUS_INTERRUPT_PORT0, 0x0},
- {OP_WR_E1H, NIG_REG_LLH0_CLS_TYPE, 0x1},
- {OP_WR, NIG_REG_LLH0_XCM_INIT_CREDIT, 0x30},
- {OP_WR, NIG_REG_BRB0_PAUSE_IN_EN, 0x1},
- {OP_WR, NIG_REG_EGRESS_PBF0_IN_EN, 0x1},
- {OP_WR, NIG_REG_BRB0_OUT_EN, 0x1},
- {OP_WR, NIG_REG_XCM0_OUT_EN, 0x1},
-#define NIG_PORT0_END 433
-#define NIG_PORT1_START 433
- {OP_WR, NIG_REG_LLH1_CM_HEADER, 0x300000},
- {OP_WR, NIG_REG_LLH1_EVENT_ID, 0x28},
- {OP_WR, NIG_REG_LLH1_ERROR_MASK, 0x0},
- {OP_WR, NIG_REG_LLH1_XCM_MASK, 0x4},
- {OP_WR, NIG_REG_LLH1_BRB1_NOT_MCP, 0x1},
- {OP_WR, NIG_REG_STATUS_INTERRUPT_PORT1, 0x0},
- {OP_WR_E1H, NIG_REG_LLH1_CLS_TYPE, 0x1},
- {OP_WR, NIG_REG_LLH1_XCM_INIT_CREDIT, 0x30},
- {OP_WR, NIG_REG_BRB1_PAUSE_IN_EN, 0x1},
- {OP_WR, NIG_REG_EGRESS_PBF1_IN_EN, 0x1},
- {OP_WR, NIG_REG_BRB1_OUT_EN, 0x1},
- {OP_WR, NIG_REG_XCM1_OUT_EN, 0x1},
-#define NIG_PORT1_END 445
-#define UPB_COMMON_START 445
- {OP_WR, GRCBASE_UPB + PB_REG_CONTROL, 0x20},
-#define UPB_COMMON_END 446
-#define CSDM_COMMON_START 446
- {OP_WR_E1, CSDM_REG_CFC_RSP_START_ADDR, 0xa11},
- {OP_WR_E1H, CSDM_REG_CFC_RSP_START_ADDR, 0x211},
- {OP_WR_E1, CSDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
- {OP_WR_E1H, CSDM_REG_CMP_COUNTER_START_ADDR, 0x200},
- {OP_WR_E1, CSDM_REG_Q_COUNTER_START_ADDR, 0xa04},
- {OP_WR_E1H, CSDM_REG_Q_COUNTER_START_ADDR, 0x204},
- {OP_WR, CSDM_REG_CMP_COUNTER_MAX0, 0xffff},
- {OP_WR, CSDM_REG_CMP_COUNTER_MAX1, 0xffff},
- {OP_WR, CSDM_REG_CMP_COUNTER_MAX2, 0xffff},
- {OP_WR, CSDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_WR, CSDM_REG_AGG_INT_EVENT_0, 0xc6},
- {OP_WR, CSDM_REG_AGG_INT_EVENT_1, 0x0},
- {OP_WR, CSDM_REG_AGG_INT_EVENT_2, 0x34},
- {OP_WR, CSDM_REG_AGG_INT_EVENT_3, 0x35},
- {OP_ZR, CSDM_REG_AGG_INT_EVENT_4, 0x1c},
- {OP_WR, CSDM_REG_AGG_INT_T_0, 0x1},
- {OP_ZR, CSDM_REG_AGG_INT_T_1, 0x5f},
- {OP_WR, CSDM_REG_ENABLE_IN1, 0x7ffffff},
- {OP_WR, CSDM_REG_ENABLE_IN2, 0x3f},
- {OP_WR, CSDM_REG_ENABLE_OUT1, 0x7ffffff},
- {OP_WR, CSDM_REG_ENABLE_OUT2, 0xf},
- {OP_RD, CSDM_REG_NUM_OF_Q0_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q1_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q3_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q4_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q5_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q6_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q7_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q8_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q9_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q10_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q11_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR_E1, CSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
- {OP_WR_ASIC, CSDM_REG_TIMER_TICK, 0x3e8},
- {OP_WR_EMUL, CSDM_REG_TIMER_TICK, 0x1},
- {OP_WR_FPGA, CSDM_REG_TIMER_TICK, 0xa},
-#define CSDM_COMMON_END 485
-#define USDM_COMMON_START 485
- {OP_WR_E1, USDM_REG_CFC_RSP_START_ADDR, 0xa11},
- {OP_WR_E1H, USDM_REG_CFC_RSP_START_ADDR, 0x411},
- {OP_WR_E1, USDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
- {OP_WR_E1H, USDM_REG_CMP_COUNTER_START_ADDR, 0x400},
- {OP_WR_E1, USDM_REG_Q_COUNTER_START_ADDR, 0xa04},
- {OP_WR_E1H, USDM_REG_Q_COUNTER_START_ADDR, 0x404},
- {OP_WR_E1, USDM_REG_PCK_END_MSG_START_ADDR, 0xa21},
- {OP_WR_E1H, USDM_REG_PCK_END_MSG_START_ADDR, 0x421},
- {OP_WR, USDM_REG_CMP_COUNTER_MAX0, 0xffff},
- {OP_WR, USDM_REG_CMP_COUNTER_MAX1, 0xffff},
- {OP_WR, USDM_REG_CMP_COUNTER_MAX2, 0xffff},
- {OP_WR, USDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_WR, USDM_REG_AGG_INT_EVENT_0, 0x46},
- {OP_WR, USDM_REG_AGG_INT_EVENT_1, 0x5},
- {OP_WR, USDM_REG_AGG_INT_EVENT_2, 0x34},
- {OP_WR, USDM_REG_AGG_INT_EVENT_3, 0x35},
- {OP_ZR_E1, USDM_REG_AGG_INT_EVENT_4, 0x5c},
- {OP_WR_E1H, USDM_REG_AGG_INT_EVENT_4, 0x7},
- {OP_ZR_E1H, USDM_REG_AGG_INT_EVENT_5, 0x5b},
- {OP_WR, USDM_REG_AGG_INT_MODE_0, 0x1},
- {OP_ZR_E1, USDM_REG_AGG_INT_MODE_1, 0x1f},
- {OP_ZR_E1H, USDM_REG_AGG_INT_MODE_1, 0x3},
- {OP_WR_E1H, USDM_REG_AGG_INT_MODE_4, 0x1},
- {OP_ZR_E1H, USDM_REG_AGG_INT_MODE_5, 0x1b},
- {OP_WR, USDM_REG_ENABLE_IN1, 0x7ffffff},
- {OP_WR, USDM_REG_ENABLE_IN2, 0x3f},
- {OP_WR, USDM_REG_ENABLE_OUT1, 0x7ffffff},
- {OP_WR, USDM_REG_ENABLE_OUT2, 0xf},
- {OP_RD, USDM_REG_NUM_OF_Q0_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q1_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q2_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q3_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q4_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q5_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q6_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q7_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q8_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q9_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q10_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q11_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_PKT_END_MSG, 0x0},
- {OP_RD, USDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
- {OP_RD, USDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR_E1, USDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
- {OP_WR_ASIC, USDM_REG_TIMER_TICK, 0x3e8},
- {OP_WR_EMUL, USDM_REG_TIMER_TICK, 0x1},
- {OP_WR_FPGA, USDM_REG_TIMER_TICK, 0xa},
-#define USDM_COMMON_END 532
-#define CCM_COMMON_START 532
- {OP_WR, CCM_REG_XX_OVFL_EVNT_ID, 0x32},
- {OP_WR, CCM_REG_CQM_CCM_HDR_P, 0x2150020},
- {OP_WR, CCM_REG_CQM_CCM_HDR_S, 0x2150020},
- {OP_WR, CCM_REG_ERR_CCM_HDR, 0x8100000},
- {OP_WR, CCM_REG_ERR_EVNT_ID, 0x33},
- {OP_WR, CCM_REG_STORM_WEIGHT, 0x2},
- {OP_WR, CCM_REG_TSEM_WEIGHT, 0x0},
- {OP_WR, CCM_REG_XSEM_WEIGHT, 0x5},
- {OP_WR, CCM_REG_USEM_WEIGHT, 0x5},
- {OP_ZR, CCM_REG_PBF_WEIGHT, 0x2},
- {OP_WR, CCM_REG_CSDM_WEIGHT, 0x2},
- {OP_WR, CCM_REG_CQM_P_WEIGHT, 0x3},
- {OP_WR, CCM_REG_CQM_S_WEIGHT, 0x2},
- {OP_WR, CCM_REG_CCM_CQM_USE_Q, 0x1},
- {OP_WR, CCM_REG_CNT_AUX1_Q, 0x2},
- {OP_WR, CCM_REG_CNT_AUX2_Q, 0x2},
- {OP_WR, CCM_REG_INV_DONE_Q, 0x1},
- {OP_WR, CCM_REG_GR_ARB_TYPE, 0x1},
- {OP_WR, CCM_REG_GR_LD0_PR, 0x1},
- {OP_WR, CCM_REG_GR_LD1_PR, 0x2},
- {OP_WR, CCM_REG_CFC_INIT_CRD, 0x1},
- {OP_WR, CCM_REG_CQM_INIT_CRD, 0x20},
- {OP_WR, CCM_REG_FIC0_INIT_CRD, 0x40},
- {OP_WR, CCM_REG_FIC1_INIT_CRD, 0x40},
- {OP_WR, CCM_REG_XX_INIT_CRD, 0x3},
- {OP_WR, CCM_REG_XX_MSG_NUM, 0x18},
- {OP_ZR, CCM_REG_XX_TABLE, 0x12},
- {OP_SW_E1, CCM_REG_XX_DESCR_TABLE, 0x240242},
- {OP_SW_E1H, CCM_REG_XX_DESCR_TABLE, 0x24027c},
- {OP_WR, CCM_REG_N_SM_CTX_LD_0, 0x1},
- {OP_WR, CCM_REG_N_SM_CTX_LD_1, 0x2},
- {OP_WR, CCM_REG_N_SM_CTX_LD_2, 0x8},
- {OP_WR, CCM_REG_N_SM_CTX_LD_3, 0x8},
- {OP_ZR, CCM_REG_N_SM_CTX_LD_4, 0x4},
- {OP_WR, CCM_REG_CCM_REG0_SZ, 0x4},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM0_0, 0x9},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM0_1, 0x29},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM1_0, 0xa},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM2_0, 0x7},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM2_1, 0x27},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM3_0, 0x7},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM3_1, 0x27},
- {OP_WR_E1, CCM_REG_PHYS_QNUM1_0, 0xc},
- {OP_WR_E1, CCM_REG_PHYS_QNUM1_1, 0x2c},
- {OP_WR_E1, CCM_REG_PHYS_QNUM2_0, 0xc},
- {OP_WR_E1, CCM_REG_PHYS_QNUM2_1, 0x2c},
- {OP_WR_E1, CCM_REG_PHYS_QNUM3_0, 0xc},
- {OP_WR_E1, CCM_REG_PHYS_QNUM3_1, 0x2c},
- {OP_WR, CCM_REG_CCM_STORM0_IFEN, 0x1},
- {OP_WR, CCM_REG_CCM_STORM1_IFEN, 0x1},
- {OP_WR, CCM_REG_CCM_CQM_IFEN, 0x1},
- {OP_WR, CCM_REG_STORM_CCM_IFEN, 0x1},
- {OP_WR, CCM_REG_CQM_CCM_IFEN, 0x1},
- {OP_WR, CCM_REG_CSDM_IFEN, 0x1},
- {OP_WR, CCM_REG_TSEM_IFEN, 0x1},
- {OP_WR, CCM_REG_XSEM_IFEN, 0x1},
- {OP_WR, CCM_REG_USEM_IFEN, 0x1},
- {OP_WR, CCM_REG_PBF_IFEN, 0x1},
- {OP_WR, CCM_REG_CDU_AG_WR_IFEN, 0x1},
- {OP_WR, CCM_REG_CDU_AG_RD_IFEN, 0x1},
- {OP_WR, CCM_REG_CDU_SM_WR_IFEN, 0x1},
- {OP_WR, CCM_REG_CDU_SM_RD_IFEN, 0x1},
- {OP_WR, CCM_REG_CCM_CFC_IFEN, 0x1},
-#define CCM_COMMON_END 596
-#define CCM_FUNC0_START 596
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x9},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0xa},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x7},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x7},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0xc},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0xb},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x7},
-#define CCM_FUNC0_END 603
-#define CCM_FUNC1_START 603
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x29},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x27},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x27},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x2c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x2b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x27},
-#define CCM_FUNC1_END 610
-#define CCM_FUNC2_START 610
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x19},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x1a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x17},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x17},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x1c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x1b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x17},
-#define CCM_FUNC2_END 617
-#define CCM_FUNC3_START 617
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x39},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x3a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x37},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x37},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x3c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x3b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x37},
-#define CCM_FUNC3_END 624
-#define CCM_FUNC4_START 624
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x49},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x4a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x47},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x47},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x4c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x4b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x47},
-#define CCM_FUNC4_END 631
-#define CCM_FUNC5_START 631
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x69},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x6a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x67},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x67},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x6c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x6b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x67},
-#define CCM_FUNC5_END 638
-#define CCM_FUNC6_START 638
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x59},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x5a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x57},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x57},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x5c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x5b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x57},
-#define CCM_FUNC6_END 645
-#define CCM_FUNC7_START 645
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x79},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x7a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x77},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x77},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x7c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x7b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x77},
-#define CCM_FUNC7_END 652
-#define UCM_COMMON_START 652
- {OP_WR, UCM_REG_XX_OVFL_EVNT_ID, 0x32},
- {OP_WR, UCM_REG_UQM_UCM_HDR_P, 0x2150020},
- {OP_WR, UCM_REG_UQM_UCM_HDR_S, 0x2150020},
- {OP_WR, UCM_REG_TM_UCM_HDR, 0x30},
- {OP_WR, UCM_REG_ERR_UCM_HDR, 0x8100000},
- {OP_WR, UCM_REG_ERR_EVNT_ID, 0x33},
- {OP_WR, UCM_REG_EXPR_EVNT_ID, 0x30},
- {OP_WR, UCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, UCM_REG_STORM_WEIGHT, 0x2},
- {OP_WR, UCM_REG_TSEM_WEIGHT, 0x4},
- {OP_WR, UCM_REG_CSEM_WEIGHT, 0x0},
- {OP_WR, UCM_REG_XSEM_WEIGHT, 0x2},
- {OP_WR, UCM_REG_DORQ_WEIGHT, 0x2},
- {OP_WR, UCM_REG_CP_WEIGHT, 0x0},
- {OP_WR, UCM_REG_USDM_WEIGHT, 0x2},
- {OP_WR, UCM_REG_UQM_P_WEIGHT, 0x7},
- {OP_WR, UCM_REG_UQM_S_WEIGHT, 0x2},
- {OP_WR, UCM_REG_TM_WEIGHT, 0x2},
- {OP_WR, UCM_REG_UCM_UQM_USE_Q, 0x1},
- {OP_WR, UCM_REG_INV_CFLG_Q, 0x1},
- {OP_WR, UCM_REG_GR_ARB_TYPE, 0x1},
- {OP_WR, UCM_REG_GR_LD0_PR, 0x1},
- {OP_WR, UCM_REG_GR_LD1_PR, 0x2},
- {OP_WR, UCM_REG_CFC_INIT_CRD, 0x1},
- {OP_WR, UCM_REG_FIC0_INIT_CRD, 0x40},
- {OP_WR, UCM_REG_FIC1_INIT_CRD, 0x40},
- {OP_WR, UCM_REG_TM_INIT_CRD, 0x4},
- {OP_WR, UCM_REG_UQM_INIT_CRD, 0x20},
- {OP_WR, UCM_REG_XX_INIT_CRD, 0xe},
- {OP_WR, UCM_REG_XX_MSG_NUM, 0x1b},
- {OP_ZR, UCM_REG_XX_TABLE, 0x12},
- {OP_SW_E1, UCM_REG_XX_DESCR_TABLE, 0x1b0266},
- {OP_SW_E1H, UCM_REG_XX_DESCR_TABLE, 0x1b02a0},
- {OP_WR, UCM_REG_N_SM_CTX_LD_0, 0x10},
- {OP_WR, UCM_REG_N_SM_CTX_LD_1, 0x7},
- {OP_WR, UCM_REG_N_SM_CTX_LD_2, 0xf},
- {OP_WR, UCM_REG_N_SM_CTX_LD_3, 0x10},
- {OP_ZR_E1, UCM_REG_N_SM_CTX_LD_4, 0x4},
- {OP_WR_E1H, UCM_REG_N_SM_CTX_LD_4, 0xb},
- {OP_ZR_E1H, UCM_REG_N_SM_CTX_LD_5, 0x3},
- {OP_WR, UCM_REG_UCM_REG0_SZ, 0x3},
- {OP_WR_E1, UCM_REG_PHYS_QNUM0_0, 0xf},
- {OP_WR_E1, UCM_REG_PHYS_QNUM0_1, 0x2f},
- {OP_WR_E1, UCM_REG_PHYS_QNUM1_0, 0xe},
- {OP_WR_E1, UCM_REG_PHYS_QNUM1_1, 0x2e},
- {OP_WR, UCM_REG_UCM_STORM0_IFEN, 0x1},
- {OP_WR, UCM_REG_UCM_STORM1_IFEN, 0x1},
- {OP_WR, UCM_REG_UCM_UQM_IFEN, 0x1},
- {OP_WR, UCM_REG_STORM_UCM_IFEN, 0x1},
- {OP_WR, UCM_REG_UQM_UCM_IFEN, 0x1},
- {OP_WR, UCM_REG_USDM_IFEN, 0x1},
- {OP_WR, UCM_REG_TM_UCM_IFEN, 0x1},
- {OP_WR, UCM_REG_UCM_TM_IFEN, 0x1},
- {OP_WR, UCM_REG_TSEM_IFEN, 0x1},
- {OP_WR, UCM_REG_CSEM_IFEN, 0x1},
- {OP_WR, UCM_REG_XSEM_IFEN, 0x1},
- {OP_WR, UCM_REG_DORQ_IFEN, 0x1},
- {OP_WR, UCM_REG_CDU_AG_WR_IFEN, 0x1},
- {OP_WR, UCM_REG_CDU_AG_RD_IFEN, 0x1},
- {OP_WR, UCM_REG_CDU_SM_WR_IFEN, 0x1},
- {OP_WR, UCM_REG_CDU_SM_RD_IFEN, 0x1},
- {OP_WR, UCM_REG_UCM_CFC_IFEN, 0x1},
-#define UCM_COMMON_END 714
-#define UCM_FUNC0_START 714
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0xf},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0xe},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC0_END 718
-#define UCM_FUNC1_START 718
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x2f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x2e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC1_END 722
-#define UCM_FUNC2_START 722
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x1f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x1e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC2_END 726
-#define UCM_FUNC3_START 726
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x3f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x3e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC3_END 730
-#define UCM_FUNC4_START 730
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x4f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x4e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC4_END 734
-#define UCM_FUNC5_START 734
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x6f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x6e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC5_END 738
-#define UCM_FUNC6_START 738
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x5f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x5e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC6_END 742
-#define UCM_FUNC7_START 742
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x7f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x7e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC7_END 746
-#define USEM_COMMON_START 746
- {OP_RD, USEM_REG_MSG_NUM_FIC0, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FIC1, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FOC0, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FOC1, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FOC2, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FOC3, 0x0},
- {OP_WR, USEM_REG_ARB_ELEMENT0, 0x1},
- {OP_WR, USEM_REG_ARB_ELEMENT1, 0x2},
- {OP_WR, USEM_REG_ARB_ELEMENT2, 0x3},
- {OP_WR, USEM_REG_ARB_ELEMENT3, 0x0},
- {OP_WR, USEM_REG_ARB_ELEMENT4, 0x4},
- {OP_WR, USEM_REG_ARB_CYCLE_SIZE, 0x1},
- {OP_WR, USEM_REG_TS_0_AS, 0x0},
- {OP_WR, USEM_REG_TS_1_AS, 0x1},
- {OP_WR, USEM_REG_TS_2_AS, 0x4},
- {OP_WR, USEM_REG_TS_3_AS, 0x0},
- {OP_WR, USEM_REG_TS_4_AS, 0x1},
- {OP_WR, USEM_REG_TS_5_AS, 0x3},
- {OP_WR, USEM_REG_TS_6_AS, 0x0},
- {OP_WR, USEM_REG_TS_7_AS, 0x1},
- {OP_WR, USEM_REG_TS_8_AS, 0x4},
- {OP_WR, USEM_REG_TS_9_AS, 0x0},
- {OP_WR, USEM_REG_TS_10_AS, 0x1},
- {OP_WR, USEM_REG_TS_11_AS, 0x3},
- {OP_WR, USEM_REG_TS_12_AS, 0x0},
- {OP_WR, USEM_REG_TS_13_AS, 0x1},
- {OP_WR, USEM_REG_TS_14_AS, 0x4},
- {OP_WR, USEM_REG_TS_15_AS, 0x0},
- {OP_WR, USEM_REG_TS_16_AS, 0x4},
- {OP_WR, USEM_REG_TS_17_AS, 0x3},
- {OP_ZR, USEM_REG_TS_18_AS, 0x2},
- {OP_WR, USEM_REG_ENABLE_IN, 0x3fff},
- {OP_WR, USEM_REG_ENABLE_OUT, 0x3ff},
- {OP_WR, USEM_REG_FIC0_DISABLE, 0x0},
- {OP_WR, USEM_REG_FIC1_DISABLE, 0x0},
- {OP_WR, USEM_REG_PAS_DISABLE, 0x0},
- {OP_WR, USEM_REG_THREADS_LIST, 0xffff},
- {OP_ZR, USEM_REG_PASSIVE_BUFFER, 0x800},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x18000, 0x1a},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x18040, 0x4e},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x18080, 0x10},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x180c0, 0x20},
- {OP_WR_ASIC, USEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
- {OP_WR_EMUL, USEM_REG_FAST_MEMORY + 0x18300, 0x138},
- {OP_WR_FPGA, USEM_REG_FAST_MEMORY + 0x18300, 0x1388},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_WR_ASIC, USEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
- {OP_WR_EMUL, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b4},
- {OP_WR_FPGA, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5000, 0xc2},
- {OP_WR_EMUL_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x0},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x1},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2000, 0x102},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4640, 0x40},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8980, 0xc8},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57f0, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8960, 0x2},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57d8, 0x5},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3228, 0x4},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x57d8 + 0x14, 0x10281},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3200, 0x9},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1c60, 0x20},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x3200 + 0x24, 0x102bb},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x2830, 0x20282},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3180, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x400},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0x8, 0x102bc},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0xc, 0x3},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b68, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x6b68 + 0x8, 0x202bd},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b10, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x74c0, 0x202bf},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c00, 0x100284},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c00, 0x1002c1},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c40, 0x100294},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c40, 0x1002d1},
- {OP_ZP_E1, USEM_REG_INT_TABLE, 0xc30000},
- {OP_ZP_E1H, USEM_REG_INT_TABLE, 0xd20000},
- {OP_WR_64_E1, USEM_REG_INT_TABLE + 0x368, 0x1302a4},
- {OP_WR_64_E1H, USEM_REG_INT_TABLE + 0x3a8, 0xb02e1},
- {OP_ZP_E1, USEM_REG_PRAM, 0x314c0000},
- {OP_ZP_E1H, USEM_REG_PRAM, 0x31b60000},
- {OP_ZP_E1, USEM_REG_PRAM + 0x8000, 0x35ef0c53},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x8000, 0x36500c6e},
- {OP_ZP_E1, USEM_REG_PRAM + 0x10000, 0x361319cf},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x10000, 0x37591a02},
- {OP_ZP_E1, USEM_REG_PRAM + 0x18000, 0x7112754},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x18000, 0x286127d9},
- {OP_WR_64_E1, USEM_REG_PRAM + 0x18ee0, 0x4e2402a6},
- {OP_WR_64_E1H, USEM_REG_PRAM + 0x1ff40, 0x401802e3},
-#define USEM_COMMON_END 842
-#define USEM_PORT0_START 842
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1400, 0xa0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9000, 0xa0},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1900, 0x10},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9500, 0x40},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1980, 0x30},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9700, 0x3c},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4740, 0xb4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2450, 0xb4},
- {OP_WR_E1, USEM_REG_FAST_MEMORY + 0x1d90, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2ad0, 0x2},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b40, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3080, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b60, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8000, 0x12c},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5318, 0x98},
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x3238, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5100, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5200, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5300, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5400, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5500, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5600, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5700, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5800, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5900, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b78, 0x52},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e08, 0xc},
-#define USEM_PORT0_END 876
-#define USEM_PORT1_START 876
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1680, 0xa0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9280, 0xa0},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1940, 0x10},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9600, 0x40},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1a40, 0x30},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x97f0, 0x3c},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4a10, 0xb4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2720, 0xb4},
- {OP_WR_E1, USEM_REG_FAST_MEMORY + 0x1d94, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2ad8, 0x2},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b50, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3100, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1be0, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x84b0, 0x12c},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5578, 0x98},
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x323c, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5080, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5180, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5280, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5380, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5480, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5580, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5680, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5780, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5880, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5980, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6cc0, 0x52},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e38, 0xc},
-#define USEM_PORT1_END 910
-#define USEM_FUNC0_START 910
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a30, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3000, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4018, 0x2},
-#define USEM_FUNC0_END 913
-#define USEM_FUNC1_START 913
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a34, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3010, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4028, 0x2},
-#define USEM_FUNC1_END 916
-#define USEM_FUNC2_START 916
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a38, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3020, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4038, 0x2},
-#define USEM_FUNC2_END 919
-#define USEM_FUNC3_START 919
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a3c, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3030, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4048, 0x2},
-#define USEM_FUNC3_END 922
-#define USEM_FUNC4_START 922
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a40, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3040, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4058, 0x2},
-#define USEM_FUNC4_END 925
-#define USEM_FUNC5_START 925
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a44, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3050, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4068, 0x2},
-#define USEM_FUNC5_END 928
-#define USEM_FUNC6_START 928
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a48, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3060, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4078, 0x2},
-#define USEM_FUNC6_END 931
-#define USEM_FUNC7_START 931
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a4c, 0x0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3070, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4088, 0x2},
-#define USEM_FUNC7_END 934
-#define CSEM_COMMON_START 934
- {OP_RD, CSEM_REG_MSG_NUM_FIC0, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FIC1, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FOC0, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FOC1, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FOC2, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FOC3, 0x0},
- {OP_WR, CSEM_REG_ARB_ELEMENT0, 0x1},
- {OP_WR, CSEM_REG_ARB_ELEMENT1, 0x2},
- {OP_WR, CSEM_REG_ARB_ELEMENT2, 0x3},
- {OP_WR, CSEM_REG_ARB_ELEMENT3, 0x0},
- {OP_WR, CSEM_REG_ARB_ELEMENT4, 0x4},
- {OP_WR, CSEM_REG_ARB_CYCLE_SIZE, 0x1},
- {OP_WR, CSEM_REG_TS_0_AS, 0x0},
- {OP_WR, CSEM_REG_TS_1_AS, 0x1},
- {OP_WR, CSEM_REG_TS_2_AS, 0x4},
- {OP_WR, CSEM_REG_TS_3_AS, 0x0},
- {OP_WR, CSEM_REG_TS_4_AS, 0x1},
- {OP_WR, CSEM_REG_TS_5_AS, 0x3},
- {OP_WR, CSEM_REG_TS_6_AS, 0x0},
- {OP_WR, CSEM_REG_TS_7_AS, 0x1},
- {OP_WR, CSEM_REG_TS_8_AS, 0x4},
- {OP_WR, CSEM_REG_TS_9_AS, 0x0},
- {OP_WR, CSEM_REG_TS_10_AS, 0x1},
- {OP_WR, CSEM_REG_TS_11_AS, 0x3},
- {OP_WR, CSEM_REG_TS_12_AS, 0x0},
- {OP_WR, CSEM_REG_TS_13_AS, 0x1},
- {OP_WR, CSEM_REG_TS_14_AS, 0x4},
- {OP_WR, CSEM_REG_TS_15_AS, 0x0},
- {OP_WR, CSEM_REG_TS_16_AS, 0x4},
- {OP_WR, CSEM_REG_TS_17_AS, 0x3},
- {OP_ZR, CSEM_REG_TS_18_AS, 0x2},
- {OP_WR, CSEM_REG_ENABLE_IN, 0x3fff},
- {OP_WR, CSEM_REG_ENABLE_OUT, 0x3ff},
- {OP_WR, CSEM_REG_FIC0_DISABLE, 0x0},
- {OP_WR, CSEM_REG_FIC1_DISABLE, 0x0},
- {OP_WR, CSEM_REG_PAS_DISABLE, 0x0},
- {OP_WR, CSEM_REG_THREADS_LIST, 0xffff},
- {OP_ZR, CSEM_REG_PASSIVE_BUFFER, 0x800},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x18000, 0x10},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x18040, 0x12},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x18080, 0x30},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x180c0, 0xe},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x5000, 0x42},
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11480, 0x1},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_WR_EMUL_E1H, CSEM_REG_FAST_MEMORY + 0x11480, 0x0},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x1000, 0x42},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2000, 0xc0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x7020, 0xc8},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3070, 0x80},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x7000, 0x2},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x4280, 0x4},
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11e8, 0x0},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x25c0, 0x240},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3000, 0xc0},
- {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x2ec8, 0x802a8},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4070, 0x80},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x5280, 0x4},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6700, 0x100},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x9000, 0x400},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x6b08, 0x2002e5},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x13fffff},
- {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002b0},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c00, 0x100305},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002c0},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c40, 0x100315},
- {OP_ZP_E1, CSEM_REG_INT_TABLE, 0x710000},
- {OP_ZP_E1H, CSEM_REG_INT_TABLE, 0x740000},
- {OP_WR_64_E1, CSEM_REG_INT_TABLE + 0x380, 0x1002d0},
- {OP_WR_64_E1H, CSEM_REG_INT_TABLE + 0x380, 0x100325},
- {OP_ZP_E1, CSEM_REG_PRAM, 0x32290000},
- {OP_ZP_E1H, CSEM_REG_PRAM, 0x32260000},
- {OP_ZP_E1, CSEM_REG_PRAM + 0x8000, 0x23630c8b},
- {OP_ZP_E1H, CSEM_REG_PRAM + 0x8000, 0x246e0c8a},
- {OP_WR_64_E1, CSEM_REG_PRAM + 0xc930, 0x654002d2},
- {OP_WR_64_E1H, CSEM_REG_PRAM + 0xcbb0, 0x64f00327},
-#define CSEM_COMMON_END 1014
-#define CSEM_PORT0_START 1014
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1400, 0xa0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8000, 0xa0},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1900, 0x10},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8500, 0x40},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1980, 0x30},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8700, 0x3c},
- {OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x5118, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4040, 0x6},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2300, 0xe},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3040, 0x6},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2410, 0x30},
-#define CSEM_PORT0_END 1025
-#define CSEM_PORT1_START 1025
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1680, 0xa0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8280, 0xa0},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1940, 0x10},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8600, 0x40},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1a40, 0x30},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x87f0, 0x3c},
- {OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x511c, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4058, 0x6},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2338, 0xe},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3058, 0x6},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x24d0, 0x30},
-#define CSEM_PORT1_END 1036
-#define CSEM_FUNC0_START 1036
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1148, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3300, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6040, 0x30},
-#define CSEM_FUNC0_END 1039
-#define CSEM_FUNC1_START 1039
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x114c, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3308, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6100, 0x30},
-#define CSEM_FUNC1_END 1042
-#define CSEM_FUNC2_START 1042
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1150, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3310, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x61c0, 0x30},
-#define CSEM_FUNC2_END 1045
-#define CSEM_FUNC3_START 1045
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1154, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3318, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6280, 0x30},
-#define CSEM_FUNC3_END 1048
-#define CSEM_FUNC4_START 1048
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1158, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3320, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6340, 0x30},
-#define CSEM_FUNC4_END 1051
-#define CSEM_FUNC5_START 1051
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x115c, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3328, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6400, 0x30},
-#define CSEM_FUNC5_END 1054
-#define CSEM_FUNC6_START 1054
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1160, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3330, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x64c0, 0x30},
-#define CSEM_FUNC6_END 1057
-#define CSEM_FUNC7_START 1057
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1164, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3338, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6580, 0x30},
-#define CSEM_FUNC7_END 1060
-#define XPB_COMMON_START 1060
- {OP_WR, GRCBASE_XPB + PB_REG_CONTROL, 0x20},
-#define XPB_COMMON_END 1061
-#define DQ_COMMON_START 1061
- {OP_WR, DORQ_REG_MODE_ACT, 0x2},
- {OP_WR, DORQ_REG_NORM_CID_OFST, 0x3},
- {OP_WR, DORQ_REG_OUTST_REQ, 0x4},
- {OP_WR, DORQ_REG_DPM_CID_ADDR, 0x8},
- {OP_WR, DORQ_REG_RSP_INIT_CRD, 0x2},
- {OP_WR, DORQ_REG_NORM_CMHEAD_TX, 0x90},
- {OP_WR, DORQ_REG_CMHEAD_RX, 0x90},
- {OP_WR, DORQ_REG_SHRT_CMHEAD, 0x800090},
- {OP_WR, DORQ_REG_ERR_CMHEAD, 0x8140000},
- {OP_WR, DORQ_REG_AGG_CMD0, 0x8a},
- {OP_WR, DORQ_REG_AGG_CMD1, 0x80},
- {OP_WR, DORQ_REG_AGG_CMD2, 0x90},
- {OP_WR, DORQ_REG_AGG_CMD3, 0x80},
- {OP_WR, DORQ_REG_SHRT_ACT_CNT, 0x6},
- {OP_WR, DORQ_REG_DQ_FIFO_FULL_TH, 0x7d0},
- {OP_WR, DORQ_REG_DQ_FIFO_AFULL_TH, 0x76c},
- {OP_WR, DORQ_REG_REGN, 0x7c1004},
- {OP_WR, DORQ_REG_IF_EN, 0xf},
-#define DQ_COMMON_END 1079
-#define TIMERS_COMMON_START 1079
- {OP_ZR, TM_REG_CLIN_PRIOR0_CLIENT, 0x2},
- {OP_WR, TM_REG_LIN_SETCLR_FIFO_ALFULL_THR, 0x1c},
- {OP_WR, TM_REG_CFC_AC_CRDCNT_VAL, 0x1},
- {OP_WR, TM_REG_CFC_CLD_CRDCNT_VAL, 0x1},
- {OP_WR, TM_REG_CLOUT_CRDCNT0_VAL, 0x1},
- {OP_WR, TM_REG_CLOUT_CRDCNT1_VAL, 0x1},
- {OP_WR, TM_REG_CLOUT_CRDCNT2_VAL, 0x1},
- {OP_WR, TM_REG_EXP_CRDCNT_VAL, 0x1},
- {OP_WR_E1, TM_REG_PCIARB_CRDCNT_VAL, 0x1},
- {OP_WR_E1H, TM_REG_PCIARB_CRDCNT_VAL, 0x2},
- {OP_WR_ASIC, TM_REG_TIMER_TICK_SIZE, 0x3d090},
- {OP_WR_EMUL, TM_REG_TIMER_TICK_SIZE, 0x9c},
- {OP_WR_FPGA, TM_REG_TIMER_TICK_SIZE, 0x9c4},
- {OP_WR, TM_REG_CL0_CONT_REGION, 0x8},
- {OP_WR, TM_REG_CL1_CONT_REGION, 0xc},
- {OP_WR, TM_REG_CL2_CONT_REGION, 0x10},
- {OP_WR, TM_REG_TM_CONTEXT_REGION, 0x20},
- {OP_WR, TM_REG_EN_TIMERS, 0x1},
- {OP_WR, TM_REG_EN_REAL_TIME_CNT, 0x1},
- {OP_WR, TM_REG_EN_CL0_INPUT, 0x1},
- {OP_WR, TM_REG_EN_CL1_INPUT, 0x1},
- {OP_WR, TM_REG_EN_CL2_INPUT, 0x1},
-#define TIMERS_COMMON_END 1101
-#define TIMERS_PORT0_START 1101
- {OP_WR, TM_REG_LIN0_LOGIC_ADDR, 0x0},
- {OP_WR, TM_REG_LIN0_PHY_ADDR_VALID, 0x0},
- {OP_ZR, TM_REG_LIN0_PHY_ADDR, 0x2},
-#define TIMERS_PORT0_END 1104
-#define TIMERS_PORT1_START 1104
- {OP_WR, TM_REG_LIN1_LOGIC_ADDR, 0x0},
- {OP_WR, TM_REG_LIN1_PHY_ADDR_VALID, 0x0},
- {OP_ZR, TM_REG_LIN1_PHY_ADDR, 0x2},
-#define TIMERS_PORT1_END 1107
-#define XSDM_COMMON_START 1107
- {OP_WR_E1, XSDM_REG_CFC_RSP_START_ADDR, 0x614},
- {OP_WR_E1H, XSDM_REG_CFC_RSP_START_ADDR, 0x424},
- {OP_WR_E1, XSDM_REG_CMP_COUNTER_START_ADDR, 0x600},
- {OP_WR_E1H, XSDM_REG_CMP_COUNTER_START_ADDR, 0x410},
- {OP_WR_E1, XSDM_REG_Q_COUNTER_START_ADDR, 0x604},
- {OP_WR_E1H, XSDM_REG_Q_COUNTER_START_ADDR, 0x414},
- {OP_WR, XSDM_REG_CMP_COUNTER_MAX0, 0xffff},
- {OP_WR, XSDM_REG_CMP_COUNTER_MAX1, 0xffff},
- {OP_WR, XSDM_REG_CMP_COUNTER_MAX2, 0xffff},
- {OP_WR, XSDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_0, 0x20},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_1, 0x20},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_2, 0x34},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_3, 0x35},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_4, 0x23},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_5, 0x24},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_6, 0x25},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_7, 0x26},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_8, 0x27},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_9, 0x29},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_10, 0x2a},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_11, 0x2b},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_12, 0x2c},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_13, 0x2d},
- {OP_ZR, XSDM_REG_AGG_INT_EVENT_14, 0x52},
- {OP_WR, XSDM_REG_AGG_INT_MODE_0, 0x1},
- {OP_ZR, XSDM_REG_AGG_INT_MODE_1, 0x1f},
- {OP_WR, XSDM_REG_ENABLE_IN1, 0x7ffffff},
- {OP_WR, XSDM_REG_ENABLE_IN2, 0x3f},
- {OP_WR, XSDM_REG_ENABLE_OUT1, 0x7ffffff},
- {OP_WR, XSDM_REG_ENABLE_OUT2, 0xf},
- {OP_RD, XSDM_REG_NUM_OF_Q0_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q1_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q3_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q4_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q5_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q6_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q7_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q8_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q9_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q10_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q11_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR_E1, XSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
- {OP_WR_ASIC, XSDM_REG_TIMER_TICK, 0x3e8},
- {OP_WR_EMUL, XSDM_REG_TIMER_TICK, 0x1},
- {OP_WR_FPGA, XSDM_REG_TIMER_TICK, 0xa},
-#define XSDM_COMMON_END 1156
-#define QM_COMMON_START 1156
- {OP_WR, QM_REG_ACTCTRINITVAL_0, 0x6},
- {OP_WR, QM_REG_ACTCTRINITVAL_1, 0x5},
- {OP_WR, QM_REG_ACTCTRINITVAL_2, 0xa},
- {OP_WR, QM_REG_ACTCTRINITVAL_3, 0x5},
- {OP_WR, QM_REG_PCIREQAT, 0x2},
- {OP_WR, QM_REG_CMINITCRD_0, 0x4},
- {OP_WR, QM_REG_CMINITCRD_1, 0x4},
- {OP_WR, QM_REG_CMINITCRD_2, 0x4},
- {OP_WR, QM_REG_CMINITCRD_3, 0x4},
- {OP_WR, QM_REG_CMINITCRD_4, 0x4},
- {OP_WR, QM_REG_CMINITCRD_5, 0x4},
- {OP_WR, QM_REG_CMINITCRD_6, 0x4},
- {OP_WR, QM_REG_CMINITCRD_7, 0x4},
- {OP_WR, QM_REG_OUTLDREQ, 0x4},
- {OP_WR, QM_REG_CTXREG_0, 0x7c},
- {OP_WR, QM_REG_CTXREG_1, 0x3d},
- {OP_WR, QM_REG_CTXREG_2, 0x3f},
- {OP_WR, QM_REG_CTXREG_3, 0x9c},
- {OP_WR, QM_REG_ENSEC, 0x7},
- {OP_ZR, QM_REG_QVOQIDX_0, 0x5},
- {OP_WR, QM_REG_WRRWEIGHTS_0, 0x1010101},
- {OP_WR, QM_REG_QVOQIDX_5, 0x0},
- {OP_WR, QM_REG_QVOQIDX_6, 0x4},
- {OP_WR, QM_REG_QVOQIDX_7, 0x4},
- {OP_WR, QM_REG_QVOQIDX_8, 0x2},
- {OP_WR, QM_REG_WRRWEIGHTS_1, 0x8012004},
- {OP_WR, QM_REG_QVOQIDX_9, 0x5},
- {OP_WR, QM_REG_QVOQIDX_10, 0x5},
- {OP_WR, QM_REG_QVOQIDX_11, 0x5},
- {OP_WR, QM_REG_QVOQIDX_12, 0x5},
- {OP_WR, QM_REG_WRRWEIGHTS_2, 0x20081001},
- {OP_WR, QM_REG_QVOQIDX_13, 0x8},
- {OP_WR, QM_REG_QVOQIDX_14, 0x6},
- {OP_WR, QM_REG_QVOQIDX_15, 0x7},
- {OP_WR, QM_REG_QVOQIDX_16, 0x0},
- {OP_WR, QM_REG_WRRWEIGHTS_3, 0x1010120},
- {OP_ZR, QM_REG_QVOQIDX_17, 0x4},
- {OP_WR, QM_REG_WRRWEIGHTS_4, 0x1010101},
- {OP_ZR_E1, QM_REG_QVOQIDX_21, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_21, 0x0},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_5, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_22, 0x4},
- {OP_ZR_E1, QM_REG_QVOQIDX_25, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_23, 0x4},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_6, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_24, 0x2},
- {OP_ZR_E1, QM_REG_QVOQIDX_29, 0x3},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_5, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_25, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_26, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_27, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_28, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_6, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_29, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_30, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_31, 0x7},
- {OP_WR, QM_REG_QVOQIDX_32, 0x1},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_7, 0x1010101},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_7, 0x1010120},
- {OP_WR, QM_REG_QVOQIDX_33, 0x1},
- {OP_WR, QM_REG_QVOQIDX_34, 0x1},
- {OP_WR, QM_REG_QVOQIDX_35, 0x1},
- {OP_WR, QM_REG_QVOQIDX_36, 0x1},
- {OP_WR, QM_REG_WRRWEIGHTS_8, 0x1010101},
- {OP_WR, QM_REG_QVOQIDX_37, 0x1},
- {OP_WR, QM_REG_QVOQIDX_38, 0x4},
- {OP_WR, QM_REG_QVOQIDX_39, 0x4},
- {OP_WR, QM_REG_QVOQIDX_40, 0x2},
- {OP_WR, QM_REG_WRRWEIGHTS_9, 0x8012004},
- {OP_WR, QM_REG_QVOQIDX_41, 0x5},
- {OP_WR, QM_REG_QVOQIDX_42, 0x5},
- {OP_WR, QM_REG_QVOQIDX_43, 0x5},
- {OP_WR, QM_REG_QVOQIDX_44, 0x5},
- {OP_WR, QM_REG_WRRWEIGHTS_10, 0x20081001},
- {OP_WR, QM_REG_QVOQIDX_45, 0x8},
- {OP_WR, QM_REG_QVOQIDX_46, 0x6},
- {OP_WR, QM_REG_QVOQIDX_47, 0x7},
- {OP_WR, QM_REG_QVOQIDX_48, 0x1},
- {OP_WR, QM_REG_WRRWEIGHTS_11, 0x1010120},
- {OP_WR, QM_REG_QVOQIDX_49, 0x1},
- {OP_WR, QM_REG_QVOQIDX_50, 0x1},
- {OP_WR, QM_REG_QVOQIDX_51, 0x1},
- {OP_WR, QM_REG_QVOQIDX_52, 0x1},
- {OP_WR, QM_REG_WRRWEIGHTS_12, 0x1010101},
- {OP_WR, QM_REG_QVOQIDX_53, 0x1},
- {OP_WR_E1, QM_REG_QVOQIDX_54, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_54, 0x4},
- {OP_WR_E1, QM_REG_QVOQIDX_55, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_55, 0x4},
- {OP_WR_E1, QM_REG_QVOQIDX_56, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_56, 0x2},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_13, 0x1010101},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_13, 0x8012004},
- {OP_WR_E1, QM_REG_QVOQIDX_57, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_57, 0x5},
- {OP_WR_E1, QM_REG_QVOQIDX_58, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_58, 0x5},
- {OP_WR_E1, QM_REG_QVOQIDX_59, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_59, 0x5},
- {OP_WR_E1, QM_REG_QVOQIDX_60, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_60, 0x5},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_14, 0x1010101},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_14, 0x20081001},
- {OP_WR_E1, QM_REG_QVOQIDX_61, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_61, 0x8},
- {OP_WR_E1, QM_REG_QVOQIDX_62, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_62, 0x6},
- {OP_WR_E1, QM_REG_QVOQIDX_63, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_63, 0x7},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_15, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_64, 0x0},
- {OP_WR_E1, QM_REG_VOQQMASK_0_LSB, 0xffff003f},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_15, 0x1010120},
- {OP_ZR_E1, QM_REG_VOQQMASK_0_MSB, 0x2},
- {OP_ZR_E1H, QM_REG_QVOQIDX_65, 0x4},
- {OP_WR_E1, QM_REG_VOQQMASK_1_MSB, 0xffff003f},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_16, 0x1010101},
- {OP_WR_E1, QM_REG_VOQQMASK_2_LSB, 0x100},
- {OP_WR_E1H, QM_REG_QVOQIDX_69, 0x0},
- {OP_WR_E1, QM_REG_VOQQMASK_2_MSB, 0x100},
- {OP_WR_E1H, QM_REG_QVOQIDX_70, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_71, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_72, 0x2},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_17, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_73, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_74, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_75, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_76, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_18, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_77, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_78, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_79, 0x7},
- {OP_WR_E1H, QM_REG_QVOQIDX_80, 0x0},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_19, 0x1010120},
- {OP_ZR_E1H, QM_REG_QVOQIDX_81, 0x4},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_20, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_85, 0x0},
- {OP_WR_E1H, QM_REG_QVOQIDX_86, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_87, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_88, 0x2},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_21, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_89, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_90, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_91, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_92, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_22, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_93, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_94, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_95, 0x7},
- {OP_WR_E1H, QM_REG_QVOQIDX_96, 0x1},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_23, 0x1010120},
- {OP_WR_E1H, QM_REG_QVOQIDX_97, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_98, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_99, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_100, 0x1},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_24, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_101, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_102, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_103, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_104, 0x2},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_25, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_105, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_106, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_107, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_108, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_26, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_109, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_110, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_111, 0x7},
- {OP_WR_E1H, QM_REG_QVOQIDX_112, 0x1},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_27, 0x1010120},
- {OP_WR_E1H, QM_REG_QVOQIDX_113, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_114, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_115, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_116, 0x1},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_28, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_117, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_118, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_119, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_120, 0x2},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_29, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_121, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_122, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_123, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_124, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_30, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_125, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_126, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_127, 0x7},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_31, 0x1010120},
- {OP_WR_E1H, QM_REG_VOQQMASK_0_LSB, 0x3f003f},
- {OP_WR_E1H, QM_REG_VOQQMASK_0_MSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_0_LSB_EXT_A, 0x3f003f},
- {OP_WR_E1H, QM_REG_VOQQMASK_0_MSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_1_LSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_1_MSB, 0x3f003f},
- {OP_WR_E1H, QM_REG_VOQQMASK_1_LSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_1_MSB_EXT_A, 0x3f003f},
- {OP_WR_E1H, QM_REG_VOQQMASK_2_LSB, 0x1000100},
- {OP_WR_E1H, QM_REG_VOQQMASK_2_MSB, 0x1000100},
- {OP_WR_E1H, QM_REG_VOQQMASK_2_LSB_EXT_A, 0x1000100},
- {OP_WR_E1H, QM_REG_VOQQMASK_2_MSB_EXT_A, 0x1000100},
- {OP_ZR, QM_REG_VOQQMASK_3_LSB, 0x2},
- {OP_WR_E1, QM_REG_VOQQMASK_4_LSB, 0xc0},
- {OP_WR_E1H, QM_REG_VOQQMASK_3_LSB_EXT_A, 0x0},
- {OP_WR_E1, QM_REG_VOQQMASK_4_MSB, 0xc0},
- {OP_WR_E1H, QM_REG_VOQQMASK_3_MSB_EXT_A, 0x0},
- {OP_WR_E1, QM_REG_VOQQMASK_5_LSB, 0x1e00},
- {OP_WR_E1H, QM_REG_VOQQMASK_4_LSB, 0xc000c0},
- {OP_WR_E1, QM_REG_VOQQMASK_5_MSB, 0x1e00},
- {OP_WR_E1H, QM_REG_VOQQMASK_4_MSB, 0xc000c0},
- {OP_WR_E1, QM_REG_VOQQMASK_6_LSB, 0x4000},
- {OP_WR_E1H, QM_REG_VOQQMASK_4_LSB_EXT_A, 0xc000c0},
- {OP_WR_E1, QM_REG_VOQQMASK_6_MSB, 0x4000},
- {OP_WR_E1H, QM_REG_VOQQMASK_4_MSB_EXT_A, 0xc000c0},
- {OP_WR_E1, QM_REG_VOQQMASK_7_LSB, 0x8000},
- {OP_WR_E1H, QM_REG_VOQQMASK_5_LSB, 0x1e001e00},
- {OP_WR_E1, QM_REG_VOQQMASK_7_MSB, 0x8000},
- {OP_WR_E1H, QM_REG_VOQQMASK_5_MSB, 0x1e001e00},
- {OP_WR_E1, QM_REG_VOQQMASK_8_LSB, 0x2000},
- {OP_WR_E1H, QM_REG_VOQQMASK_5_LSB_EXT_A, 0x1e001e00},
- {OP_WR_E1, QM_REG_VOQQMASK_8_MSB, 0x2000},
- {OP_WR_E1H, QM_REG_VOQQMASK_5_MSB_EXT_A, 0x1e001e00},
- {OP_ZR_E1, QM_REG_VOQQMASK_9_LSB, 0x7},
- {OP_WR_E1H, QM_REG_VOQQMASK_6_LSB, 0x40004000},
- {OP_WR_E1H, QM_REG_VOQQMASK_6_MSB, 0x40004000},
- {OP_WR_E1H, QM_REG_VOQQMASK_6_LSB_EXT_A, 0x40004000},
- {OP_WR_E1H, QM_REG_VOQQMASK_6_MSB_EXT_A, 0x40004000},
- {OP_WR_E1H, QM_REG_VOQQMASK_7_LSB, 0x80008000},
- {OP_WR_E1H, QM_REG_VOQQMASK_7_MSB, 0x80008000},
- {OP_WR_E1H, QM_REG_VOQQMASK_7_LSB_EXT_A, 0x80008000},
- {OP_WR_E1H, QM_REG_VOQQMASK_7_MSB_EXT_A, 0x80008000},
- {OP_WR_E1H, QM_REG_VOQQMASK_8_LSB, 0x20002000},
- {OP_WR_E1H, QM_REG_VOQQMASK_8_MSB, 0x20002000},
- {OP_WR_E1H, QM_REG_VOQQMASK_8_LSB_EXT_A, 0x20002000},
- {OP_WR_E1H, QM_REG_VOQQMASK_8_MSB_EXT_A, 0x20002000},
- {OP_ZR_E1H, QM_REG_VOQQMASK_9_LSB, 0x2},
- {OP_WR_E1H, QM_REG_VOQQMASK_9_LSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_9_MSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_10_LSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_10_MSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_10_LSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_10_MSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_11_LSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_11_MSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_11_LSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_11_MSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQPORT_0, 0x0},
- {OP_WR, QM_REG_VOQPORT_1, 0x1},
- {OP_ZR, QM_REG_VOQPORT_2, 0xa},
- {OP_WR, QM_REG_CMINTVOQMASK_0, 0xc08},
- {OP_WR, QM_REG_CMINTVOQMASK_1, 0x40},
- {OP_WR, QM_REG_CMINTVOQMASK_2, 0x100},
- {OP_WR, QM_REG_CMINTVOQMASK_3, 0x20},
- {OP_WR, QM_REG_CMINTVOQMASK_4, 0x17},
- {OP_WR, QM_REG_CMINTVOQMASK_5, 0x80},
- {OP_WR, QM_REG_CMINTVOQMASK_6, 0x200},
- {OP_WR, QM_REG_CMINTVOQMASK_7, 0x0},
- {OP_WR_E1, QM_REG_HWAEMPTYMASK_LSB, 0xffff01ff},
- {OP_WR_E1H, QM_REG_HWAEMPTYMASK_LSB, 0x1ff01ff},
- {OP_WR_E1, QM_REG_HWAEMPTYMASK_MSB, 0xffff01ff},
- {OP_WR_E1H, QM_REG_HWAEMPTYMASK_MSB, 0x1ff01ff},
- {OP_WR_E1H, QM_REG_HWAEMPTYMASK_LSB_EXT_A, 0x1ff01ff},
- {OP_WR_E1H, QM_REG_HWAEMPTYMASK_MSB_EXT_A, 0x1ff01ff},
- {OP_WR, QM_REG_ENBYPVOQMASK, 0x13},
- {OP_WR, QM_REG_VOQCREDITAFULLTHR, 0x13f},
- {OP_WR, QM_REG_VOQINITCREDIT_0, 0x140},
- {OP_WR, QM_REG_VOQINITCREDIT_1, 0x140},
- {OP_ZR, QM_REG_VOQINITCREDIT_2, 0x2},
- {OP_WR, QM_REG_VOQINITCREDIT_4, 0xc0},
- {OP_ZR, QM_REG_VOQINITCREDIT_5, 0x7},
- {OP_WR, QM_REG_TASKCRDCOST_0, 0x48},
- {OP_WR, QM_REG_TASKCRDCOST_1, 0x48},
- {OP_ZR, QM_REG_TASKCRDCOST_2, 0x2},
- {OP_WR, QM_REG_TASKCRDCOST_4, 0x48},
- {OP_ZR, QM_REG_TASKCRDCOST_5, 0x7},
- {OP_WR, QM_REG_BYTECRDINITVAL, 0x8000},
- {OP_WR, QM_REG_BYTECRDCOST, 0x25e4},
- {OP_WR, QM_REG_BYTECREDITAFULLTHR, 0x7fff},
- {OP_WR_E1, QM_REG_ENBYTECRD_LSB, 0x7},
- {OP_WR_E1H, QM_REG_ENBYTECRD_LSB, 0x70007},
- {OP_WR_E1, QM_REG_ENBYTECRD_MSB, 0x7},
- {OP_WR_E1H, QM_REG_ENBYTECRD_MSB, 0x70007},
- {OP_WR_E1H, QM_REG_ENBYTECRD_LSB_EXT_A, 0x70007},
- {OP_WR_E1H, QM_REG_ENBYTECRD_MSB_EXT_A, 0x70007},
- {OP_WR, QM_REG_BYTECRDPORT_LSB, 0x0},
- {OP_WR, QM_REG_BYTECRDPORT_MSB, 0xffffffff},
- {OP_WR_E1, QM_REG_FUNCNUMSEL_LSB, 0x0},
- {OP_WR_E1H, QM_REG_BYTECRDPORT_LSB_EXT_A, 0x0},
- {OP_WR_E1, QM_REG_FUNCNUMSEL_MSB, 0xffffffff},
- {OP_WR_E1H, QM_REG_BYTECRDPORT_MSB_EXT_A, 0xffffffff},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_0, 0x0},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_1, 0x2},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_2, 0x1},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_3, 0x3},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_4, 0x4},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_5, 0x6},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_6, 0x5},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_7, 0x7},
- {OP_WR, QM_REG_CMINTEN, 0xff},
-#define QM_COMMON_END 1456
-#define PBF_COMMON_START 1456
- {OP_WR, PBF_REG_INIT, 0x1},
- {OP_WR, PBF_REG_INIT_P4, 0x1},
- {OP_WR, PBF_REG_MAC_LB_ENABLE, 0x1},
- {OP_WR, PBF_REG_IF_ENABLE_REG, 0x7fff},
- {OP_WR, PBF_REG_INIT_P4, 0x0},
- {OP_WR, PBF_REG_INIT, 0x0},
- {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P4, 0x0},
-#define PBF_COMMON_END 1463
-#define PBF_PORT0_START 1463
- {OP_WR, PBF_REG_INIT_P0, 0x1},
- {OP_WR, PBF_REG_MAC_IF0_ENABLE, 0x1},
- {OP_WR, PBF_REG_INIT_P0, 0x0},
- {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P0, 0x0},
-#define PBF_PORT0_END 1467
-#define PBF_PORT1_START 1467
- {OP_WR, PBF_REG_INIT_P1, 0x1},
- {OP_WR, PBF_REG_MAC_IF1_ENABLE, 0x1},
- {OP_WR, PBF_REG_INIT_P1, 0x0},
- {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P1, 0x0},
-#define PBF_PORT1_END 1471
-#define XCM_COMMON_START 1471
- {OP_WR, XCM_REG_XX_OVFL_EVNT_ID, 0x32},
- {OP_WR, XCM_REG_XQM_XCM_HDR_P, 0x3150020},
- {OP_WR, XCM_REG_XQM_XCM_HDR_S, 0x3150020},
- {OP_WR, XCM_REG_TM_XCM_HDR, 0x1000030},
- {OP_WR, XCM_REG_ERR_XCM_HDR, 0x8100000},
- {OP_WR, XCM_REG_ERR_EVNT_ID, 0x33},
- {OP_WR, XCM_REG_EXPR_EVNT_ID, 0x30},
- {OP_WR, XCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, XCM_REG_STORM_WEIGHT, 0x3},
- {OP_WR, XCM_REG_TSEM_WEIGHT, 0x6},
- {OP_WR, XCM_REG_CSEM_WEIGHT, 0x3},
- {OP_WR, XCM_REG_USEM_WEIGHT, 0x3},
- {OP_WR, XCM_REG_DORQ_WEIGHT, 0x2},
- {OP_WR, XCM_REG_PBF_WEIGHT, 0x0},
- {OP_WR, XCM_REG_NIG0_WEIGHT, 0x2},
- {OP_WR, XCM_REG_CP_WEIGHT, 0x0},
- {OP_WR, XCM_REG_XSDM_WEIGHT, 0x6},
- {OP_WR, XCM_REG_XQM_P_WEIGHT, 0x4},
- {OP_WR, XCM_REG_XQM_S_WEIGHT, 0x2},
- {OP_WR, XCM_REG_TM_WEIGHT, 0x2},
- {OP_WR, XCM_REG_XCM_XQM_USE_Q, 0x1},
- {OP_WR, XCM_REG_XQM_BYP_ACT_UPD, 0x6},
- {OP_WR, XCM_REG_UNA_GT_NXT_Q, 0x0},
- {OP_WR, XCM_REG_AUX1_Q, 0x2},
- {OP_WR, XCM_REG_AUX_CNT_FLG_Q_19, 0x1},
- {OP_WR, XCM_REG_GR_ARB_TYPE, 0x1},
- {OP_WR, XCM_REG_GR_LD0_PR, 0x1},
- {OP_WR, XCM_REG_GR_LD1_PR, 0x2},
- {OP_WR, XCM_REG_CFC_INIT_CRD, 0x1},
- {OP_WR, XCM_REG_FIC0_INIT_CRD, 0x40},
- {OP_WR, XCM_REG_FIC1_INIT_CRD, 0x40},
- {OP_WR, XCM_REG_TM_INIT_CRD, 0x4},
- {OP_WR, XCM_REG_XQM_INIT_CRD, 0x20},
- {OP_WR, XCM_REG_XX_INIT_CRD, 0x2},
- {OP_WR_E1, XCM_REG_XX_MSG_NUM, 0x1f},
- {OP_WR_E1H, XCM_REG_XX_MSG_NUM, 0x20},
- {OP_ZR, XCM_REG_XX_TABLE, 0x12},
- {OP_SW_E1, XCM_REG_XX_DESCR_TABLE, 0x1f02d4},
- {OP_SW_E1H, XCM_REG_XX_DESCR_TABLE, 0x1f0329},
- {OP_WR, XCM_REG_N_SM_CTX_LD_0, 0xf},
- {OP_WR, XCM_REG_N_SM_CTX_LD_1, 0x7},
- {OP_WR, XCM_REG_N_SM_CTX_LD_2, 0xb},
- {OP_WR, XCM_REG_N_SM_CTX_LD_3, 0xe},
- {OP_ZR_E1, XCM_REG_N_SM_CTX_LD_4, 0x4},
- {OP_WR_E1H, XCM_REG_N_SM_CTX_LD_4, 0xe},
- {OP_ZR_E1H, XCM_REG_N_SM_CTX_LD_5, 0x3},
- {OP_WR, XCM_REG_XCM_REG0_SZ, 0x4},
- {OP_WR, XCM_REG_XCM_STORM0_IFEN, 0x1},
- {OP_WR, XCM_REG_XCM_STORM1_IFEN, 0x1},
- {OP_WR, XCM_REG_XCM_XQM_IFEN, 0x1},
- {OP_WR, XCM_REG_STORM_XCM_IFEN, 0x1},
- {OP_WR, XCM_REG_XQM_XCM_IFEN, 0x1},
- {OP_WR, XCM_REG_XSDM_IFEN, 0x1},
- {OP_WR, XCM_REG_TM_XCM_IFEN, 0x1},
- {OP_WR, XCM_REG_XCM_TM_IFEN, 0x1},
- {OP_WR, XCM_REG_TSEM_IFEN, 0x1},
- {OP_WR, XCM_REG_CSEM_IFEN, 0x1},
- {OP_WR, XCM_REG_USEM_IFEN, 0x1},
- {OP_WR, XCM_REG_DORQ_IFEN, 0x1},
- {OP_WR, XCM_REG_PBF_IFEN, 0x1},
- {OP_WR, XCM_REG_NIG0_IFEN, 0x1},
- {OP_WR, XCM_REG_NIG1_IFEN, 0x1},
- {OP_WR, XCM_REG_CDU_AG_WR_IFEN, 0x1},
- {OP_WR, XCM_REG_CDU_AG_RD_IFEN, 0x1},
- {OP_WR, XCM_REG_CDU_SM_WR_IFEN, 0x1},
- {OP_WR, XCM_REG_CDU_SM_RD_IFEN, 0x1},
- {OP_WR, XCM_REG_XCM_CFC_IFEN, 0x1},
-#define XCM_COMMON_END 1538
-#define XCM_PORT0_START 1538
- {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
-#define XCM_PORT0_END 1546
-#define XCM_PORT1_START 1546
- {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
-#define XCM_PORT1_END 1554
-#define XCM_FUNC0_START 1554
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC0_END 1563
-#define XCM_FUNC1_START 1563
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC1_END 1572
-#define XCM_FUNC2_START 1572
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC2_END 1581
-#define XCM_FUNC3_START 1581
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC3_END 1590
-#define XCM_FUNC4_START 1590
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC4_END 1599
-#define XCM_FUNC5_START 1599
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC5_END 1608
-#define XCM_FUNC6_START 1608
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC6_END 1617
-#define XCM_FUNC7_START 1617
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC7_END 1626
-#define XSEM_COMMON_START 1626
- {OP_RD, XSEM_REG_MSG_NUM_FIC0, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FIC1, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FOC0, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FOC1, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FOC2, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FOC3, 0x0},
- {OP_WR, XSEM_REG_ARB_ELEMENT0, 0x1},
- {OP_WR, XSEM_REG_ARB_ELEMENT1, 0x2},
- {OP_WR, XSEM_REG_ARB_ELEMENT2, 0x3},
- {OP_WR, XSEM_REG_ARB_ELEMENT3, 0x0},
- {OP_WR, XSEM_REG_ARB_ELEMENT4, 0x4},
- {OP_WR, XSEM_REG_ARB_CYCLE_SIZE, 0x1},
- {OP_WR, XSEM_REG_TS_0_AS, 0x0},
- {OP_WR, XSEM_REG_TS_1_AS, 0x1},
- {OP_WR, XSEM_REG_TS_2_AS, 0x4},
- {OP_WR, XSEM_REG_TS_3_AS, 0x0},
- {OP_WR, XSEM_REG_TS_4_AS, 0x1},
- {OP_WR, XSEM_REG_TS_5_AS, 0x3},
- {OP_WR, XSEM_REG_TS_6_AS, 0x0},
- {OP_WR, XSEM_REG_TS_7_AS, 0x1},
- {OP_WR, XSEM_REG_TS_8_AS, 0x4},
- {OP_WR, XSEM_REG_TS_9_AS, 0x0},
- {OP_WR, XSEM_REG_TS_10_AS, 0x1},
- {OP_WR, XSEM_REG_TS_11_AS, 0x3},
- {OP_WR, XSEM_REG_TS_12_AS, 0x0},
- {OP_WR, XSEM_REG_TS_13_AS, 0x1},
- {OP_WR, XSEM_REG_TS_14_AS, 0x4},
- {OP_WR, XSEM_REG_TS_15_AS, 0x0},
- {OP_WR, XSEM_REG_TS_16_AS, 0x4},
- {OP_WR, XSEM_REG_TS_17_AS, 0x3},
- {OP_ZR, XSEM_REG_TS_18_AS, 0x2},
- {OP_WR, XSEM_REG_ENABLE_IN, 0x3fff},
- {OP_WR, XSEM_REG_ENABLE_OUT, 0x3ff},
- {OP_WR, XSEM_REG_FIC0_DISABLE, 0x0},
- {OP_WR, XSEM_REG_FIC1_DISABLE, 0x0},
- {OP_WR, XSEM_REG_PAS_DISABLE, 0x0},
- {OP_WR, XSEM_REG_THREADS_LIST, 0xffff},
- {OP_ZR, XSEM_REG_PASSIVE_BUFFER, 0x800},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18000, 0x0},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18040, 0x18},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18080, 0xc},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x180c0, 0x66},
- {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
- {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18300, 0x138},
- {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18300, 0x1388},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18340, 0x1f4},
- {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18340, 0x0},
- {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18340, 0x5},
- {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18380, 0x4c4b4},
- {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
- {OP_WR_EMUL_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x0},
- {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3d60, 0x4},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x1},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d60 + 0x10, 0x202f3},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x29c8, 0x4},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3000, 0x48},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29c8 + 0x10, 0x20348},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2080, 0x48},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9020, 0xc8},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3128, 0x8e},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9000, 0x2},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3368, 0x0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x21a8, 0x86},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3370, 0x202f5},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2000, 0x20},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3b90, 0x402f7},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x23c8, 0x0},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3e20, 0x202fb},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x23d0, 0x2034a},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1518, 0x1},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2498, 0x4034c},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1830, 0x0},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2c20, 0x0},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1838, 0x0},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2c10, 0x0},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1820, 0x202fd},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2c08, 0x20350},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4ac0, 0x2},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3010, 0x1},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b00, 0x4},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x4040, 0x10},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1f48, 0x202ff},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x4000, 0x100352},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6ac0, 0x2},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b00, 0x4},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x8408, 0x20362},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100301},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100364},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80311},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80374},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x2000000},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c60, 0x80319},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c60, 0x8037c},
- {OP_ZP_E1, XSEM_REG_INT_TABLE, 0xb50000},
- {OP_ZP_E1H, XSEM_REG_INT_TABLE, 0xbd0000},
- {OP_WR_64_E1, XSEM_REG_INT_TABLE + 0x368, 0x130321},
- {OP_WR_64_E1H, XSEM_REG_INT_TABLE + 0x3a8, 0xb0384},
- {OP_ZP_E1, XSEM_REG_PRAM, 0x33660000},
- {OP_ZP_E1H, XSEM_REG_PRAM, 0x34060000},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x8000, 0x38b30cda},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x8000, 0x37960d02},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x10000, 0x3bb11b07},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x10000, 0x3bc31ae8},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x18000, 0x2a2629f4},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x18000, 0x382629d9},
- {OP_WR_64_E1, XSEM_REG_PRAM + 0x1d6c0, 0x45280323},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x20000, 0x124537e3},
- {OP_WR_64_E1H, XSEM_REG_PRAM + 0x22220, 0x3bbc0386},
-#define XSEM_COMMON_END 1741
-#define XSEM_PORT0_START 1741
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3ba0, 0x14},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc000, 0xfc},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c40, 0x24},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24a8, 0x14},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1400, 0xa},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2548, 0x24},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1450, 0x6},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2668, 0x24},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3378, 0xfc},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2788, 0x24},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b58, 0x0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x28a8, 0x24},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d78, 0x20325},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa000, 0x28},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d88, 0x100327},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa140, 0xc},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1500, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29e0, 0x20388},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1508, 0x1},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3000, 0x1},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5020, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5030, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5000, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5010, 0x2},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5040, 0x0},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x5208, 0x1},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ac8, 0x2038a},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50b8, 0x1},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b10, 0x42},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x20337},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d20, 0x4},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b10, 0x42},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d20, 0x4},
-#define XSEM_PORT0_END 1775
-#define XSEM_PORT1_START 1775
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3bf0, 0x14},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc3f0, 0xfc},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3cd0, 0x24},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24f8, 0x14},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1428, 0xa},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x25d8, 0x24},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1468, 0x6},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x26f8, 0x24},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3768, 0xfc},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2818, 0x24},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b5c, 0x0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2938, 0x24},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d80, 0x20339},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa0a0, 0x28},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3dc8, 0x10033b},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa170, 0xc},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1504, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29e8, 0x2038c},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x150c, 0x1},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3004, 0x1},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5028, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5038, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5008, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5018, 0x2},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5044, 0x0},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x520c, 0x1},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ad0, 0x2038e},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50bc, 0x1},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6c18, 0x42},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x2034b},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d30, 0x4},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4c18, 0x42},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d30, 0x4},
-#define XSEM_PORT1_END 1809
-#define XSEM_FUNC0_START 1809
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e0, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29f0, 0x100390},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
-#define XSEM_FUNC0_END 1812
-#define XSEM_FUNC1_START 1812
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e4, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a30, 0x1003a0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
-#define XSEM_FUNC1_END 1815
-#define XSEM_FUNC2_START 1815
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e8, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a70, 0x1003b0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50b8, 0xe},
-#define XSEM_FUNC2_END 1818
-#define XSEM_FUNC3_START 1818
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7ec, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2ab0, 0x1003c0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50f0, 0xe},
-#define XSEM_FUNC3_END 1821
-#define XSEM_FUNC4_START 1821
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f0, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2af0, 0x1003d0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5128, 0xe},
-#define XSEM_FUNC4_END 1824
-#define XSEM_FUNC5_START 1824
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f4, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2b30, 0x1003e0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5160, 0xe},
-#define XSEM_FUNC5_END 1827
-#define XSEM_FUNC6_START 1827
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f8, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2b70, 0x1003f0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5198, 0xe},
-#define XSEM_FUNC6_END 1830
-#define XSEM_FUNC7_START 1830
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7fc, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2bb0, 0x100400},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x51d0, 0xe},
-#define XSEM_FUNC7_END 1833
-#define CDU_COMMON_START 1833
- {OP_WR, CDU_REG_CDU_CONTROL0, 0x1},
- {OP_WR_E1H, CDU_REG_MF_MODE, 0x1},
- {OP_WR, CDU_REG_CDU_CHK_MASK0, 0x3d000},
- {OP_WR, CDU_REG_CDU_CHK_MASK1, 0x3d},
- {OP_WB_E1, CDU_REG_L1TT, 0x200034d},
- {OP_WB_E1H, CDU_REG_L1TT, 0x2000410},
- {OP_WB_E1, CDU_REG_MATT, 0x20054d},
- {OP_WB_E1H, CDU_REG_MATT, 0x280610},
- {OP_ZR_E1, CDU_REG_MATT + 0x80, 0x2},
- {OP_WB_E1, CDU_REG_MATT + 0x88, 0x6056d},
- {OP_ZR, CDU_REG_MATT + 0xa0, 0x18},
-#define CDU_COMMON_END 1844
-#define DMAE_COMMON_START 1844
- {OP_ZR, DMAE_REG_CMD_MEM, 0xe0},
- {OP_WR, DMAE_REG_CRC16C_INIT, 0x0},
- {OP_WR, DMAE_REG_CRC16T10_INIT, 0x1},
- {OP_WR_E1, DMAE_REG_PXP_REQ_INIT_CRD, 0x1},
- {OP_WR_E1H, DMAE_REG_PXP_REQ_INIT_CRD, 0x2},
- {OP_WR, DMAE_REG_PCI_IFEN, 0x1},
- {OP_WR, DMAE_REG_GRC_IFEN, 0x1},
-#define DMAE_COMMON_END 1851
-#define PXP_COMMON_START 1851
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x400, 0x50573},
- {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x400, 0x50638},
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x420, 0x50578},
- {OP_WB_E1H, PXP_REG_HST_INBOUND_INT, 0x5063d},
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT, 0x5057d},
- {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x20, 0x50642},
-#define PXP_COMMON_END 1857
-#define CFC_COMMON_START 1857
- {OP_ZR_E1H, CFC_REG_LINK_LIST, 0x100},
- {OP_WR, CFC_REG_CONTROL0, 0x10},
- {OP_WR, CFC_REG_DISABLE_ON_ERROR, 0x3fff},
- {OP_WR, CFC_REG_INTERFACES, 0x280000},
- {OP_WR, CFC_REG_LCREQ_WEIGHTS, 0x84924a},
- {OP_WR, CFC_REG_INTERFACES, 0x0},
-#define CFC_COMMON_END 1863
-#define HC_COMMON_START 1863
- {OP_ZR_E1, HC_REG_USTORM_ADDR_FOR_COALESCE, 0x4},
-#define HC_COMMON_END 1864
-#define HC_PORT0_START 1864
- {OP_WR_E1, HC_REG_CONFIG_0, 0x1080},
- {OP_ZR_E1, HC_REG_UC_RAM_ADDR_0, 0x2},
- {OP_WR_E1, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1, HC_REG_LEADING_EDGE_0, 0xffff},
- {OP_WR_E1, HC_REG_TRAILING_EDGE_0, 0xffff},
- {OP_WR_E1, HC_REG_AGG_INT_0, 0x0},
- {OP_WR_E1, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_PORT0_END 1882
-#define HC_PORT1_START 1882
- {OP_WR_E1, HC_REG_CONFIG_1, 0x1080},
- {OP_ZR_E1, HC_REG_UC_RAM_ADDR_1, 0x2},
- {OP_WR_E1, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1, HC_REG_LEADING_EDGE_1, 0xffff},
- {OP_WR_E1, HC_REG_TRAILING_EDGE_1, 0xffff},
- {OP_WR_E1, HC_REG_AGG_INT_1, 0x0},
- {OP_WR_E1, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_PORT1_END 1900
-#define HC_FUNC0_START 1900
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x0},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC0_END 1915
-#define HC_FUNC1_START 1915
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x1},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC1_END 1930
-#define HC_FUNC2_START 1930
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x2},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC2_END 1945
-#define HC_FUNC3_START 1945
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x3},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC3_END 1960
-#define HC_FUNC4_START 1960
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x4},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC4_END 1975
-#define HC_FUNC5_START 1975
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x5},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC5_END 1990
-#define HC_FUNC6_START 1990
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x6},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC6_END 2005
-#define HC_FUNC7_START 2005
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x7},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC7_END 2020
-#define PXP2_COMMON_START 2020
- {OP_WR_E1H, PXP2_REG_RQ_DRAM_ALIGN, 0x1},
- {OP_WR, PXP2_REG_PGL_CONTROL0, 0xe38340},
- {OP_WR, PXP2_REG_PGL_CONTROL1, 0x3c10},
- {OP_WR_E1H, PXP2_REG_RQ_ELT_DISABLE, 0x1},
- {OP_WR_E1H, PXP2_REG_WR_REV_MODE, 0x0},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_0, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_1, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_2, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_3, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_4, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_5, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_6, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_7, 0xffffffff},
- {OP_WR_E1, PXP2_REG_PGL_INT_USDM_1, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_2, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_3, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_4, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_5, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_6, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_7, 0xffffffff},
- {OP_WR_E1H, PXP2_REG_PGL_INT_XSDM_1, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_2, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_3, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_4, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_5, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_6, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_7, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_0, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_1, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_2, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_3, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_4, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_5, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_6, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_7, 0xffffffff},
- {OP_WR_E1, PXP2_REG_PGL_INT_XSDM_0, 0xffff3330},
- {OP_WR_E1H, PXP2_REG_PGL_INT_XSDM_0, 0xff802000},
- {OP_WR_E1, PXP2_REG_PGL_INT_XSDM_1, 0xffff3340},
- {OP_WR_E1H, PXP2_REG_PGL_INT_USDM_0, 0xf0005000},
- {OP_WR_E1, PXP2_REG_PGL_INT_USDM_0, 0xf0003000},
- {OP_WR_E1H, PXP2_REG_PGL_INT_USDM_1, 0xf0008000},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ6, 0x8},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ9, 0x8},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ10, 0x8},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ11, 0x2},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ17, 0x4},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ18, 0x5},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ19, 0x4},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ22, 0x0},
- {OP_WR, PXP2_REG_RD_START_INIT, 0x1},
- {OP_WR, PXP2_REG_WR_DMAE_TH, 0x3f},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD0, 0x40},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD1, 0x1808},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD2, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD3, 0x803},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD4, 0x40},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD5, 0x3},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD6, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD7, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD8, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD9, 0x10003},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD10, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD11, 0x803},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD12, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD13, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD14, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD15, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD16, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD17, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD18, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD19, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD20, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD22, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD23, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD24, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD25, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD26, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD27, 0x3},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD28, 0x2403},
- {OP_WR, PXP2_REG_RQ_BW_WR_ADD29, 0x2f},
- {OP_WR, PXP2_REG_RQ_BW_WR_ADD30, 0x9},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND0, 0x19},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB1, 0x184},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB2, 0x183},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB3, 0x306},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND4, 0x19},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND5, 0x6},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB6, 0x306},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB7, 0x306},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB8, 0x306},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB9, 0xc86},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB10, 0x306},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB11, 0x306},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND12, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND13, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND14, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND15, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND16, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND17, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND18, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND19, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND20, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND22, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND23, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND24, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND25, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND26, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND27, 0x6},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB28, 0x306},
- {OP_WR, PXP2_REG_RQ_BW_WR_UBOUND29, 0x13},
- {OP_WR, PXP2_REG_RQ_BW_WR_UBOUND30, 0x6},
- {OP_WR, PXP2_REG_PSWRQ_BW_L1, 0x1004},
- {OP_WR, PXP2_REG_PSWRQ_BW_L2, 0x1004},
- {OP_WR, PXP2_REG_PSWRQ_BW_RD, 0x106440},
- {OP_WR, PXP2_REG_PSWRQ_BW_WR, 0x106440},
- {OP_WR_E1H, PXP2_REG_RQ_ILT_MODE, 0x1},
- {OP_WR, PXP2_REG_RQ_RBC_DONE, 0x1},
-#define PXP2_COMMON_END 2137
-#define MISC_AEU_COMMON_START 2137
- {OP_ZR, MISC_REG_AEU_GENERAL_ATTN_0, 0x16},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_NIG_0, 0xf0000000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_0, 0xf0000000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_NIG_1, 0xf0000000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_PXP_1, 0x0},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_PXP_1, 0x10000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE3_PXP_1, 0x5014},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
- {OP_WR_E1H, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0xc00},
- {OP_WR_E1H, MISC_REG_AEU_GENERAL_MASK, 0x3},
-#define MISC_AEU_COMMON_END 2156
-#define MISC_AEU_PORT0_START 2156
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xbf5c0000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xff5c0000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff51fef},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff55fff},
- {OP_WR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_0, 0xffff},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0x500003e0},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0xf00003e0},
- {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_1, 0x0},
- {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_1, 0xa000},
- {OP_ZR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_1, 0x5},
- {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_2, 0xfe00000},
- {OP_ZR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x14},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x7},
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_4, 0x400},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_5, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_5, 0x1000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_NIG_0, 0x0},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_6, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_6, 0x4000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_7, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_7, 0x10000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_PXP_0, 0x0},
- {OP_ZR_E1H, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x4},
- {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x0},
- {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_0, 0x3},
- {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_0, 0x7},
-#define MISC_AEU_PORT0_END 2188
-#define MISC_AEU_PORT1_START 2188
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xbf5c0000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xff5c0000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff51fef},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff55fff},
- {OP_WR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_0, 0xffff},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0x500003e0},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0xf00003e0},
- {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_1, 0x0},
- {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_1, 0xa000},
- {OP_ZR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_1, 0x5},
- {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_2, 0xfe00000},
- {OP_ZR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x14},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x7},
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_4, 0x800},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_5, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_5, 0x2000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_NIG_1, 0x0},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_6, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_PXP_1, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_6, 0x8000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_PXP_1, 0x55555555},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_7, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE3_PXP_1, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_7, 0x20000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
- {OP_ZR_E1H, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x4},
- {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x0},
- {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_1, 0x3},
- {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_1, 0x7},
-#define MISC_AEU_PORT1_END 2220
-
-};
-
-static const u32 init_data_e1[] = {
- 0x00010000, 0x000204c0, 0x00030980, 0x00040e40, 0x00051300, 0x000617c0,
- 0x00071c80, 0x00082140, 0x00092600, 0x000a2ac0, 0x000b2f80, 0x000c3440,
- 0x000d3900, 0x000e3dc0, 0x000f4280, 0x00104740, 0x00114c00, 0x001250c0,
- 0x00135580, 0x00145a40, 0x00155f00, 0x001663c0, 0x00176880, 0x00186d40,
- 0x00197200, 0x001a76c0, 0x001b7b80, 0x001c8040, 0x001d8500, 0x001e89c0,
- 0x001f8e80, 0x00209340, 0x00002000, 0x00004000, 0x00006000, 0x00008000,
- 0x0000a000, 0x0000c000, 0x0000e000, 0x00010000, 0x00012000, 0x00014000,
- 0x00016000, 0x00018000, 0x0001a000, 0x0001c000, 0x0001e000, 0x00020000,
- 0x00022000, 0x00024000, 0x00026000, 0x00028000, 0x0002a000, 0x0002c000,
- 0x0002e000, 0x00030000, 0x00032000, 0x00034000, 0x00036000, 0x00038000,
- 0x0003a000, 0x0003c000, 0x0003e000, 0x00040000, 0x00042000, 0x00044000,
- 0x00046000, 0x00048000, 0x0004a000, 0x0004c000, 0x0004e000, 0x00050000,
- 0x00052000, 0x00054000, 0x00056000, 0x00058000, 0x0005a000, 0x0005c000,
- 0x0005e000, 0x00060000, 0x00062000, 0x00064000, 0x00066000, 0x00068000,
- 0x0006a000, 0x0006c000, 0x0006e000, 0x00070000, 0x00072000, 0x00074000,
- 0x00076000, 0x00078000, 0x0007a000, 0x0007c000, 0x0007e000, 0x00080000,
- 0x00082000, 0x00084000, 0x00086000, 0x00088000, 0x0008a000, 0x0008c000,
- 0x0008e000, 0x00090000, 0x00092000, 0x00094000, 0x00096000, 0x00098000,
- 0x0009a000, 0x0009c000, 0x0009e000, 0x000a0000, 0x000a2000, 0x000a4000,
- 0x000a6000, 0x000a8000, 0x000aa000, 0x000ac000, 0x000ae000, 0x000b0000,
- 0x000b2000, 0x000b4000, 0x000b6000, 0x000b8000, 0x000ba000, 0x000bc000,
- 0x000be000, 0x000c0000, 0x000c2000, 0x000c4000, 0x000c6000, 0x000c8000,
- 0x000ca000, 0x000cc000, 0x000ce000, 0x000d0000, 0x000d2000, 0x000d4000,
- 0x000d6000, 0x000d8000, 0x000da000, 0x000dc000, 0x000de000, 0x000e0000,
- 0x000e2000, 0x000e4000, 0x000e6000, 0x000e8000, 0x000ea000, 0x000ec000,
- 0x000ee000, 0x000f0000, 0x000f2000, 0x000f4000, 0x000f6000, 0x000f8000,
- 0x000fa000, 0x000fc000, 0x000fe000, 0x00100000, 0x00102000, 0x00104000,
- 0x00106000, 0x00108000, 0x0010a000, 0x0010c000, 0x0010e000, 0x00110000,
- 0x00112000, 0x00114000, 0x00116000, 0x00118000, 0x0011a000, 0x0011c000,
- 0x0011e000, 0x00120000, 0x00122000, 0x00124000, 0x00126000, 0x00128000,
- 0x0012a000, 0x0012c000, 0x0012e000, 0x00130000, 0x00132000, 0x00134000,
- 0x00136000, 0x00138000, 0x0013a000, 0x0013c000, 0x0013e000, 0x00140000,
- 0x00142000, 0x00144000, 0x00146000, 0x00148000, 0x0014a000, 0x0014c000,
- 0x0014e000, 0x00150000, 0x00152000, 0x00154000, 0x00156000, 0x00158000,
- 0x0015a000, 0x0015c000, 0x0015e000, 0x00160000, 0x00162000, 0x00164000,
- 0x00166000, 0x00168000, 0x0016a000, 0x0016c000, 0x0016e000, 0x00170000,
- 0x00172000, 0x00174000, 0x00176000, 0x00178000, 0x0017a000, 0x0017c000,
- 0x0017e000, 0x00180000, 0x00182000, 0x00184000, 0x00186000, 0x00188000,
- 0x0018a000, 0x0018c000, 0x0018e000, 0x00190000, 0x00192000, 0x00194000,
- 0x00196000, 0x00198000, 0x0019a000, 0x0019c000, 0x0019e000, 0x001a0000,
- 0x001a2000, 0x001a4000, 0x001a6000, 0x001a8000, 0x001aa000, 0x001ac000,
- 0x001ae000, 0x001b0000, 0x001b2000, 0x001b4000, 0x001b6000, 0x001b8000,
- 0x001ba000, 0x001bc000, 0x001be000, 0x001c0000, 0x001c2000, 0x001c4000,
- 0x001c6000, 0x001c8000, 0x001ca000, 0x001cc000, 0x001ce000, 0x001d0000,
- 0x001d2000, 0x001d4000, 0x001d6000, 0x001d8000, 0x001da000, 0x001dc000,
- 0x001de000, 0x001e0000, 0x001e2000, 0x001e4000, 0x001e6000, 0x001e8000,
- 0x001ea000, 0x001ec000, 0x001ee000, 0x001f0000, 0x001f2000, 0x001f4000,
- 0x001f6000, 0x001f8000, 0x001fa000, 0x001fc000, 0x001fe000, 0x00200000,
- 0x00202000, 0x00204000, 0x00206000, 0x00208000, 0x0020a000, 0x0020c000,
- 0x0020e000, 0x00210000, 0x00212000, 0x00214000, 0x00216000, 0x00218000,
- 0x0021a000, 0x0021c000, 0x0021e000, 0x00220000, 0x00222000, 0x00224000,
- 0x00226000, 0x00228000, 0x0022a000, 0x0022c000, 0x0022e000, 0x00230000,
- 0x00232000, 0x00234000, 0x00236000, 0x00238000, 0x0023a000, 0x0023c000,
- 0x0023e000, 0x00240000, 0x00242000, 0x00244000, 0x00246000, 0x00248000,
- 0x0024a000, 0x0024c000, 0x0024e000, 0x00250000, 0x00252000, 0x00254000,
- 0x00256000, 0x00258000, 0x0025a000, 0x0025c000, 0x0025e000, 0x00260000,
- 0x00262000, 0x00264000, 0x00266000, 0x00268000, 0x0026a000, 0x0026c000,
- 0x0026e000, 0x00270000, 0x00272000, 0x00274000, 0x00276000, 0x00278000,
- 0x0027a000, 0x0027c000, 0x0027e000, 0x00280000, 0x00282000, 0x00284000,
- 0x00286000, 0x00288000, 0x0028a000, 0x0028c000, 0x0028e000, 0x00290000,
- 0x00292000, 0x00294000, 0x00296000, 0x00298000, 0x0029a000, 0x0029c000,
- 0x0029e000, 0x002a0000, 0x002a2000, 0x002a4000, 0x002a6000, 0x002a8000,
- 0x002aa000, 0x002ac000, 0x002ae000, 0x002b0000, 0x002b2000, 0x002b4000,
- 0x002b6000, 0x002b8000, 0x002ba000, 0x002bc000, 0x002be000, 0x002c0000,
- 0x002c2000, 0x002c4000, 0x002c6000, 0x002c8000, 0x002ca000, 0x002cc000,
- 0x002ce000, 0x002d0000, 0x002d2000, 0x002d4000, 0x002d6000, 0x002d8000,
- 0x002da000, 0x002dc000, 0x002de000, 0x002e0000, 0x002e2000, 0x002e4000,
- 0x002e6000, 0x002e8000, 0x002ea000, 0x002ec000, 0x002ee000, 0x002f0000,
- 0x002f2000, 0x002f4000, 0x002f6000, 0x002f8000, 0x002fa000, 0x002fc000,
- 0x002fe000, 0x00300000, 0x00302000, 0x00304000, 0x00306000, 0x00308000,
- 0x0030a000, 0x0030c000, 0x0030e000, 0x00310000, 0x00312000, 0x00314000,
- 0x00316000, 0x00318000, 0x0031a000, 0x0031c000, 0x0031e000, 0x00320000,
- 0x00322000, 0x00324000, 0x00326000, 0x00328000, 0x0032a000, 0x0032c000,
- 0x0032e000, 0x00330000, 0x00332000, 0x00334000, 0x00336000, 0x00338000,
- 0x0033a000, 0x0033c000, 0x0033e000, 0x00340000, 0x00342000, 0x00344000,
- 0x00346000, 0x00348000, 0x0034a000, 0x0034c000, 0x0034e000, 0x00350000,
- 0x00352000, 0x00354000, 0x00356000, 0x00358000, 0x0035a000, 0x0035c000,
- 0x0035e000, 0x00360000, 0x00362000, 0x00364000, 0x00366000, 0x00368000,
- 0x0036a000, 0x0036c000, 0x0036e000, 0x00370000, 0x00372000, 0x00374000,
- 0x00376000, 0x00378000, 0x0037a000, 0x0037c000, 0x0037e000, 0x00380000,
- 0x00382000, 0x00384000, 0x00386000, 0x00388000, 0x0038a000, 0x0038c000,
- 0x0038e000, 0x00390000, 0x00392000, 0x00394000, 0x00396000, 0x00398000,
- 0x0039a000, 0x0039c000, 0x0039e000, 0x003a0000, 0x003a2000, 0x003a4000,
- 0x003a6000, 0x003a8000, 0x003aa000, 0x003ac000, 0x003ae000, 0x003b0000,
- 0x003b2000, 0x003b4000, 0x003b6000, 0x003b8000, 0x003ba000, 0x003bc000,
- 0x003be000, 0x003c0000, 0x003c2000, 0x003c4000, 0x003c6000, 0x003c8000,
- 0x003ca000, 0x003cc000, 0x003ce000, 0x003d0000, 0x003d2000, 0x003d4000,
- 0x003d6000, 0x003d8000, 0x003da000, 0x003dc000, 0x003de000, 0x003e0000,
- 0x003e2000, 0x003e4000, 0x003e6000, 0x003e8000, 0x003ea000, 0x003ec000,
- 0x003ee000, 0x003f0000, 0x003f2000, 0x003f4000, 0x003f6000, 0x003f8000,
- 0x003fa000, 0x003fc000, 0x003fe000, 0x003fe001, 0x00000000, 0x000001ff,
- 0x00000200, 0x00000001, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8, 0x00000000, 0x00003500,
- 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003,
- 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
- 0x00000003, 0x00bebc20, 0x00002000, 0x000040c0, 0x00006180, 0x00008240,
- 0x0000a300, 0x0000c3c0, 0x0000e480, 0x00010540, 0x00012600, 0x000146c0,
- 0x00016780, 0x00018840, 0x0001a900, 0x0001c9c0, 0x0001ea80, 0x00020b40,
- 0x00022c00, 0x00024cc0, 0x00026d80, 0x00028e40, 0x0002af00, 0x0002cfc0,
- 0x0002f080, 0x00031140, 0x00033200, 0x000352c0, 0x00037380, 0x00039440,
- 0x0003b500, 0x0003d5c0, 0x0003f680, 0x00041740, 0x00043800, 0x000458c0,
- 0x00047980, 0x00049a40, 0x00008000, 0x00010380, 0x00018700, 0x00020a80,
- 0x00028e00, 0x00031180, 0x00039500, 0x00041880, 0x00049c00, 0x00051f80,
- 0x0005a300, 0x00062680, 0x0006aa00, 0x00072d80, 0x0007b100, 0x00083480,
- 0x0008b800, 0x00093b80, 0x0009bf00, 0x000a4280, 0x000ac600, 0x000b4980,
- 0x000bcd00, 0x000c5080, 0x000cd400, 0x000d5780, 0x000ddb00, 0x00001900,
- 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8,
- 0x00000000, 0x00001500, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x00000000, 0x00007ff8, 0x00000000, 0x00001500, 0x00001000, 0x00002080,
- 0x00003100, 0x00004180, 0x00005200, 0x00006280, 0x00007300, 0x00008380,
- 0x00009400, 0x0000a480, 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680,
- 0x0000f700, 0x00010780, 0x00011800, 0x00012880, 0x00013900, 0x00014980,
- 0x00015a00, 0x00016a80, 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80,
- 0x0001bd00, 0x0001cd80, 0x0001de00, 0x0001ee80, 0x0001ff00, 0x10000000,
- 0x000028ad, 0x00000000, 0x00010001, 0x00350804, 0xccccccc1, 0xffffffff,
- 0xffffffff, 0x7058103c, 0x00000000, 0xcccc0201, 0xcccccccc, 0x00000000,
- 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8, 0x00000000,
- 0x00003500, 0x000e01b7, 0x011600d6, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x00100000, 0x00000000, 0x007201bb, 0x012300f3, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x00100000, 0x00000000, 0xfffffff3,
- 0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xfffffff1, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
- 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
- 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7,
- 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xfffffff5, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x310fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
- 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
- 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
- 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x30efffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
- 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0xfffffff3, 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
- 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
- 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
- 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
- 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xffffff97, 0x056fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
- 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3,
- 0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
- 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
- 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffff8a, 0x042fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97,
- 0x05cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x300fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
- 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
- 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
- 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x040fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
- 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0x00100000, 0x00070100, 0x00028170, 0x000b8198, 0x00020250,
- 0x00010270, 0x000f0280, 0x00010370, 0x00080000, 0x00080080, 0x00028100,
- 0x000b8128, 0x000201e0, 0x00010200, 0x00070210, 0x00020280, 0x000f0000,
- 0x000800f0, 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000b8280,
- 0x00080338, 0x00100000, 0x00080100, 0x00028180, 0x000b81a8, 0x00020260,
- 0x00018280, 0x000e8298, 0x00080380, 0x00028000, 0x000b8028, 0x000200e0,
- 0x00010100, 0x00008110, 0x00000118, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000
-};
-
-static const u32 init_data_e1h[] = {
- 0x00010000, 0x000204c0, 0x00030980, 0x00040e40, 0x00051300, 0x000617c0,
- 0x00071c80, 0x00082140, 0x00092600, 0x000a2ac0, 0x000b2f80, 0x000c3440,
- 0x000d3900, 0x000e3dc0, 0x000f4280, 0x00104740, 0x00114c00, 0x001250c0,
- 0x00135580, 0x00145a40, 0x00155f00, 0x001663c0, 0x00176880, 0x00186d40,
- 0x00197200, 0x001a76c0, 0x001b7b80, 0x001c8040, 0x001d8500, 0x001e89c0,
- 0x001f8e80, 0x00209340, 0x00002000, 0x00004000, 0x00006000, 0x00008000,
- 0x0000a000, 0x0000c000, 0x0000e000, 0x00010000, 0x00012000, 0x00014000,
- 0x00016000, 0x00018000, 0x0001a000, 0x0001c000, 0x0001e000, 0x00020000,
- 0x00022000, 0x00024000, 0x00026000, 0x00028000, 0x0002a000, 0x0002c000,
- 0x0002e000, 0x00030000, 0x00032000, 0x00034000, 0x00036000, 0x00038000,
- 0x0003a000, 0x0003c000, 0x0003e000, 0x00040000, 0x00042000, 0x00044000,
- 0x00046000, 0x00048000, 0x0004a000, 0x0004c000, 0x0004e000, 0x00050000,
- 0x00052000, 0x00054000, 0x00056000, 0x00058000, 0x0005a000, 0x0005c000,
- 0x0005e000, 0x00060000, 0x00062000, 0x00064000, 0x00066000, 0x00068000,
- 0x0006a000, 0x0006c000, 0x0006e000, 0x00070000, 0x00072000, 0x00074000,
- 0x00076000, 0x00078000, 0x0007a000, 0x0007c000, 0x0007e000, 0x00080000,
- 0x00082000, 0x00084000, 0x00086000, 0x00088000, 0x0008a000, 0x0008c000,
- 0x0008e000, 0x00090000, 0x00092000, 0x00094000, 0x00096000, 0x00098000,
- 0x0009a000, 0x0009c000, 0x0009e000, 0x000a0000, 0x000a2000, 0x000a4000,
- 0x000a6000, 0x000a8000, 0x000aa000, 0x000ac000, 0x000ae000, 0x000b0000,
- 0x000b2000, 0x000b4000, 0x000b6000, 0x000b8000, 0x000ba000, 0x000bc000,
- 0x000be000, 0x000c0000, 0x000c2000, 0x000c4000, 0x000c6000, 0x000c8000,
- 0x000ca000, 0x000cc000, 0x000ce000, 0x000d0000, 0x000d2000, 0x000d4000,
- 0x000d6000, 0x000d8000, 0x000da000, 0x000dc000, 0x000de000, 0x000e0000,
- 0x000e2000, 0x000e4000, 0x000e6000, 0x000e8000, 0x000ea000, 0x000ec000,
- 0x000ee000, 0x000f0000, 0x000f2000, 0x000f4000, 0x000f6000, 0x000f8000,
- 0x000fa000, 0x000fc000, 0x000fe000, 0x00100000, 0x00102000, 0x00104000,
- 0x00106000, 0x00108000, 0x0010a000, 0x0010c000, 0x0010e000, 0x00110000,
- 0x00112000, 0x00114000, 0x00116000, 0x00118000, 0x0011a000, 0x0011c000,
- 0x0011e000, 0x00120000, 0x00122000, 0x00124000, 0x00126000, 0x00128000,
- 0x0012a000, 0x0012c000, 0x0012e000, 0x00130000, 0x00132000, 0x00134000,
- 0x00136000, 0x00138000, 0x0013a000, 0x0013c000, 0x0013e000, 0x00140000,
- 0x00142000, 0x00144000, 0x00146000, 0x00148000, 0x0014a000, 0x0014c000,
- 0x0014e000, 0x00150000, 0x00152000, 0x00154000, 0x00156000, 0x00158000,
- 0x0015a000, 0x0015c000, 0x0015e000, 0x00160000, 0x00162000, 0x00164000,
- 0x00166000, 0x00168000, 0x0016a000, 0x0016c000, 0x0016e000, 0x00170000,
- 0x00172000, 0x00174000, 0x00176000, 0x00178000, 0x0017a000, 0x0017c000,
- 0x0017e000, 0x00180000, 0x00182000, 0x00184000, 0x00186000, 0x00188000,
- 0x0018a000, 0x0018c000, 0x0018e000, 0x00190000, 0x00192000, 0x00194000,
- 0x00196000, 0x00198000, 0x0019a000, 0x0019c000, 0x0019e000, 0x001a0000,
- 0x001a2000, 0x001a4000, 0x001a6000, 0x001a8000, 0x001aa000, 0x001ac000,
- 0x001ae000, 0x001b0000, 0x001b2000, 0x001b4000, 0x001b6000, 0x001b8000,
- 0x001ba000, 0x001bc000, 0x001be000, 0x001c0000, 0x001c2000, 0x001c4000,
- 0x001c6000, 0x001c8000, 0x001ca000, 0x001cc000, 0x001ce000, 0x001d0000,
- 0x001d2000, 0x001d4000, 0x001d6000, 0x001d8000, 0x001da000, 0x001dc000,
- 0x001de000, 0x001e0000, 0x001e2000, 0x001e4000, 0x001e6000, 0x001e8000,
- 0x001ea000, 0x001ec000, 0x001ee000, 0x001f0000, 0x001f2000, 0x001f4000,
- 0x001f6000, 0x001f8000, 0x001fa000, 0x001fc000, 0x001fe000, 0x00200000,
- 0x00202000, 0x00204000, 0x00206000, 0x00208000, 0x0020a000, 0x0020c000,
- 0x0020e000, 0x00210000, 0x00212000, 0x00214000, 0x00216000, 0x00218000,
- 0x0021a000, 0x0021c000, 0x0021e000, 0x00220000, 0x00222000, 0x00224000,
- 0x00226000, 0x00228000, 0x0022a000, 0x0022c000, 0x0022e000, 0x00230000,
- 0x00232000, 0x00234000, 0x00236000, 0x00238000, 0x0023a000, 0x0023c000,
- 0x0023e000, 0x00240000, 0x00242000, 0x00244000, 0x00246000, 0x00248000,
- 0x0024a000, 0x0024c000, 0x0024e000, 0x00250000, 0x00252000, 0x00254000,
- 0x00256000, 0x00258000, 0x0025a000, 0x0025c000, 0x0025e000, 0x00260000,
- 0x00262000, 0x00264000, 0x00266000, 0x00268000, 0x0026a000, 0x0026c000,
- 0x0026e000, 0x00270000, 0x00272000, 0x00274000, 0x00276000, 0x00278000,
- 0x0027a000, 0x0027c000, 0x0027e000, 0x00280000, 0x00282000, 0x00284000,
- 0x00286000, 0x00288000, 0x0028a000, 0x0028c000, 0x0028e000, 0x00290000,
- 0x00292000, 0x00294000, 0x00296000, 0x00298000, 0x0029a000, 0x0029c000,
- 0x0029e000, 0x002a0000, 0x002a2000, 0x002a4000, 0x002a6000, 0x002a8000,
- 0x002aa000, 0x002ac000, 0x002ae000, 0x002b0000, 0x002b2000, 0x002b4000,
- 0x002b6000, 0x002b8000, 0x002ba000, 0x002bc000, 0x002be000, 0x002c0000,
- 0x002c2000, 0x002c4000, 0x002c6000, 0x002c8000, 0x002ca000, 0x002cc000,
- 0x002ce000, 0x002d0000, 0x002d2000, 0x002d4000, 0x002d6000, 0x002d8000,
- 0x002da000, 0x002dc000, 0x002de000, 0x002e0000, 0x002e2000, 0x002e4000,
- 0x002e6000, 0x002e8000, 0x002ea000, 0x002ec000, 0x002ee000, 0x002f0000,
- 0x002f2000, 0x002f4000, 0x002f6000, 0x002f8000, 0x002fa000, 0x002fc000,
- 0x002fe000, 0x00300000, 0x00302000, 0x00304000, 0x00306000, 0x00308000,
- 0x0030a000, 0x0030c000, 0x0030e000, 0x00310000, 0x00312000, 0x00314000,
- 0x00316000, 0x00318000, 0x0031a000, 0x0031c000, 0x0031e000, 0x00320000,
- 0x00322000, 0x00324000, 0x00326000, 0x00328000, 0x0032a000, 0x0032c000,
- 0x0032e000, 0x00330000, 0x00332000, 0x00334000, 0x00336000, 0x00338000,
- 0x0033a000, 0x0033c000, 0x0033e000, 0x00340000, 0x00342000, 0x00344000,
- 0x00346000, 0x00348000, 0x0034a000, 0x0034c000, 0x0034e000, 0x00350000,
- 0x00352000, 0x00354000, 0x00356000, 0x00358000, 0x0035a000, 0x0035c000,
- 0x0035e000, 0x00360000, 0x00362000, 0x00364000, 0x00366000, 0x00368000,
- 0x0036a000, 0x0036c000, 0x0036e000, 0x00370000, 0x00372000, 0x00374000,
- 0x00376000, 0x00378000, 0x0037a000, 0x0037c000, 0x0037e000, 0x00380000,
- 0x00382000, 0x00384000, 0x00386000, 0x00388000, 0x0038a000, 0x0038c000,
- 0x0038e000, 0x00390000, 0x00392000, 0x00394000, 0x00396000, 0x00398000,
- 0x0039a000, 0x0039c000, 0x0039e000, 0x003a0000, 0x003a2000, 0x003a4000,
- 0x003a6000, 0x003a8000, 0x003aa000, 0x003ac000, 0x003ae000, 0x003b0000,
- 0x003b2000, 0x003b4000, 0x003b6000, 0x003b8000, 0x003ba000, 0x003bc000,
- 0x003be000, 0x003c0000, 0x003c2000, 0x003c4000, 0x003c6000, 0x003c8000,
- 0x003ca000, 0x003cc000, 0x003ce000, 0x003d0000, 0x003d2000, 0x003d4000,
- 0x003d6000, 0x003d8000, 0x003da000, 0x003dc000, 0x003de000, 0x003e0000,
- 0x003e2000, 0x003e4000, 0x003e6000, 0x003e8000, 0x003ea000, 0x003ec000,
- 0x003ee000, 0x003f0000, 0x003f2000, 0x003f4000, 0x003f6000, 0x003f8000,
- 0x003fa000, 0x003fc000, 0x003fe000, 0x003fe001, 0x00000000, 0x000001ff,
- 0x00000200, 0x00000001, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8,
- 0x00000000, 0x00003500, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
- 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
- 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003,
- 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
- 0x00000003, 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
- 0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff,
- 0x00000000, 0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff, 0x00000000,
- 0xffffffff, 0x00000000, 0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff,
- 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003, 0x00bebc20,
- 0x00002000, 0x000040c0, 0x00006180, 0x00008240, 0x0000a300, 0x0000c3c0,
- 0x0000e480, 0x00010540, 0x00012600, 0x000146c0, 0x00016780, 0x00018840,
- 0x0001a900, 0x0001c9c0, 0x0001ea80, 0x00020b40, 0x00022c00, 0x00024cc0,
- 0x00026d80, 0x00028e40, 0x0002af00, 0x0002cfc0, 0x0002f080, 0x00031140,
- 0x00033200, 0x000352c0, 0x00037380, 0x00039440, 0x0003b500, 0x0003d5c0,
- 0x0003f680, 0x00041740, 0x00043800, 0x000458c0, 0x00047980, 0x00049a40,
- 0x00008000, 0x00010380, 0x00018700, 0x00020a80, 0x00028e00, 0x00031180,
- 0x00039500, 0x00041880, 0x00049c00, 0x00051f80, 0x0005a300, 0x00062680,
- 0x0006aa00, 0x00072d80, 0x0007b100, 0x00083480, 0x0008b800, 0x00093b80,
- 0x0009bf00, 0x000a4280, 0x000ac600, 0x000b4980, 0x000bcd00, 0x000c5080,
- 0x000cd400, 0x000d5780, 0x000ddb00, 0x00001900, 0x00000028, 0x00100000,
- 0x00000000, 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000,
- 0x00007ff8, 0x00000000, 0x00001500, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x00000000, 0x00007ff8, 0x00000000, 0x00001500, 0x00001000,
- 0x00002080, 0x00003100, 0x00004180, 0x00005200, 0x00006280, 0x00007300,
- 0x00008380, 0x00009400, 0x0000a480, 0x0000b500, 0x0000c580, 0x0000d600,
- 0x0000e680, 0x0000f700, 0x00010780, 0x00011800, 0x00012880, 0x00013900,
- 0x00014980, 0x00015a00, 0x00016a80, 0x00017b00, 0x00018b80, 0x00019c00,
- 0x0001ac80, 0x0001bd00, 0x0001cd80, 0x0001de00, 0x0001ee80, 0x0001ff00,
- 0x10000000, 0x000028ad, 0x00000000, 0x00010001, 0x00350804, 0xccccccc5,
- 0xffffffff, 0xffffffff, 0x7058103c, 0x00000000, 0xcccc0201, 0xcccccccc,
- 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc,
- 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc,
- 0xcccc0201, 0xcccccccc, 0x00000000, 0xffffffff, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x00000000, 0x00007ff8, 0x00000000, 0x00003500, 0x000e0232, 0x011600d6,
- 0x00100000, 0x00000000, 0x00720236, 0x012300f3, 0x00100000, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
- 0x0000ffff, 0x00000000, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x30efffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
- 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3,
- 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
- 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x31efffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x302fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
- 0xfffffff3, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd,
- 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3,
- 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd,
- 0xfffffff7, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x304fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x31efffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd,
- 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff,
- 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd,
- 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x056fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd,
- 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
- 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3,
- 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
- 0xffffff8a, 0x042fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3,
- 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x05cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x310fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
- 0xfffffff3, 0x316fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x302fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd,
- 0xfffffff6, 0x30bfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf314, 0xf3cf3cf3,
- 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd,
- 0xfffffff7, 0x31cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0020cf3c, 0xcdcdcdcd, 0xfffffff0, 0x307fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0x00100000, 0x00070100,
- 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000f0280, 0x00010370,
- 0x00080000, 0x00080080, 0x00028100, 0x000b8128, 0x000201e0, 0x00010200,
- 0x00070210, 0x00020280, 0x000f0000, 0x000800f0, 0x00028170, 0x000b8198,
- 0x00020250, 0x00010270, 0x000b8280, 0x00080338, 0x00100000, 0x00080100,
- 0x00028180, 0x000b81a8, 0x00020260, 0x00018280, 0x000e8298, 0x00080380,
- 0x000b0000, 0x000100b0, 0x000280c0, 0x000580e8, 0x00020140, 0x00010160,
- 0x000e0170, 0x00038250, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000,
- 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x04002000
-};
-
-static const u32 tsem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x19d9458a, 0x1138fc18,
- 0x5980a1fc, 0xd8181998, 0x88039880, 0x81b8803d, 0x91a18191, 0xdafd7891,
- 0xbf760862, 0x6ec30330, 0x0211e620, 0x1082239a, 0xf354029f, 0x0f5fc806,
- 0x6512b315, 0x3a263860, 0x06a77ef0, 0x298d2ade, 0xc1124536, 0x1e4586de,
- 0x93476f19, 0xca8922ff, 0xff4041df, 0x65296340, 0x229dbe54, 0x04a65e84,
- 0xe4d1a5a1, 0xd7f2a1ed, 0x5192fea1, 0x0dee6ec6, 0xf8003ca8, 0x6065495c,
- 0x00606549
-};
-
-static const u32 tsem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0x49999cce,
- 0x424e4cce, 0x4c22f212, 0x21a08812, 0x8a80af0c, 0x2201277f, 0x282039f5,
- 0x4201d458, 0xd4837908, 0xcdedaf4b, 0x11102484, 0x0547f435, 0x5088768b,
- 0x340da2d1, 0x0ec160d2, 0x6d7b1420, 0xc0faf06f, 0x480bf5ea, 0xb12f3141,
- 0xcbc57e20, 0xe7dad6bf, 0x264ce664, 0xafdbd880, 0xb4fdffff, 0xece7d9b8,
- 0xebdaf7b3, 0x7b5ad7b5, 0x75923ded, 0xc7bf9302, 0x03fc45d8, 0x8c4d4fe5,
- 0xf2c109b1, 0x80f66667, 0xc9b18727, 0x473afebd, 0x6d55633c, 0x9da23b19,
- 0x99ec258c, 0x50281421, 0x2c23d5fe, 0xbfdf8250, 0xf097c365, 0x4219b6ff,
- 0xd0977c3e, 0xc3e611e9, 0x02d5e4fb, 0x933a876b, 0xea0c319c, 0x4b19b98c,
- 0x126b2c64, 0x4b223fa3, 0xe0ff828d, 0x8f392573, 0x27fc34b1, 0x61467574,
- 0xc678c0ae, 0x5c531e32, 0x38a9d0d4, 0x843f7815, 0xbcd2c67f, 0x0731b725,
- 0xbc03cf63, 0xbcf071c9, 0x61de3a5a, 0xc22eefe5, 0x3af3a1df, 0xae58cd6a,
- 0x32773e30, 0x416589a7, 0xf3e33ebf, 0x3d6346ac, 0x4fe3d99b, 0xec3fc346,
- 0x8c517ecc, 0xb1138f30, 0xcb3c018c, 0x632f0e54, 0x5467b2bd, 0x6a9b1f10,
- 0x2c32a258, 0x852f0f58, 0x56338765, 0xed975e03, 0xf8165c16, 0x2f6c39fe,
- 0xbed7e631, 0x15ead66b, 0xa362593e, 0xb50404a1, 0x67eff4e4, 0x11bfcb11,
- 0x2b30fef1, 0xea4ab2a0, 0xaf805595, 0xfb765aaa, 0x67edfe95, 0x54e88933,
- 0x5bf6b929, 0x5adefc61, 0xf1866ae6, 0x02d59997, 0x91fb2fac, 0x7a83e5d3,
- 0x21476366, 0x36d0fa83, 0xc1198981, 0x9e00afef, 0x007f91db, 0xa52b2a1e,
- 0x740642de, 0xb02bddec, 0x871c0ce6, 0x776cbbf7, 0x0c65f306, 0x6658e70c,
- 0x32e73826, 0x74893a41, 0xd2073071, 0xf324bcc1, 0xcea84289, 0xb0f3dc54,
- 0x9de29f7f, 0xe7f4ed87, 0x38e60b49, 0xf25700bd, 0x57a06650, 0x9d3ab5b1,
- 0xea563265, 0xbe442969, 0x8decb538, 0x9e025855, 0xf7c02413, 0x08a78b7c,
- 0x5798a9fb, 0xa780cd9d, 0x8d1859e6, 0xff2db43f, 0x0cf80933, 0xc4c5f3ba,
- 0x76313f21, 0xf04f843c, 0x5a11f1cf, 0xde981c5d, 0xb08b2b97, 0x05f1091f,
- 0x1f011772, 0x26a0423f, 0x544d28e0, 0x29fc573a, 0xd0a0d86b, 0xc3595bfa,
- 0xe50069c6, 0x3f0cbc11, 0x0843ac61, 0x1cbd4be5, 0xb0ff3bba, 0x3c303b94,
- 0x04f3d3ff, 0xab7e1274, 0x1fc8b700, 0xbfd97615, 0xca61f812, 0xf7c0e6ab,
- 0x362a3f80, 0xd40b7e0b, 0xe8dbaf4d, 0x5e26f77d, 0x3765d80f, 0x16d74ff2,
- 0xbdf00ba8, 0x1bf1fda5, 0x155ebf91, 0x3b763359, 0xfa84ca22, 0x3b06a4e5,
- 0xc0750f1b, 0x578db147, 0xbbef362b, 0x692fbf1f, 0xf41b30b3, 0xf17bb157,
- 0x7d42371d, 0xc33361f1, 0x6b5b1526, 0x2fa814e5, 0x582d0bf1, 0xf0e029ef,
- 0xfe8976f9, 0xc7bed0ad, 0x1b389ed1, 0xc6ba73e8, 0x63329cca, 0xc4f6f675,
- 0xa567c059, 0xf8851dfe, 0xc176e95d, 0xf29f6885, 0xc943d6ea, 0xb917af38,
- 0x8b6d977c, 0x7f1d4e66, 0xab64f7f0, 0xbc1ef818, 0x64f3065f, 0xd662efd0,
- 0xb07a8854, 0xd93aeb62, 0xebe20f69, 0xe34a8d74, 0x8bdfc9f4, 0x577c0e30,
- 0xc2e08af9, 0x989a5629, 0x7bb0e517, 0xf3ce6db7, 0x56afce0a, 0xbce3b6ce,
- 0x6ed8cb56, 0x2efe7fb1, 0xfea5cd54, 0xbc2172cd, 0x59b4dd2f, 0xdb910e2e,
- 0x8c836db2, 0x1ac86d70, 0xd7208dec, 0xd7807841, 0x52f583b2, 0x0fa803d4,
- 0x233cbf25, 0x852acf84, 0xb2cbe258, 0x1a73226d, 0xddd388f8, 0x13fc2ef7,
- 0x6bdbe5f0, 0x74eabc27, 0x1aa7d3eb, 0x1aa8cedd, 0xbcdea51d, 0xf8f81119,
- 0xc003a471, 0x827884d3, 0x9f06ad72, 0x97cb3263, 0x9b877fa0, 0x3cbb02a9,
- 0xd999365f, 0xf563067c, 0xd2dd07b0, 0xd99750f5, 0xf582e652, 0x7bb1fa50,
- 0x0493d42a, 0x9f3867ef, 0xc25bc17a, 0x2496abd7, 0x9579e00f, 0xfce0e6c0,
- 0x30d0218f, 0xc0c955af, 0xa6f7809f, 0x8bcf7969, 0x3c7b0682, 0xb17f8bd6,
- 0x39fa8326, 0xa198fd43, 0xf7cbac9f, 0x324e16a3, 0x9616a3f4, 0x8dfcfde8,
- 0x595db1fa, 0x37854d3f, 0x2c29e118, 0x0491fbd5, 0xbf6f5768, 0x37a979b2,
- 0x73c2364f, 0x13f53973, 0xbcc5d53b, 0x1ae7ae0a, 0xb776b03f, 0xed95ef08,
- 0xb0d763b1, 0x5028be50, 0x0edb8005, 0x17ca1252, 0x0ca29331, 0x8eeb187c,
- 0x27a1d433, 0x4175e4f5, 0x958813fd, 0x45397c69, 0x9f90bd26, 0x43faa562,
- 0x85e90a29, 0x5ef06e87, 0x8e20eb83, 0x2ea192cd, 0x11ab477b, 0x14e01af8,
- 0x60961258, 0x7ff52417, 0xf1ccdabf, 0x217a9050, 0x5f7c18fb, 0x8ecdea65,
- 0xa635fa85, 0x6f116bfc, 0xe5eb812e, 0x63559128, 0x230b28bb, 0x233ab4fd,
- 0x085f79ef, 0x00871a9e, 0xbf6085fd, 0x126f668d, 0xdaf8d7f2, 0xc0127c67,
- 0xcc086ab7, 0x12ba0527, 0x60f8099e, 0xa43d5a3d, 0x69f10938, 0x43be4191,
- 0xfc6197c7, 0x06ff1a1c, 0xc71ba3c4, 0xbe3fe84f, 0x61927325, 0x897a6b7c,
- 0x0cab7c61, 0x4fbf03e3, 0xc6d66dad, 0xc0ddfc07, 0x99a134d8, 0x97a4b7c6,
- 0x65abf8d0, 0x3f186256, 0x5bfc6faa, 0x819efe70, 0x83799fe6, 0xa5e9fe71,
- 0x7ccbf9c6, 0x5f6ab3fe, 0xa28fc6d2, 0x5e16cff9, 0x2f4ff3e2, 0xf0b7f3e5,
- 0x77c6fb7e, 0x5effe1f4, 0x8077bf9c, 0x93592df1, 0x5a1ff38d, 0x85bf9c6e,
- 0xbb545f8f, 0xa15f1b53, 0x3b0917f1, 0x9687fcf9, 0xc5b2f8d3, 0x923e42eb,
- 0xfdaaa353, 0x81a44f68, 0x1d260c40, 0x0472a6e5, 0x1fa00518, 0x04990a86,
- 0x9c5143c7, 0x0145ceef, 0x7d4129bf, 0x5120fcc7, 0x352acfa0, 0x9edb2f9e,
- 0xa59ea32f, 0x376889f7, 0x6d453ff1, 0x6c37ad22, 0x1c3fc5bd, 0x136eede0,
- 0x5a2f587d, 0xa45f937f, 0xe5db8ef5, 0xf005c660, 0x1c9e5ff9, 0xaf3a1cd5,
- 0x935172f0, 0x418764f9, 0xbe3c388e, 0x1aa23602, 0x26476be0, 0x9fac1098,
- 0xc60a3d04, 0x7a0e3b2f, 0x6653cb14, 0x009c8f6e, 0x50e4cb3d, 0xf6e5a9b9,
- 0x93bd8f88, 0x5bbaf303, 0xc4a4ff83, 0xb9727df1, 0x9ffc47e0, 0x4654b75b,
- 0x09a8b4fd, 0x7910e98c, 0xd4e8d2af, 0x6fe2dbbb, 0x4e9f0816, 0x243dcfc4,
- 0x97fd8c8a, 0xde2fd766, 0xddf0c830, 0x486fe63c, 0xd70bf682, 0xc2a21fce,
- 0xc7307ffc, 0x53ed1632, 0x13548490, 0x354b31c9, 0xa7316f81, 0x15399d75,
- 0x31ccf72a, 0xb9faec1b, 0x07fd635e, 0xb77ac625, 0xa1366fd9, 0x6044b1bd,
- 0xfbdfa19b, 0xf5ef8daa, 0x71093671, 0x78daae9c, 0x78722777, 0x2c72c3ef,
- 0xae89563e, 0x5bfcabf7, 0x87aa9e1d, 0xeb402ccd, 0x43024765, 0xc812fa3a,
- 0x7caaf35e, 0xdef0e1de, 0x3dbab66f, 0x3ffdcf00, 0xe19f0912, 0x1ebc77f0,
- 0x1d8136ed, 0x4be1b1d7, 0xe1b7da33, 0xff8709f3, 0xf3e11581, 0xf7d46551,
- 0xcfe17df3, 0xf3849f39, 0xfe5b5553, 0xed2113a0, 0x3fbe5a2a, 0x7f0844e8,
- 0x619b6d95, 0xcff12fa8, 0xbc5fb435, 0xfde1be61, 0x8625a6a2, 0x971b0bf7,
- 0x7df3ea1a, 0x7fb4323f, 0xe1ad4560, 0x8fd57dfd, 0xa0ffde18, 0x3ea19d64,
- 0xd0d1bbd7, 0x9b399efe, 0xaf4def0d, 0xe513bc8f, 0x915deea8, 0x5671bae1,
- 0xda38f939, 0xc9156783, 0xb4f8f485, 0xe0e48926, 0xca938d74, 0x5671b6ee,
- 0xc583d72f, 0x5e9c4c0c, 0x71af9ce1, 0x4665ea32, 0xc2aff3fa, 0xea0f9f05,
- 0x849c137f, 0xcc83713f, 0x02c2c002, 0xe3e3eb8b, 0x7de4315e, 0x6fde65c7,
- 0xd71f4100, 0x11d8bdff, 0xf35579f9, 0x046aa1fc, 0xb72821ff, 0xb9d7152c,
- 0x0f7d6d1e, 0x302e5f7f, 0xc673e84f, 0xd79c9256, 0xb94ceb69, 0xf941f5cc,
- 0xf402e4ce, 0x40e5cbbf, 0xc6a5f576, 0xa2a4016b, 0x3ceb449e, 0xa401f901,
- 0x592fc0c0, 0xdceef906, 0x955c1227, 0xaf4013a8, 0xc19e63ae, 0x8133d426,
- 0x8d77e903, 0x49dc3842, 0xa04b6f54, 0x66b3bd75, 0x1213a0fa, 0xe543c7d2,
- 0xa87335a7, 0xa5e3593c, 0x094d44f2, 0xaa6bc795, 0x59a8eca9, 0x35c7e541,
- 0xaa3f2a3e, 0xcff2a469, 0x1e544d35, 0xe540d9ad, 0x2a7e357b, 0x54dc6bbb,
- 0xba2bf9f6, 0xecd78dfe, 0x80afcd55, 0x67ea8795, 0x43d4b9b4, 0x739276db,
- 0xf9ca1257, 0x365ce519, 0x8e67e3da, 0x31996382, 0xf9c2be30, 0xba3a606d,
- 0xf6295ec9, 0xf5c7fd03, 0xe28b6f7f, 0xd899b274, 0xd9a67074, 0xe17fc323,
- 0x7543905a, 0x16065909, 0x7b0cd724, 0xed617e84, 0x8e5d7a43, 0x9bddcc4e,
- 0x71e8133b, 0xe5bf99f2, 0xda75bf61, 0x407517fa, 0x059875a4, 0xbd21779e,
- 0xeb46f042, 0x9aabef5a, 0xfe0cbfbe, 0xd7f0faba, 0xfbfe8e9e, 0xfea54141,
- 0x985ab4cf, 0x13dc7884, 0x67e607ed, 0xef3f0e67, 0x965c7940, 0x444f5264,
- 0x565e83c0, 0x4aa864b4, 0x66d3fae8, 0x12699fac, 0x7ad0b7a6, 0x35998cec,
- 0x554af90a, 0xfa430c4f, 0xf7a95127, 0x56492cb3, 0x9ebc804f, 0xc31596de,
- 0x5f3f6fd7, 0x12c7b707, 0x485f82bf, 0xf0deffed, 0x0e8fd40c, 0xecad630f,
- 0x03ea2b13, 0xedf59778, 0xfd2672fd, 0x6c57e295, 0xda1cf98f, 0x7bf8160b,
- 0x1207e291, 0xab7ef5d5, 0x659f445a, 0x6edf3e34, 0x73be0f18, 0xc5f73eea,
- 0xadf14bcc, 0xc4864ec4, 0xf169d611, 0x366db2c6, 0xc4aeb8d5, 0x6d55ea1a,
- 0x9d61aac9, 0xfc807fc1, 0x42416ab3, 0xb8d729be, 0x1a5247a8, 0xdcaf8005,
- 0xab7ea4e4, 0xc2aede04, 0xe17b21da, 0xa72b5751, 0x9df040db, 0x94ec39ae,
- 0xac4bde40, 0x7c0201e0, 0xa7232d25, 0x6aeb9ea2, 0x7b444bad, 0xf33c4cb0,
- 0xf7c22790, 0x8d024d3b, 0xee6fc4b7, 0x1aa3ae35, 0x57e8307f, 0x167e4e7f,
- 0xd4864e53, 0xcedc4d3b, 0x80f7ef0e, 0xf0e5efd6, 0x48fdb953, 0xfece8de1,
- 0xfb6caa78, 0x1c92f642, 0x82f2ffc1, 0x57f1d278, 0x401cf26e, 0xedba5a7d,
- 0x9fa3d918, 0x0fd97d9a, 0xf53f425f, 0x44929f9f, 0x5e7d5271, 0x6129303e,
- 0x7c5a059c, 0x9ef7f817, 0xfd3d610f, 0x6ccddfec, 0x2ec7c00d, 0x6f782b40,
- 0x13335fd6, 0xa17d4133, 0x5ad05b56, 0xcfdd7146, 0x2a8edc4c, 0xd1071e62,
- 0xa1e53581, 0x4cc5d91d, 0x5d4f11d3, 0xb8c76dec, 0x329c3a10, 0x1667a4c9,
- 0x18ed1a36, 0xf50d7fb0, 0xf58c1bc5, 0x11333662, 0x7af149f5, 0x340bf333,
- 0xf7fbc33f, 0x7fe12a4d, 0x855eab31, 0xf9a4aaeb, 0x26540b23, 0x157c02a5,
- 0x6f3679bf, 0x4c5fc63e, 0xe3d10fdc, 0x38e24b23, 0x7ef1a5fc, 0x3fef0dd9,
- 0xf7771d69, 0x8b06488d, 0x89c6157f, 0x6d730c58, 0xfbf1fd65, 0x870fe16d,
- 0xfbaf5f57, 0x383469c5, 0xdb826dc4, 0x2f7f811f, 0xeba67c68, 0xd5445beb,
- 0x8ddc17e0, 0x21bf10f5, 0xb2e2d446, 0xee911322, 0x67d5aa5d, 0x14f7a18a,
- 0xb4edf7b7, 0xde80eab8, 0x0679373f, 0x4ec81389, 0xed2165c8, 0xd2f26e7e,
- 0xade14ef3, 0x995bb462, 0x3b45c814, 0xe218d614, 0x07e35953, 0x8b91ca31,
- 0x833b66f1, 0x6fe81475, 0x9fa0f841, 0xdb92f655, 0xbbc62e58, 0xbfa1de41,
- 0x87851cc7, 0x94dba805, 0x59fd8656, 0x7cf18c92, 0xaf58d39b, 0x1d207fc2,
- 0x3f8a3046, 0xc2908f45, 0xa86018f0, 0xe32eed0f, 0x84e851f3, 0x201fdd91,
- 0x8b10763e, 0x02556943, 0x26cf8c22, 0xfe7d9d49, 0x7bfa2656, 0x2f8a7e1c,
- 0x2ae5fb40, 0xc5a95f6f, 0x507f97cf, 0x12ee3830, 0x3ceaa8fa, 0x21419068,
- 0x7fbe3d75, 0x71fe625e, 0x3a6f41df, 0xd10d5561, 0xde4d739b, 0xd40f4869,
- 0x009f0893, 0x760d78e3, 0x2a1a9a60, 0xf8c20be7, 0x88e1aae3, 0x5dfd0667,
- 0x2ddef26e, 0xe387f426, 0xea4ffbaa, 0x4882ffd7, 0xfeeabcf3, 0xbfebf587,
- 0x15ff5232, 0x977979bf, 0xf4a9f80f, 0x803a4f57, 0x5267d999, 0xe80ba253,
- 0xc1b5be5e, 0xa9f97281, 0x5d2073e4, 0xd38bf33f, 0x16e7c923, 0xb74f9751,
- 0xff11e422, 0x7e9d1f10, 0xd03bd1e9, 0xd5b73aae, 0x607c52ac, 0x0160259b,
- 0x5d6caca6, 0x9b63e5c2, 0xafaf18e5, 0xb3f902fe, 0x2fa8cdaa, 0x32785f4a,
- 0x40cde311, 0x0e7fcd49, 0xb9507f90, 0x68852fe5, 0x5eb15577, 0xdfe17bd2,
- 0xe3e7f8e1, 0x2f981ec8, 0xaf7ff4c7, 0x6955f3ef, 0x7d6aa978, 0x84910bf4,
- 0xcdfc83a5, 0x9a25f6f0, 0x68a4ffbd, 0xdf38a78f, 0xf9113644, 0xf307c74c,
- 0xeebf7b73, 0x8f73a7c5, 0x5b9d3c01, 0xe421ddfe, 0xd727f284, 0x165a677b,
- 0xe735fcfe, 0x0dd4f2c0, 0xaed4317a, 0x6767d7d6, 0xeca7e69b, 0x39b965e1,
- 0xb03f40e0, 0xe5d9b37c, 0xfcbeba43, 0xc19e2ffc, 0x1607ccb8, 0xbfe870d7,
- 0xef83e5ec, 0xb2f500dd, 0xdbf8e61d, 0x211434f8, 0x2a974831, 0x6c62bbf8,
- 0xbfa50e90, 0x473b283e, 0x8e3fe7f1, 0x6ca3d20b, 0x8d993ec7, 0x298f8fea,
- 0x0ee4fb2d, 0x5a5d0225, 0x3fa2158e, 0x57e2f751, 0xcfafea32, 0xe0d8175e,
- 0xdcf8088c, 0x62ec907c, 0x51d113c4, 0xdd1f53a3, 0x0157dac2, 0xeabf505d,
- 0xff7f0a74, 0xc7fe9a2f, 0xc4399cfe, 0x86bcafcf, 0xb67f28fb, 0x25fe70b8,
- 0xc0e83caf, 0xaa929c79, 0xdb3f5f39, 0x7186e890, 0x44becc4b, 0xbcfe4a95,
- 0x121fb9e4, 0xf23e2dbf, 0x7f8a44c3, 0x89b27730, 0x325f056c, 0xa6d16fce,
- 0x62bf34d9, 0x2bbe25e6, 0xe0f45679, 0x8959e0fe, 0x4111df4d, 0xae24522e,
- 0x5b354f8f, 0xa7654d70, 0x7dc0e170, 0xff45b785, 0x2dff8a56, 0x0fcaf8a5,
- 0xb620fdf5, 0xad67ea8c, 0x885f4e9c, 0xac1abefa, 0xbafca13c, 0xd23b7565,
- 0xf710f4e7, 0x571b8c60, 0xe1a7c931, 0xfd08b843, 0x0da6478a, 0x4e61f4e6,
- 0x0efb4f29, 0x7c14fdf4, 0xcddbed8e, 0xe1ae5b6e, 0x2331763b, 0x6d72fe38,
- 0x0a3b807c, 0x8953d5ed, 0x9845ff60, 0xafa4a15f, 0x85576037, 0x7c8857f0,
- 0xf2df7973, 0x5d6f9708, 0xa633fdde, 0xbebffbe3, 0xbf07e5c3, 0xe0057b43,
- 0xf7a60c0a, 0xa40966fb, 0x102c2c0f, 0x98b7ae49, 0xbe36b935, 0xe004f9d7,
- 0xeddd7096, 0x3fec17e3, 0x764ff08e, 0xf87af16c, 0x565f442e, 0xfe8e78e1,
- 0xbb72e9fd, 0x04ff9358, 0x6cff28c9, 0x81fb9713, 0x8f1f09fd, 0xbffd984b,
- 0x15e50678, 0xaff713e4, 0x7b365fcb, 0x6f9fde70, 0xbddef03f, 0xb79fa720,
- 0xd46a72e8, 0x5a72e19f, 0x8b0273b2, 0x639fa724, 0x3924421a, 0xe511e785,
- 0x3e20e954, 0x4fe947fe, 0x85377f1d, 0x87d74fe1, 0x5c31e103, 0x7459fe1f,
- 0xf087d446, 0xd7961de7, 0xbe74ff9f, 0xf4adf9d3, 0x29431597, 0xa5f3a63e,
- 0x7c7d77ce, 0xbf5df3a9, 0x7f01a378, 0x182defe1, 0x3cb80183, 0x4714cdbb,
- 0xf7c3df28, 0x43bbe17f, 0x4f09e3a9, 0x58c65a6e, 0xf8d4a1d3, 0xac3fbad0,
- 0xded612de, 0x84f7561d, 0xd586f7b5, 0xcbed0dab, 0x3cc80edb, 0x686025af,
- 0x8678ae27, 0x1228327d, 0x5fb9fabf, 0xec85fada, 0x7a50be43, 0x4af37be9,
- 0x3c63b3e6, 0xf148af7c, 0xf1c01e91, 0x67a7182a, 0xf31f867b, 0x3c6c1a24,
- 0xf6a3d4ee, 0x6c5ed03a, 0xdef5e588, 0xea157904, 0xaf79fd3d, 0x7af5c78d,
- 0xd88ebd3c, 0xd8edfb10, 0x76f4911e, 0x8f4d9f87, 0x8ac267e4, 0xc1d47242,
- 0xe3cf7a06, 0x2544d3fd, 0x5fc6057d, 0x8617449a, 0xef6a8a74, 0x419e6071,
- 0x3bac9ecf, 0x45f3c0e7, 0x8db48a6f, 0x7b7683d8, 0x2dc7920c, 0x77f88725,
- 0x53df329f, 0xbf7e3193, 0x4579fb87, 0x11ecc36b, 0xa9f896b6, 0xa32e5958,
- 0xecbf053e, 0x82ff71b8, 0xd6a945cb, 0xe326c95f, 0xdc7bfd7b, 0xbdfb45c1,
- 0xbdf18b74, 0x34078b57, 0x863272eb, 0x71fcd18d, 0xf4d28f1e, 0xe73134f2,
- 0x8f4039ce, 0xc322c39e, 0x7b33fbfd, 0x99c7a244, 0x9ebf7ced, 0x23d7f6e2,
- 0x3e92f77f, 0x89d4f1d4, 0xac0f24f2, 0xfd5f3aaf, 0x9187bcaf, 0x987d766f,
- 0x3b2833fb, 0xfd907d77, 0xe6ffac5b, 0x590ff4fd, 0x5e53f6ff, 0x493ed1b7,
- 0xe276ebcf, 0x7fbd9ef7, 0xeb187f4c, 0x9f142dbb, 0xabfd79ee, 0x9e9fe45c,
- 0xd4129695, 0x80433d77, 0xec1f68fe, 0x83b72afd, 0xa27ad7d6, 0x99251fdb,
- 0xfe7b47db, 0x8f10b1f6, 0xed0acc25, 0x49a3d786, 0xb35eaa9e, 0x67ad3c51,
- 0xa17957ef, 0x9d77ff76, 0x7fb6a54f, 0x736763d9, 0xb17c2276, 0xeaa7df7c,
- 0x5f3fd7b7, 0xad17f98b, 0xf085e4fb, 0xbeefca7e, 0xda3d45c9, 0x43db93b3,
- 0xe78ee6dd, 0x68ee7f70, 0x6695dcfd, 0x0a3773c0, 0x9bac0a55, 0xa014cf0d,
- 0xcbc7f4dc, 0xbc271437, 0xfcf47c52, 0xc10f835f, 0xdd9df5cd, 0xde70156f,
- 0x21fc7f5f, 0x2dd785ea, 0x7cfa97c4, 0x25a96f3f, 0xf372e57b, 0x9c799876,
- 0x799dffe4, 0x992b810b, 0x3ff328f7, 0x2d7fbd37, 0xe12e8939, 0xcf9fd072,
- 0xf5443ef7, 0x822eed97, 0xfdf90af7, 0xf9f27ff6, 0xefba6b7f, 0x2e3bba04,
- 0x7ff2ef3f, 0x4c0f79f2, 0xd7ef37f7, 0x7e62aee8, 0xbeefd54b, 0xadbef821,
- 0x4ffb5b9e, 0xcd03ef2e, 0xd7ebb75f, 0x994d5c98, 0xaf439f18, 0xc569d601,
- 0xc311b33e, 0xcc466b85, 0x14ced154, 0xf52bf6c3, 0xfb99af72, 0x5bee224d,
- 0x086f9c62, 0xcd31f38f, 0x3d2da28f, 0x8a525a18, 0x94958ec9, 0x96bedc55,
- 0xc06eed5c, 0x176b9acb, 0x887728b8, 0xc5ea3d8d, 0x1764da7a, 0xfcc3afc5,
- 0xb9817ac9, 0xa56fb005, 0x8c396f6b, 0x84798dfe, 0xa5c96029, 0xab9618f2,
- 0x59a4b8b5, 0x8f7e0d95, 0xdbac6392, 0x45bac69c, 0x38cacfeb, 0xe624d6fc,
- 0x38b4f8c7, 0x798abf72, 0x8918e26d, 0xb1b75009, 0x17fa1f26, 0xf7e32496,
- 0x1ec0311b, 0x5abdcf12, 0xe1f6f63c, 0x1bbb6c71, 0x44d238f1, 0x2e4a6b71,
- 0xfcb8bc25, 0x8d9e786b, 0x55d788d5, 0x094f88ed, 0x7f6e5ffd, 0x34ccdf91,
- 0xbad2597f, 0xdc984690, 0xcd3b6336, 0x9d2cbe4f, 0xcbd25d38, 0x332d3a35,
- 0x43a745d0, 0xe818fa04, 0xdbf9e3a2, 0x2e9c27d2, 0x6fdff8e1, 0x07fe1276,
- 0x974e97a2, 0x50cdc534, 0xbf9acd5e, 0x49fd1530, 0x1879a7ac, 0xfe6b33ed,
- 0x66ef1482, 0xea93a43e, 0xf42f4862, 0xb7e002db, 0xf3fb7efd, 0x7aea2714,
- 0x081dd8e9, 0x456fd94f, 0x75fc0566, 0x00b3b76f, 0x65f92f7e, 0x5b4b43f4,
- 0x33fb8a45, 0x57779029, 0x6eafbec8, 0xcafd97f7, 0xdd29f34e, 0x06dff169,
- 0xfaee97df, 0xb0ec9724, 0xd7e4bd95, 0x38125ef8, 0xb91d7ddd, 0x2a5bafb8,
- 0x9c23ff71, 0x9e65625f, 0x3bb9d027, 0x6dc60e7a, 0xdf3c6d84, 0x1ee5b4b6,
- 0x7f90c5b3, 0x91dbd666, 0x28bdf05e, 0xc213be50, 0xa9e79a17, 0x2f9d1dfb,
- 0x36be1c0a, 0x76f31fb3, 0xe8edb74b, 0xe953f8c6, 0xc30b8b51, 0xbedb55d2,
- 0x298dfda0, 0xd1d97abf, 0x68b6fe41, 0xf3f43f88, 0xc489b7fb, 0x15ad951f,
- 0x9d4087e4, 0x25b2a2f8, 0x72ebfc72, 0xafd969fe, 0x01f2eef6, 0xfd7ecb0a,
- 0x5be30382, 0x3ab7dba7, 0x76dfffc8, 0x3f5bb8e9, 0x91e5bf3f, 0xa7f9fa4b,
- 0xbfe01ff1, 0xc58720dc, 0x220db649, 0xcbe0047f, 0xadef948b, 0xcbd95bf3,
- 0x38c39f67, 0xcfcee774, 0xcb78439f, 0xe7cbfbff, 0xaf609fd0, 0x88add4db,
- 0xa5de9797, 0xddfe9e38, 0x9dc7992c, 0x817c5fbb, 0x1fdd9fe2, 0x7f01df80,
- 0x4a9ef7ba, 0x7bb27f47, 0x1889d7c7, 0x77be592f, 0xef9c60da, 0x0ca757f2,
- 0x88f41166, 0xfadf225e, 0x1afe20af, 0xad03af4e, 0xe9efc807, 0xdfa37a02,
- 0x69b717d9, 0x3071e0a9, 0xd9af16a7, 0xddce391e, 0x7ad33e2f, 0x8d379dd7,
- 0x72ecd2c7, 0xd3882bb2, 0x1c7403bc, 0xdbf4057d, 0x7fe688fe, 0x175fa646,
- 0xb4e803fe, 0x677e8c2c, 0xfcfd175b, 0x3ad77c19, 0x4d38c068, 0xa6f00ae0,
- 0x27bfd1c7, 0xa3227fbb, 0x25fced7c, 0x6e90c5c5, 0xbb44c1b7, 0x8e9b3e5f,
- 0x9a9f0ffb, 0xe7e7ef7b, 0xc62a2c32, 0xbef74a1b, 0xfdd3f24f, 0x538a11ea,
- 0xdd9e2d33, 0xf0fefacd, 0x5396a3f8, 0xcec5b559, 0xfe1a3be3, 0x74e3fe31,
- 0xce2d73d0, 0x8f58f9c3, 0xf7140cff, 0xde799569, 0xafdf1e88, 0x16a1f2d8,
- 0x4bd2094f, 0x3a748498, 0x08fdc976, 0xe22a0f1d, 0x1c686261, 0xad7c7233,
- 0xd1adde2f, 0xf187e90b, 0x2538becb, 0x6e30d3d4, 0x67de17e5, 0xf741f411,
- 0xecff1e66, 0xa3ce4736, 0xbf9ae3d2, 0xff53970a, 0x2f33c595, 0xc5b7ff07,
- 0x52765f8f, 0xea78e1bf, 0x8f5910bc, 0x75f32dbf, 0xc5f7aaff, 0xbe4305ca,
- 0x7bc9b941, 0xa2b1f904, 0xcfcc98f5, 0x52f3f0a5, 0xb53b7cfa, 0x97ced1bc,
- 0xad778a44, 0x7a40396a, 0xe85f5c3c, 0xf0e1a6fb, 0xade0d09e, 0x44ebe36c,
- 0x5fbb4ee7, 0xf73a7e81, 0xae7e26ef, 0xe28c7edc, 0xfdb6876d, 0x5908ee5a,
- 0xf09d7157, 0xf9dfc087, 0x1e5cbeca, 0xec79e5b7, 0xd19ce3e1, 0x9ed561f4,
- 0x6d54e3c8, 0x4e30c2ff, 0xe645af99, 0xc7a5fdeb, 0xefb92d3b, 0xb74efec1,
- 0x79e6199b, 0xa7116e9e, 0xf5173a47, 0xea6eb6ae, 0xbd707ee7, 0x23fd7ca4,
- 0xf8cc5cfc, 0x1f28a3b7, 0xe991f97e, 0x63c4c61f, 0xfe878409, 0x9f396b5a,
- 0x9dc4feb6, 0x3d6ef48a, 0xeb88af72, 0x6fc42ed4, 0xf79f9d88, 0x3b14f54e,
- 0x8fbc85e8, 0x5d91e33c, 0xc4cdf5c3, 0xfc0326a3, 0x5c60ce30, 0x1fa1ea07,
- 0xf982a73c, 0xe88f086e, 0xf08e9c28, 0xb549aa88, 0x61e7fd09, 0x5e743c56,
- 0xacd7ef40, 0xb003cf1a, 0xd89ce30b, 0x1e4cd24f, 0x8bbe4c47, 0x3cfd3e97,
- 0xbf94714e, 0xa059e60e, 0xf02cd378, 0x7d7d927d, 0xe78641c6, 0xde5126bf,
- 0x78c59676, 0x554bac6e, 0xdfd0267c, 0x596ce4cf, 0xf949d937, 0x4258d707,
- 0x20580ff3, 0x6f51f917, 0x587defd7, 0x7e1a427e, 0x1a88fd02, 0x7e5a597c,
- 0x21d610c2, 0xc9bd7da0, 0x0e27cfce, 0xf84de255, 0xbd9af3fd, 0xec3f9fa9,
- 0xec315e77, 0xcee5e29c, 0xc94fc627, 0x05d43a5f, 0xcf7ab4fc, 0x8f5fcc14,
- 0x477f27bf, 0x12798aaa, 0xe7829e7f, 0xc85fe257, 0xf50c931f, 0x9c1fab13,
- 0xc8fff54a, 0xf50e931f, 0x8dff1a6f, 0xca04cbd7, 0x3d582d57, 0xebf22a7a,
- 0x2cf9cb55, 0xce5188c0, 0x75bc40ef, 0x7bba3e79, 0x1ff31391, 0x5f8e657a,
- 0x4376c1e6, 0xa5bc7126, 0x40ed1f29, 0x75350d3c, 0xfe7f22d4, 0xb157ef7c,
- 0x4c9c17a8, 0xaca8fc25, 0xc1fa455e, 0x2f1749a3, 0x9e174791, 0x93eba64f,
- 0x01f78acd, 0xf991e384, 0xe05ce823, 0xad332533, 0x98cf5f3c, 0x78d4c0c7,
- 0x469167a2, 0x1ad3844f, 0x58bf8f92, 0x5cfcc9f4, 0xafa6934c, 0x9e38aaa6,
- 0x2f172be0, 0xe1edf75e, 0x4be7507a, 0xc8695ced, 0x1087c679, 0x7de29f5e,
- 0xffd092c8, 0x161de33c, 0x9f7c0acf, 0x1d3e7c5c, 0x9f3f5bf9, 0x91ce7e18,
- 0x48a6bd49, 0x76b35ff6, 0x782071ce, 0x2aef563d, 0x77f3371c, 0x41879dce,
- 0xc91746be, 0x1ccd4c2e, 0x827c62bd, 0x5215cfc4, 0x4695439e, 0x971324bf,
- 0xa310f643, 0x8b1ed67d, 0xb9bf46e0, 0xf49541e7, 0x6dd15a77, 0x44f557e4,
- 0x3e60b467, 0xfcc3cf50, 0x4c66295c, 0xd90d1ca3, 0xbf401313, 0x5ce0e40f,
- 0x339c1c98, 0x71c673ae, 0xdb3a2e7b, 0x553fa83a, 0xb00c0feb, 0xe0b9e0c4,
- 0xe5eb911e, 0xc1271a9e, 0xf6f98431, 0xa57efae1, 0x18b56de3, 0xde02fdcf,
- 0xe8bc405f, 0xc0e5ff78, 0xa3457bf4, 0xe8912bdf, 0x74fe7e17, 0x6bfbc5be,
- 0xf8aa7f6c, 0x15742ad0, 0x869dcfc3, 0x6a4ab5d3, 0x78ae88da, 0x682f9ee2,
- 0x36e9d19d, 0x412b857a, 0xe3a0641a, 0xe8efd8eb, 0x10985f3d, 0x4f7e9d5e,
- 0xfdef900f, 0xcf5f0b07, 0x9c4bc7c2, 0x8de291d3, 0x1060feb4, 0xcf58212e,
- 0xf8d1e6b5, 0xde3c4d83, 0x10bdbfd3, 0x7fd03e71, 0x30f2a5e6, 0x2fde5573,
- 0x50fdffe0, 0xf110ffbe, 0xfe22223f, 0x03bc463f, 0xf6c63ffe, 0x4fff8057,
- 0xdd7f852e, 0xf4d32fae, 0x2bee1942, 0xc5fcff01, 0x13313339, 0x15142dc6,
- 0x5b25ffe2, 0xd21f6d45, 0x62725b7d, 0xb92c8f50, 0x199f7abe, 0xb3c970f8,
- 0x9169f102, 0x73fd5e76, 0x784b5ced, 0x1cf15f5e, 0xcbc9e91f, 0x49f9f7e7,
- 0x336d950f, 0xe410bf3e, 0xc7ca74db, 0x93f3f1f5, 0xe11726a2, 0x68a33ff8,
- 0xd628a2fa, 0x0e9c2ed0, 0x864daa43, 0x29e4f03c, 0x9f90fd7d, 0xbe726497,
- 0x3fb5f14f, 0x07c61998, 0xf8fc52dc, 0xbc63e200, 0xcdfb1530, 0xef56e4d7,
- 0xe30ae86f, 0x33e19f3a, 0x6acbfb9e, 0x1bfb9e34, 0x686294de, 0x4c86cd7f,
- 0xfe91fbc3, 0xafef0d6b, 0x50d636db, 0x8372d51f, 0xb6e8fda1, 0x4c7d4302,
- 0xfb4316e0, 0x1a678771, 0xefda13ea, 0x789fb435, 0xfde18174, 0x86a51df5,
- 0xba7e37f7, 0xa9bf50cc, 0xed0d5ff7, 0x5eb88b03, 0x94935fdc, 0x740ae786,
- 0x2a5fecbc, 0xbe7c549b, 0xe6a4db34, 0x744f3e86, 0xccb1733b, 0x357fa373,
- 0xb14cbc90, 0xae85a726, 0x6cccf9cf, 0xac536bd0, 0x55817ac6, 0xe07497e3,
- 0xcdfe2017, 0xa55ca356, 0x026bcf56, 0x2ca59bb3, 0xd2f94619, 0x58b75f20,
- 0xc5bb7eb9, 0xedfa657a, 0xaa7f6c4e, 0xece74032, 0x444be5c3, 0xd2a2caf9,
- 0xcca9fb47, 0x1b96f945, 0x4d3e466d, 0xccaf401a, 0xc3cf1ab3, 0x9b61ea8b,
- 0xfd139064, 0xd0a8f9f9, 0xdbe2c2e7, 0xa0676f28, 0x05a4e57e, 0x7d016eb7,
- 0xa97b2729, 0x9aaf9fd4, 0x97988a63, 0x3bf590f7, 0xfa1b49fa, 0x210f4fd9,
- 0xde92bb7e, 0xccf30a7e, 0x92f5e72a, 0x316c94bf, 0x775825e2, 0x5479e60d,
- 0x508e7e4e, 0x54dcffe5, 0xae2b78d3, 0x173cfaf7, 0x1133307d, 0x06d203f3,
- 0xd55e9ff0, 0x4d5cf1e6, 0xc345adc9, 0x14d53fb0, 0x7a45bf7a, 0xfd10aaa0,
- 0x1e5aa198, 0xc8a653f4, 0xd53f4af9, 0x0a8c19fa, 0x5503ed14, 0xaba0fb21,
- 0x048723f8, 0x9377f8f3, 0x17c8a7f7, 0xe7b7460b, 0x6ecb73f1, 0xabb24cd7,
- 0xd75f8254, 0xe78ae943, 0xe92bd429, 0x66731249, 0xf06787f4, 0x06636f3c,
- 0x338fafbc, 0xf7aa14b9, 0xe59e380a, 0x820d8cc7, 0x5bffeaf1, 0xf7eaf824,
- 0x3cf94f5f, 0xe29aa516, 0x993cfaa7, 0xc7afdfb6, 0xcd26cf8b, 0xd63c418a,
- 0x6e77db5f, 0xacfd6187, 0x7ec76de2, 0xd337aecf, 0x8205f5b8, 0x6f3ebde1,
- 0x741dc369, 0xe15d2b1e, 0x79862ef3, 0x3496dc23, 0x73fd570e, 0xb8234b02,
- 0x43d2f7fe, 0x8aecbfe8, 0x0dbc6176, 0xe889b1f0, 0x6738ceed, 0xf30f27d2,
- 0x34a418aa, 0x25fb21af, 0x96fa1fb2, 0x4cdbaf95, 0xf688959d, 0x4635f254,
- 0x66f5c5b8, 0xc51707f2, 0xe0af942a, 0xd1a159af, 0x55ef38d5, 0x9cef3349,
- 0xbdd4f00b, 0xfd4c3223, 0x2d347671, 0x15df043d, 0xfcbb46b7, 0xef78fece,
- 0x01387272, 0x6e10b7ee, 0xcd214371, 0xdc21da9b, 0x33d8173f, 0xde77c819,
- 0x14ff44e9, 0x977dc313, 0xd3fff870, 0xefc4e3ca, 0x879a5558, 0xeb7c549c,
- 0x16584196, 0xb51ddc91, 0x7fceb80e, 0xfcebe568, 0xeb08d687, 0xfdeee5fc,
- 0x7ed39f28, 0x6dd14b08, 0xeadaecd2, 0x197b50ec, 0xec49d6f4, 0x318baf57,
- 0x7ec5ce3f, 0x3ccbb607, 0x9719d94d, 0x1ed0cbb7, 0xedd3fe43, 0x8d5abfb1,
- 0x9e886476, 0xb3d34afd, 0x9ea15d5f, 0x4eed80bd, 0x68881bdd, 0x91c824c7,
- 0x1b38dcf5, 0x2a957fc7, 0x1be3ca33, 0x6d9f9e20, 0x0e1f6c8b, 0xce5d0eb4,
- 0xd68cc8cf, 0xefd754f9, 0xc560dfdc, 0x9c2fed32, 0x247fe0d9, 0xe329f71b,
- 0xedde5187, 0xaea4fd40, 0xf10d83f8, 0x886de3ab, 0xc04f88cd, 0xf9c6d3a3,
- 0x648b69c4, 0x1e03960f, 0x0e3c064d, 0xd903f6c7, 0xdfad5783, 0x6ee78c4b,
- 0x837c35ba, 0xbc71979e, 0xce3ebbae, 0xe545b8c3, 0xe7a473ec, 0x399c7aaf,
- 0xf74475c6, 0x011c61bf, 0xd77ddfe7, 0xb7716b7f, 0xd5178a0e, 0x0c4d7abd,
- 0x0a2aa7c6, 0x9586f4fa, 0xa49985db, 0x5976bb07, 0x576708dc, 0xece7cf1c,
- 0x10f135da, 0xaf3e39c6, 0x85299c39, 0xaf5d2dd8, 0x4333c91c, 0x8f3b5d7f,
- 0x209449e4, 0xd17e27e7, 0xfc5c57df, 0x128f3ccf, 0xc7d0273c, 0x0ebe566f,
- 0xf8f1b7ad, 0xc798d3c9, 0xf7b19a36, 0xfaf963a3, 0x1c7a6891, 0xe3bf479f,
- 0x7f7ea1f3, 0xc7e57054, 0xdd262b00, 0xab664c55, 0x00a68de5, 0x6e0a8f96,
- 0xbe55e311, 0x4d3cfc91, 0x911b1652, 0x4728fd01, 0x8e0803db, 0x8dd7a3a3,
- 0xa7ea29db, 0x0b2c3eea, 0xc402ef14, 0x2baf5c7b, 0x37fc7d09, 0xa1b38d87,
- 0xe14d215f, 0x7e77b77a, 0x29ef1f94, 0x8fb9344a, 0x6767aa80, 0xc58c2f0e,
- 0xe68b7ff7, 0xd258f2f2, 0x8e5c2689, 0x38a03970, 0x5a669bd4, 0x710d96df,
- 0xef822f27, 0xe7884d97, 0x9805e97e, 0x9639c87d, 0x0967e3c7, 0x00b90714,
- 0x14e78178, 0xb53e02fa, 0x3317cc4b, 0x89b0f416, 0x0bf055b9, 0xee4293ec,
- 0x68ffc1d9, 0x4d60fc76, 0x4d38f6ff, 0x45e0333e, 0xd5db1976, 0x5c0cee09,
- 0xfc81774f, 0xb4fa030d, 0x7ca958d5, 0x184d46ad, 0xa7b8f206, 0xafea8926,
- 0x0ca938d7, 0xe7a08cd4, 0x545c6bfb, 0xa7b5368f, 0x552c7ad3, 0xfe879baf,
- 0x0b12fdf5, 0xbc23b7bd, 0x8e567bc4, 0x97f9c887, 0x0093e62e, 0x3d352fae,
- 0x38d6fb52, 0xc6a7afe2, 0xfd31d400, 0x8ad9ffbf, 0x054d643f, 0xa3fa983d,
- 0x415359c3, 0x78129f8e, 0x181e02fe, 0x552e748e, 0xb7329f2f, 0xf0a9a2c4,
- 0x4df31b6b, 0xc8bcc24d, 0x8e153fde, 0xe8f6cc61, 0x1d4ea69f, 0xfdc7f309,
- 0xf6c614fe, 0xc7abdeda, 0xfba9d873, 0x818bab3f, 0xfc6dc8f9, 0x82899f3e,
- 0x7d4056a7, 0x0bf39b33, 0x98b53c93, 0x3773d9cf, 0xbefee273, 0x1b5ece3e,
- 0xdb7613b7, 0x51399db8, 0xe6c1fce0, 0x411e5aca, 0xbae86e6f, 0xef3ede11,
- 0x8f74d7c0, 0x2fb78c0f, 0x2f5e30d5, 0xfa0711c5, 0xd7ff752e, 0xe95c8eb4,
- 0x491f3d77, 0xc4847cfc, 0xe6ba2bf3, 0xfda66e26, 0xba1f6878, 0x4723da8f,
- 0xd2ded7b6, 0xed0681d6, 0x659fb7be, 0xa68372f0, 0xf5c62457, 0x05d16bff,
- 0x61b947bf, 0x5fda38de, 0x09e2d3aa, 0xe57a3a93, 0x2f7e76f9, 0x13d43e5c,
- 0x3c04784e, 0xd1a5d70f, 0x1e605533, 0x6048ffcc, 0x28028433, 0xdbcf36dd,
- 0xc2d24fd8, 0xd197be4d, 0x7165d85e, 0xe3a3d9a2, 0xd903eeab, 0x6121fa8a,
- 0x8fda31cf, 0x643a13aa, 0x8f97f7a4, 0xcb714d7c, 0x3275733a, 0x1b176dd5,
- 0xbdb4feb0, 0x99d6237a, 0x6fa9ebef, 0xd60c3f00, 0x13e3e1ce, 0x90bb63d4,
- 0x3b5829e8, 0x7e06ef57, 0xf5e665d8, 0x4b391f2f, 0x5ccbb1fc, 0xe18d9f3d,
- 0xef987af5, 0xaa6f58ae, 0x52905409, 0xe1fd65fb, 0xb7aeb09b, 0x77da92ff,
- 0x3f6e54db, 0xa40cde2a, 0x855d5f7f, 0x2ea43dba, 0xf2b33af1, 0xc55f9f52,
- 0x7f29af81, 0xe70f72b8, 0xce1bc447, 0xc3cdef13, 0x7a8ce975, 0xa4eb51d4,
- 0xd73673b8, 0x9f0301d7, 0xb753e7e9, 0x2a2cbc98, 0x085ecf44, 0xce42ff5b,
- 0x84a8b1d9, 0x38b4fe90, 0xbb033a76, 0x6f182b34, 0x2a2e64cd, 0x950f3187,
- 0xee96dbd9, 0xbb2db447, 0x7a89d5af, 0xfad73e2b, 0x68e89780, 0xd09e1ff4,
- 0xe8fae2f4, 0x01a31bfc, 0x7782f59e, 0xf17a888d, 0xe74ab365, 0xb2243a2f,
- 0x35b53b37, 0x5330ad8c, 0xf73b5cbd, 0x5de95e6d, 0xeef51233, 0x19ab9322,
- 0x4f0cb3d7, 0x2fbe19be, 0xaae19ddb, 0xe7bcc165, 0xc496d8b2, 0xef304ab1,
- 0xaa3faf59, 0xb546d9f1, 0xd2f786c9, 0x9543fbe8, 0x71d2eb6d, 0x7db3fb7f,
- 0xbd3c901f, 0x7c41951f, 0x447ad15c, 0xbf69daf6, 0x29f3c64c, 0xd6fad99f,
- 0xbef75a3f, 0x0b74196c, 0xeb2ff5ea, 0x79b8744d, 0x06f43d20, 0x38373fe8,
- 0xac6a87c8, 0x5dc2fe54, 0xde9a2d7d, 0xd3295105, 0xbfb4606c, 0x9156e990,
- 0xb9ade68f, 0x7c0ac1a6, 0x8eac82f4, 0x179b3e44, 0x5b7c4b95, 0xbe722b16,
- 0xdd07b964, 0x0dcfb692, 0x6535d4f5, 0x3c53bed3, 0x6f68c8be, 0x88526d54,
- 0xc80ec00f, 0xdca83e47, 0x7ee1f260, 0x4edac9a2, 0x45e77de7, 0x368fcd31,
- 0xaf5c4f9e, 0x6cdf3be9, 0xdcbddf1e, 0xf392c539, 0x511e7451, 0xe51fbfaf,
- 0x9128be24, 0x55ffb47c, 0xe741de72, 0x38fbbf18, 0xc879c356, 0x0428e3fe,
- 0x794e3e87, 0x57d21c70, 0x27ec1fe5, 0x6b8df83f, 0x4dd67b75, 0x3be5ac71,
- 0x9b05fcb4, 0xf3f6307b, 0x1827a6b4, 0x7780b1fa, 0xeeafa329, 0x1ccf4093,
- 0xf933d3ec, 0x90d3530d, 0x6cf7c1be, 0xb90f4192, 0xc1d3a025, 0xfbeead28,
- 0x51f6e47e, 0xf533ed61, 0xa986ccfa, 0xf3c3fb93, 0xb7582db4, 0x1be97b42,
- 0xe11d5f4b, 0xa1f573a3, 0xe3e9c5fd, 0xe9fd4bdf, 0xb51a97fc, 0xf80fa0f0,
- 0x27ac60ef, 0x7a7cf31f, 0xca273367, 0x8d4966e1, 0x21d08572, 0x37af8a35,
- 0x35afe725, 0xf7883fe0, 0x4ffd035c, 0xfb0d38d5, 0x968b8b8a, 0x549879d1,
- 0xc7cc5e9d, 0xca6d77cf, 0xfe27ec32, 0x16ae387f, 0x7000f70e, 0xc307fd4c,
- 0x5e30c231, 0x031c8e10, 0x870b577c, 0x7a6b3b18, 0x8f6bda06, 0x280f2898,
- 0x66b3e4d1, 0x6ff65da2, 0x0ca78a26, 0x880f3c67, 0xfb0de329, 0x2c7b99b4,
- 0x9efe31f3, 0xd2c3b129, 0xb7279458, 0xa9d716b3, 0x5f64489f, 0x39ab73c1,
- 0x726e870e, 0x204ffde3, 0x665fd495, 0x1f82b7b9, 0x82fbe6f2, 0x70d33efa,
- 0xbde3e595, 0xe7a39ba0, 0xfb8d18df, 0xaa1e7366, 0xe7983cc2, 0x352ff195,
- 0x92bc8330, 0x2c20d21d, 0xabe33b25, 0x701b87a8, 0x147076bf, 0xf6045bb7,
- 0xe4e1c370, 0xbcb9ef48, 0xf0f35b9e, 0x341b8c34, 0x8b5e74af, 0xcdb353fe,
- 0xf31fb2df, 0xe8531e76, 0x47acd6de, 0x50998dfd, 0x6899d717, 0xfd6314bd,
- 0xdf719adb, 0x176cc9fd, 0x68cd11da, 0x47fb60bf, 0x566bf214, 0xf0d338d5,
- 0x6d3a927e, 0x76b2d81d, 0xc1798ab2, 0x87148af5, 0x732addeb, 0x773c5cf5,
- 0x8dd1ee31, 0x51ebd60d, 0x071ab98f, 0x949ebca9, 0x339aeb8c, 0x7b463ad3,
- 0xae68c80f, 0xb1a8a675, 0x6ff0fac1, 0x3d20fac0, 0x9dc1b1b3, 0x2b2efd86,
- 0x883bfad5, 0xe2178a71, 0xef68bc34, 0xd2f4fb33, 0xcbcc06c6, 0xf5836b12,
- 0xaddf30a9, 0x353d72cf, 0xfb47fa18, 0xc3e3e60b, 0x877b057b, 0xca4e744b,
- 0x603b6306, 0x9991b67e, 0x0cd7dfb4, 0x2bef117a, 0xdfc91dee, 0xf234fbeb,
- 0xd3ed1370, 0x6f5c7b60, 0xbdbcc96c, 0x57df833c, 0x8a15db20, 0x307ac037,
- 0x149ef315, 0xf371ffa6, 0x8fb6a4b8, 0x01f78511, 0x75a3f084, 0xf73a32ed,
- 0xdc661d69, 0x8cd3979f, 0x16798975, 0xaa27bfa0, 0x4637e7c6, 0x8341f96b,
- 0x6dda0a58, 0x133e4dc3, 0xfcc91bb6, 0x02c75e54, 0x628d8f64, 0x8d1f541d,
- 0x1e16635e, 0x41d2725b, 0x2dcc71ab, 0x47aa38f2, 0x71313b44, 0xf2471eae,
- 0x74be414e, 0x61766b47, 0x7e3fef0a, 0xf7ca2cc6, 0xcdef69f5, 0x313d8633,
- 0x7eb5e60d, 0x50ceddc6, 0x2f5f4efb, 0x48adfb75, 0x68cbf983, 0xa0bda221,
- 0x364575db, 0xe5984f5e, 0xc6147a7e, 0x26cddb11, 0x58ad9fbc, 0x6f16638b,
- 0xbb444fc8, 0x5cdf68ac, 0x44d787b2, 0xd16cbb73, 0x77b219fa, 0x9af79e14,
- 0xfe7f764f, 0x183109ba, 0xb9b06fa7, 0xfe47ae62, 0xdfbf23fd, 0xb1ed4af5,
- 0x0a6bc4e6, 0xc19b1e50, 0x8ffbc6af, 0xcadd9a0e, 0x758be418, 0x6ccec8c3,
- 0xc7d6f28e, 0xffcdbf42, 0x41d574ea, 0xf73667fd, 0x4e3823f8, 0x8f7f1443,
- 0x6f2126f7, 0x3ff7edf6, 0x1e8c5c2f, 0xfdf0fc78, 0x91b183fe, 0x43bdf1ef,
- 0xfed05fc3, 0xd9dd90f0, 0xdcc4f660, 0xcbbdf087, 0xead679e7, 0x112f5189,
- 0x86b4fb67, 0xd67603e7, 0xe64058b8, 0xbd62d1f7, 0xdd3f68a4, 0x22d25caf,
- 0x097cdc50, 0x3a3d226b, 0xeed5894c, 0xc5e631a7, 0x4dbd1696, 0x795b4bed,
- 0x42d632fb, 0xe17a75ed, 0x8301b5bd, 0xf0ce3a1d, 0xdcd11dfd, 0x78acdd6f,
- 0xfffb431f, 0xc4d91991, 0x1167c04f, 0x07e22df3, 0x31b977d8, 0x371faf9a,
- 0xf6c8db62, 0xb863f128, 0xe05cb87d, 0xc207b3e7, 0x9379d553, 0xde0a3d61,
- 0x7ad3219f, 0x49f9add4, 0xeb7c9387, 0x7ff9846f, 0x244af59f, 0x23bddaa7,
- 0x425f8275, 0x33befaf9, 0x2d1bdeec, 0xa6ba680f, 0xcb43fe25, 0x6b3ef9ef,
- 0xfd0dc379, 0xf402cedc, 0x9eed61dd, 0x48a41412, 0xafd01979, 0x3adc1f41,
- 0xddbf58c2, 0x39dfac65, 0x7d3df229, 0xb4d46b6b, 0xd6aa7bd0, 0xf38e700e,
- 0x575e8d2d, 0x0b12df7f, 0x0b7bebcf, 0xf9815ee9, 0xc17fb494, 0x1b14faf3,
- 0xd91ea0f3, 0xfb46cfbf, 0xbc8a5521, 0x55164319, 0xbde2efe0, 0x9f9d8af0,
- 0x17ff4037, 0x998a05e3, 0x97de0fb7, 0x1251f7c4, 0x3c5a493c, 0x633495c3,
- 0x1b87b7d4, 0x0bca2afd, 0xdc46d896, 0x27e60d77, 0xe8edef1a, 0x0f38fe8a,
- 0xcf9863fd, 0xe84f8c6c, 0x3e7d5a71, 0x2c7f28ff, 0x39cfbb5a, 0x346b6e9c,
- 0xa30ba8f9, 0x39d23d73, 0xb973df07, 0x87bb52f9, 0x43c129ff, 0x26896879,
- 0xb3ac171e, 0x9c528eb9, 0xea0ff344, 0xf306b8b4, 0x56ef5d7d, 0x1095ecc2,
- 0xed7d22ff, 0x39f5f5d7, 0x38f377e4, 0x156a2d88, 0x360dc3ae, 0xfaa66ebd,
- 0x00a6e6d3, 0x5aaffdf9, 0x831f189c, 0x6718ddef, 0x411dcdf3, 0x065d5d7e,
- 0x0e7bc14b, 0xb4cbb0de, 0x6abdd6fe, 0xd8f5c669, 0xdb76f36d, 0xba49f242,
- 0xf9d1efec, 0xf9fd08a6, 0xf90dfd0c, 0xf8c1fd76, 0xfd7788ad, 0xa7f61bfd,
- 0xceff2202, 0x691bf949, 0xa17b1fed, 0x42cbb89e, 0xf7fd4f71, 0xe7cfca0f,
- 0x7a8cfdd1, 0x4e14137f, 0xd51ace87, 0x8e5d8f90, 0xe507377a, 0x67f49da0,
- 0x8320cb45, 0x69f5d4de, 0x681bf9c5, 0x57482cbf, 0xb5212e2d, 0x38aa5e93,
- 0xbc68bfff, 0x349e903b, 0xf7e9124e, 0x3549c781, 0x38e0e3e8, 0xf7700c93,
- 0xc132671f, 0xdac38fa1, 0x9fe70ca2, 0xae3ccceb, 0x33986672, 0x1e823626,
- 0x83714bd1, 0x60ff70c9, 0x62b2e49d, 0x4eca75ff, 0x287f3435, 0xef005f7c,
- 0xf02164c5, 0x867ac1d5, 0xf30b72c1, 0x3d405e52, 0x072213f6, 0x62a5d9a2,
- 0xf8c262bf, 0xc62ef9e9, 0xbdb945fe, 0x33727d10, 0x8bd82df2, 0x7e3b583f,
- 0x49ec0f95, 0x4769ecc9, 0x93764aba, 0x6b68f313, 0x45c51315, 0x64ac92eb,
- 0xca12adff, 0xbd739455, 0x2243a95f, 0x8f7df438, 0x9f29e681, 0xc33cd077,
- 0x9ffb3bef, 0x76a14f1b, 0x3b57eefd, 0x0f93d730, 0x93545bfd, 0x4e5d450b,
- 0x2127d853, 0x47ef0ff4, 0xec4520da, 0x8e9dbc27, 0x6ce901ff, 0x3d2070ee,
- 0x88a5e3ba, 0x951b1079, 0x310798ef, 0x271f4c2f, 0xe00ecd1c, 0x238742f7,
- 0xe5f48323, 0xa5f50546, 0xdc9fccfd, 0xb4cbd24e, 0x7fafadef, 0x56a984e6,
- 0xbc6c4f9e, 0xfe206f57, 0x7d62f1d3, 0xf3c641f3, 0x7f94bd53, 0x483c3972,
- 0xfb43cb82, 0xe2297600, 0x425836be, 0x4938fc86, 0x354fe631, 0x63e21e48,
- 0x56d54df3, 0x5b4927da, 0x927dc569, 0x063392d5, 0x37ded8fd, 0xf983fec1,
- 0xbe793a35, 0x6bff786a, 0xb4661ef0, 0xc4531573, 0x06a379fb, 0x34baafb0,
- 0x77d9acfa, 0xf501fe69, 0x3775c1e1, 0x71524e2a, 0x399b35dd, 0x4bad03bc,
- 0xe103bf7a, 0xfc7dd1eb, 0x392c1bf7, 0xffae3f56, 0x4a35e3e1, 0xbc3e4f1e,
- 0x7078046f, 0xcd31acdf, 0x546df84d, 0xd5fd1525, 0xcc5111e8, 0x656fea1a,
- 0x67f7a2cc, 0xccf1e3e2, 0x8f8c6b22, 0xe3a3979c, 0x1df2b769, 0x186f1ded,
- 0x8f7f0e5f, 0x7c21e8e2, 0xe84ca9d9, 0x91bb97cf, 0xfc381317, 0x5aa6f7a1,
- 0xbc458633, 0x7f1fb27f, 0xde4df186, 0xf7e74664, 0x19b94306, 0xeed56efa,
- 0xb5c0aa43, 0xf2f4fc0b, 0xc2a6147b, 0xe477e6fa, 0xc939405f, 0xcfcfdf6b,
- 0xf026b4d1, 0xefb51e7b, 0x625dc7c3, 0x12c8fee7, 0xcc654abb, 0xf12ff751,
- 0xdb5a37f7, 0x5e789ca3, 0xb22e35b1, 0xd763931f, 0xb49a68f3, 0xb41d0873,
- 0xcfb7a14f, 0xcddcc79b, 0x1b3dc50a, 0x257fe0ad, 0xa9ffb5f4, 0x82023fb6,
- 0xf9dce30b, 0xf99aebdb, 0x7f3e51f9, 0xfb62ab8c, 0x5c8ec4c4, 0x740efc41,
- 0xf70cc6db, 0x3b5855db, 0xe7ce51b2, 0x7699bc9a, 0x68eaa718, 0x5bd62247,
- 0x4e9d3edf, 0xb71d6f7e, 0x47777b37, 0x3fa0dc53, 0x79f96a7d, 0xcc29f3f2,
- 0xdd3fa837, 0xad00a5ca, 0xd3e7e5ab, 0xcd1c6f99, 0x0b8d67db, 0xc2d3bfbe,
- 0xc8b1a4d8, 0x884f1c00, 0x30f4489f, 0x7a064ddb, 0x675e3c80, 0x7881e8d7,
- 0x76b7a3ea, 0x76a74bef, 0xcd71e0bf, 0xf72a615f, 0xa5fbf5d7, 0xe5f7678e,
- 0x5b7dd05b, 0x13f736e5, 0x3b0b4f78, 0xe6be5222, 0xfefc29c2, 0x771685c4,
- 0x0b57da0c, 0x6a1453ff, 0xf3937f69, 0x7f0d22fd, 0xf745cc9d, 0xdad6f80e,
- 0x984ebef8, 0x54f1967f, 0xc23fb8fe, 0x44da8bf7, 0x305f1bca, 0xbf61f145,
- 0xbf05ed79, 0xe2f9fdc4, 0x773a68c6, 0xae7bf0be, 0x2dd76893, 0xc4e6c27c,
- 0xfe597bdf, 0x327e6641, 0xc9fcbbf4, 0xdf07d50c, 0x24f0af45, 0x27a05d59,
- 0x8853db1f, 0x3083457e, 0x0630be7f, 0x0ec7cafc, 0x98b8c2ac, 0xcf94cdf4,
- 0xf47f506d, 0x615677b1, 0x18b7e9bc, 0xf63b26e7, 0x63b442dd, 0xf4d0425f,
- 0xc1c03ffd, 0x5a4d874b, 0xa9aac4fd, 0x4daff2a0, 0x2a293568, 0x562765fa,
- 0xc4d939e1, 0x1318f738, 0xfd8ef78c, 0x6fec42b3, 0xcea313c1, 0xe7f7806d,
- 0xbec817ed, 0xdf693a00, 0x014f370b, 0xb278bbbb, 0x582d975e, 0x86668f8f,
- 0x3339be38, 0xd9da3e38, 0x8b7c7aad, 0x718cdd45, 0xd505e3f7, 0x3fe82453,
- 0xceaea1c3, 0xc4d8c919, 0x1baaf9f5, 0xc476cfc6, 0x98f18cdd, 0x837dbed6,
- 0x1f18d5f8, 0x03de656b, 0xd37f7866, 0xb66e43e3, 0x07e36202, 0x30a8c679,
- 0x29d641ff, 0xf4dfa7ab, 0x4463e41d, 0x0d59f3bf, 0x939204f6, 0xf4d28843,
- 0xc2defc15, 0xe34ef93e, 0x1f57db7c, 0xc3cfc1d1, 0x5e24f5e8, 0x59195d6f,
- 0xc312dc5f, 0x2a35baf9, 0x4d66fbf2, 0x03be003f, 0x8b6d7f14, 0x08cf0ff6,
- 0x1f900fea, 0xa79224eb, 0x807f5c75, 0x93b4cd1c, 0xefec46dc, 0xab6bcadb,
- 0xab79af76, 0xf8c68ee4, 0x30c7ae82, 0xcce38682, 0xfa0d3bb5, 0x017daf39,
- 0x3151d7e9, 0xc9c7872a, 0xc53093f1, 0xb59847a8, 0xdf743b3d, 0x3cda77fe,
- 0xe3d3ae33, 0x7439013f, 0x8ef969df, 0x9f9e4bfc, 0x7f38c72d, 0x9c1dbd88,
- 0x678a54c7, 0xfa17ebf4, 0xbbfd6a73, 0x5f04ae72, 0x15f065ea, 0xdcbaf84f,
- 0x19fd833c, 0xfbfd2fe3, 0xc17db593, 0x223ae326, 0xa4f38647, 0x7f8027ce,
- 0x2cfe8853, 0x9ea9f4d6, 0x6bbdd107, 0x064fe524, 0x31e7e5c7, 0xc4bfbe81,
- 0x81f25ddf, 0x963d453e, 0xc56fb927, 0x71ed79f6, 0xc0efda2a, 0xbf1af56f,
- 0x3a6fc849, 0xaae35b9d, 0xebbe69f3, 0xfa4bb204, 0x3ada41d9, 0xd024d79a,
- 0x9e0d99ef, 0x87e715e7, 0x7beba7c0, 0xeb55bfe8, 0xe7e73c7f, 0xf9f8fb67,
- 0xcd1f943e, 0x0eae679f, 0x1c3d5fba, 0x732885fe, 0xd5eb2109, 0xeb8a36ab,
- 0x5abb78eb, 0x85edd7fe, 0x25d701f2, 0xf8377d07, 0x84e1c068, 0x1e518b76,
- 0x7cb55f50, 0xb664f742, 0x7f0c89b6, 0x8de700b2, 0xd74f237a, 0x8795be93,
- 0x5bb2240a, 0x49d97a82, 0x37ae8bf6, 0xb06b5603, 0x2bb5b9fd, 0xaf51eb0b,
- 0xc7ecf76a, 0xc7c5a08b, 0x7348e106, 0x9277bb70, 0xddfc4597, 0x5dbb1cb8,
- 0x8f3423d7, 0xe80a2b8d, 0x6d2a855e, 0xe1d49d3d, 0x345378a3, 0x104271e2,
- 0x7d7afa1f, 0x15e3a5a7, 0x8197bced, 0xd83af51f, 0xaca69525, 0x7ef8ff60,
- 0xe7df0866, 0x841f3839, 0xeabbe7d3, 0x0f83c027, 0x0d43f0f1, 0xc75009ef,
- 0x04982d7b, 0xfde617eb, 0x6b5c50cc, 0x56e04232, 0x104e3eb8, 0x5d8f5c4d,
- 0x07e22e46, 0x58f7ed31, 0x41cf24ec, 0xe5bb707c, 0xe7168701, 0x3f29eed5,
- 0xa1390268, 0xcf3e367d, 0xd4c95dee, 0xddad6cef, 0x6f2f4bdf, 0x7496f2d6,
- 0xb5e2b17b, 0xf846cdd4, 0x1cbb7f79, 0x47792f1c, 0x8ed063dd, 0x5c51ee19,
- 0xb5e41fe8, 0xf98fdccf, 0xf07bd924, 0x7c820407, 0xe5c2dd9e, 0xc34bb814,
- 0x43db9bcb, 0xd874adfb, 0xbbfb3975, 0x28fb23cc, 0xcba457e7, 0x5a72217d,
- 0xbe3850e3, 0xc4167e60, 0xa3d464a7, 0x83f7f97a, 0xcf1fb3c3, 0x3e039525,
- 0x78eb6d50, 0xbf996d6b, 0x7c7286d2, 0x8e50b994, 0x9be65bbb, 0x315d2146,
- 0xa219cc11, 0x79f3d61f, 0xf02876e8, 0xe5f20b65, 0x1a10c73a, 0x7751f86f,
- 0x1fbc0e74, 0xc613768e, 0x7eec5b7d, 0x0efc23f4, 0xe2072eef, 0x14ef5673,
- 0x8cad4fdc, 0x85b5aeae, 0xdf6bef3c, 0x8f89ed06, 0x1fee22bd, 0xf8c03f95,
- 0x7cdaf1bd, 0x02cfa9a0, 0x20c855e3, 0x0f5459a7, 0x655ade20, 0x3ef7bede,
- 0x5611a5fa, 0xf97bf229, 0x95befd60, 0x536df3f8, 0xfd17d21c, 0xcb93b424,
- 0xee1a4f45, 0x16c1b27b, 0xe003ae17, 0x1fbf1077, 0x06c931b4, 0x4a1efffd,
- 0xc4d3d3d4, 0x6b8e74a5, 0xfb40965a, 0x8f7fba44, 0xa4fd0b7a, 0x4d17bf3b,
- 0x3c2ec8fc, 0xd3e30c38, 0x4e9cd109, 0xeb558fd0, 0x1b1d6ac7, 0x48ffbf94,
- 0x8efe491f, 0x141dbebe, 0xe0e7ea04, 0xd735d74d, 0xd841f885, 0x83ffea1f,
- 0xa5b48cc2, 0x1f9affc8, 0x7c61f647, 0x7b45dd70, 0xce21ac65, 0xebe0d3e6,
- 0x0a3e4748, 0x3ed147b5, 0x7d67b3ed, 0x0cdf57f3, 0xf4e2767a, 0x715e0096,
- 0x6e8acb5f, 0x6fe817fe, 0x36b3d81a, 0x8d3ec3c0, 0xf8660e2f, 0x3d4fdc44,
- 0xfba05c38, 0x79450fdc, 0xe095aa73, 0x5c5a8938, 0x33cb5120, 0xe5e28c4f,
- 0x1eb8620f, 0xaf863cfc, 0xbca837d7, 0x1c88e89e, 0xbdad9847, 0xeb89a9ff,
- 0x91f935f7, 0x684fd1f3, 0xedaaf5fa, 0xfc211cde, 0x8e13eebe, 0xdd7dda09,
- 0xe3c76f94, 0xfe340bfd, 0xe8873b06, 0xf8abb414, 0x876e9d7e, 0x4d9f6d9e,
- 0xf78213f5, 0x2c047bbd, 0x9f904f3d, 0xf148aef4, 0x6f58e2a1, 0x55a5e622,
- 0xcb8e4544, 0xf4f0d20c, 0x38a30d59, 0xcfdc29ef, 0xb7bfe6cb, 0x1b25f585,
- 0x1d7ba49e, 0xe29f994a, 0x1a1b45bd, 0xc8aebf68, 0x80a7302f, 0xc78799fe,
- 0x943a3581, 0x710d116e, 0xb552c5e7, 0xe4139b1c, 0xae1dfc5b, 0x9b25f7d0,
- 0x57ea19c6, 0x1816976f, 0x7a823bf2, 0xbfec90a7, 0x3e757ef0, 0x8f4fb70f,
- 0xf10d38d7, 0x861b05ee, 0x78cdf217, 0x73217ede, 0x36177cd1, 0x11ef1966,
- 0xb2b84c6e, 0x1ec1827b, 0x538445f5, 0x3fa8fd26, 0xf7f80e3f, 0x17f7c485,
- 0xe08c3a7c, 0x7bc38bf8, 0x8e018c5d, 0xc433e668, 0xdff326cf, 0xf8f1b429,
- 0xef8ff023, 0x7e407652, 0x07f577cc, 0x1fc01dae, 0xfa87fdc8, 0xb9937903,
- 0x024d65fe, 0x9c4ce0e5, 0x66cfb46a, 0x6e75f0c7, 0xc1b44c76, 0x679a2b3e,
- 0x6b57376c, 0x776b5737, 0xa84a38b9, 0xa164265d, 0xe9fde33e, 0x71951fbf,
- 0xffca6dfa, 0xedc310dc, 0x6eaa9fd7, 0xbbf40c6f, 0xd0773b56, 0xefdade6f,
- 0xf735ad4a, 0x5e5285e5, 0x1e6fe6e0, 0x09dfc3ac, 0xf601dde9, 0xfcc1e83f,
- 0x7ba0df67, 0x6eeff4ba, 0xb432d15f, 0xa954f008, 0x8bb973c9, 0x15dcafcf,
- 0x3f418790, 0xae1ce529, 0x827d96b4, 0x5a5df214, 0x22b76f09, 0x2ff06cc6,
- 0xffd5a27f, 0x6549c635, 0x1840495a, 0x3652ed06, 0xec24116d, 0x0b577f0f,
- 0x66a949e0, 0x93dfd0fe, 0xedcf194a, 0x6fc7db9a, 0x04e61616, 0x9a68d0f1,
- 0x5c62a391, 0x85da3135, 0xaa47cceb, 0x50f10eb7, 0xce8051fe, 0xa8fc4c49,
- 0xbdbb425d, 0x23d7755b, 0x7078eb7f, 0xae0a6a8a, 0x711fd1a3, 0xfcfa9b38,
- 0x30bebe62, 0x4766a8f6, 0xe976eb37, 0x42edc661, 0x5712a75a, 0x3efc308e,
- 0xb69c6261, 0xef32244e, 0x37da854e, 0xa327a232, 0xccae24f9, 0x2c76e66e,
- 0x2cb4f7a7, 0x3e7c16cf, 0xb1c8f06d, 0xd647df78, 0xbf8480da, 0x26dafe3b,
- 0x51fbc453, 0xc3fc359a, 0xf9c59e3c, 0x9cb8f3e9, 0x99dbd05e, 0xe84f8807,
- 0x3d3d10f2, 0xd8c1dfb2, 0xff3ef4e3, 0xe97bf8d9, 0x997acafe, 0xc74e4f7e,
- 0x69eab77f, 0xb4a6bc41, 0x3708166c, 0xdc7a78da, 0x5ca39f0e, 0xe78d971e,
- 0xfb94073a, 0x16873b15, 0xbd7dca85, 0x1cd9f44c, 0xdbafe796, 0xe1887ff7,
- 0x5890eaeb, 0x4bc43ecf, 0x8a3adb65, 0xc2d92cef, 0x4067f77f, 0xfe215cfc,
- 0x07ee1284, 0xfbe1cf94, 0x4acff95e, 0x7ab2ff44, 0xe5acfbfe, 0xb8f077db,
- 0x0b998fce, 0xcb7943f5, 0x0728a10e, 0x8773077f, 0x9f0428b0, 0xca7ee5a9,
- 0xaec6bf83, 0x5bd71fcb, 0x718efce1, 0x0e53b462, 0xe87eb8d9, 0xb87c57cc,
- 0xf669dc1f, 0xcebb6396, 0xe61768e4, 0xfff8e977, 0xe99b8efd, 0xa77db5dc,
- 0xa3658025, 0x8ac939a9, 0xcad70efb, 0x6eabe42e, 0xe9127bd5, 0x5a792713,
- 0x78d8fbf1, 0xbe16abbb, 0x58d85a75, 0x3c72b955, 0x8fe30c4c, 0x72e63f89,
- 0xf43aa493, 0x24b186bc, 0xeb9daa37, 0x67d7132d, 0x1e7ccc87, 0xf787193b,
- 0xb3ee3107, 0xe3878724, 0xf294dc68, 0xca1f9d00, 0x70d3bd38, 0x5fc830ce,
- 0x1b7dbfee, 0x2c3fff7e, 0x00284ba1, 0x0000284b, 0x00088b1f, 0x00000000,
- 0x7dd5ff00, 0xc5547c7b, 0xbddcf8f5, 0x0dd90afb, 0xdc3bf79b, 0x24280c10,
- 0x01049e6c, 0x878424d9, 0x28026e20, 0x47796bc8, 0xd2026c92, 0x6dfad0fe,
- 0xe5318316, 0x16d46b6b, 0x882ea945, 0x835ab696, 0xb80d06a2, 0x47d62228,
- 0x2d8aa523, 0x2220a5da, 0xfb1b6484, 0x6fcb56c0, 0xec9999ce, 0x0f0d9bde,
- 0x7cf9fb6b, 0xdcc98fe1, 0xe6739f79, 0x9ce7339c, 0xb5331d99, 0x228ca8cd,
- 0x389aa6a4, 0xfd2d34bc, 0x84e90ee9, 0xf00b9085, 0x8321226f, 0xf121326c,
- 0xbd3ca484, 0x582c524d, 0x1c5a7fbe, 0x052627d6, 0xaed84bbe, 0xa0af9686,
- 0x84225ba9, 0xa0e4258c, 0x31cc7881, 0x2ae8b484, 0xfd68d947, 0x7b488496,
- 0x663b2d13, 0x68db4573, 0x9d63967f, 0xeab4ac07, 0xa33e6398, 0xda4bf68b,
- 0x4264c7e9, 0x121230de, 0x8c1ddb41, 0x6dd3ed60, 0x42229074, 0x07891b26,
- 0x233d1bbf, 0xc1dfda14, 0xbfb083a1, 0xa6eab797, 0xc37b697a, 0x19d8b220,
- 0x9b74ef32, 0x6ca5db0e, 0xe8e921dd, 0x5a48b8f7, 0x513f321e, 0x595b01ef,
- 0xcc67cc26, 0x43844ed4, 0xae3d56dd, 0x1ce8c2a7, 0xb05466b6, 0x8fe868de,
- 0xe6ed7bd6, 0xfa7e8c4f, 0xbd2fc7fd, 0xbf50246f, 0xc1b47255, 0x37df5bfc,
- 0xa9a1c9ce, 0x4932e7e7, 0x613a6420, 0xf0bf36ff, 0xdfa151be, 0x70a6efa7,
- 0x76eaf5a2, 0xa32fd2ef, 0xc5a95769, 0x24268d23, 0x8b6bccf3, 0xdefd2148,
- 0x74112266, 0x5736dd6e, 0xfbce8d91, 0x0e535dcd, 0x58845149, 0x20f9339f,
- 0xc421f015, 0x06b4e19f, 0x3a5225e7, 0x722fce30, 0x10b3fd2a, 0x55ef46b2,
- 0x95ddf099, 0xb7eb4559, 0xccf830c6, 0x42e0cc1f, 0x157bec2c, 0x0b80975f,
- 0x8c0a7f1d, 0xdce5915f, 0x2454fd01, 0x329bd846, 0xaff99e61, 0xebdc2999,
- 0x823d92ec, 0x672b8d56, 0x579d0cf0, 0x79b84e65, 0xe2f1c06d, 0x44f8d963,
- 0x7180cfef, 0xefb2f109, 0xf9216932, 0x3873f6c1, 0x1f77e9be, 0x3a864efb,
- 0xd7f38273, 0x4d836fe2, 0xe861fac2, 0xa3ac116c, 0xc7cf98f6, 0x0f53ace8,
- 0xe6799674, 0xd043e230, 0xeab6cfcd, 0xd5fd1531, 0x5fd88cd9, 0x708f4d9d,
- 0x1a780cd9, 0x2c03534c, 0xcc1ba69a, 0xc7850f5e, 0x1f26f39b, 0x7e297292,
- 0x20fa316e, 0xb4b7437d, 0x48dfca16, 0xe8b7e361, 0xdf216b74, 0x34859772,
- 0x6e1d5e21, 0x376bcf98, 0x6a7e2147, 0x26bd1ae7, 0x9f8fcfda, 0x63de5897,
- 0x67fa12f1, 0x72f66bad, 0x22e24768, 0xfe024fec, 0x738c075c, 0x4ae9fdac,
- 0x51bf6e79, 0xb7a7dfa1, 0xf027fdb1, 0xe8c6db50, 0x0107ec4b, 0xbd3c20d7,
- 0xf024fdaa, 0x8db07f31, 0x17a505d1, 0xcecd7780, 0x3349db08, 0x0102eb1b,
- 0xe5568cfa, 0x6d93dbeb, 0xf3044727, 0xd007f035, 0x81620ec1, 0x79f2d679,
- 0xeeb9d3ce, 0x6755fd83, 0x50341ff6, 0x0d1f16d4, 0x881f7ee0, 0xffd66b7e,
- 0x0164fb3a, 0x0e93ab21, 0xadf62a61, 0x7f7aa861, 0x6f78e56f, 0x7bb69482,
- 0x4d4dd382, 0xcbee1b61, 0xb80d939a, 0x19532d9f, 0x231cb35f, 0x133c508e,
- 0xdebe43f2, 0x457db17b, 0x9964db64, 0x71e2bdc2, 0xfa44d6c9, 0xaba44fcf,
- 0xa36ce224, 0xf5b67dfd, 0x0025a8f5, 0xc82eafdf, 0x37ae98a4, 0x3777ad82,
- 0x3b5d3be7, 0xde91c029, 0xcc248c1b, 0x3fb72f7a, 0x01223be2, 0xec386b3c,
- 0x1f2e9ebb, 0x17a529fb, 0xf6c1cecf, 0xcf92e8ab, 0xf6eb3d3e, 0xbbbce94f,
- 0xcbb44c76, 0x4e4d3640, 0x7c409fa4, 0xa53b7d84, 0x4c99389f, 0x37de2895,
- 0x351ebdb4, 0xfcfbb68e, 0x81f3a397, 0xf7cdbf6f, 0xe5e799fd, 0xbb9700f5,
- 0x75ecf67e, 0x95e35e50, 0xce304d62, 0x95ffc7ce, 0xdea9fb42, 0x26100f51,
- 0xd57cbf4d, 0x74f5a7e8, 0xfbec6dde, 0xa836c1ce, 0xf713f9f7, 0x6ef0075f,
- 0xf2c26b6a, 0xc36c4f33, 0x7b3f6bfc, 0x683fdf76, 0x94675abd, 0x799dea1d,
- 0xa5e23f7e, 0xc077a5d6, 0xeba2077a, 0x33f6bbcd, 0xe126d97e, 0x1973237e,
- 0x2d74131f, 0x9ff3f7e8, 0x2a1b1e2d, 0x16f7c437, 0x833b9723, 0xcb391c98,
- 0x994d6ff7, 0xb3d205a5, 0x85cc44cf, 0xfe8dbaf5, 0xcf9868ec, 0x1f174628,
- 0xb6d47871, 0x2db831ad, 0xf9fb1ed8, 0x487bee80, 0x9e7d2873, 0x6b4ef4a2,
- 0x0050b8ed, 0xeb0afde3, 0x11257ad3, 0x2f37be14, 0x7cc12e38, 0x18354722,
- 0xbf9e706a, 0xd574e564, 0xebc5e5a1, 0xe96a3d18, 0x059b0be0, 0x907d8beb,
- 0x4d32bbb2, 0xb2603e41, 0xd6ce3e33, 0x6aed5297, 0xd7efd2b2, 0x65d973af,
- 0x4f97c78a, 0x4a9c9e1f, 0x211b3ff3, 0x65fe2015, 0x8f39c989, 0x5ba9c705,
- 0xd04e465f, 0xd9a2eaf9, 0x11b0497e, 0x07c8b5fd, 0xd7ba31b6, 0xf205bd13,
- 0x89f200fa, 0x072e16ba, 0x1279b077, 0x96632073, 0xae59db15, 0x83ce098d,
- 0x3058b3b6, 0x29b8c81f, 0x678ee407, 0xc51dca2e, 0x233df388, 0xe4f101f8,
- 0xee09cc2e, 0x711d04b7, 0x8c13fe01, 0x7e30b534, 0x4ffb4953, 0x8a4d2e8f,
- 0x09a60a2e, 0x16b95883, 0xf2f0b74e, 0x923b451f, 0x3b5e01a2, 0x60f25563,
- 0xdaf2be20, 0x6e4cddcd, 0xe91c72bf, 0x08740dd0, 0xaa4ebbe3, 0x6472f6e4,
- 0xf70e94ae, 0x5c3a471c, 0xabf8cede, 0xb8d4bdbb, 0x259ba68c, 0xefe61732,
- 0x7404f4e6, 0x9bf9a764, 0x7d71a3a2, 0xd9fcebee, 0x39baa7c0, 0x61ef75dd,
- 0x4e86f6f4, 0xbcf801e7, 0x36e47db1, 0xf95a0790, 0x113b5528, 0x6f8a6edf,
- 0xd67a0493, 0x67a0c3ba, 0x3b1355d5, 0x6ef757ec, 0x081a1fbe, 0x7b7707ee,
- 0x2fe872e5, 0x5d9a6e35, 0x992f5096, 0xeef34a9c, 0xfb04525a, 0xd96b652d,
- 0xd20ba01e, 0x20ab912e, 0x0ddced5f, 0xab8fafed, 0x2099cbb3, 0x9927b6f7,
- 0x47ebfd69, 0xcdfb6314, 0xf4294ae9, 0xb620a9e7, 0x706f2127, 0x9cdb3ca1,
- 0xf20ed23c, 0x88daedce, 0x0651177a, 0xb89ca1d9, 0xbea16bf4, 0x6c80b3db,
- 0xe3ecc292, 0xcb03923d, 0x08de91bd, 0x3b7a7eda, 0xeddc7fd3, 0x139f1f6c,
- 0xa1a911f0, 0xd78c1173, 0x788982fd, 0xbd9d20a4, 0x930a67b9, 0x509a2fb3,
- 0x746d9ece, 0x34541390, 0x10568c8f, 0x358e02af, 0xa03a99ad, 0x9966425b,
- 0xf8cb1e60, 0x4c0d5a3c, 0x3973446e, 0x9b2f7590, 0x1fbe72c7, 0x78eb4796,
- 0xaffbe46a, 0x9b05c995, 0xe0e41727, 0x921e3e39, 0x73970245, 0xe5bae874,
- 0xb527dc3e, 0xe2feb34f, 0xdbbc8e4c, 0xe855e842, 0x6c7a5a47, 0x6ca6e3e2,
- 0x3301203d, 0xa55ad949, 0x57d7e7da, 0x5d3d5f13, 0x755bf5e7, 0xa8b989be,
- 0xfc82dd37, 0x6c91837c, 0x77f7fa97, 0x5be3344f, 0x3cceb115, 0xcdd7e409,
- 0xfa3fd416, 0x8720e9f6, 0xb8f4022e, 0x84dec97c, 0xea1670ab, 0x09d3bd68,
- 0xede03b56, 0x5a8e1c47, 0xbdafab7d, 0xd19c0f46, 0x4325c9ea, 0x4186e969,
- 0x549e0173, 0xa198b75f, 0xa7b68d9d, 0x8fb612f5, 0xf213627b, 0xf7ec26ab,
- 0xeb1b68f6, 0xd859d627, 0xcb2e2c00, 0x27c98eb9, 0x7adc3dab, 0x9e85a3d2,
- 0x074f28bd, 0x82db33f4, 0xafc7e1fb, 0xbd194b48, 0x01284151, 0x41fdb23d,
- 0x5278fee8, 0x3d447a41, 0xf4e0ddca, 0xb647a786, 0xaf54dc5f, 0xd29b3d02,
- 0x27a65ae3, 0x4fdb085b, 0xa7232e8c, 0x7c007932, 0x159f542b, 0xefbb54fb,
- 0xedf6fd05, 0xefdccbfb, 0x1fb606dd, 0x801c29bb, 0xfce8fbde, 0x9be74665,
- 0x48fdd036, 0xfdd137cb, 0xffc214d8, 0x981fe7b5, 0x04079c27, 0x73663dbf,
- 0x745f0076, 0x19ab7f6f, 0x47f396c9, 0xc83fcbf7, 0x65de98be, 0x5fb4ca86,
- 0xa1afdd33, 0xe0a663f4, 0xea63e6b6, 0xb9113901, 0x8947ad5e, 0x266883f4,
- 0xdeb1bebf, 0xa3d24238, 0x55f1c3de, 0x007d73ab, 0x46f41e7c, 0x6324114a,
- 0x131bd33d, 0xde00e640, 0x417a47b6, 0x20484e3f, 0xccc2e7ae, 0x67df3f67,
- 0xfce29f02, 0xeac51090, 0xff7df2f7, 0x4ff7af29, 0x4b9c869e, 0x3a283f70,
- 0x0f2271d7, 0x3b448f2c, 0x172c2f3a, 0xd73be9f3, 0x137cd998, 0xbedecaee,
- 0xc18f0429, 0x3e75757d, 0x5eeb37e0, 0x25a97e9f, 0x8b908e38, 0xf981ba5a,
- 0xf581fc83, 0xb81a8e54, 0x7e7eeb5e, 0x71d0d33e, 0x7b5fdf04, 0xb482b8a8,
- 0x2bfbe0d5, 0x5635c7ee, 0x2522fa02, 0x9d2c4707, 0xe1befd57, 0x088d1f6c,
- 0xeafb4364, 0x314dd758, 0x9331dfb4, 0xdfa0fef8, 0xa09ce0ab, 0x0c531e27,
- 0xf5e0dde0, 0xd3f9e087, 0x8f7fd618, 0xe991ecd5, 0xd623b8fe, 0x3ded0d15,
- 0x03eec465, 0xe5077339, 0x896fb027, 0x4df808af, 0x0147f13d, 0x5d58c79c,
- 0xbf4031f1, 0xc9366772, 0xf257fca2, 0x63f7c2e7, 0x84b95111, 0xfb71f3f6,
- 0x85799f6f, 0xcaf85ab6, 0x03df85b9, 0x22317afa, 0x18e2e803, 0x513b97d5,
- 0x830656df, 0x944bddbe, 0xfc30b6c1, 0xcc0ba457, 0x20beb33a, 0x55663f98,
- 0x7a442f9f, 0x6fc30c4d, 0xe214f9fd, 0x09fe8589, 0x627bbf9e, 0x1f5df614,
- 0x56ea8230, 0x78833e7f, 0xeb1f7f68, 0x985b7548, 0x30c53771, 0xc84ddb7a,
- 0xf7e570d4, 0x0f7671f1, 0xb030fb65, 0x7f02f24d, 0xe1bf5eac, 0x07e532cf,
- 0x3eacebd5, 0xe831694c, 0x8f36d56f, 0xc7f3474f, 0xd11f8c0c, 0xc5cdb37f,
- 0xeb47b941, 0x0e03c7e9, 0x4b20f43c, 0x2e52e0f9, 0xbc3596b7, 0x13d825f9,
- 0x3cc4f5aa, 0xdcb3f69e, 0x4a983cec, 0x2cb33e8b, 0xbfb6028f, 0x25b73bf2,
- 0x5c4a5c80, 0x32eccad0, 0xf40d9264, 0x4331c95e, 0x317910be, 0xfa8f4b3d,
- 0xe29fe231, 0xe7188beb, 0x82f7c04c, 0x80f504c1, 0x7a45b705, 0xd07c213d,
- 0xa5a1e1cc, 0x7eb84f9b, 0x767feda5, 0xfe81196c, 0x739ca23a, 0xdc163e81,
- 0xcfc54e76, 0x53ff25ba, 0xad5d028f, 0x649fdab1, 0x433865dd, 0x623bfee8,
- 0xc43af3bc, 0x675e4f53, 0xa04cfaf6, 0x87c640df, 0x30eacf60, 0x940a3cd9,
- 0xa2cf111b, 0x291a9fdd, 0xe60ecbe3, 0x361e9e97, 0x196be819, 0xde0337b1,
- 0x1244b597, 0x033f084f, 0xc3e81805, 0x3f609e7d, 0x3cde3b4b, 0xaddcfc0a,
- 0x2c9d23f7, 0x8f105b35, 0x9c7af3ee, 0x74316907, 0x8a7b45f9, 0x8e5123fb,
- 0x9e7d60db, 0x9f47c67b, 0x263f491a, 0x7eb8efd2, 0xfdf0edd7, 0xe228c8a1,
- 0x4b78fa00, 0xf3a70ef6, 0x832b35ef, 0xeabc2863, 0x460e948d, 0x734e3763,
- 0xd243fe88, 0x77fc6aac, 0xcc25f5bc, 0x65d9b967, 0xc2be3904, 0x32a7cf41,
- 0x6457c9e0, 0xef8a151b, 0x9185f2f1, 0x45ef8f97, 0x6c7fbf7c, 0x661ff4a4,
- 0xe1c7dd1f, 0xa5ea23df, 0x71f27db0, 0x0e7ea906, 0x4a686bd2, 0x943c7ddb,
- 0x3e79f3e7, 0x604bd79b, 0x9f7c1df9, 0xeacb9c7c, 0xc5f1c769, 0x3b36fe30,
- 0xe015b1d6, 0x8cf9db45, 0x22fb1740, 0x16b7a8bc, 0xfc077e52, 0xea3a6d6d,
- 0xedaf94ad, 0xc4d97ac0, 0x4cf58d17, 0x03485728, 0xcfb07be5, 0xcf84148b,
- 0x274a52a6, 0xd7b03cb4, 0x04aedb64, 0xa9f02af1, 0x8c7b63c5, 0xc3c9eff4,
- 0xd43e9251, 0x61e5428e, 0xa3b30c7b, 0xd27f6118, 0x9e991899, 0x85f10c36,
- 0x3e5f2274, 0x608c6ebe, 0xf4fba078, 0x7bd418b5, 0xfba1397d, 0x97c704e5,
- 0x0f1f67e0, 0x8ab5e352, 0x5e6de1e3, 0x8d8c516f, 0x007b4fc9, 0x31c7ddf7,
- 0x165c7eac, 0x0f424393, 0xcb8703ff, 0xc8549a4d, 0xd5533195, 0x1c4dc5fa,
- 0x44c5379f, 0x087ebc09, 0x88f215f3, 0x345f17f2, 0x5e0b0fdd, 0x217f2135,
- 0xb0d9031b, 0x63bd68ff, 0x2c0a6e58, 0xe472a58a, 0x18dfaa26, 0x22ddb1f3,
- 0x3cefdf68, 0x85d04a3f, 0x3e9c8095, 0x1853d625, 0xe54f7e40, 0x296bae1d,
- 0xba437ca1, 0xd037fe34, 0xd694c93a, 0xd8560c87, 0x03a64ef9, 0x208fed02,
- 0xe147f40a, 0xb850e7fe, 0xc63bc76b, 0x319fe0e9, 0x96f11e92, 0x9f70f247,
- 0x7585ffbd, 0x9cf2ed21, 0x51d1eccd, 0xceb8ffbe, 0xe9fa0175, 0xd42dfdba,
- 0x7d198fcb, 0x3096add9, 0x63df46e5, 0xf2c1490f, 0x3d973fc5, 0x762fca46,
- 0xe4fd7677, 0xa5eeba66, 0x861db29d, 0x5fe77a5c, 0x7a031ddf, 0x0ec1a775,
- 0xdf2a46e7, 0xbcc3d5ef, 0x791e981b, 0x83a6a74c, 0x9f55dfb3, 0x1962d273,
- 0x83dea8be, 0x3be09cfa, 0x4adf7e42, 0x5c81577c, 0x461c465f, 0x66b4ff48,
- 0xe1420cd5, 0x0eb2c2b7, 0x6be7d1f9, 0xbc1ea1a7, 0x7cb07892, 0x4fe18b59,
- 0x4561f2a1, 0xeabf3aab, 0x56fe7561, 0x67df3aaf, 0x2f0f2e7f, 0x32c7a7df,
- 0xd94b3e3a, 0xb03fe03e, 0x3d05e4c1, 0x98af5b48, 0x3ca4cbd7, 0x24f813b1,
- 0x4760fb95, 0x48e11758, 0x6ebebe04, 0xc5e2696f, 0xe7f57cec, 0x10de21af,
- 0x37a8237d, 0x6c6f12e4, 0x63cb7eff, 0xf4238415, 0xe071f0ab, 0x2cb671bc,
- 0xc6263afc, 0x10653d0a, 0x8bbe27f6, 0x45e3827e, 0xcfea3ce1, 0x8f98079b,
- 0x5d9fdb05, 0x1b9c7e19, 0xa9b1c6fa, 0x7db064e4, 0xfc6b931c, 0xa3e82d1c,
- 0x7e127cfe, 0x07a17917, 0x31a5db07, 0xd9a48afd, 0xf906454e, 0x8b63b094,
- 0x224270fd, 0x3bb464e6, 0xebcfcfdd, 0x5fb05cf6, 0x083d009f, 0x6514e3f6,
- 0x714e9f9f, 0x66c6f7d9, 0xf70687eb, 0x941d768b, 0x43f8ceae, 0x58b2eef8,
- 0x6b8e1c6b, 0x57187627, 0xdba2fbd0, 0xe8bb062b, 0x6778ff7c, 0x546ba279,
- 0x30f53f28, 0xe85189bf, 0x9c95165f, 0xbc391a25, 0xd42dfdac, 0x95bea8bb,
- 0xd3e74c0d, 0xbd23b7bd, 0x04ce24af, 0xbd9ef3a0, 0xff5c33c3, 0xf315fc86,
- 0x6259e599, 0x9ba79820, 0x2abfee98, 0x1d599f3e, 0x99d3ef4c, 0xc71c061d,
- 0x025b1441, 0x7cd9a51e, 0xd3d4f329, 0xf9be84fc, 0x908e9183, 0x12fe7cf1,
- 0x9df0a7b4, 0xd4b253c0, 0x36f30495, 0xbc74b8c1, 0x824de208, 0x5dac69b4,
- 0xe4a27481, 0x3079b3d4, 0x0d264f3c, 0x675f5069, 0x9d6ccbf6, 0xd0090674,
- 0x985e0fbe, 0xc6fcf2b7, 0x568bbdd9, 0x158b77c0, 0xcf9188f9, 0xe52c4763,
- 0x2fe46687, 0xc9b75866, 0xfd1cfbe2, 0x94f53c64, 0x3d8fb829, 0x3bda0943,
- 0x02369106, 0xe72c5ae3, 0x1b58b03c, 0x8f9049b1, 0xe0faf5b0, 0x66ce70fc,
- 0x2346e8f1, 0x0b19dc9f, 0x677a527c, 0xf285e025, 0x19ff6665, 0xc3ef5ca8,
- 0x73e0b773, 0x4d7e7c31, 0x1325cf9c, 0xe2588706, 0xb01ef1c0, 0x40419cae,
- 0x49d65984, 0xd44b7ed0, 0x25eff454, 0x7969e000, 0x8abd54ec, 0xd53bc56f,
- 0xeab9c4f9, 0x9d4bb27c, 0x3f93d337, 0xcf928be8, 0x16217499, 0xc02359cf,
- 0xfce062de, 0xebcf99a2, 0x3d74a408, 0xfd3e71ef, 0xbb13f58d, 0x8eeebcfa,
- 0xe3b41231, 0xd0cd9825, 0xde57d53f, 0xcafa658b, 0x97281e27, 0xf3cfc803,
- 0xc0f9b626, 0x837cd3ae, 0x7e8bbf64, 0x1b2ab66f, 0x3d5494f4, 0xc76624d3,
- 0xf54adbd1, 0x865b7cb4, 0xe689becd, 0x1d7ec1eb, 0xd5b7f30b, 0x49f68d3c,
- 0x0247ab13, 0xdc8fe0cd, 0x8366c9b6, 0x81e5717a, 0x8bd046c9, 0x76db1057,
- 0xbfbe8612, 0xce86fba2, 0x53c809f7, 0x5e9c48bc, 0xf3290f22, 0x7cbc0d71,
- 0xc59dfc07, 0xe18b13f2, 0x65feca5c, 0x3a75e475, 0x90e0eec0, 0x77d62e51,
- 0xa16ebde4, 0xcecd65e3, 0xb3bc3b43, 0x0973f99c, 0x3463f7df, 0x905c6afb,
- 0x8f3cb1ce, 0x707587e7, 0x899c6ebb, 0x746d6bf9, 0x36666288, 0x8c71fac0,
- 0xfc44edfe, 0x5af2fb63, 0xfd07fc12, 0x47fb0795, 0x5829343e, 0x7467dc1c,
- 0xbdb37ca8, 0x1bd696a9, 0x87edf7a3, 0xa78e3c7d, 0xa37d3c79, 0xbf9406f4,
- 0x628b3a9d, 0x6d7db1d4, 0x861302ce, 0x14b80653, 0x04d07edb, 0x7c904cfd,
- 0xbd4c6698, 0x5fa609bf, 0xd147edc5, 0x06ef4649, 0x12a68eba, 0x77b4678a,
- 0xd820f9fc, 0x4907e5a5, 0x88e9e001, 0x0739c841, 0x7a15d39e, 0x3a1afb1c,
- 0xfd406c98, 0x2a932ffc, 0xd5013bf0, 0xd2bbce8c, 0xbe2116c6, 0x755f2c0f,
- 0xe36a3f28, 0xb337e464, 0x6abf32a6, 0x57b35cfd, 0x10ce4092, 0xbbd277e6,
- 0xb10a6f32, 0xc43f0897, 0x773206fb, 0x44f39857, 0x4fd31c6d, 0x3b3066ab,
- 0xa346fd6f, 0x1d537fca, 0x335eecc7, 0x8c8f26e3, 0xfcc47943, 0x5c7179a7,
- 0x46411b6f, 0xe10a9f00, 0xaf504523, 0x81edf4ab, 0x9cba8cf8, 0x8e3999f3,
- 0xfdea0302, 0xbe08df9c, 0xf6c41cee, 0xd2423cf3, 0x9367ae81, 0x87ffe406,
- 0x7e456f4b, 0x18f11373, 0x951f6f00, 0x310278b1, 0xd55359ef, 0xa71cd27a,
- 0x5cf37f3a, 0xf0c51ead, 0xe79dc621, 0x09579752, 0x5aaa783d, 0xfff05e0f,
- 0xb9468abe, 0xdd54f89a, 0xe7e02185, 0xc000f660, 0xe873f30b, 0x1bdc6e91,
- 0xbebc3f99, 0x388def3d, 0x127767d8, 0x4976cfbe, 0xb2ffd1cb, 0x82115a4b,
- 0xaf5ad4ff, 0xb8647204, 0x987dd855, 0x7934e4de, 0xc3df83f7, 0x91128359,
- 0x49e3cebc, 0x493c400e, 0xadbe907e, 0x57165665, 0x30b51c41, 0xa45b349f,
- 0x16fef41d, 0x65da3e5d, 0x2aaca25b, 0x0da6fa3b, 0x13d4054a, 0x44c558f6,
- 0x6e9c6df2, 0xd7779dc2, 0xbafe31c5, 0x71766259, 0x9e333ccf, 0x9cb3e32b,
- 0xbc413f2a, 0x9d828e4c, 0x229c6470, 0x63fda3ea, 0x5c95c1b3, 0x44af5340,
- 0xd2171197, 0xd11b265e, 0x4fe1a8ae, 0xb476b1f1, 0xce0fc7eb, 0x9cfd3b41,
- 0x2fb43c8e, 0xfd844b12, 0xffd8292a, 0xf4dbd99c, 0xdf53a710, 0xdcbf4db1,
- 0x7bbba412, 0x8d5cb8e2, 0xaf409124, 0xe7ba767d, 0x7ba7684c, 0x5ffce75c,
- 0xa35acba0, 0x2171ed0f, 0x07df8af4, 0x38ab8b92, 0x9cca18bd, 0xf9d056f3,
- 0xb46bbcf5, 0x1d19f9c3, 0xe7ffb46d, 0x9da344f7, 0x50455f51, 0x652c6d3e,
- 0xec07a47c, 0x9f1d745f, 0xf9e35745, 0x8ad4a360, 0x663ba3f2, 0x6af1d232,
- 0x073c01cb, 0x74a56f57, 0x569f2218, 0x6be750ef, 0xdf9e2748, 0x47ee9f6b,
- 0x0517c8cf, 0x56ef761f, 0xd4c323b7, 0xcb8f377c, 0x7da77c8b, 0x7d4c0556,
- 0x9d8b3dae, 0x8641e9c3, 0x1de8a3ae, 0x2eefb723, 0x008a9db0, 0x7494fb56,
- 0xc7adfd31, 0xfb665a7a, 0x2283c99f, 0x6e568e3e, 0xedbd7115, 0xe0bfca3a,
- 0xb0f42afc, 0x07f2c222, 0x92721d74, 0x42df382e, 0x7fe84ede, 0x7c084e42,
- 0x52109695, 0xa743f742, 0xc9434fe0, 0xed37c050, 0x0489f71f, 0xd8314391,
- 0x7dce07bf, 0x9478f8e3, 0xb7203c1e, 0x17b33a3d, 0x6a59abe8, 0x06693940,
- 0x9ba69f3d, 0x83ca1724, 0x323daa97, 0x692c7bc0, 0xd6833598, 0x8cee6f1b,
- 0x3a513804, 0x3f4a1239, 0xb197c44d, 0x11d1524b, 0xbf457796, 0x848e961d,
- 0xc47df33c, 0x74e998f4, 0x054fd0c5, 0x7a687e38, 0xc8e76240, 0xeb1f9629,
- 0xbadbfda1, 0x53274869, 0xf30f5789, 0xf1a9b0ab, 0x9d49253f, 0xa3f4a69f,
- 0x70c38c0f, 0x1f4e7870, 0x08772ea1, 0xfcd4477e, 0x857c932e, 0xc1f9187a,
- 0x5d80efc1, 0x193d7221, 0xd50dfa01, 0x6a1f7144, 0xb8ebe0e9, 0xf26fdd6f,
- 0xbf185c75, 0x13b70f49, 0x2bfc4b5f, 0xd3fa969f, 0xeb1bf759, 0x7a10a4e5,
- 0x65e2fb14, 0x907f8b03, 0xa9fe655e, 0xe5193312, 0x642afa03, 0x3fb14576,
- 0x8cfa05ae, 0x315dd209, 0xcf119eff, 0x19086ce9, 0xa1367402, 0x5327c23d,
- 0xfef1e4bc, 0xcbba05ae, 0xe223ea0f, 0xd254d15c, 0xa532be8f, 0x705fd42c,
- 0xa47d09df, 0xd26b6a40, 0xb91f0267, 0x1be609a7, 0xe3434f42, 0x512f808b,
- 0xda7dc27a, 0xcbaace4f, 0xf026f435, 0x52e5f42e, 0x367480d2, 0xea60a75b,
- 0xf2855cab, 0x5b32dcb5, 0xacdfed0f, 0x0936f462, 0xea0b31e8, 0xdca5e9ab,
- 0xe96bceac, 0x0ba88e91, 0x9f4b571d, 0x10dbd103, 0x5f2137a0, 0x6f4d2f63,
- 0x75bfe3d3, 0x7f1e9b7a, 0xd2d37a11, 0xbb5fe099, 0xa0e56c22, 0x4b57d73f,
- 0xde0a0f28, 0xf904d61d, 0xa89975e1, 0xb68aef4f, 0xdf5d7ea3, 0x3b0bcac0,
- 0xbdc4321d, 0xe5e3ad64, 0xc872ce99, 0xe5a7afd7, 0x23a2ebb4, 0xd8662e2c,
- 0xef3cac9d, 0xadd786ae, 0x587867a0, 0x6f3f97fb, 0xb968a396, 0x2fb799b7,
- 0x7c872d6d, 0xff6b0b7d, 0x46a9f819, 0xb79a7c43, 0x7d5fbe09, 0x1d9da66f,
- 0x3efe99ab, 0x9777af91, 0xd8ebdcf4, 0x5bb595ae, 0x883cd075, 0xe99ff9e0,
- 0x75f1d7e5, 0xd6cadc4e, 0xfae27719, 0x8ba50aa9, 0xea0f0115, 0xb574a76f,
- 0x06dfc8c5, 0x4a973f38, 0x4e9069ad, 0x5217eca1, 0x22ded987, 0xcc7e650f,
- 0x7b8874ed, 0x45fd99e2, 0xce20fff8, 0x9f4432a0, 0xd99e27b8, 0x84bd4563,
- 0xa0018a18, 0xa8ac4787, 0xa4ff0b5f, 0x812221ef, 0x723587bc, 0xbfac243d,
- 0x03564a72, 0x865311ea, 0x5fa53f08, 0x9b8e94bf, 0xc98be177, 0x3f43ece1,
- 0xe69ee3e2, 0x7a7d1371, 0x075337b2, 0x880bb174, 0xf4800524, 0x7f41afde,
- 0x487e05db, 0xa43ca426, 0xf2caf004, 0xbd7fe35b, 0x853c65a9, 0xef41aeaf,
- 0x2196a101, 0xccc9dc61, 0x1c1be24e, 0x53fe7fd5, 0xc467c4f4, 0xff362638,
- 0x1e544d95, 0x7e31d123, 0x8fe38736, 0xe90abf8c, 0xd3c73677, 0x2a7f05cf,
- 0x9fc00520, 0xddbc70e6, 0x347aa664, 0x8356c3f2, 0x133c6f86, 0xcb6a720f,
- 0xbabbfa80, 0xaa57c35c, 0xb92bb8f9, 0x092b7ede, 0x4a727ea0, 0x7a7a62f2,
- 0x6bdbd30b, 0xbf50472c, 0xe98479e9, 0x8fc4b5ed, 0xbed68ffa, 0x9d53b359,
- 0xe7536baf, 0xf9d5dbeb, 0x8e0f1c9e, 0xaea5b3d3, 0xd58aec18, 0x768bbf0f,
- 0x5fc16aec, 0x42fe6abc, 0x5fc67115, 0xed06ba1e, 0x6f98df51, 0x6f4f4d3c,
- 0xd0b8aac5, 0xfa9c02df, 0xb22f35ec, 0x613714f8, 0xeb1e8276, 0x4e70f988,
- 0xa4791a25, 0x9c7927e5, 0x86fb089f, 0x84792fe0, 0x8e7a23c9, 0x8241d77d,
- 0xd7ab5c7c, 0xbd73c4f5, 0x84d39f97, 0xfa0793fe, 0x35d3d00f, 0x4164480d,
- 0xdb7f6439, 0x9fc88724, 0xc0668579, 0xee99be73, 0x6c978067, 0x545971c9,
- 0xca05f0f4, 0x7bcf8199, 0xbd0d72ea, 0x2dd6f388, 0x81665e9c, 0xff8e8527,
- 0xe781c97b, 0x32b7c3ba, 0x5963997a, 0xd1faf487, 0xe22f466a, 0xe7e577dc,
- 0x4dfc873c, 0x747d79ce, 0x5ef54112, 0x17491e9a, 0x8fe67ce7, 0x1d1897af,
- 0xf87d55d4, 0x82cfe818, 0x246e1c2f, 0x3e10faf1, 0x64cd34d1, 0x934a3b06,
- 0xaa839d81, 0xbc5c7fa6, 0x38cf8434, 0x13134a22, 0x88ee5940, 0x5d6cfb47,
- 0x669c7aa4, 0x7fbbf3a9, 0x4fd2f380, 0xd44ed123, 0x954130fb, 0x70eb77a4,
- 0x6b3edb8c, 0x31527e60, 0x7707559f, 0x7ec3f3ee, 0x08ebff5c, 0x359f953d,
- 0x5ac5f792, 0xe4c4b65a, 0x6a7186ca, 0xb3233e74, 0x5fa27663, 0xb03b8c57,
- 0xf283d65d, 0x931af8d5, 0x106901c3, 0xefd2e1c6, 0xb5fea1d9, 0x4f8c89d1,
- 0x2aeb11df, 0xca0f8848, 0xa43f614b, 0xc6a49652, 0xc126fd04, 0x376606f8,
- 0x5c710bf9, 0x6361be32, 0xb69e7d88, 0x568f1b0f, 0xf5f8c096, 0x61ce29f7,
- 0x1da307de, 0xd39f30e5, 0x9a7b8fdc, 0x474efdfb, 0xcce03f31, 0x752cfabe,
- 0xf734f4f1, 0x518e9e13, 0xbd4487fb, 0x8ecc09a5, 0x6cd1b272, 0xbf07a8de,
- 0x1c6f313a, 0x21ec4946, 0x93c60353, 0xea78602c, 0x6dbd13d9, 0xa5ff8853,
- 0xfbf4a12e, 0xd87f9f30, 0xba43379c, 0x31b8f5bc, 0x23df0ed4, 0x0f77f3b1,
- 0x089e97a7, 0xeb718a96, 0x0fbf2a12, 0xe799ec78, 0xe5f63c47, 0x13bc8ac7,
- 0xc099effb, 0xfe5f6bf8, 0xb84f2c3b, 0xf5d843dd, 0x69f7f207, 0xd0547bfd,
- 0x044073b0, 0xfd6bcfb3, 0x3f050bf3, 0x05f9fee3, 0xec2d1f9c, 0x45827e60,
- 0x4a9cd266, 0x247717cb, 0x946e73b2, 0x9fe55b27, 0x515e44f7, 0xcba0863c,
- 0x3ecef49e, 0x2123f67f, 0xee3aecfe, 0xeb13accf, 0xdf5eaddb, 0xbadf0903,
- 0x8481fb3f, 0x6d6cfe30, 0xa08bc3dc, 0xe20b0c47, 0xc18dad61, 0x2dae42ad,
- 0xef6f7b07, 0xe8718272, 0xd65adf6b, 0xb5e0f604, 0x2a0b003f, 0xa7d431f2,
- 0x079c38eb, 0x53bc575a, 0x9d951447, 0x4251107d, 0x8aec9fe6, 0x4351e551,
- 0x4d03890f, 0xb5514ead, 0xaa186f4f, 0xfd643faa, 0x4cf2aa35, 0x9f2abe4f,
- 0xaaad72d5, 0x65ad55fe, 0x87f0fcaa, 0xcfd557af, 0xa3074323, 0x0c90ecfd,
- 0xb57221b6, 0x3e554ab7, 0xaa2de772, 0x86919ff6, 0xbd69e3cd, 0x79fe42dd,
- 0x8aa39d1c, 0x39ce7183, 0xed554b6d, 0x62b6a49b, 0x9f46f01f, 0xbd6893e4,
- 0xcb5f1c15, 0x62ff993b, 0x556afb74, 0xd8a367ff, 0x5fad183d, 0xa32e7696,
- 0x912ed61e, 0x7efea447, 0xfb8eeada, 0xa8ee219b, 0xf296bfbf, 0x356eda4d,
- 0xfe80bf3d, 0x8e6fd5a6, 0x5d3f7026, 0x7461490a, 0x0b0ba5ad, 0x5bbd7fea,
- 0xe627b465, 0xc687ec91, 0xc40cbc23, 0x5fc7f4ab, 0xae76612f, 0x76ada7de,
- 0xf559ff88, 0x47a432d6, 0x2e9a9253, 0x5d351422, 0xd3508e44, 0xa6aed585,
- 0x6a25c183, 0x3dc2d03a, 0x0ba6a1da, 0x43ffa7e2, 0x2ae02de0, 0x553b1ee0,
- 0x785a374d, 0xda0093e7, 0xc95eddd9, 0xfc6123ee, 0x70dbede2, 0x1fd2975d,
- 0xf86a89f5, 0x34701c16, 0x2c6e1059, 0x61e84cbe, 0x68ffae26, 0xaf4213fd,
- 0x7ae44b89, 0xf847ef15, 0x0f259a17, 0xfe7d51ea, 0x865f12c2, 0xa7f4132f,
- 0x44ecc206, 0xf0c4a4ce, 0x3efc4676, 0xc0519d90, 0x2620f675, 0x03886b2f,
- 0x882be1ed, 0xc9ddf90b, 0x3ed15bca, 0x63f2cab4, 0xad9ebbf4, 0x35527a62,
- 0xbf9f22f1, 0xaa02b8e2, 0xfb109287, 0x528e16ab, 0x02b3e487, 0x20f2e1bf,
- 0x79087485, 0x1378c2e0, 0x62e6864a, 0xad471f95, 0x30df82e7, 0xbd097f84,
- 0xe0278c57, 0x189af829, 0xe41a44cf, 0x1a17d824, 0x6846473e, 0x3b6a48fd,
- 0xe0f3b08d, 0x22fe2160, 0x44265dad, 0xe9916e0f, 0xcc90f238, 0x57f14226,
- 0xdda07360, 0xce7488af, 0xe625ef87, 0xc2bd26b6, 0x935713ed, 0x80c4fb3e,
- 0xfe12eaf2, 0xc91e59e8, 0x7f6668ff, 0x6bf0b43f, 0xf89fe5d3, 0x5e3c6d03,
- 0x55ef1052, 0x078f0f2f, 0xa76fea7a, 0x857d1fb4, 0x02eb23f6, 0xc3f6a1b1,
- 0x9206fbbe, 0x1373d71f, 0x424ddc71, 0x693710f4, 0x133f3c9b, 0x4e54c4ec,
- 0xecca4146, 0xab5da458, 0x8ed1eb07, 0x012ba3ac, 0x2121afba, 0x60ccda7e,
- 0xfee5e639, 0x74371179, 0x42e27d29, 0x3fc78da2, 0xc22778b0, 0x5f38a0f9,
- 0x139e740e, 0xcf701471, 0x2221fc16, 0x9139a84e, 0x4973839f, 0xf74ff42e,
- 0xb444a6db, 0x29fdd01f, 0xbec7ee85, 0xef2c22b8, 0xeb351fb7, 0xb2147117,
- 0x42ed10b5, 0x7bd742cb, 0x7a10f019, 0x3ea86fcb, 0x1234f780, 0x0dd7a615,
- 0x0381f63a, 0x553b0b8a, 0x46f59e71, 0x7b01807a, 0x8e3c8bc1, 0xafad4daf,
- 0xe3c89b3f, 0xe739f893, 0x181af052, 0x4eee3c1f, 0xf532e3e0, 0x27771130,
- 0x7f42f8e0, 0xc151efb8, 0xd8bcefb5, 0xe13df707, 0x72e02ee0, 0x29f3a8ae,
- 0x3d6c97c0, 0xeef00092, 0x83ee7288, 0xfd47e9fa, 0x705d24a7, 0x1772155e,
- 0xb6f6cbc6, 0xcf3f78cb, 0x5bc5813d, 0xc8c8f7b9, 0x4c3bba1a, 0x6ead37e8,
- 0xc2f51d7f, 0x68ca46ae, 0xa6761ea9, 0xbfa90e91, 0x0340bd88, 0x47ce81ef,
- 0x681f3d62, 0x75e22fd6, 0x7f7f3ae8, 0x3efc3809, 0xe42a1c1c, 0x9ee18351,
- 0x919c5f57, 0x1551903e, 0x75da1f42, 0xb0f4e66c, 0x013cef56, 0x4cef1dfd,
- 0x55fd0cdb, 0x53071dc8, 0x24eb3e00, 0xd1357fbc, 0x26cbeec4, 0x2574fbf3,
- 0xdc3b06fe, 0xb34a4e37, 0xe1a9fde0, 0xe09d91df, 0xdd78fe17, 0x4f70316d,
- 0x5c3ff44c, 0x4efde1d2, 0xe4fb9e42, 0x57f0428e, 0xa26fb02e, 0x162685b9,
- 0xddf99197, 0xe5165f48, 0x891aaf23, 0x61a3f619, 0x6bde0368, 0x68cb4409,
- 0xc9938cb7, 0x313ba024, 0x561f716f, 0xfafb877c, 0x7c52ef70, 0x2814d89f,
- 0x0ed34b58, 0xdd620f4e, 0x0503cb13, 0xfc20960d, 0x16a65c45, 0x3c385b3e,
- 0x66c6f1dc, 0xcdbb17d0, 0x52c9fce2, 0x9f23d362, 0xfb666759, 0xe255d8e6,
- 0xc2b3edfc, 0xe11dd4b9, 0xf6063c18, 0x7932fbdf, 0xb17f2692, 0xe3470639,
- 0xc7d415fa, 0xbb58d9d7, 0xbf071e6e, 0x44b2a3ee, 0x6f8e5f88, 0xa66f1f0a,
- 0x5c73b124, 0x8beff72d, 0x1f7ab5ef, 0x42d58dc6, 0xf04176bc, 0x6bc695fb,
- 0x01fc788b, 0x27ad10e1, 0xef78d1fa, 0x7ab179dc, 0x0e4bfcaf, 0x3ebebe7b,
- 0x0fe22749, 0xcf4defd1, 0x0be3615b, 0xf9d8934b, 0xe807182a, 0x7dc37bc7,
- 0x4a7b85f1, 0xce45c913, 0x0ef3eefb, 0x889fdc55, 0x9f9f7737, 0xfd7e7184,
- 0x29fda5fa, 0xe15c6096, 0x92dff040, 0x86e5e6c8, 0xd082bf78, 0xdefb0aef,
- 0x8f1c4e37, 0xc147f3df, 0xbb45fd3e, 0x7feaf78c, 0x75374871, 0xd779987b,
- 0x5db83127, 0x7dc7af13, 0x1c47d233, 0x2f8cc2db, 0x35fb89ea, 0x76aa9ee2,
- 0xfccbbb7e, 0x10fe608b, 0xbc6e1c47, 0xc48e9ca5, 0x30c777bc, 0x99f7b87c,
- 0xed059ef0, 0x77bde317, 0xe257f8c7, 0xf1a9b0be, 0xd7b73b7c, 0x9fdebeec,
- 0xa6bcf781, 0x40c33b31, 0x728de0f4, 0xd8f504fd, 0x4a65699b, 0x06fac53f,
- 0xffb216c9, 0x410f452e, 0x7854ebb8, 0x23770fed, 0xfbf457e2, 0x4fbe61f9,
- 0xe702c389, 0xbe5c25b7, 0x8351d92d, 0x1f38affa, 0x8cb0fe7d, 0x139f17f1,
- 0xbcf927e6, 0xcff3c255, 0xeb211752, 0xf95a1f29, 0x88334164, 0x844925b9,
- 0xbec3175c, 0x46e909df, 0xf97c9fb5, 0x87ecfdbd, 0xaeae5424, 0x57280d20,
- 0xdd58fe56, 0xfbdc9aae, 0xb49fd067, 0xdce1fbfe, 0xb1d6272e, 0x479e8939,
- 0x2629ef40, 0xd61f20c5, 0x3185f93e, 0x1f78194a, 0x777ca69c, 0xaff81e98,
- 0x46aed319, 0x48bfa61b, 0x44963c72, 0xc927b7f1, 0x9ed20db5, 0xbdff59f7,
- 0x7e4cbdb5, 0xb9438d6c, 0x2efd64d5, 0x087975f2, 0xc0f7ebe3, 0x1e14093b,
- 0x97d31326, 0x720d7412, 0x5e2dea14, 0xf1e387a4, 0x6266aa6b, 0x74049ede,
- 0x29cbf71f, 0xefce3153, 0x800e9197, 0x4752a6f7, 0x3625d81e, 0x997bb255,
- 0xb3f31366, 0xf6317f7b, 0x0c837035, 0x0cbfbb6b, 0x8eb6c1ce, 0xf7b03efd,
- 0x7cfee8b4, 0x5a57e210, 0x8bf163ae, 0xfeff3a09, 0xe2f190d4, 0xe049bd23,
- 0x691f8f87, 0x388f38c4, 0x21af34b9, 0xcdca5e24, 0x9edbd171, 0x1ec27685,
- 0xb61bb083, 0xa8bde045, 0x8183a1da, 0x18435c8f, 0x1bdc459e, 0xdf5421cc,
- 0x8470a2ed, 0xbf914ba0, 0x19f24da6, 0x12fdf0a2, 0xded4e3f4, 0x0f984be5,
- 0x7ae7ea72, 0xf98983f4, 0x5c9abdc5, 0x212efe06, 0x364be69f, 0xfae34766,
- 0xfe223cfc, 0x5cd97f31, 0xb8f3274e, 0x923f3f1e, 0xb1297bc1, 0x5bbb4067,
- 0x474a24cc, 0xf2fcd4b7, 0x675c22b6, 0xf41a218d, 0x19f7e105, 0x6f08cf58,
- 0x653f72ff, 0xa58df765, 0x72743640, 0x62e7c286, 0xf9c030fb, 0xdd9b3bb2,
- 0x88c323bb, 0xee8cfc03, 0x81b7c37d, 0x8834c27d, 0x7f29aff9, 0xa3e49732,
- 0x73866d5e, 0x44afadd4, 0x2f22f8f0, 0xc8ec4fbf, 0xfa9cf883, 0x8c7cb4aa,
- 0xc01a3913, 0x0dba3777, 0xc7dc0cfe, 0x5448ef94, 0xf2da0e36, 0xb87a19fd,
- 0xf54299af, 0xd92f9a35, 0x0fcb2f72, 0xd1d4aff5, 0x4f2d92fc, 0xfdd3d0cd,
- 0x7fc6bee1, 0x5b35f20a, 0xbe7cb176, 0xf34ca57f, 0x655e5bcd, 0x4960e1f5,
- 0x2dc1ec09, 0x68786707, 0xb9a267ff, 0xf1fbb7bc, 0xe5fbb59e, 0x3b50bae1,
- 0xe332636b, 0x9db8675b, 0x59264cf8, 0x1ef0055c, 0xb2febe11, 0x5a0f1d64,
- 0xac54c569, 0x4927b457, 0xf325dbe1, 0xf7e56e71, 0x924627a3, 0xb7e60896,
- 0x3c5144f3, 0x8e18e81c, 0x93afc77e, 0x6e9e9862, 0x38fbe3f3, 0x4f011fa2,
- 0x77189fd1, 0xe067c835, 0xac789acb, 0x3f8664ec, 0x1c46ce3a, 0xdd839867,
- 0xcb4aae2b, 0xbc51fc03, 0xf4de39e9, 0x8dbbfcec, 0x1bf68fcd, 0xa0728b9d,
- 0x07f8ec00, 0x33f5a2be, 0xd2d6f383, 0x93324149, 0x3136b72f, 0x3a206b7f,
- 0x6269e90b, 0xa5677f24, 0x668ebd50, 0xe4c6870e, 0x466f7e68, 0xc2512bc0,
- 0x1c389a71, 0xcf78fcd3, 0x5dd74af2, 0x775a1ff1, 0xf01cbe08, 0xf681ca5e,
- 0xf5b3b7ab, 0xcd7bf0c4, 0xd4188cfe, 0xf557eef7, 0xa6836677, 0xb8c1097d,
- 0x164c7736, 0x8227bfb6, 0xd93bf198, 0x332ed7de, 0xa0ade997, 0x2c778acf,
- 0x123ae788, 0x7bec47ea, 0xc58da2af, 0x39d70667, 0xd3af90a3, 0x6369d7c6,
- 0xe8aaf4eb, 0x64091c95, 0xa7f6b6cc, 0xf7f83ee3, 0x9f2a37f5, 0xe7daa7f7,
- 0x7d83fae1, 0xd65e103d, 0xd6f93a73, 0xa9e622f0, 0x9c1f6781, 0xf013f335,
- 0xed8dfd84, 0x52e9a946, 0x5926b3cc, 0xfb35939c, 0x8e1bf33b, 0xd5daca57,
- 0xb9e2cedd, 0xeba6a289, 0x3a99ddba, 0xed102b88, 0x1027c16a, 0x3dffb41f,
- 0x89edcc9a, 0x806d2469, 0x93c7c4f8, 0x0ddac28b, 0x9cf6bbf1, 0xe2cd13d8,
- 0x8af6b5d5, 0x277b789e, 0x9cf4afdc, 0x8c0aef63, 0xc06fd8d3, 0x259cf4cf,
- 0x5f282ed8, 0x9c73f9d4, 0x3fb7f63f, 0x7e603205, 0xe7b2a685, 0x47d53b15,
- 0x7e431cb6, 0xecb8385d, 0x7f9a4cb6, 0xc88ff935, 0xcb530bcf, 0xfca4c8be,
- 0x9fb27f7c, 0x7d9647e5, 0x5bf21431, 0x44feacfc, 0xefc0f3c7, 0x633fc789,
- 0xaf507252, 0x41592d78, 0x3ae5c9b8, 0x02647402, 0xc7ae8625, 0xe309aaf4,
- 0x075c04f6, 0xba4d0b4a, 0x6ff77086, 0x07a3eedf, 0x812957e6, 0xf3b0153f,
- 0x5f803b71, 0xf403b2af, 0xdf7bb144, 0x8eff7b3d, 0x483e5df7, 0x1e027576,
- 0x16bb23ea, 0x5dfcd265, 0x1fa09f91, 0x3dd0724f, 0xc515f601, 0xf9d01646,
- 0x9c9b5d4a, 0xd5913fa0, 0xe11eb376, 0x745eedca, 0xfc28178d, 0xf3f7d95e,
- 0x61b2a5ef, 0xb18f309c, 0xefd40f9c, 0xe06ff2fb, 0x633fadf7, 0x7af983b1,
- 0xdb96c76c, 0xdb1aff40, 0x4c97f6f1, 0x39fbb30e, 0xc163de62, 0x97bf49ae,
- 0xfe709bb4, 0x5eae3b63, 0xfdc7f501, 0xe80b23b6, 0x5f31c264, 0x9e85b013,
- 0xaaa52fbd, 0xcf90e5ee, 0x39d71a2e, 0xc04ddfa0, 0x54aa53e3, 0xf478460d,
- 0x857c7832, 0xf1dd67f1, 0x68fd9b87, 0x7fdf54fc, 0xfa3afaa2, 0x20c97b91,
- 0xc433f83b, 0xbdad7a7d, 0x5d2568f4, 0x213efd1f, 0xa2106740, 0x6f3c4f4f,
- 0x98248ca6, 0xaad1252f, 0x5939b97c, 0x96c2bf55, 0x929f2aa9, 0x7caab574,
- 0xcaa7929a, 0x56311f4f, 0x7b06ff55, 0x637f2aa9, 0xfd5534c9, 0x2aa5474a,
- 0x536be79f, 0xd4382fd5, 0x423f2eae, 0xfe43c064, 0x90ebfb51, 0xa0749d16,
- 0x74f8b5d9, 0x8e90ebc3, 0x87030bfd, 0xed7c5ed6, 0xe1d7b6f9, 0x6b17b0bb,
- 0xfb0933ef, 0xc5b2cdf1, 0x276f0c6b, 0x0567d24e, 0x75901fdf, 0x18d33eec,
- 0x94eaebab, 0xa67de0a2, 0xa62f6089, 0x7c58a848, 0x00e347ee, 0x3d980b4f,
- 0x062028ed, 0x68adbee3, 0x686a3c87, 0x2c0fe678, 0xf81d200e, 0x5cc084de,
- 0x9e27bad5, 0x5dd6a977, 0xe0d56e4a, 0x5f2a8d69, 0x555dbb61, 0x06d24a7f,
- 0xe534f955, 0xdd3c1a07, 0x60dfcaaf, 0xd3c1a2df, 0x7e9e0d36, 0xf4172aae,
- 0x5aedc1dd, 0x451ec0fb, 0xcefef1d3, 0x75c3c072, 0x8f8803a7, 0x72d6ce92,
- 0x47b5d3c0, 0x855f10db, 0xb039673e, 0x0d43e2cb, 0xa3ea43af, 0xf76831e7,
- 0xa612635a, 0xb4151a07, 0x1c6c1d6b, 0x46a1e981, 0x75ff7e3b, 0xefa60963,
- 0x7d303a34, 0xa62a71af, 0x4c4e8d9d, 0xb0db1adb, 0xed8d73fe, 0xdb162ecc,
- 0x3a45def7, 0x75ba07d8, 0x8278377e, 0x77923f17, 0xeecbf003, 0xc86efe41,
- 0x37ec45df, 0x25f9a24c, 0xbee844c0, 0x374f29fc, 0x80023aa4, 0xca1c3757,
- 0x18f1828a, 0x1e473a6d, 0xa477e1e8, 0x3ea1f84c, 0x37bb909d, 0xd16c9338,
- 0x79a66f2c, 0xb3c63644, 0x83a1f84d, 0x2033d712, 0x33a9d04a, 0xf7c806e1,
- 0x7772b044, 0x401b84ca, 0xfec6ff0f, 0xff3f4773, 0x61291df9, 0x9ccfe7fc,
- 0xd760ac56, 0x70d5fc39, 0x30e3c02b, 0x48396fb7, 0x4d09619e, 0x0679f54b,
- 0x0747b390, 0x80f0b7b8, 0xe009b4ae, 0xcfb3a6d0, 0xebef78c1, 0xb7e8040d,
- 0x5fe7624a, 0xca95cf51, 0x0dcf41e4, 0x1d4f3c26, 0x605639d1, 0x7814995c,
- 0x3dbce00c, 0xdee112a5, 0x00640d63, 0x4e29bcfc, 0x3c0f8f96, 0xf243d926,
- 0x079f0606, 0xb6fc6e52, 0x3858f3e1, 0x62913cf8, 0xcfb6fa63, 0x807a0e91,
- 0x74a91fc8, 0x3e7ec1d4, 0x0ab8ea52, 0x4d38cfef, 0xad3aff6c, 0x3ed0abde,
- 0x139a28e4, 0x9219e762, 0xd1f7606a, 0xd82262e1, 0x71916f3b, 0x39e16b9f,
- 0x7be99521, 0xce702748, 0xe789179c, 0xf63a2382, 0xfeb6819e, 0xb3d70e02,
- 0xe3dbc283, 0xbd32a616, 0xdd566ca2, 0xfed02f33, 0x6045d67a, 0xe1ce3dd7,
- 0x34f58fa8, 0x342ae850, 0x8e70dd3d, 0x1cec9b95, 0x9dbfe824, 0xf2d17f0f,
- 0xfb6e3a67, 0xfd68efeb, 0xda45d64f, 0xaed88651, 0xc2ddf841, 0x358c2f2b,
- 0xb0b4fea3, 0xe40cbd2a, 0x07ee7ce2, 0x27d5645c, 0x1f503ba0, 0x1727846d,
- 0x9af25b97, 0xcac90429, 0x3c234ab8, 0xb69d5525, 0xd5d219a6, 0xc237eec3,
- 0xa3b52913, 0x1a833576, 0x70b7475b, 0xff3ff211, 0x5e748dbb, 0x0acbd78b,
- 0xfb89cf3b, 0x145735ae, 0xf7e822cf, 0xa23b8f08, 0xeaf3c040, 0xd16f0e22,
- 0xd787116e, 0x3fae1489, 0x0b9c90e6, 0x67d63f6a, 0x0b5def40, 0xc01ecddf,
- 0xe72ea0cf, 0x4607e3fa, 0xfdf6ae36, 0xe2ee3112, 0x3afe7654, 0x0994a462,
- 0x4c2de4fa, 0xfdcee40e, 0xba22aee2, 0x9b0edcfe, 0x1615e30e, 0x7800bdd7,
- 0x78e76de8, 0xd8769034, 0x4b3cb34f, 0x221df93e, 0x8f754e26, 0xd2f252f7,
- 0x0f2b69de, 0x7e859795, 0xbca87967, 0x96b4092c, 0xf2145c83, 0x7d4ff851,
- 0x2f9cd58d, 0x3d3f2037, 0xf31eb8d0, 0x983d1b07, 0xe16c6a1e, 0xcb15b97c,
- 0x987c69df, 0xe72f65f3, 0x7bf13bcb, 0x4c5ce347, 0x58ba35f7, 0x9519ca3e,
- 0xecc4fb0a, 0x37c4f8c2, 0xf80898b6, 0x4c3b7ae7, 0x77419f18, 0xc68f63c4,
- 0x0991fc41, 0xe36a71ef, 0xbe7cb490, 0xf7761e8f, 0x0525377b, 0x1f8be9c6,
- 0xc8717d02, 0x9874f4c0, 0x4be05628, 0xe4fe8ff9, 0x0fafd006, 0xf4158a2b,
- 0xcdd482e9, 0xac50ef2c, 0x7c2f9a06, 0x8a5de794, 0x22ac04d5, 0x5be421f5,
- 0x358a3d87, 0x1f8be682, 0x7b95887d, 0xc7f33a09, 0x06f5ba3d, 0x2259f00f,
- 0x51fd801d, 0x449cce6e, 0xd79505c5, 0x5f6007a5, 0x325a494c, 0xcec5f609,
- 0x63e90514, 0x00e1b29a, 0xd88fa7e4, 0xfaab87a6, 0x46de4b0e, 0x57165768,
- 0x937687a9, 0x846cd6d2, 0xdd879376, 0x376d0faf, 0x8daed475, 0xdf619f90,
- 0x74fd07a6, 0xf8b1f027, 0x2f223f60, 0x169f05ca, 0x3ba37271, 0x720f289c,
- 0x0f289ddb, 0x66ca5c04, 0xf60dde57, 0xc976facf, 0x663cc126, 0x0a417d4b,
- 0x86e89310, 0xbf2949f7, 0x97f53ebe, 0x5db40dd6, 0xc5afe43d, 0x7c370ffc,
- 0xa6fbfcbb, 0xfbfc30d4, 0x41dfbe43, 0xfbdc43de, 0x0ef64687, 0x2e1c33cc,
- 0xac4b1df5, 0x712a8ef8, 0x7acf4159, 0x97f3cb9e, 0x9fe5a520, 0x7f8bb4f1,
- 0x70e7407f, 0x52ab38c1, 0x3fb21fb9, 0x6549a87f, 0x8f735ffb, 0xce728064,
- 0x6d52ea1f, 0xea3cf7aa, 0x76bfbb08, 0x6d3b38a9, 0xee36b89c, 0x3b693564,
- 0x1fecc8e8, 0xf70b526f, 0xc7fab2dc, 0x6a788b7f, 0xdf781c6d, 0xe3106ab9,
- 0xd78173a7, 0x496eba50, 0xde4f901d, 0xdc38097b, 0xfd0e0e1b, 0x9c5843d6,
- 0x2438bf7b, 0x5daeef1e, 0xb3c57117, 0xfc798d77, 0x827d76bb, 0xafaffa2e,
- 0xcf5fc195, 0xbbf54fe0, 0x157e60c7, 0xec04ad8b, 0xe7fca156, 0x3fe11777,
- 0x6df67e5a, 0x179bc9f1, 0x65bbe1d7, 0xf3d8f861, 0xb898f8e1, 0x854dafcf,
- 0xf3f70a9e, 0xde121e20, 0x7e738239, 0x1f6ba265, 0x1653d3f4, 0xce0e9bf8,
- 0xddec71a1, 0xaed183f0, 0x325df0fd, 0x1106b8b2, 0xe75a7c97, 0x6de815f9,
- 0x19fa3def, 0x106eb3f2, 0xbc8f7416, 0x97a0f341, 0x7ce6c3fd, 0x4647e013,
- 0xefa18df8, 0x7f140f8f, 0xff2e1bfb, 0xdf6ca7fa, 0x9ed43889, 0xa0665f6d,
- 0xfb12eefd, 0x54782062, 0x70fde3c8, 0x24b7a43f, 0x9767e512, 0xdef07c44,
- 0x02695771, 0xe95d2dea, 0xdfa43d46, 0x2bb8b9f6, 0xd7fb1b3d, 0x92bb8f9e,
- 0xdc6ccc4b, 0x7d2153c9, 0x2154f92f, 0xf0dfbdc8, 0xa376cbf8, 0xb03de0a7,
- 0x408d8f0f, 0x928dfeff, 0xa0e010bf, 0xbd77573d, 0xc94ca0b5, 0xa6be7fed,
- 0xeb049beb, 0xbbae3dab, 0xe95dbe1b, 0xfd76bb79, 0xb9c408df, 0x15ff5b8f,
- 0xaeeff781, 0x19ddfcfc, 0x5e80ab93, 0x12026ae1, 0xf545d319, 0x54bf9a09,
- 0x8939d6fc, 0x4333d39e, 0x6f25e5ce, 0x9e2e38b3, 0xfde7cf6a, 0xed5c09de,
- 0x960dc751, 0x5e308afa, 0xe147f645, 0x7b1d60bd, 0x73c4436f, 0xf3cfc9bd,
- 0x243ebcf4, 0x9d70ed0d, 0xfaf3aa19, 0xfa2d1f1d, 0x0881f21e, 0xa678ef8c,
- 0xcc3c44fd, 0xf19d8ff5, 0x0945793f, 0xedbd77d2, 0x9df4246f, 0xbdf5dac0,
- 0x86d77caa, 0x7056fbe0, 0x5ff6ab1f, 0x2a25ca32, 0x4f105ac7, 0xdae335e4,
- 0xda4af910, 0xef07dcfe, 0x55df94d1, 0xbe50c002, 0xd074cf36, 0x3cfc9576,
- 0x8de44844, 0x92aeda0e, 0x67891f9f, 0xe78f2b25, 0xb09f3df5, 0xff28ba7c,
- 0x7fac4ce3, 0x1c6fe895, 0x79164f2b, 0x22d5dfde, 0x9623789f, 0x25f68a67,
- 0xc6239f2c, 0xaded64af, 0xade4feac, 0x7a099cff, 0x33f7e08d, 0xe09cb8d2,
- 0xfe5152ef, 0xba2b4cef, 0xba8ebc68, 0xf107cb9c, 0x1dc5550e, 0x85df22d3,
- 0x6126dc7d, 0x9ded61ec, 0x9fe7b406, 0x0dcb698d, 0xe22f2fbd, 0x56e59c7a,
- 0x7baaf38c, 0x9976f871, 0x1e813bc7, 0xe9fb9cb3, 0xfa0b642b, 0x65ef7a61,
- 0x3d207e7c, 0x97fae570, 0x57ecf855, 0x46d3dfce, 0xef1d2547, 0xf1130fdc,
- 0xd619027e, 0xee02f189, 0x27c44934, 0x116abde0, 0x45971757, 0x8e7e701c,
- 0xbd82297b, 0x13b27aa7, 0x97caeff9, 0x6ebb7d98, 0xef28ebcb, 0xda0aca96,
- 0xea1ebe97, 0xe9f0075a, 0x2f77b2b6, 0x87dfae57, 0xc531f4fb, 0x8160fdc6,
- 0xbcf0a151, 0x3dfc3fb3, 0x8517f169, 0x3ffcbabf, 0x5dad7f0c, 0x5fd7dc5d,
- 0x7ff1857d, 0x07e656dd, 0xfd3c73b6, 0x7314a749, 0xf0023d78, 0x33a2b73a,
- 0x20865a3b, 0x778c4eee, 0x29df90ab, 0x6f56f382, 0xde009583, 0xdccea5bb,
- 0x5fe0c30f, 0x9f38ae7b, 0x69715441, 0xf7c3fb3b, 0xf7d04be9, 0xfa4dffd3,
- 0x8dfbd44e, 0x1f1bf076, 0x15e5ef65, 0x18c9fe77, 0x4ef41f1a, 0x0f073b1a,
- 0x317e676e, 0x2c171711, 0x713c32b7, 0xd55d53ff, 0xffc1e33b, 0xc4c3f624,
- 0xfe06d248, 0x76d74a04, 0xa076d74e, 0x41bf416b, 0x176d143f, 0xfa41be06,
- 0x912e2c25, 0xfdb7e9c3, 0x25e1fae1, 0x7fe1fae0, 0xa9bbae13, 0xdbfe8c3e,
- 0x4ed02217, 0x3ff385a3, 0xbc055c38, 0x0e2fd323, 0xfff4c8e7, 0xd3239c0c,
- 0x439d9515, 0xf9207bc0, 0x988fc5a4, 0x5a7d9877, 0xe9f64df4, 0x4f9c1923,
- 0x8f18fde9, 0x4c7bc5ab, 0x27bc3f7a, 0xef1c5fa4, 0x30fff2ea, 0xd370b5de,
- 0x9fdcb5a6, 0x985efdab, 0xfbbf203e, 0x7ff8e056, 0xb0b04fcd, 0x7caabf61,
- 0x54b7faf1, 0xef3c4be5, 0x415f965f, 0x5bfffbd8, 0x57e105fe, 0x2afcf998,
- 0xb51ff81d, 0xc43741f2, 0xc7a023f9, 0x7afe5f1b, 0xf93087d4, 0xb78c6cea,
- 0xe5af8dba, 0xff7ff18b, 0xbe947be4, 0xf66068be, 0x3ffb63d6, 0xfd392837,
- 0x79e165e9, 0xd084711d, 0xeff5c2d9, 0x5acf401b, 0x54fbd848, 0xa60ffada,
- 0xc6307b33, 0x30be5149, 0x710c4cd7, 0x9dcc1f94, 0xcf4beecb, 0x0c630705,
- 0x2d173ea6, 0x3e27a99f, 0xd2bb8f78, 0xd099f7a2, 0xffbea9ef, 0x75efe26e,
- 0xd558b893, 0x21d9783d, 0x9cdf9c63, 0xbd2fe612, 0xf786d2c5, 0xba1de787,
- 0x60f7dceb, 0x14f46f2f, 0x7177b8b1, 0xbaf7f0ff, 0x3e83f12b, 0x9c2a7a08,
- 0x5fee24fb, 0xff40635f, 0x2addb6ba, 0xca669fbe, 0xd9a38b12, 0xc533e2c3,
- 0x3beba4fe, 0xf767ca64, 0x48f7e060, 0xbe0c1b2a, 0x67a0b9e1, 0xbb3d47ef,
- 0x2e4364be, 0x927eafe0, 0x1b94dc74, 0xafd4ef3c, 0xd7b60bff, 0x7a6d67f2,
- 0x4fd5f6b9, 0xbd210f1a, 0xb1d17388, 0xb5e61f46, 0x1305d6f6, 0x93fd17ff,
- 0x6de2ff63, 0x57dc7482, 0xd0c70f8e, 0x3b1bfb75, 0x827b2dff, 0xbb0823b0,
- 0x214ed682, 0xbf7888f8, 0xe36e97d2, 0xa296b2ef, 0x59e883df, 0xc1edf82a,
- 0xd7f9fcfe, 0x27d717e9, 0x61ffe5d5, 0xf4b97cfe, 0xe4c49b5f, 0x8fee96aa,
- 0xed0cfd56, 0xb5be82cf, 0x6200bff4, 0x0bf8e852, 0x27bc25ea, 0xab55773e,
- 0xcdf49c61, 0xe5b57de9, 0x9b830664, 0xb15c2e46, 0x3c78503c, 0x0be78c87,
- 0x0ec6bc93, 0x87810f76, 0xefd5d3af, 0x48bc5303, 0xab971719, 0xfafff2ea,
- 0xa2e4e039, 0x8917266f, 0xcb489f4a, 0xe56eb7e8, 0xfe56eb12, 0xb90eeb9b,
- 0xd648b4a7, 0x40e3ef05, 0x81c435fc, 0xfdd978f6, 0x56ccead4, 0x5203ddfc,
- 0x7e028812, 0x995eeb77, 0xde8e9efd, 0x790e4fa1, 0xf88bad3f, 0x5c7a003e,
- 0x3bbd9e35, 0x769b8da4, 0xd5ea78f3, 0xbf78dd96, 0x9a0efb51, 0xf376cb88,
- 0xa1efb4fe, 0x9de2f689, 0x687bed03, 0x1c783253, 0x67c93e76, 0xe7172971,
- 0xcf20dda3, 0xdd35fc43, 0x5da2355f, 0x4ac7c6e1, 0x05a4f3ee, 0xa32732f1,
- 0x9799df1f, 0xa3be7171, 0xd32fff2e, 0x81dd6caf, 0x94aed8f7, 0x3a64477e,
- 0x827f40dc, 0x9bf1f72f, 0x6fc84c57, 0x3df33bc4, 0xf7c19e6b, 0x24be7a87,
- 0xd4bd97e8, 0xbb13e33b, 0x09c435d8, 0x564dbd27, 0xc771d78a, 0x1baf683c,
- 0xf785c47b, 0xe3bcc776, 0x927f8880, 0xc329c077, 0x233e85bc, 0xff209bf4,
- 0x78d9f7e2, 0xf2e5d59c, 0x37f52bb9, 0x8cfca7fe, 0xb75d5ee2, 0xbf0457c1,
- 0x13d9e0e7, 0xa103bf81, 0x1993ff9d, 0x93be8bba, 0x7ae511dc, 0x8b34f012,
- 0x5ef109cb, 0xdecc8572, 0x94edef49, 0xeeb85ed1, 0xabfb7e7f, 0xdb4b9547,
- 0xbd6dea15, 0x2265cf61, 0x7bb1d7ad, 0x0ae5f92d, 0x79c249c6, 0xc287ec0d,
- 0x7fada89e, 0x297b294a, 0xe35bed03, 0xdeda3df1, 0x067cd987, 0xfafd57c2,
- 0x603f8e00, 0x7ebf1f39, 0xf42d916f, 0x19f3959d, 0xdb43e77d, 0xdf107329,
- 0xff174b97, 0x332dced7, 0xa891e265, 0xbc91cd7c, 0x4c25ef4c, 0x3a405dff,
- 0x02445d31, 0xbb08ba98, 0xd894b0cf, 0x9c4e5d31, 0x5c55ae98, 0x3718195d,
- 0xf8c04814, 0x39ff17d3, 0xdce6e80a, 0x215ae375, 0xf2dbf146, 0xbef56923,
- 0xbd853c9e, 0x3fc2f497, 0xd9f4077f, 0xcb863ff3, 0xa2471be2, 0x1848641c,
- 0xa57bd33f, 0x54d7bb32, 0x17dc5df2, 0x325dfde2, 0x96e1f989, 0xfee26627,
- 0xc4cdf209, 0x826f826d, 0xb8e7393f, 0xdcc3c58e, 0xc67be12a, 0x6e1d7eed,
- 0x99159cb1, 0xb9ddf85e, 0x3cacddf6, 0x2bda2ea7, 0xd8ce7cd1, 0x26be5608,
- 0x4ff70bda, 0xee3f1216, 0xfb70c5cb, 0x4bfb8644, 0xdf8a2f8c, 0x8227a00b,
- 0xbf6d12a1, 0xeeccc3a2, 0x30ff1051, 0x70b9ffe0, 0x4f170a7e, 0xf1f18433,
- 0xbf1943d1, 0xb6a65d1f, 0xe5e50c87, 0xdf6529f7, 0x0cb47807, 0x810d6471,
- 0x9b9d31fa, 0x3b042c1e, 0x9f808e90, 0xb7b1b3e6, 0xb4535fa3, 0x1b29517b,
- 0x959ff501, 0x67bfbc58, 0x4c6fbf2f, 0xfea10902, 0x794ab5b1, 0x1a2bd42e,
- 0x40d3f8c2, 0x51df8570, 0x2f398674, 0xd1d1f88a, 0xbb436670, 0xd277c13c,
- 0x7e58959e, 0x6f5be3f2, 0x5f4168dc, 0xe3f40782, 0x44d71517, 0x91b46f18,
- 0xffcc0b10, 0x1b7efca7, 0xbb00c869, 0x4cc7aae8, 0x3e2fd03a, 0xee18e2a2,
- 0x9e81fcf7, 0x98fd21b7, 0xfd219b9e, 0x43373d23, 0x9b9e9c7a, 0xcf413d21,
- 0x38ae90cd, 0xccc7876f, 0x8e2189c9, 0xf0bfd0b9, 0x5be769f7, 0xd7f18439,
- 0x1af7f1be, 0x14fbfc71, 0x0fb7c217, 0xfe087bdf, 0xd1b3edde, 0x8b989481,
- 0xdecf5bd0, 0x749fa3bf, 0xff08b820, 0x0a7cb6a3, 0x6eee6bc7, 0xdcffca3d,
- 0xcad47f76, 0x872b7a90, 0xce7db118, 0xa0a3270b, 0x1f5b6eff, 0x5d121d7c,
- 0xcb1d4cf2, 0xb9fc7caf, 0x828e371b, 0x0fbe3bf9, 0xf9f74174, 0xdb73486a,
- 0xfc00fb7f, 0x1fed2a5e, 0xa47a24e3, 0x2f3c66c0, 0x85a1d668, 0xb3d75883,
- 0xa09b9dd1, 0x0c2fb3fd, 0xbe509585, 0x01bed843, 0xadc2923a, 0xe7ae0377,
- 0x10a05346, 0x78dd0bee, 0xa71b0e41, 0x8a529f7d, 0x7a064e70, 0xcaddfe43,
- 0x025f4653, 0x7f74df6f, 0xe223fb6b, 0xa5e015fd, 0xafa5c80a, 0xac2f40a2,
- 0xed04f1e4, 0x06fd87bb, 0x2439e9d6, 0xdabdf813, 0xfdea31d1, 0x49e38bb7,
- 0x8d7b39a4, 0xb3d7c04e, 0x830d4f7b, 0x7e2989f7, 0xc57bc186, 0x455c86db,
- 0x31ef7f42, 0x8f97ec67, 0xf587183c, 0xe769f7f1, 0x10156d91, 0xbcdf3337,
- 0xd2580dff, 0x0af1db42, 0x9c599b88, 0x74841d24, 0x19399289, 0x7dc465e2,
- 0x4a236583, 0x9a96c20f, 0x7d44af61, 0x4c9814ae, 0x37287c88, 0xd847f247,
- 0x558a3c85, 0xa524a7e5, 0x534feaaa, 0xd3e554b2, 0x95548c47, 0xd867718b,
- 0x46f5540b, 0xc28604c7, 0x83ae8e79, 0xa4ff03bd, 0x3986f18c, 0x7eb91c2f,
- 0x7ccfcd24, 0x43be0e6a, 0x9f2f2cf9, 0x17b95cf9, 0xe143d1f0, 0xd50aa469,
- 0x6c1f92e9, 0xd33a107e, 0xf76a179c, 0xa1d0713e, 0xe179c65c, 0x8184e712,
- 0xed164fde, 0xca04e7b5, 0xbe001f37, 0xd9c5fa39, 0x3edbf036, 0x14cbf63b,
- 0xcdfd4788, 0x0caefe10, 0x440c3f3f, 0x43fb7d37, 0xbcdd1852, 0xc3279325,
- 0xf2440dd0, 0xe9643a32, 0x7eecc3cc, 0xb5f295de, 0xa1af814f, 0x4243c0bd,
- 0x6b577f7f, 0xb46d1bdf, 0xb036e6ff, 0xc32bbd47, 0x7bbea50d, 0x6fe12b93,
- 0x64ef4839, 0x93bbb6f9, 0x07bbf0e3, 0xb73761f4, 0xb8520df7, 0xffbb553e,
- 0x60c2e4ee, 0x5c775939, 0x29dc9f55, 0x1bf2ab35, 0x7bf9d533, 0xdb439b4b,
- 0xad8fa40f, 0xd189787c, 0x6ef70395, 0x37bfb0a5, 0xfff3e62c, 0xd5800901,
- 0x00800020, 0x00000000, 0x00088b1f, 0x00000000, 0x19b5ff00, 0x6554540b,
- 0xcef7bbfa, 0x7860190b, 0x77421028, 0x840a4498, 0xb0285789, 0xd71ea08d,
- 0x8f4c1ada, 0xe5935654, 0xe04d7903, 0xe3d8f4b6, 0xb68fad18, 0x695b6d07,
- 0x9656356b, 0xb139e4e7, 0x36254644, 0xeb495bae, 0x66a254d6, 0x42d899e4,
- 0x7a26704c, 0xf75a9d6d, 0x5efffefb, 0x5b602e67, 0xe74ed69d, 0xffffef9f,
- 0x27ef7ffb, 0x70ca1490, 0xf60800ce, 0x9970ccac, 0xd6f70601, 0x8018e41a,
- 0xe2eff4d3, 0xf9b8daf0, 0xcf03837a, 0x3a380057, 0x01cfe3cc, 0x031401d6,
- 0x7b81295c, 0x5914f3a2, 0xff60e760, 0x2fbdf165, 0x00490801, 0xde8d179e,
- 0xe38456ed, 0x6e67065c, 0xf08d9ef8, 0xd918064e, 0xbfefff72, 0x25f5c22a,
- 0x8c0ee3b0, 0xbd0d43c4, 0x5c75d79b, 0x9fcd7114, 0x77d1d704, 0x98809679,
- 0x55706b80, 0x00e207b4, 0x3c636a9a, 0x679e3e62, 0x2e990e86, 0xa6f1c804,
- 0x01529bb5, 0xc0228a8e, 0x78074439, 0xe3ef14a0, 0x245f041b, 0xa4ef39a7,
- 0x67c8b9df, 0xe7c72fcc, 0x35b03245, 0xe99432bf, 0x7ed77bc6, 0xbf1ce787,
- 0xce91a203, 0x8f4a803f, 0x2e5c4c03, 0x19bdbb04, 0x3f233ffe, 0x1812bd4d,
- 0xf0619f90, 0x605aba1d, 0x25a9ccd7, 0xa7e92b00, 0x061dfb4c, 0x196fd890,
- 0xb2957f70, 0xe57cb2bf, 0xf08b10a5, 0x2040fd56, 0xa70fbd9b, 0x7fd5fff1,
- 0xf198376f, 0xda53f57c, 0x530f427d, 0xfbe52f90, 0x77b3f03a, 0x3de277eb,
- 0x235ef853, 0x8499fddc, 0x697636ef, 0xc7245fbf, 0xe0e60d24, 0x3828028f,
- 0x916db12d, 0xf1366bde, 0xdf4ae6f7, 0xea097bbd, 0xc925e9b1, 0xd1adc46e,
- 0x00e2d3dd, 0xa83983f9, 0xf2f1d4e4, 0x7a8cda6b, 0xa7c30c2a, 0xbdf34b76,
- 0xca175f74, 0x5e319ea8, 0xe2c960ce, 0x5f1c2cf8, 0x0bd7c573, 0xf735f101,
- 0x7ed0d0e8, 0x1146cf00, 0xcf3c08e4, 0xf2ae31ed, 0x07f4c39a, 0xfcc79c2d,
- 0x66132f9e, 0x1d75f2e7, 0x1ced01d1, 0x98bf702f, 0x093e8021, 0x60b541f1,
- 0x5f4b8edf, 0xc925724f, 0x9f004fbf, 0x589ec05c, 0x5cfd4264, 0x7da39fc1,
- 0x8fe02433, 0xe11d6c94, 0xfdc8a859, 0x7c7fd28a, 0x8b77e023, 0x434f167b,
- 0xd750e00a, 0x0cd43eb2, 0x0c6d906c, 0xe8f012df, 0xf17d2f49, 0xa416f4ce,
- 0x604932f3, 0x1f17dff6, 0x7f10161a, 0xd0b4455f, 0xeff7b026, 0xbe55f7a4,
- 0x74cef4fa, 0x8e6be337, 0x26f51065, 0x4e902e38, 0x47978f47, 0x183aae58,
- 0x712bf554, 0x9c7f2177, 0xfb3edd2b, 0xd1dbf412, 0x223160a5, 0x684b97bd,
- 0xabc30838, 0x49ab8fdc, 0xae5133d6, 0xe8813f82, 0x6e17966c, 0xe4bbf191,
- 0x97417bd6, 0x1d372118, 0x2f5533f7, 0xd3c71caa, 0xf72de2a1, 0xd1bf903b,
- 0x9fb3021d, 0xecccbb46, 0xe4fcb1b3, 0x7f104b83, 0x0bb25fa3, 0xeeb2cf48,
- 0x7e4847bd, 0x403b6b1d, 0xe7401e77, 0x2eb66eda, 0x527d9933, 0xd98be31e,
- 0x414688ad, 0x6056ad7c, 0x7c35a7c6, 0x0c7be61e, 0x7c3f51bc, 0x3804ce06,
- 0x9e7ceb18, 0xfbf35bf8, 0x1096fbcf, 0xe3ca1bb5, 0xad901f99, 0x3fa61b9d,
- 0x466000df, 0xa3db43fa, 0x3c304fbd, 0x6125af68, 0x27b13d7b, 0x9e0b70eb,
- 0xcf53789f, 0xc55f75cc, 0x416ea7c3, 0x68f6cd78, 0x0913e726, 0xf3a549e0,
- 0x3d7ba627, 0x18a56178, 0xb9216fea, 0xb7d8c677, 0x47f1f9e3, 0x13bb3fa7,
- 0xa767dae1, 0xf24c89d9, 0x7de5191f, 0xda011d3c, 0x7d953e7f, 0xef1c2907,
- 0xa52fc50a, 0x57dc6667, 0x24cfe74e, 0xaa8f09da, 0xa347a1bf, 0xfaf2801c,
- 0x16797c12, 0x8293bd34, 0x87c45067, 0xc79dc4eb, 0xdbcbb404, 0xc483ae0c,
- 0xfe47eaf7, 0xf90ca87a, 0x37e67aa9, 0xfa44cf0f, 0x0c9bdf6a, 0xaf584ef4,
- 0x6c40e2e3, 0xdffc9720, 0x915ffdc6, 0x288edd4f, 0x7111c7cb, 0x5e23a1a6,
- 0xa7753703, 0x888e3e5a, 0x65c07537, 0x8e82f50c, 0xfc57a9f8, 0x1d745eaa,
- 0x201aba25, 0x8422e3c0, 0x0557640c, 0x78a0e092, 0xc8c7ba10, 0xced63fe4,
- 0xd1916546, 0x8b822f51, 0x224179e2, 0x6fc85298, 0xc17e5c5d, 0x713fa67b,
- 0x9266ca17, 0xfbf54135, 0x223385ac, 0xf1bfb3ed, 0xcdcfb215, 0xc39f6646,
- 0x8d2f3c51, 0x391ff3c5, 0xc2bf7d9e, 0x87f305f4, 0xf5a4f933, 0x17385adf,
- 0x0aef141c, 0x9bc2e4da, 0xf4516d70, 0x29c52c72, 0x1dee4958, 0xc03aeff7,
- 0xe6f5b9e4, 0xbf7784a3, 0x0e0fe999, 0x0507b970, 0xf7d5279e, 0xa0429856,
- 0xb77a242b, 0xfdd57a31, 0xf3872dc1, 0xe0fef85c, 0x8079390b, 0xf24cbcf6,
- 0xe505fe0f, 0x7fc62a73, 0x3b5c36ec, 0x853bbff7, 0x7a58e0f2, 0xd9475beb,
- 0x2c3c2a7b, 0x4f5438f0, 0xf7fee07c, 0xa264ce99, 0x8b08c313, 0xcd77030f,
- 0x2b9bf260, 0xfe91c6e5, 0xf4b42783, 0x7d53a58d, 0x7d4fa55f, 0xcd37bd5f,
- 0x8e39322a, 0x9479fc18, 0x90cc5ff7, 0xc48d7c35, 0xcde2f3fa, 0x75e16fb4,
- 0x11c20244, 0x3f4356f6, 0x2635bf51, 0x5f48db8c, 0x6f608d4d, 0xa1efb603,
- 0xcfab89b8, 0x29f5e785, 0x03722b2f, 0x78ed09a7, 0x906762b1, 0x6eecc894,
- 0x5ebb7011, 0xabedc4ac, 0xe80f43a0, 0x75c4472f, 0xfda035bf, 0xa03c770d,
- 0x5dc64577, 0x74f151cf, 0xbb8f4fce, 0xa6c84a9e, 0x31623df8, 0x9e66bab3,
- 0x7bb1d055, 0xf74e90e9, 0x43eedcf0, 0x1a74f03b, 0xcf486ded, 0x8173a2e3,
- 0x6f53e515, 0x1f91e5f0, 0x2e3ddfa8, 0xb0fed8ba, 0xe9056070, 0x3cbe741b,
- 0x1bc4ef56, 0x233ac040, 0x77eed938, 0x25f65d50, 0xd412b8b0, 0xe2274d43,
- 0xdd12aa2d, 0x3c70e69d, 0x5167e354, 0x5ca3ee0e, 0xf55f682b, 0xa29bb457,
- 0x30fded7c, 0xb8f85a3f, 0x515dfb95, 0x98eee8a2, 0x576e5fc0, 0x1d06dcf4,
- 0x9e67f712, 0xb914cb47, 0x4522dd63, 0x4a8d2dd6, 0x9ac60f9c, 0x53f2123c,
- 0x82f51bb6, 0xb7ce9970, 0x028c5697, 0x9dfa8ad0, 0x5efe3e05, 0x539e36b7,
- 0xf2ca590e, 0xcbcb0e72, 0xaf7514b3, 0x7a40dc17, 0xc2fe5135, 0x2fc12ef5,
- 0x082bfad1, 0x1601d5b1, 0x06a8ad1d, 0x2701ceb6, 0x9b81e75b, 0x9da1f3ad,
- 0x83a00bad, 0x9f8297ad, 0xaf8170ad, 0xb83e580d, 0xf98832dd, 0x52bd7e18,
- 0xb45cbca4, 0xfc7ae264, 0x675e4571, 0xf9460797, 0x8f2f9f92, 0x614ae079,
- 0x2e4d9d74, 0xdd99b353, 0x923172ab, 0x5177e27d, 0xb5a14de0, 0x9dec0202,
- 0xf190c98b, 0xeb20d99d, 0x0702ae08, 0x48fee783, 0x5c069479, 0x04ee573a,
- 0xd89aa972, 0x7628764e, 0x5d364c52, 0x87d7d61c, 0x54171e56, 0x49d201bd,
- 0x3ebc60f9, 0x2ce88321, 0x5cfcae8a, 0xdaf190c6, 0x3a9df7b6, 0x8545a38c,
- 0x84362d95, 0xe53f590f, 0xf3e55970, 0xd91f0899, 0x9ba9d276, 0x595e7649,
- 0x1563b7a8, 0x39d86eba, 0x184dcf07, 0x4e50a3fc, 0x52824d92, 0xb1515d5c,
- 0x677e8079, 0x74ebac94, 0xdbc657e8, 0x5719c580, 0xd59f8014, 0xe46568b3,
- 0x7ebc3527, 0x7ae1635d, 0xbd706bdb, 0x60da7e4a, 0xc8cac5f2, 0x73759ad3,
- 0x6e5f2993, 0x3ff7f030, 0xbce72c9a, 0x22327282, 0x9841533e, 0x44f73c4f,
- 0xe4101c21, 0x186b5696, 0xf7c08fff, 0x77c21fcf, 0x5deb8a6b, 0x594dcf16,
- 0x534ffa40, 0x676779f2, 0x245d8a59, 0x3f8616fc, 0xd2d59310, 0x5207478a,
- 0x7bd21f9c, 0x776e18c1, 0x5eb95a1f, 0x329ab6ce, 0x27581f1d, 0xfbae0fd8,
- 0xe28f977a, 0x084827d0, 0xd599f3be, 0x34744035, 0x428c8189, 0xd11dd7d4,
- 0x27640cc7, 0xa80b1daa, 0x7fc8a5bc, 0x06bc039b, 0x96e51fe6, 0x2d98f533,
- 0xe5c107ec, 0xa5ca1ef8, 0xd2ace9c8, 0x8d4971e3, 0xa5ad1f7b, 0x3c2af6ae,
- 0xa2413c21, 0xad0a49a7, 0x1538bb20, 0x13e19eff, 0xb953a7e6, 0xabf12a3d,
- 0x6def4f67, 0x42741c69, 0xed361f84, 0x0fabe6f9, 0xa34ddf50, 0x0f5d3b66,
- 0x1696dffb, 0x1ab00bea, 0xd517c4d4, 0x1b75672f, 0x955fd47d, 0x397f3eed,
- 0xaf78abdd, 0xfa7146df, 0x1b40fee2, 0x9ec1cb95, 0x2fdc69c3, 0x6bfe3ad4,
- 0x93e4e7e1, 0x750512b9, 0x905ecbac, 0xabe446bc, 0x050bea99, 0xdc7c20f6,
- 0x47137684, 0xa9bf79f7, 0xbd0d95f6, 0x2fa819af, 0xc43c67c1, 0xff42ad6f,
- 0x5c37adaa, 0xad62f54a, 0xd62fdb57, 0x13d77bf5, 0xb43b75dd, 0xd9bf6afb,
- 0x4f5f7ca4, 0xea8d9af5, 0x26bded3e, 0xa8f337ea, 0x67eed3fe, 0xa6fd2a66,
- 0xa940ff92, 0x772a5733, 0xeb333f88, 0x235e0cff, 0x68fcd6f2, 0x7042dd8b,
- 0xe2ced9ba, 0x6606fd6d, 0xd87deac7, 0x446cc89a, 0x8ddadbf5, 0x5567eac0,
- 0x1b4ff98e, 0xfc8fa41d, 0x5d5993a7, 0xab3cf58c, 0xf09e3047, 0x22651efe,
- 0x173ddda0, 0x1114ca1f, 0xd93d73cf, 0x5fb7aa76, 0x7f80eb5e, 0x4fa6179d,
- 0x4ae7f7ad, 0xd40cab3b, 0x7d88dd47, 0xf7356e14, 0x4266d93e, 0xd01379b8,
- 0x3b2d240d, 0xe2a6ea8e, 0xe97812fd, 0x503ef01d, 0x1a976b8e, 0xbeb0524f,
- 0x9447908f, 0x09e4093c, 0xa2a379fa, 0x04ece8b7, 0xfd8c79cd, 0x71f7cd1c,
- 0xefda99a5, 0x6e7f0e3d, 0xfe73c509, 0x02e3bc7d, 0xc136fdcd, 0xcd91f76d,
- 0xbc3ff004, 0xb188ae57, 0xcd82bfc2, 0x17e7121d, 0x886fee68, 0xec9fb79d,
- 0xdd0bfcbb, 0x4b703b18, 0x01657764, 0x2f504780, 0xe7b586b3, 0x21db07c5,
- 0x1d47f116, 0x57998dd4, 0x16ea8078, 0x5fddaca3, 0x54c5daae, 0x4399aa98,
- 0xb73b919c, 0x9121d1fb, 0x9c0945d9, 0x117970f7, 0x5e0f59c9, 0x46dcbc79,
- 0x66fba569, 0x598bf303, 0x8a762dbd, 0x5a9d9347, 0x68d727f9, 0xd2ea9fe5,
- 0x956d3bca, 0x6ee9de56, 0x6dcfbcad, 0xead7cad5, 0xb6cfcad1, 0xfee69671,
- 0x0d4af6b4, 0x02f37d3c, 0xbdf3fdcd, 0xce70350b, 0xf734ab8e, 0xd32c7467,
- 0xaf77e79c, 0x76ab9cd6, 0x2e0ed636, 0xb18f35f4, 0x08c41133, 0x567aabfd,
- 0xff70a0ed, 0xff3c1aad, 0x1f6ffd6f, 0xc8a7ffa3, 0xbdde31d7, 0x37743b15,
- 0xd165ebb9, 0x999dae3c, 0x59eb9427, 0x9cb6f6bf, 0x77431558, 0x54e6fc95,
- 0xff941bf2, 0x0e16c391, 0x7df6fddb, 0x8e0acf14, 0xae88ab38, 0x1f7b80a2,
- 0xa192f385, 0xba38aaf6, 0x32d900ef, 0xe89c8f85, 0x02a5e5fe, 0x857e34e8,
- 0x3cb094f0, 0x93acf0af, 0xd972f0e2, 0x1636de77, 0x4be9c96e, 0xa120f3c2,
- 0x6a85e794, 0x22e81447, 0xeca152e4, 0x29e92503, 0xf3abf961, 0xc007ec23,
- 0x6880fd40, 0x2759b6f2, 0x9bec77aa, 0xb98f5625, 0x86f67d58, 0xa57362e0,
- 0x067f2645, 0x25dff7c5, 0xc4cedebb, 0xb44a76b8, 0x139eaccb, 0x54c46d02,
- 0xa4a31890, 0x76afa9e5, 0xed871f50, 0xff2bcd2c, 0xb56d4774, 0x6f919727,
- 0xb6f09409, 0x67f5fe99, 0xa2648eba, 0xcb0407fc, 0xf6fc42fa, 0x332759ad,
- 0x25197f28, 0xcd014494, 0xe9471c4f, 0x24dcccfc, 0x78c3f919, 0x0f65101b,
- 0xab73c289, 0x9390fac0, 0x08ccd8f4, 0x67a8ddff, 0xbe940b79, 0x5e451aec,
- 0x54b65f6a, 0x4f803fc1, 0x7e78c2ac, 0x4c1bf74d, 0xc329752e, 0x6dca1cca,
- 0x37fbe0b7, 0x5017354c, 0x428e0a5f, 0xd5e7ef3b, 0xfa4d2d3e, 0xed557929,
- 0xbf76cf6b, 0xd348652e, 0xc4cec32f, 0x6391e709, 0xbe615ee7, 0x9b03fbf9,
- 0x1a1e59a2, 0xe6ce94d8, 0x4ff7e18b, 0x71aff7b1, 0x93b1a3bf, 0xd7df5aeb,
- 0x9ef5dfd8, 0x81e7348f, 0x0d3e90a4, 0x4aec0ff9, 0xca35779d, 0x6305e46f,
- 0xa8abf509, 0x715b38b7, 0x3dc0fdf8, 0xbe10e7d3, 0xa7e7cdff, 0x6bfdbe4c,
- 0xa6ee6cfd, 0xed6c79f2, 0xd6070611, 0x963ad806, 0x55bfb54f, 0x20dfc357,
- 0x90e5ea9b, 0xd13ec930, 0x1b31e6bc, 0x67fa83ef, 0x7ca4a94f, 0xd06e9fdc,
- 0xc38b35f1, 0x0e26a5a9, 0x6b4f9bcf, 0x48de6f50, 0x00bf6dfd, 0x61ed010e,
- 0xec7ce0a9, 0x3abbe47a, 0xa36b95d9, 0x2875727a, 0xd0fe874f, 0x56b81f94,
- 0x1ebe7d40, 0xfe27caef, 0x53062c05, 0x599d1813, 0x890c37d4, 0x63013c9e,
- 0x764f4dc1, 0x3ffd5357, 0x8a73c934, 0xadad7632, 0x83fa9aab, 0x8ff70321,
- 0x847c9e5b, 0x16b7c3f9, 0xe77a4cd7, 0x31f24113, 0xf0497e7b, 0x16f6676e,
- 0xf88c2c30, 0xaf3a82bb, 0xfa9b7ea1, 0x5f14609b, 0xdff8db67, 0xacc72a5f,
- 0xae3c6d4b, 0x316b42dd, 0x2ceee5e9, 0xe8ca7bfa, 0x5f902366, 0x48873e20,
- 0x5cf87af8, 0x40f20a76, 0x6f560d75, 0x78285fac, 0xf8a3e8d5, 0x1675cea1,
- 0xbdecacdb, 0xd79f1b24, 0xf467dd24, 0xeefcb1b6, 0x3a46a8cf, 0xef58f5db,
- 0x1070df50, 0x846d1cd8, 0x7a1161e6, 0xfde36c59, 0xc008dc17, 0xd1b793cf,
- 0xc0ef4379, 0xdf278a31, 0x24aeba67, 0x72880c39, 0x8693c509, 0xdeacbdd8,
- 0xecc9b66b, 0xf197a43b, 0x4ee1718f, 0x382fcfd2, 0xfa455c0f, 0x7805306d,
- 0x03ccaadd, 0x91b726cf, 0x7287fee5, 0x9ecbfcd9, 0xf4a9f441, 0xb6cdfd22,
- 0x4a9db988, 0x1f9df87f, 0xae750bf6, 0x5b83c2a5, 0x9f916436, 0xbcf85ea1,
- 0x5bae1251, 0x0ff7c138, 0x963efa2a, 0xfe10f4e2, 0xf73e6ed5, 0xfb4ddb0b,
- 0xcf4947cd, 0x271666bd, 0x58fdf6cf, 0xf4f61b3e, 0x9f207932, 0x117f12d7,
- 0xc91bde7c, 0xe1cf48e7, 0x9fe57287, 0x9d305fcf, 0xb8291dff, 0x190c9bed,
- 0xfdd86fbf, 0xbbb211c6, 0xdf1e7506, 0x18339da5, 0x9aff6127, 0x1d1cd130,
- 0x5d444fb3, 0x9fbf5466, 0x8f7ed3aa, 0xa9cd3905, 0xa9dfc9bb, 0xbff0717e,
- 0xb8f9a98b, 0x846be94b, 0x1f2cebc0, 0x87f23e10, 0xe58782f5, 0xd18e7545,
- 0x23de6026, 0x585abadd, 0x35ce909e, 0xbb9ec9db, 0xe4fd06d0, 0x34473a07,
- 0xe98f5f9b, 0xb835bfa3, 0xd6fc9176, 0x4c9953bc, 0x9be7767d, 0x8d7e940b,
- 0xc562a9e7, 0x3f098b2e, 0xc71b9fd1, 0xa148b5ec, 0xf584c4af, 0x7c852650,
- 0x15e7c48f, 0xd363fcca, 0xef3e9aeb, 0x685932bf, 0x001e0053, 0x00000000
-};
-
-static const u32 usem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x1915c58a, 0x19d44418,
- 0x18344c18, 0x20685618, 0xb58969c4, 0x9fd329b8, 0x90c0c2c9, 0x40b9c40d,
- 0x7cc40f9c, 0xfc0c0c4c, 0x17ebc44c, 0xf5b04514, 0x84181904, 0x026ffc80,
- 0x85d70c0c, 0x8bbe1818, 0x03083030, 0xf1402ef9, 0x01ce2004, 0x58a06f62,
- 0x045e900b, 0x2c40ddc4, 0x7cdf8a22, 0x6bf20251, 0x37f95185, 0x847bf8d1,
- 0x1057ebf0, 0x47af2fc1, 0x161b1e40, 0x3e3f22d1, 0x3bd02922, 0x015f5810,
- 0xc7265f95, 0x0f27d0c0, 0xb8a87f8c, 0x4bfc9201, 0x0e5cbb20, 0x6096f6c2,
- 0xf2062860, 0x9bb0150d, 0x2f9403eb, 0x857dca01, 0xcc0003ca, 0x688cbacc,
- 0x00688cba
-};
-
-static const u32 usem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0x4514780b, 0x74f570b6, 0x9924ccf7,
- 0xf2124c99, 0x00493de0, 0x210e0311, 0x9970c044, 0x46a2c024, 0x141a020d,
- 0x84920275, 0x7e889790, 0x33feaeec, 0xa8a08901, 0x17acb9f1, 0x376141dd,
- 0x0c06e8b2, 0x60e03518, 0xba2eb300, 0xe7c045c1, 0x36bc8026, 0xb9f04324,
- 0x9d6f5ecb, 0xdd33d553, 0xc7c4099d, 0xffef7fde, 0xa55f9f8f, 0x71ebaaba,
- 0xe9d4e7de, 0x278f3242, 0xdf210a64, 0x9f968fc1, 0xf890848b, 0x206f5950,
- 0x8841922e, 0x6df466d7, 0x88cfa64c, 0x68e67a23, 0xd11d985a, 0xef435837,
- 0x9ed5cbe9, 0x186934a4, 0x1c790f21, 0x23e21258, 0x5ab54e84, 0x16f50520,
- 0xe0933ba8, 0x213e3a7d, 0x0ff8e8fd, 0x30f8e246, 0x1a18992d, 0xe0311067,
- 0xf9ad537b, 0x421eb089, 0xc3e6476a, 0x213b16fc, 0x9f9f7bfd, 0xa7eb888e,
- 0xf7c10def, 0xb59efa24, 0x6529efef, 0x13fd0e57, 0xf66ddff6, 0xf108146d,
- 0x71c7fcef, 0x8699ef58, 0x5d130e39, 0xd9b7766f, 0xbeea053f, 0xb6899f6c,
- 0xc0fb6ee7, 0xe5fed126, 0xda0944db, 0xf0233b0d, 0x8275cefd, 0xa695ea0f,
- 0xa4ae47d6, 0x9136c0f5, 0xf8d30f3c, 0x4092062d, 0x613371c8, 0xeb15873f,
- 0x5aac1145, 0x6dd77ebe, 0xa3495f30, 0xf7d04489, 0x2e88378f, 0x28d92fa8,
- 0xaf9d08f8, 0x8c07b5fc, 0xc578e803, 0xc23ea13e, 0x1f1beb41, 0x3ee83a33,
- 0xd8fcef97, 0x7ce146d6, 0x0e2663da, 0xa4a3ee23, 0x52908d3e, 0x03e996df,
- 0x9ba5fbe8, 0xbe802705, 0x4ed9dd74, 0x83695f58, 0xe3a45c3c, 0x228bae2d,
- 0xee6c918e, 0xd7cc08ef, 0xdbe7147c, 0xf9830f26, 0x65dfce4a, 0x6ee52404,
- 0xca2e9193, 0xdf603ae9, 0x3da7bcca, 0x053e716b, 0xd22fe59e, 0x8abf68f9,
- 0x6c270597, 0xdc40c2b1, 0xd7ce8eb0, 0xb05e0a22, 0x8daafec0, 0x7deaac23,
- 0x7d876e14, 0x1bd6fa94, 0x7d605ba7, 0x69458deb, 0xd716f1a1, 0x7d76a7fd,
- 0xdd13536b, 0xf3e3bd69, 0x748287b4, 0x4a5ea844, 0x4fe90b88, 0x8e8119f2,
- 0x85e7e795, 0xe2f7c418, 0xcc38913a, 0x3a15f1a1, 0xe9c07ef0, 0xf1958774,
- 0x12dbc701, 0x842ce03b, 0xc73b6eb7, 0x54c814a3, 0x8f94af8f, 0x7ae83e00,
- 0x2c763d6a, 0x6124f71f, 0x81c7a4f9, 0x33da7b70, 0x1eb5cb12, 0xc67f3e27,
- 0x75cb0133, 0xcf96171e, 0xe9606679, 0xbf63e4f3, 0x58053de7, 0xf1b8f06e,
- 0x253d6ff9, 0xaa79d658, 0xcf26f9f0, 0x7b372c32, 0x65fcf8bc, 0xeb2c2acf,
- 0x6e58b53d, 0xb2d17c05, 0x7ec3e3c1, 0x58753ddb, 0xf1ea7a36, 0x469eebf9,
- 0x3870d72c, 0xb648b2da, 0x7360e144, 0x3b453b11, 0x6573cd89, 0x9b1eb4cb,
- 0xf309eacf, 0x5a46d9bc, 0x3ad3704f, 0x3280cb85, 0xd689b67f, 0xf6b15407,
- 0x1c92f721, 0xf10fad33, 0x3594f6b2, 0x5a089cae, 0xed65a94f, 0x7379d623,
- 0x847d6922, 0xda8fb58f, 0xa289cfec, 0xacf551f5, 0xc9134c7d, 0x18fad0b5,
- 0xefa7ab3f, 0x695ae573, 0xd595bd3d, 0xe6f13f33, 0xb33d68da, 0xa93fbd8d,
- 0x2c3a27c3, 0x55b0f13d, 0x14202c76, 0xb9de4d57, 0x9bca892e, 0x5dc746ad,
- 0x7bc849c4, 0x892ef9de, 0xd90687ca, 0xde6ded85, 0x746eacc5, 0x77b77b61,
- 0x2edff629, 0xaa5db1bb, 0xb7db0fbe, 0x9ed8dd1b, 0xed835d50, 0xdb17b28d,
- 0x8a3f5647, 0x2f468ded, 0x5eaa4fb6, 0x65d7f58b, 0x55e7b61f, 0xaffec7af,
- 0xfed87d1b, 0x5c9bfdf8, 0x05fd6953, 0xe41dbdc1, 0x5dc10ade, 0x9e815242,
- 0xee4093ea, 0xf9f970d5, 0x6d1d101c, 0x446fe9af, 0x6efadc3e, 0xbfc00be6,
- 0xf507ebf8, 0x983edfa2, 0x89bce38c, 0x1c74c8e3, 0xa4e3e2f1, 0x334137bf,
- 0x257bfa4e, 0x382d38ca, 0xc6df444e, 0x24defad9, 0x2bde7aed, 0x0fd9c655,
- 0xdac2b4fc, 0xffa57db7, 0x9ebb4b39, 0xe329973f, 0x89eb847c, 0x1a7adbe9,
- 0xa7c2d03e, 0x7c2083e1, 0xf138e28e, 0xc64f5b7d, 0x327c2d41, 0xd3e1060e,
- 0xeff4e381, 0x070d38db, 0x3869f0b5, 0x97cf8418, 0x7dc19f08, 0x21c657db,
- 0x0e327c2d, 0x5ff3e105, 0xbee49eb8, 0x53fdb38d, 0x7fb67c2d, 0x498f841a,
- 0xef0cf580, 0x3f32bedb, 0xf327c2d3, 0xec7c20b3, 0x7da5ce38, 0x67fb671b,
- 0xff6cf85a, 0xfe9f082c, 0xbee8ce38, 0xaff32bed, 0xfe64f85a, 0x149f0835,
- 0xb633e001, 0xfc69eb6f, 0xc69f0b5c, 0xb9f083cf, 0xdf19c70c, 0x384cf5b7,
- 0x84cf85ae, 0x64f841e3, 0xf626bee0, 0xe3c69c6d, 0x1e34f85a, 0x3267c20f,
- 0x6fb9338e, 0x42709afb, 0x27099f0b, 0x8e99f082, 0xebbb64e3, 0xc7465198,
- 0xce3ef6b1, 0xf0b467eb, 0x104cfd79, 0x38e3d73e, 0xa938e8d3, 0x52671f17,
- 0x933e16a7, 0x29f0833a, 0xeaae71c0, 0x77af38db, 0x7af3e16a, 0x853e1067,
- 0x7db5ce38, 0x2ea4d7db, 0x75267c2d, 0x3b8cf831, 0xa36b9550, 0x3a1754ed,
- 0x95cafa45, 0x40972e1d, 0xd59da2eb, 0x8093bb45, 0xf62a225d, 0x89756906,
- 0xe6cb7df4, 0x8907f498, 0xb9c8eeda, 0x4ac7e813, 0xddb531ad, 0x52213d11,
- 0xb8c4e763, 0xb8f53562, 0xfd340319, 0x3453f3e3, 0xa30589ed, 0xddfded34,
- 0xc0fa9ae9, 0xfe9a4992, 0x3472ab83, 0xaecba1f5, 0xf64ff4d6, 0xa7a9a0de,
- 0xd359baae, 0x7ced787f, 0x6b25fb4d, 0x97ed354b, 0xea6896fa, 0x42fdd597,
- 0xfd747fd3, 0xe5fb4d72, 0xda6a0f8d, 0xd71ffac7, 0x3cb5c7d4, 0xbe3fe9a3,
- 0xfb4d79f5, 0x69378715, 0x6db627da, 0x3cafd4d5, 0xcecebaf9, 0x5f8fd8b3,
- 0xd022ebc6, 0x7f76613d, 0xf8f7e67f, 0x1bac46ad, 0x8ed05807, 0x722d65df,
- 0x35f8a31c, 0xd1c0b5be, 0x7017e28f, 0xf6457e0a, 0xda4b9280, 0x267bf3e8,
- 0xd3b12fb9, 0xdd18f7e7, 0xd8c3db97, 0x041e94a7, 0xc3a50492, 0xfdbea500,
- 0x63d19901, 0x23f3c0ce, 0x95fbe9da, 0x1888c086, 0xb312cf5a, 0x777e811b,
- 0x8a2fcc0a, 0xf4154914, 0xf411348b, 0xce481e0b, 0xa2abc17c, 0x298355d7,
- 0x71a10a1f, 0x24eec957, 0xaade33b0, 0x1d82f76e, 0xee983352, 0xcd21006b,
- 0x4bdfbb42, 0x0607b4fd, 0xe9b92517, 0xb5232678, 0x1bf3d5d3, 0x3869fce9,
- 0xebd00b7f, 0x7c7f307b, 0x294df9cf, 0x9bf33413, 0xe6689487, 0xfce91b37,
- 0xafde4276, 0xa7e7c53e, 0xc8449848, 0x3853845f, 0x094869bf, 0x9180ffce,
- 0xf9ea2bfa, 0x1ff38323, 0xd67ffd86, 0x2653fedb, 0xa43ff769, 0x237fbb54,
- 0xea91ffdb, 0x48fe7cb3, 0xe151ffdc, 0x90ffdb2c, 0x137fb652, 0xbf38371b,
- 0x93ff082d, 0x2f677f30, 0xb3529bf3, 0x5a1ffbb4, 0x89bfdda6, 0xfd5ddfcd,
- 0x82df9f2d, 0xbe139ff3, 0x5a1ffb65, 0x4d1bf386, 0x8fd0276e, 0x95646071,
- 0x1d4fce8f, 0x04490761, 0x40f3a172, 0xfd163239, 0x148497e4, 0x913dc75c,
- 0x8abede8c, 0xf286f4a4, 0x58fccbc6, 0x996c951f, 0xb4e2efd4, 0xb67378be,
- 0xb612e411, 0x21657f53, 0x8d1dea5f, 0x7937d222, 0x4e1be4d2, 0x28d9dbd7,
- 0xc77ea17a, 0x207d9393, 0xe44d2aff, 0x4f787cf6, 0xfe787e22, 0x9fa353f9,
- 0x5f4bef57, 0x8f95ac2e, 0x2df8a9b7, 0x90e547e8, 0x98165591, 0x1fa9aed7,
- 0xa1107ea1, 0xd427c5fe, 0x249420cf, 0xbe6cca8f, 0x04bfa8cf, 0x2fea36f5,
- 0xd5213b41, 0x75e25fb8, 0xae8c307d, 0x3f289f3f, 0x26f3ee17, 0x9e3a2964,
- 0xc8f7f8c4, 0xf807c11a, 0x14597db8, 0x3d687e05, 0x4d38de85, 0xfb0fee9d,
- 0x7c12ae07, 0x86380bcf, 0x9333e01b, 0xbd60478f, 0x67605eb4, 0xe8a21cef,
- 0xb0514fef, 0x8a40d560, 0xb338d08b, 0xa44e4b88, 0x5a59cfef, 0xa2e84328,
- 0x2f061055, 0x2059fa01, 0xe0119753, 0x69278de7, 0x7ae8389c, 0xf1b3b66f,
- 0x63e4ba67, 0x14f5aa6d, 0x3e5766c8, 0xa1414f5d, 0x359feb88, 0xd1fedb43,
- 0x619728ce, 0x3d572d0c, 0xc9ccf381, 0x54dfb6d7, 0x75cfada0, 0xef54eb6b,
- 0x6ef7a0c9, 0xa73fd129, 0x9cfba160, 0x5d2b8417, 0xade75d28, 0x56b70e1c,
- 0x5e0d5ec9, 0xda556dc1, 0x26e0a021, 0x5f7c2fb8, 0xf6ffd9ec, 0xa17ada65,
- 0xb05f5b57, 0xa73e374a, 0xff1ce39b, 0x683e8047, 0x83e80279, 0xa718f3c2,
- 0xd55c908f, 0xc18dc7d2, 0x50fa306d, 0x625c71f6, 0x8ebe3828, 0xdac2c7d1,
- 0x50f4f0a8, 0x9707a418, 0x7a14be9a, 0xc3d38db8, 0x8a1e9ca7, 0x6ae96ad7,
- 0x4cadf12e, 0xb2dfefa2, 0xe9e21766, 0xe8c850a0, 0x3d0a97e1, 0xc1e869b4,
- 0x8f41e9cd, 0x3d38dbbf, 0x4673f6dc, 0xb67c7a0f, 0x5b687a71, 0x29264e7b,
- 0xf14af13d, 0x3c53a9a0, 0x376ef0e8, 0x7c503d02, 0xf987a584, 0x8dd37dc1,
- 0xde02fad3, 0x9c5f03d6, 0x053db01e, 0x4e104ec0, 0xcf6a7ef8, 0x684e54fe,
- 0xc36bc5ea, 0x31b2bfe3, 0x6a98ee3b, 0x57f5e55d, 0xf5531dc5, 0x53375c5b,
- 0x9be45f53, 0xbc5fe9ab, 0xbed350b6, 0xa69176b0, 0x3baac17d, 0xef42f535,
- 0x6ffd35cf, 0x69ad565f, 0xb56ab5bf, 0x9296fda6, 0xb9f534c7, 0xfa6b5fee,
- 0x5eb054df, 0xff273ed3, 0xacfb4d45, 0xf5345b19, 0x34d7ae99, 0x2f3b0dfd,
- 0x31e81ebd, 0xc048a0eb, 0x71e638fe, 0xf71fdd20, 0xa4f2c48c, 0x717c89c7,
- 0xcb0133da, 0x4fcd8d7d, 0x7cbb495c, 0x26882819, 0x91167f4c, 0x2cf64218,
- 0xcaaf5777, 0x504e7d02, 0x7971feef, 0x1077b551, 0x07065395, 0xad6f39c2,
- 0x11c7f891, 0xe2528022, 0x50c407f3, 0x6d1b567b, 0x3dbdeb8f, 0xb614ad6f,
- 0x0a4dab3d, 0xe3e56e3b, 0x61ed4385, 0x7e2133e2, 0x3ec10326, 0xb9f6e2ea,
- 0x204cbdbe, 0x84e7eaf9, 0x8ffe472c, 0x5cfd3031, 0xa2726466, 0x1cff6b6c,
- 0x7fba8362, 0xe685d544, 0x95cca7ab, 0xaa91f408, 0xb5e2e3e1, 0x3ce46997,
- 0x3c6de881, 0xcd38d9d0, 0x5775c5f3, 0xd8ebde6a, 0x2bbae225, 0x7d508640,
- 0x07e48c3d, 0xfd97a00c, 0x8d6643cd, 0xceba7586, 0x355e401a, 0xd8fda3c6,
- 0x771199e1, 0xe63c024c, 0x53d27963, 0x8f71e580, 0x9e63cb1b, 0x788f2c12,
- 0xf36cb0aa, 0x33f2c32c, 0x4fcb178f, 0xfcb0ab3c, 0xe58b53c8, 0x2c5acf61,
- 0x587c7a0f, 0x61d4f01e, 0x1ea7bef9, 0x234f56cb, 0x171e9d96, 0x29bf0a96,
- 0xddd3d0f0, 0x4fa7ae49, 0x805dfd03, 0x07c4e2ce, 0x0a0d57aa, 0x8ae259d1,
- 0x59bdab87, 0xd6f371a1, 0x249d389a, 0x0861e868, 0x81e364f8, 0x5e9c4c5e,
- 0xade7b7c2, 0x9ed82f95, 0x1d8726d5, 0x7ff9f2bf, 0xf9cdbd0d, 0xa216f491,
- 0x7a3a81a7, 0x3d18bd4a, 0x87c7124d, 0xc18e69e8, 0xa71ff4ce, 0x1f6087a7,
- 0x628ffc61, 0xabc6ea30, 0x14573aec, 0x73f3678b, 0xb2d16a07, 0x7b9f3678,
- 0x15ae1d05, 0x48df3fed, 0xc8f773c0, 0x78808fbf, 0xaa61f77d, 0xdf7b9328,
- 0x7a5e9e9f, 0xfd0bbb87, 0x551f22a0, 0xb67ae3a2, 0xb8324447, 0x0cc81846,
- 0xeac84e92, 0xce75bfe1, 0x44bac34f, 0x9f7de162, 0xf3986673, 0x4f670228,
- 0xeb871789, 0x6357eb0a, 0xcfe3bc60, 0xca1323fc, 0xe6148639, 0x688b34df,
- 0x0bff13df, 0x506f804e, 0x499c991f, 0x0c0f0710, 0x3ed1da37, 0xf0b459f0,
- 0x667ad2f3, 0x29ab7e08, 0xdf515a8c, 0xfc2126d7, 0xa2357d86, 0x77e01f7f,
- 0x317f3931, 0x0df7ce78, 0xf3c097f8, 0x62f1f262, 0x1cb89172, 0xfdd2372f,
- 0x9d1ced77, 0xe403a0fe, 0xade185e0, 0xd7e95f9c, 0x7d28bcf3, 0x4aee3a2f,
- 0x75b8e850, 0x88f3a108, 0xefc71da2, 0xc984b86e, 0xdbeec52f, 0x05f5f266,
- 0xb59267af, 0xf9c53de3, 0xbbaf194f, 0xf81b05e5, 0x0c924b5b, 0xf06163f6,
- 0xf5e594a0, 0xda8b76c9, 0xd6d46cfe, 0x19856bbb, 0x3a2768f5, 0x068f67a2,
- 0x1fb7613d, 0x3b72061b, 0x9c654b09, 0xfb464925, 0x4ef72a31, 0x3346a5d7,
- 0xe4c7cf3f, 0x9418e6c1, 0x663da717, 0xaf53ffec, 0x9471b7a7, 0x40d210f5,
- 0x1e419a8e, 0xded4b6d3, 0xcf4af7fb, 0x3c4617d2, 0xbf926df7, 0x4cd0fb02,
- 0xfc0effff, 0x5d61220d, 0x5eb2b719, 0x872e9af4, 0xf3359be7, 0xca1cf7d1,
- 0x2977eb19, 0x891be217, 0x96e8571c, 0x5c638bea, 0x8bae2c9f, 0xcfed6bb0,
- 0xb2bd4d18, 0x635dbfb1, 0x541fc28f, 0x412a92fe, 0xe329fa02, 0x5925d3e4,
- 0x7d740956, 0x1090426f, 0xfd6056e8, 0x466dcdca, 0x95ce03b7, 0x5b7ade19,
- 0x4cdfc51f, 0x897c9289, 0x61cf16b9, 0x9d2fea4b, 0x4ce67a0a, 0x88048ac3,
- 0xbb162c1b, 0xf30fc9ef, 0x79312cbe, 0x0727c8bf, 0xa73df6b4, 0x55c7420f,
- 0x945c639e, 0xeaab8e58, 0x8f16061d, 0x009b8fd1, 0x1c5fc6e3, 0xf79b153e,
- 0x413b074f, 0xc68aa70f, 0xca3746b3, 0x665ffa45, 0xfc0a4e08, 0x13f314de,
- 0x697e3a24, 0x2dc63b5d, 0x11deca4e, 0xbc80bcbf, 0x4b3fb9ec, 0xd528f1d2,
- 0x15a4bcbe, 0x813f99e6, 0x371c444f, 0xf8e54c7d, 0x04c93fa9, 0x4f3910e4,
- 0x4862657b, 0x063bfb86, 0xf90cc862, 0x161bf33b, 0x4fbc01e7, 0xe547bf81,
- 0xdf241de6, 0xb5207886, 0x9cdfe099, 0x00198621, 0x7de433a7, 0x1e1538db,
- 0x87232572, 0x94829533, 0xf1c14c1e, 0xefc1fddd, 0xb4d41532, 0xb9e0638a,
- 0xc23ff8a4, 0x72471877, 0x50b7980b, 0x897b9ec0, 0x97e81ab9, 0x3f1a51fa,
- 0x9a51fa8d, 0x34a3f53a, 0x437222f5, 0x1425e402, 0x9f13293d, 0xb4d27080,
- 0x88ec928f, 0x555262c7, 0xafd1f603, 0xbe6dfc79, 0xe903489d, 0x7d5fcb3e,
- 0xee90b336, 0xc5896ae7, 0xf57394fd, 0x0e0cb145, 0xa33e25a5, 0x7f73d2cb,
- 0xddc61b47, 0x8c3f2548, 0x6fcfcec7, 0x051e6236, 0xdc994ab4, 0x7de949f4,
- 0xa20d89ff, 0xfd06c22b, 0xbd6573e8, 0xff7fdfc9, 0xf212fdfa, 0xb4a3ee38,
- 0xfa01266e, 0xc02791eb, 0x09d723f7, 0x7e185f2e, 0xaf74e42a, 0x013ba7e8,
- 0xf143e37e, 0xf574fbac, 0x4abe1cd5, 0xfb5d29fd, 0xfd2f960f, 0xbcbe4688,
- 0x93efba29, 0x027933c6, 0x00a417f0, 0x1e0fd7f2, 0xf8c7a93f, 0x7f1f81ab,
- 0x6907f1b2, 0xff8e9ef9, 0xfeba4fd4, 0xbfd63d61, 0xcbfadc3e, 0xbb697d5f,
- 0xd297ea97, 0x23653c3f, 0x494edf94, 0x8a4e09b5, 0x2b8db2f7, 0x3b902e6d,
- 0x7c06d792, 0xce27ca71, 0x870f4708, 0x06a57cb8, 0x78804588, 0xc749fc2b,
- 0xa1e9bd3f, 0xf89ec0eb, 0xc76ca36a, 0xc99d6a38, 0x5cf4a26f, 0x8f28b0d1,
- 0x3b7ac18c, 0x16703fab, 0x51b2bfe8, 0xd3a6a23e, 0x953ddfd2, 0x94357900,
- 0x921a0652, 0x7fa3f4a0, 0xf3e1b152, 0x546f60e9, 0xabf20092, 0xff983dfe,
- 0x87d4589b, 0x9ee8c685, 0x499818ed, 0xafd9f780, 0xb3a1e1b2, 0x6afe0da2,
- 0xbe9038c3, 0x37f7097f, 0x3f6b245a, 0x82b9273c, 0x54f2015c, 0x31f10781,
- 0x8bc5637f, 0x4ed31abf, 0xe1b1d3d7, 0x0541364f, 0xea4fc527, 0x9bf05fae,
- 0xcbbd1dd7, 0x87ca4eef, 0xd156bb6a, 0xee468e4f, 0xb2b13527, 0xaedbf64c,
- 0x6ca4f2a4, 0xd2f4ecbd, 0xbd2f65c7, 0x2067dbf0, 0xc9a1fd7e, 0xbf8e9c39,
- 0x073da5f8, 0xe2fad127, 0x3cbf722d, 0x908b0db6, 0x254bc210, 0x7a597ffd,
- 0xafa50f08, 0x463a31ec, 0xc6f7e7b3, 0x78b1f086, 0x19232ecb, 0xb91e13dd,
- 0x6d8cbbf5, 0xa9783096, 0x760e9f6f, 0xbf178adf, 0x3bbc8236, 0x892053b5,
- 0xb9e061c9, 0x85da0f7e, 0x23c42700, 0x6f1053c7, 0x1495feba, 0x145fa02f,
- 0x37dbe93c, 0xe3027971, 0x9e90d239, 0xce9d7e5f, 0xc991f25f, 0x792ffb09,
- 0xec1b2ef9, 0xc55484e3, 0x95d9fae8, 0x4adf2009, 0x1d826f64, 0xe4bcf64b,
- 0xde91bbb9, 0x9ddff78a, 0xae92e2c0, 0x95d406fe, 0xbfb0fede, 0xe0e6eb85,
- 0x1b888afe, 0x59e4aee9, 0xcb47df31, 0x6332252f, 0xb8be184b, 0xf2726656,
- 0x2354f3c4, 0x509dfdd0, 0x22fbc0f4, 0x627703d7, 0xbe6ef3dc, 0x62316a17,
- 0xc3334bfd, 0xc0d930d3, 0x2bd32ce5, 0xf0dd7a41, 0xd38bea00, 0x70895d83,
- 0xd21956be, 0xc437a80f, 0x1912d3fd, 0xc19e987e, 0xc99ea8f7, 0xbfd0e785,
- 0x8c457655, 0x7a87bcd1, 0x297f9945, 0x3bae9f9f, 0x13b5ec12, 0x8ffde109,
- 0xdf0acb9f, 0x4542bb53, 0x66fe2a5f, 0x3561befc, 0xdf856fe3, 0x4067337d,
- 0x180717fb, 0xa07bc0ff, 0xfcbae967, 0x6bbed889, 0xc0f280b6, 0xf8e1fc44,
- 0xf9cc837a, 0xd0aedb5a, 0x24b75d09, 0x05e8ab44, 0xf8458fc6, 0x7a2f5ea3,
- 0x92a7be92, 0x9f309597, 0x0a78e7ad, 0xfe7316df, 0xf96b219f, 0xef8bac9f,
- 0x99653e53, 0x33edfbec, 0x3f94afc0, 0x57e00ebd, 0xfdf61f39, 0x07cdcdb7,
- 0xfa7ca66f, 0x4f857ab7, 0xcf53f2b5, 0xef5b25a7, 0x7a9f4026, 0xa0dbfd3e,
- 0x4f96122a, 0x7cb0f3e9, 0x7feda83a, 0xf02a7e54, 0x45f802ab, 0xc8a7e085,
- 0xa8e0dec3, 0xd9568797, 0xd21e5611, 0xd99201df, 0xba14fe93, 0xf4ade853,
- 0x4143e5f7, 0x52e904ee, 0x5d20bba1, 0xdfa7742a, 0xfa7e16af, 0xc13249f6,
- 0x26bfe575, 0xd65cffa3, 0xe942f2c4, 0x66077b7b, 0xa85c9c20, 0xdeed48c6,
- 0x75d4fd81, 0xaf5eae9f, 0xd5d2efeb, 0xddfd75f3, 0xa6957aba, 0xb363597f,
- 0xfdfe2091, 0xb2e27e9a, 0xb8d1c867, 0x63eaf470, 0x59c3597e, 0xc2e817a3,
- 0xe5f7c012, 0x790bc4e5, 0x221d8186, 0x28ba05c6, 0x7e206b8c, 0xe7d939b1,
- 0x656372a5, 0x743f8b04, 0x58b603d9, 0x618cae5a, 0xb1bc40f5, 0xf29ee406,
- 0xe2c1103c, 0x01f95d8a, 0x9fca8c5b, 0x51126f6a, 0xc8f9b76e, 0x167e708c,
- 0x47c828d5, 0x76b7a46d, 0x4d35ee76, 0x06590cb4, 0xd15aa571, 0x1df83609,
- 0xe0d937d5, 0x29aba9dc, 0xfa02faf5, 0x451fe17c, 0x8ae97b4c, 0x75818db4,
- 0xea4baf11, 0x4e6ff2af, 0x59d3ef12, 0x9a0b7f74, 0xc7739f98, 0x423d9d1a,
- 0x153d20d6, 0x411a9659, 0xe27f529e, 0x86bcf688, 0x1f2945f1, 0xb69d64af,
- 0xd29f795d, 0xa5f3fa01, 0x6eedb41b, 0xa07f0fee, 0x3258c9f0, 0x2ca3fb96,
- 0xf2e5c30e, 0xfaed3134, 0xae8f8a02, 0x68989116, 0x4449bbbd, 0x166f747c,
- 0x234f107c, 0xb7e478de, 0x7940120a, 0x03a9c0a8, 0xbbd8c9f8, 0xf6d8eabc,
- 0x812fe669, 0x3c7fb66e, 0xd9693fe6, 0x11c3fdb1, 0xd5fd406f, 0x263e4343,
- 0xeee7fb3d, 0xff73c08c, 0xa4569dae, 0xef1daef7, 0xd425f90e, 0x6139335f,
- 0xbf3b5d9d, 0xd3f4031e, 0x0254dcb5, 0x306baef2, 0xd8aec78b, 0x3698f5f1,
- 0x33f7afd4, 0xfe6461fd, 0x3fd37761, 0x41fa133e, 0x76057749, 0xe428cec3,
- 0x23d7caa7, 0x6bbbdf30, 0x6e99d7c7, 0x9fb74fcb, 0xd1e79e0a, 0x5b052565,
- 0x2c317d61, 0x8df2a18f, 0xd3542f89, 0x761bcbf9, 0xf6d01719, 0x39ff37dc,
- 0xd768e406, 0x750f6656, 0x41cf6dca, 0xf194431e, 0xe29972dc, 0x8a9813ab,
- 0x33bfcd3a, 0xdf02e466, 0x3fcb84f4, 0x57d63e31, 0xaffca478, 0x62e08781,
- 0x33eacef2, 0x6fefb00b, 0xe318fb3f, 0x4ba4269a, 0xab7fbf65, 0xe57b46af,
- 0xfecefb62, 0x82df6e7f, 0x76fb2fbf, 0xfbef9bff, 0x7abbd738, 0xe749e83e,
- 0xfac1ee3b, 0xae27564b, 0xeef48fb7, 0xffc7fd85, 0x7bffeefb, 0xc52b7de3,
- 0xfbe2edbb, 0x5affcdfe, 0x36f1ffbc, 0x7e3b778e, 0x3fe6f3d7, 0x57df7d71,
- 0x6ff9bdce, 0xf6def78e, 0xadf5d8af, 0x067b2a86, 0xa9015f5d, 0x316182b5,
- 0x92dbbe37, 0xd76c80e1, 0x8f30fd73, 0xc34bce0e, 0x23014df8, 0x904d0bf3,
- 0xfb7e0747, 0x0b89411c, 0x1d751fa2, 0x1bae1fb7, 0xc8768254, 0x9987ae75,
- 0xb55520dd, 0xadfed366, 0x989c0b39, 0x0fd24973, 0x7b3ea1bb, 0xfd6baf32,
- 0xe204f7c9, 0x7f1da812, 0x2d35ce5d, 0xef5ed760, 0xa5eed112, 0x1fbbda25,
- 0x9ece990c, 0x3dfad04f, 0xfadadd73, 0xfada054d, 0x8dde3e1c, 0xc6ffad84,
- 0x7107c17c, 0x13f65355, 0x356710f1, 0x9089942d, 0x5542f90c, 0x98bfc12b,
- 0x7f7daf93, 0xe3c1f81f, 0x531c3c7f, 0x971c0a4d, 0xb6485c20, 0xfa48dce8,
- 0xeebe4700, 0x7d63d9d6, 0x244ccf90, 0x8de38327, 0x838c4ee5, 0xe65b7f73,
- 0x5596cbef, 0xb2cfc0ad, 0xfc56cfce, 0x4de0dee5, 0xe38dffb8, 0x2fe084a4,
- 0xbff444bb, 0xadff9d65, 0xe2fbe5e0, 0x8fe3c143, 0x3a97cbc5, 0xb8b20cbc,
- 0xccabf008, 0x16a985fd, 0xca0fab27, 0xc8de7827, 0x9fa905fd, 0x42d3788b,
- 0xcc8bdf79, 0x5f386ce6, 0x30148f33, 0x1afd71de, 0x3983f511, 0xe575c04d,
- 0x8f31904f, 0x7e4373f8, 0x6f3be026, 0xbf1515dc, 0x0270cb60, 0xb871173c,
- 0xb42a9117, 0xeff9c95f, 0x84cacbbe, 0xf6820673, 0x211722ef, 0xadbf52d7,
- 0x47f04b28, 0x4b157852, 0x0e9d1bc4, 0x1c816f71, 0xb5bdc4d1, 0x47fdf875,
- 0x8b9c6842, 0xbe4deff5, 0x5fe5d4fc, 0x323b3ca9, 0x1e41fa8c, 0x5849bb9e,
- 0xaff156dc, 0x70626f6f, 0x7c132cac, 0x7e774829, 0xee755f39, 0x83e71cf8,
- 0x0e3bdebf, 0xa3f664e5, 0xefd1a3a3, 0x6fd03977, 0x437ee4a8, 0x0d11d7b7,
- 0xa6eeae71, 0x9b3e7e54, 0x55cb536b, 0xfdcfdca5, 0x7e40bfee, 0xa6bb2d21,
- 0xf822b50a, 0xf1802471, 0x08d4ef5c, 0xfe4c31b2, 0x1931ffeb, 0x6154fd38,
- 0x627e001c, 0xfd91e026, 0xd1abe98a, 0xadbc2ab1, 0x3494f6b9, 0xe01e27a6,
- 0x0e754477, 0x0be163f9, 0x75c03e7e, 0xf4db447f, 0xadfb30fc, 0x5638b135,
- 0xe2df5bde, 0x34379c77, 0x9700cb25, 0x9a8aa61b, 0x2655fb73, 0x238d97ee,
- 0x795d60e3, 0x9b655d6f, 0x11697808, 0x66ddf09d, 0xa359d365, 0xb079cc3b,
- 0x3e309e1e, 0xca8fd5c4, 0xe78022ce, 0x082387d1, 0xf2efd1f8, 0xf834c673,
- 0x430d226e, 0x2b882e3a, 0xb5c39afe, 0x72c764d3, 0x1cb65e56, 0x6b4de74f,
- 0xa3858fb0, 0x7fbc01d4, 0xe3211827, 0xbd878921, 0x501bf4a7, 0x1bb5fac6,
- 0xf6e115ed, 0xed823c3f, 0xef3898bf, 0xfbfc2099, 0x51fb2de1, 0xec073fab,
- 0xae3ca983, 0x09ae83d2, 0x0cf747f2, 0x1bfa07c1, 0xe7ac61fc, 0xdf84efb1,
- 0xbeb3be55, 0x8559e981, 0xde70f5ee, 0xccace1cb, 0xe2c4dc7f, 0xfce27faf,
- 0x8159c0a5, 0x4abd7eaf, 0xa6af2a7f, 0xd751e3a8, 0x197d8e37, 0x268a9bec,
- 0x43a06ec1, 0x466d4855, 0xc6cac3e0, 0x6f3864c7, 0xe360eb99, 0x8c7f2912,
- 0xd3a09f3a, 0x9a3bf2c4, 0x0dbcafd3, 0x1adce4e8, 0xe242e813, 0x0dace3ba,
- 0x06bbf0e4, 0x7be19fe7, 0x227bef6a, 0x790178d9, 0xcea7b1f5, 0x8f525535,
- 0x9ceb8c9b, 0x432d9655, 0xb296ecf8, 0x8aa2725d, 0xb14d3a9e, 0x1f3caed8,
- 0x8748e650, 0x5c3e74e7, 0x1311f787, 0xd242ef81, 0xfbf15bea, 0x62aa5bd4,
- 0xd4961d18, 0x3d6232ef, 0xf32bfb19, 0xf9e8f329, 0x369e7669, 0x6e4178ef,
- 0x4b8020db, 0xd4bfc99e, 0x1f4e8619, 0x8ee72b33, 0xb84f53df, 0xf98edd28,
- 0x2c4f48ff, 0x1b44f455, 0xef2bb9e6, 0x3e3335cf, 0xc489e957, 0x49627a70,
- 0xf01123b5, 0x6a4764b0, 0x92c93022, 0x084b4e3f, 0xf03e27a7, 0x43e373b0,
- 0xaeeebbfc, 0x5c4f54d9, 0xb313d2ae, 0xf44e9023, 0x959ae5ef, 0xe88b8d73,
- 0xff6f0509, 0x03e6f2c3, 0xf86113d0, 0x56b346fb, 0x54d8dc4f, 0xc6e27a88,
- 0xfbe6a2d9, 0x17cd6baa, 0x09d913d3, 0x3b2eb173, 0xcfd0c2a3, 0x39bfdc07,
- 0x61fbf3c4, 0x6b17d01e, 0x9b8476cc, 0x26f46f5e, 0x55f6c7d7, 0x825fffae,
- 0x97d722b3, 0x43f761cc, 0x8243a4f4, 0x2e64bcf4, 0xd002eb95, 0x4beb9323,
- 0x4e71e56e, 0x07cd9c9d, 0x96a19b39, 0x0afdecb3, 0x950bd337, 0x9abfc98d,
- 0xae6fdb47, 0xda669d95, 0xdc90e6ff, 0xddcb54cd, 0xe1096635, 0x96ee43dc,
- 0xae7bb930, 0x4fda1c69, 0x53efedbd, 0x3ca96f2e, 0x430ce61b, 0xa2f3051f,
- 0x1ddfdf34, 0xda76fb1d, 0xef2fc02b, 0xfb7e788a, 0xf603b739, 0x033b7d8d,
- 0x7c53e9ec, 0xfcb8db3d, 0x5cf8f4eb, 0xc81ca953, 0xd3d983bd, 0x84459be5,
- 0xe303455f, 0x91618aff, 0x4fad073e, 0xcf16ff4f, 0x60ef1761, 0x0774b0e7,
- 0xfc2ad979, 0xadb77e2f, 0x1605ce06, 0x1cf017af, 0x005fbe19, 0x78731678,
- 0xe3173916, 0xdaf14a39, 0xe53fe7f0, 0xa6a2dfbc, 0x5f0f18f5, 0x2bf6d3e4,
- 0x29f5761f, 0x4cf247f0, 0xaf790f0c, 0xc9f5be08, 0xeba0cf90, 0xe78d5ce7,
- 0xdaf5e547, 0x7ef907e7, 0xb4fe8a17, 0xe4fbe857, 0xd3bfcccf, 0x1ea0fbc3,
- 0x123f252e, 0x5c29fb2e, 0x70f5fe32, 0xd40e0de9, 0x01f3c7be, 0x2b0e3c3d,
- 0x649d2572, 0x6e7e1f00, 0xf15ca170, 0x42e143be, 0xb1e3bbe7, 0x40fb9ae1,
- 0xbcb8738e, 0xf4d7706b, 0x02157e87, 0xb75e2bf6, 0xad024f65, 0x6327abcf,
- 0x78a178e1, 0x070f56ad, 0x03837ef5, 0xaabcfaf5, 0xc7e4022d, 0xfbdfe42e,
- 0xc31ef895, 0x5d6e547b, 0xed3cf546, 0xe4dd20bf, 0xfdf07386, 0x9b940111,
- 0x47c6dd0a, 0x8e25fb30, 0x03a3a1cb, 0x3f515302, 0xe4760a35, 0xd3047f47,
- 0x704f1457, 0xc4f34bbf, 0xbc73a7af, 0x2352b8b0, 0xc52563c3, 0xf4f3f01b,
- 0x63af5e26, 0x4a2de076, 0x39f05ebd, 0xbbab9004, 0x8c5f7664, 0x8e04e240,
- 0x847e9504, 0x04ecd5f3, 0xb4779e15, 0x28dffa33, 0x8f81f138, 0xf043f7fe,
- 0x33dd2bdc, 0xf4afa63b, 0x3e29c0ae, 0xfde78b42, 0xe379ad11, 0x9bf9c1fa,
- 0x737bc4e0, 0x9cf0629a, 0xbb2d58e8, 0xbf9525ff, 0xf00be7a7, 0xd1f7d43b,
- 0x438584cc, 0x088cf37e, 0x79c50fcc, 0xa65d9853, 0x7bfa4f96, 0xfe6fbe80,
- 0x45692551, 0xc7942c7b, 0x04de7ee8, 0x3410cde3, 0x09104ef9, 0x09ff3a03,
- 0x7cd5bfc6, 0x9249f181, 0xef96f31d, 0xedcf2bb2, 0x5e2cbbec, 0x799c1e6f,
- 0xef851e68, 0x13a255b9, 0x0c9ba85c, 0x2059838e, 0x09941e6f, 0x7db9cbf0,
- 0x81e98bb2, 0x853bd428, 0xefc51eef, 0x0e590ad9, 0x8fbc291a, 0x7ca397e9,
- 0xbd511f3d, 0x0a5882ed, 0xf70f1fa9, 0xee76cce0, 0x7880e69a, 0x95fec64b,
- 0x2b39ce70, 0x20f07ed7, 0xbb3573e0, 0xaac8e907, 0xeed3f45c, 0x7e4053ba,
- 0x06f14c3b, 0x9d99cfef, 0x9d20f07c, 0xf155d6f7, 0xcf396e78, 0x9c237f15,
- 0x27dbce63, 0xdfb41d3a, 0x16adeb82, 0x66bcc738, 0x2adc48a4, 0x5a4adcf8,
- 0xaf33be31, 0xb039ceea, 0x0faa12ee, 0xf72864c5, 0xfa844b4f, 0xafdf013a,
- 0xf08dbaf4, 0xdaeb66bd, 0x3a0cc6b3, 0x07ed117f, 0xc75caf60, 0x106e55fa,
- 0x5dfa909c, 0xca18f4d4, 0x020da2cb, 0x4ad3345e, 0x1b335fed, 0xe3a667d7,
- 0xefa3aeb6, 0xbc317ad3, 0x886ee30f, 0x27ce11b9, 0xf13ae92b, 0x78d509fd,
- 0xdf445d2e, 0x75a4cda3, 0xde389dc3, 0x810275a2, 0x264b03ef, 0x01323f24,
- 0x3b27dbc6, 0xaed0fda1, 0xdd611b5f, 0xfaf9d1b7, 0x8817f1d3, 0x3fa0d36d,
- 0xc760a5f9, 0x46ea87fb, 0x0baddc60, 0x542f0c36, 0xe63ac70d, 0x0c103b13,
- 0x651f3a92, 0x4efb0447, 0x755968b8, 0xcdabec0d, 0x406c9f1b, 0x046b3aba,
- 0xc28c7e3d, 0x3c874ddb, 0x2e79646a, 0xc6a3decd, 0xfd1c9536, 0xdf152228,
- 0x1b31a3bf, 0x921626f3, 0x709bcc7c, 0xa47b3357, 0x0f84657d, 0xb2ed6ae2,
- 0x6f3c087d, 0xe7c2695e, 0xfd312f9d, 0x0db839d3, 0xd627dbe3, 0x5fbe04c9,
- 0xf52eb15c, 0x89e3c069, 0x9bd232cd, 0x1bcb2cf8, 0xc5897e28, 0xb1d79ac9,
- 0x352c4f71, 0xa0b57bb2, 0x5f8bd69d, 0xb40af254, 0x51c8ac72, 0x2f4a728a,
- 0x6b72f497, 0x46d593d1, 0xf21ed920, 0x9474e96a, 0xef54a557, 0x90f5a100,
- 0x306a8357, 0x5797aa6e, 0xc8a2c495, 0x5f8874a9, 0xbe0f9616, 0xf1d02d6d,
- 0x8183ecad, 0x5f6bff56, 0xb77a053e, 0x49e04acc, 0x5a7f6485, 0x80417460,
- 0x6d35e65f, 0xa0f812f9, 0xde045e64, 0xf01c75c7, 0x26b37c00, 0x8bafcf0e,
- 0x6f08857c, 0x78b72f25, 0x95ce96ad, 0xb75ce3f8, 0xfd6a5c48, 0x5c451255,
- 0xee877eaa, 0xe74af4a3, 0xf051bdb9, 0x743ca881, 0xbbdefb5f, 0xc76eb033,
- 0xf6e32d75, 0xd22b1ac1, 0x9f9fa1f3, 0x7af4095d, 0x0102bddb, 0xdd789d7b,
- 0x2b0fa035, 0x880e0ad6, 0xcbdf170f, 0xefa62fde, 0xfd0fbac3, 0xa515d19a,
- 0x7fd0076f, 0xf6c7bac5, 0x820dff62, 0xb43fc603, 0x89ed10be, 0xb048af12,
- 0xfa3b437d, 0x614f540f, 0x57b3599e, 0xaffa004c, 0x0764dfb8, 0x23a14953,
- 0xf9db2e85, 0xecc4087d, 0xbe8b331c, 0x15160ab7, 0xc51e93df, 0x4fa82102,
- 0xbd2a4e81, 0x5fdace8c, 0x36409d92, 0xf64ba717, 0xae09fc1d, 0xe767c55f,
- 0x74ef874c, 0x047ea98a, 0x975e6d3a, 0xe23b046b, 0xfcc04f84, 0x49749e8a,
- 0x4a3b6a2c, 0x0567cba1, 0xd07baf26, 0x7b0e8ea3, 0x4ba71dd0, 0x5128fe85,
- 0xb6595fa3, 0xfdf0264f, 0xdd1e9ebd, 0x908dfd72, 0x32f851ff, 0x6f5d0fdd,
- 0xd1cfcd6e, 0x48e0575e, 0x2f5009eb, 0x8fde5892, 0x12e50fc2, 0xdefb0fcb,
- 0xbfcdd3eb, 0x87e78229, 0x2c883f01, 0xe74fc97f, 0x0bf37b7d, 0x66792f98,
- 0x6875fb53, 0xe941bcdf, 0xd9bfe000, 0x7fe8fc4a, 0x950e50f8, 0x6f988836,
- 0xe67f244d, 0xaedf952c, 0xfe2cbfe4, 0x5de11583, 0xcbe4d5ba, 0x6e97efa3,
- 0xf3063a3f, 0x30079611, 0x49bbc7bf, 0xde1fe760, 0xfdf031b6, 0xf2c4a950,
- 0xc176f470, 0xe71648f0, 0xaa2d78ea, 0xa136ec00, 0x57b3dd8e, 0x6c937f5a,
- 0x0775c552, 0x2f38ca45, 0x63e787ed, 0xb8678a5e, 0xa7d6011f, 0xc94ddfbe,
- 0x9178e9bf, 0xa3695fd1, 0x695cf68c, 0xc84e96dd, 0x6c3d2cc3, 0xb2b73f42,
- 0xfc11acee, 0xbc3fdcd8, 0x55f3f784, 0x3c9a8a36, 0x6ff91ebc, 0x04dfa275,
- 0xe50d5bf9, 0xeb437e78, 0x0faf58ed, 0xb17a079f, 0x7fc5ad3c, 0x4bddb1d8,
- 0x95f8b841, 0xbef0d9df, 0x368dd6be, 0xeea9eefc, 0x3da7f9c2, 0x57eaddf2,
- 0xeddf305f, 0x0941fc34, 0x5d48baeb, 0x931d60be, 0x997d746b, 0xc4e261f9,
- 0xa5eb7b41, 0x7c839f2f, 0x7fad8eec, 0x5bd60e7b, 0x9ee75ff6, 0xb21abc83,
- 0xf60ec233, 0x0fa6e548, 0x79559f30, 0xd99224af, 0xfe2f9d7f, 0x3b80f30e,
- 0x6139343f, 0x271dceb4, 0xd1bd8086, 0x04dbe5b9, 0xba5defc8, 0x73c61a63,
- 0x4dcb6e96, 0x05e26124, 0xeb74094a, 0xb21e43eb, 0x0dcd5f1e, 0x73ff98cd,
- 0xe41be286, 0xb17f3043, 0x83e59cbe, 0xe2de783a, 0xdef9f0e6, 0x1b14f23d,
- 0x193f5d66, 0xb30362e4, 0xaf9a2e0b, 0xf1e28078, 0x6fe03ef2, 0x4f2e6af3,
- 0x0cefe3c2, 0x54f141fc, 0x57cda913, 0xe161b2fc, 0xb6819e6f, 0xf35eb886,
- 0x807dfd15, 0x3e4f929b, 0x58f5d22b, 0xd6cdf024, 0x287e63df, 0x01cf2de0,
- 0x21cbf9f2, 0x293e1710, 0x10fe3007, 0xefc261d8, 0x1c774b2c, 0xdce9fe42,
- 0xb5f31fb6, 0xeeebcf09, 0xcb1fc124, 0x9eb1e5c3, 0x96560dca, 0x0fe1c8e7,
- 0x1b0e9079, 0x8ef9e73e, 0x3c958e8c, 0x1ff2dec8, 0xf853225b, 0x4f2c2a7d,
- 0xc7c37cb3, 0x8430af3c, 0xe002612f, 0x7982fda9, 0xec1c0aa5, 0xd42b8700,
- 0xf3e1bcf9, 0xdf79834c, 0x3f805f1c, 0x7cc1d390, 0x041f5a5d, 0xe13e9bf9,
- 0x0f230910, 0x3cb3d73a, 0xfc394ee0, 0x7e4accf7, 0x4f9eb36f, 0xebcb7d7d,
- 0xbffad8bd, 0x221a7c2f, 0x1eae381d, 0xc3e71d4e, 0x9ce3f1cb, 0xf7f07fef,
- 0xfe826521, 0x81cf93fb, 0xda1bcb1e, 0x899f788d, 0xfdf13fe2, 0x5a78f076,
- 0xf31126c7, 0x9bea6b3e, 0xe5eb8e51, 0x273f0545, 0x1bf7afd1, 0x468adebe,
- 0xb63a27a6, 0x3a167d5a, 0xaf5bc74e, 0x6c573d21, 0xd3bcc76e, 0x18af75bd,
- 0xcbe754db, 0xaa7c27a0, 0xbcbc77f5, 0x6dca0c6b, 0x7e98bf7e, 0x9b14631e,
- 0xfc29b2a7, 0xcf9b953c, 0xec59e66a, 0x2dda37ad, 0xb4ef9f17, 0xc609bae4,
- 0xeccadd3b, 0xe2f5d3a5, 0xf9985f0c, 0x49bd714f, 0x0f3b2d48, 0xef12faa5,
- 0x7bb2b359, 0x245b44d5, 0xad4b5fda, 0xf7470e13, 0x7988d283, 0x79aa2b2f,
- 0xce7dcc9e, 0x0af7c024, 0xd604d5eb, 0xabe012bb, 0xbb65e3f2, 0x26dd809b,
- 0xa867e527, 0xf59459cf, 0x8819fb1b, 0xa5ff854f, 0xe08919d6, 0x3bc9127f,
- 0x5d71d608, 0xe812d7ca, 0x8b0f56bf, 0x47f393df, 0x56f3c187, 0x8e27bec9,
- 0x553adb8e, 0xb5e84270, 0x34fbdd27, 0x2e998671, 0xf8b17ded, 0x5fdd1c0d,
- 0xf680d3b7, 0xb7e0d5a0, 0x1ac42ed3, 0x0e849ad1, 0xa43883ac, 0x0214fc04,
- 0xf41e21f3, 0xfdc16798, 0xcd4236c8, 0x94e7e853, 0x449ff734, 0xf774904f,
- 0xc30390a1, 0x385abd28, 0x39712abd, 0x8e9bfb2b, 0xacf786db, 0x6a91a4c4,
- 0x5635df20, 0x4f0dda37, 0xe869fbf0, 0x41e4246f, 0xa74892c4, 0x3a26fefa,
- 0x38fbe6af, 0x1ea6af3a, 0xe3d6d2e3, 0xc2c74866, 0xbe3897e9, 0x05a2e98e,
- 0xcd3310e1, 0x796bf8a0, 0xeb4213c3, 0x4e27898e, 0x6b5fb43f, 0x2801efc1,
- 0xfbd5797b, 0xebb458b0, 0xc8d3eba6, 0x36b4e889, 0x53ad81af, 0x1c4edcf3,
- 0xa5dfee02, 0xabd74e7d, 0x714617a9, 0x09112779, 0xdcc59de4, 0xbbfc384a,
- 0x5fbef035, 0x013837da, 0x5fb843f0, 0xcf9025ed, 0x41f7cd12, 0xb7f4d7e7,
- 0xcd807443, 0x0c871daf, 0x43bfabb2, 0xbfeb9cbd, 0x25fc9651, 0x329e9451,
- 0x62615687, 0x49125676, 0x9ba5efc3, 0x4a7ca1fa, 0x79839659, 0xa32d4227,
- 0x086b61ab, 0x00b0cdf2, 0x3fba9bcf, 0x9351ed12, 0xd2237899, 0xe2367be1,
- 0x1661d395, 0x7043cf1f, 0xa1d0372c, 0xd69455a4, 0x814d7be8, 0x8a42c31c,
- 0xa2687a84, 0xb94657e3, 0x9f28a3aa, 0x2774ccd6, 0xf6c2c619, 0x3bb95ede,
- 0x52f6b90b, 0xaa1a0888, 0x1969eef7, 0xef04228c, 0xbdde20f1, 0x6bc6807b,
- 0xec153a95, 0x6d7f9df0, 0x32eeb064, 0x9b5f7953, 0x3e8feac2, 0xdc2577b4,
- 0xcf6e9337, 0x49f6147f, 0x7851f6cc, 0xd58fe5de, 0x9bddf3dc, 0x39d6517e,
- 0x173f8372, 0x3abe05ee, 0x1df5eec0, 0x777e0d6e, 0xa3787a8f, 0xd1fba945,
- 0xd86fc88f, 0xbcad728f, 0x1bb63f7e, 0xa1cb4ea0, 0x81dcfe71, 0x472f9f74,
- 0x74969a1d, 0xa1af1d29, 0xd93e0930, 0xd0ea357f, 0x30eef81e, 0x578f8704,
- 0x82141eee, 0xc3fcb483, 0xd5932d3d, 0x0f70f870, 0x857d21d8, 0x7d0fabc3,
- 0xebe87088, 0x6c5d29be, 0x935cbc07, 0xd6fbc06d, 0xc16c38ae, 0x45fd0af8,
- 0xe3e23ea0, 0xbbe5efac, 0xa11fc56c, 0xd354ece3, 0x429ef297, 0x4dd1bd57,
- 0x628fb12a, 0xe96a6cf7, 0xf5ca2ba7, 0x25abac36, 0x358f75ca, 0xf78ff71e,
- 0x76e35c00, 0x0b8ea73b, 0xb8b135d1, 0xeefdc1c7, 0x5bf32ca3, 0xf2f254a3,
- 0x6225ec9a, 0x81c9c40a, 0xfb43e217, 0x8de65f89, 0x19f74118, 0xde6032ef,
- 0xfb8b28fc, 0x2b63cc20, 0x7721f808, 0x1ee20aec, 0xbe218827, 0xd9abe650,
- 0x9af5fcc1, 0x396f8342, 0x6015ef3b, 0xb47d10bc, 0xc023e8e9, 0x1db1a3e8,
- 0xa9a2a3e9, 0x6347d19d, 0x06644e75, 0x3f03373b, 0xc60496bf, 0xa23bde02,
- 0x51269abe, 0x151a1ffa, 0x91ba01a8, 0xe5a6e7bd, 0x3d708a5d, 0x7c3f161d,
- 0x7abeca7d, 0x4b6d6fc3, 0xe06943ca, 0xe033ee4f, 0x37029779, 0x858c5fa5,
- 0x58b6c5e5, 0xfc035fdd, 0xedb4272a, 0x6d6fed85, 0x36f31f79, 0xd86efb6c,
- 0x66dbef05, 0x42390c53, 0x5beed6f3, 0xd767f78e, 0xd87dd806, 0x05e024d1,
- 0x3c3bdebd, 0xe104ff18, 0x1a4f7601, 0xf91da3c0, 0x5eff1365, 0x7051ab2c,
- 0x1a1f9e81, 0x890deec5, 0xebf3b0b4, 0xd7111621, 0xcec2c439, 0xbdf7e259,
- 0x95bf8225, 0xfb01bf75, 0xa69943c7, 0xbcfdffde, 0xaf89a4bf, 0xe854f82b,
- 0x28d24a89, 0x4ce47fb8, 0xa2d13b8c, 0xa8d89fa1, 0xca78d514, 0x88788f7b,
- 0x47aa0ef3, 0xff3dd8af, 0x94abd02e, 0xfc00be7e, 0x968dfb04, 0x4a6e0023,
- 0x70cfa07f, 0x0defa1f8, 0x1e60f987, 0xecb617b0, 0x3de2225e, 0x6bc47d1a,
- 0x491bdc26, 0x914667fb, 0xfdf4adaa, 0x425a68cc, 0x13d78e3d, 0x2b207d79,
- 0x1a713f53, 0x3d7cfa04, 0xb64ebb8f, 0xc931fcf0, 0xd186ea3e, 0x5c766750,
- 0xea245256, 0xe16f8505, 0xb738080e, 0x75f9f896, 0x00c5204a, 0x58f85378,
- 0x56fc180a, 0x2452b4aa, 0x18f20187, 0x7dd0f1de, 0x9dcbbd4b, 0xdf652fab,
- 0xcf9fea71, 0xc1f9ebe4, 0x3d17f5f6, 0x099eefbe, 0xb7372df0, 0xad03723d,
- 0x0e7a5c57, 0x479707cf, 0xa1795c55, 0xebf42f7b, 0xdbfce77f, 0x4d874051,
- 0x7ec298df, 0xe1c3550f, 0xc029e2d6, 0xbdf932f7, 0xc951242e, 0xb1e55633,
- 0xcbb71b42, 0xf8299510, 0xffaced1c, 0xf8081140, 0xf0b14af4, 0x9e32547e,
- 0xe5d14e1f, 0x9f87fead, 0xc132f9c5, 0x71250030, 0xcf3628c9, 0x324ecc37,
- 0x9ce0ffd3, 0x173f1a69, 0xaf72477b, 0xdef1d2b0, 0x357cec21, 0x19aaae33,
- 0xc6c4c4ea, 0xfbda26cf, 0x6b13320a, 0xb8c2c6a7, 0xdf18c9d1, 0xdaeb35ca,
- 0xc812bd53, 0x8c9a9269, 0x88d38979, 0x7a633eca, 0x08eeed03, 0xe3902eba,
- 0x742c8cd7, 0xe7ede54e, 0x4d43ffe8, 0x2a99f6e4, 0xc72ae37f, 0x8d54e75c,
- 0xf78b52fd, 0x9fe9fd01, 0xf2e1ede2, 0xfce33e2c, 0x77c9e2df, 0x1eb3f9c2,
- 0xe10e399e, 0x27a3ab7e, 0xd470f5dc, 0xab815dc3, 0x9fd98e1e, 0x86c6a738,
- 0x2e1e9381, 0x48ed48d3, 0xdc0a63d0, 0xc77970f5, 0x9de2e8cc, 0xabde1334,
- 0xe0c48ef8, 0x23350ef8, 0x9ba41ea1, 0x01ef1168, 0xf5e28cce, 0xbab04737,
- 0x64a8ef82, 0xae1eb7c4, 0xc666387a, 0x58e3f7f1, 0x2f00bdff, 0xe202e509,
- 0xcc9ba147, 0x31ddaad4, 0xec507a2a, 0x2e1c69eb, 0xfb46bed4, 0x8ade3739,
- 0xafb02671, 0xe08425a7, 0xd6ce5b96, 0xf2dc3b95, 0xf4a9f83c, 0x72bfbc75,
- 0xff3fe10a, 0xca2f3c14, 0xce0555e4, 0xdad1be53, 0xa69ad3c9, 0xc338829f,
- 0x7efb9350, 0x1080cfa0, 0x1475e783, 0x707447ee, 0xd767bed7, 0xf870f5d6,
- 0xb131fc03, 0x3a14bc27, 0xe3c2c0fb, 0x20c8034e, 0xbcc797b0, 0xf20d1196,
- 0x86c5349b, 0x715c4b8d, 0x0e383f38, 0x63a457a7, 0xcf83b881, 0x423fa9ed,
- 0x5aa3ed8e, 0x36c72552, 0x96d3ee8b, 0x4c729ef8, 0x8e64d3c1, 0xbbc4c987,
- 0x934be20b, 0xd045f489, 0xed0e481f, 0xe7d95bbf, 0xf6103240, 0xc1c58379,
- 0x67df3fe4, 0xbcd4df70, 0xf8b3f984, 0x0b6659fc, 0x02435f7e, 0xce104752,
- 0x91df7829, 0x5a1b18d7, 0x4fbf9287, 0x66115486, 0x7bc3cdcf, 0xc85c29ae,
- 0x75a15177, 0x8482ac98, 0x75f0fdf7, 0x7b33a99c, 0x5bad8f21, 0x9d814774,
- 0x1bec21d7, 0xfc93fb83, 0xe9ff4023, 0xee35cfdb, 0xda7680ae, 0xf1fb08af,
- 0x59162ff5, 0xc3b021fc, 0xb93e7be4, 0xb2953b77, 0x8509ea35, 0xfbe0b37e,
- 0xde81cbd4, 0xdd6103fd, 0xd1d54053, 0xf659e772, 0x6376431d, 0xecf304ba,
- 0xff7966e9, 0x8125c439, 0xdfa7ab7d, 0xa1a74bef, 0x08604578, 0x5d8a29f8,
- 0x1eead536, 0x57cfa569, 0x9b66eff3, 0x05188ece, 0xf4c1f978, 0x4f4b4074,
- 0xba511d0a, 0xecf00f1a, 0x69fcf8ca, 0xcddfc730, 0x7a009738, 0x43dfb151,
- 0x026b8a76, 0x3b37a7ac, 0x3dd5897e, 0x3b017ac5, 0x2e67b15e, 0xdd9087e6,
- 0x74a641d4, 0xcbc71b74, 0xccab733c, 0x600fcdee, 0x48eafdfe, 0x473b5ee5,
- 0xb791d824, 0x54d94ead, 0xd586e707, 0x6b7efe2c, 0x83f1ac95, 0x86dd90dd,
- 0x66fbb3ef, 0x6da65f6f, 0xfe604cff, 0xfb57a17e, 0x3412589c, 0x9cf6edf7,
- 0xc035e0d7, 0x3123c3bc, 0xaf3f413f, 0x79fa7f7e, 0xe6adf3f5, 0x636ad57e,
- 0xcaa748ed, 0x6560592e, 0xaaf750f6, 0xcae0ebc7, 0xe7e0deba, 0x93480f36,
- 0xb5abf754, 0x082c8ead, 0x328c6f77, 0x79ef029e, 0x00e2cfc4, 0xc3dff255,
- 0xe59b83dd, 0xde81f166, 0x98161de6, 0xe1a0768a, 0xf608bf49, 0x4100b0fc,
- 0xe02b3bfb, 0xf8d02c32, 0xee4fcc01, 0xbdc007e1, 0xd65eb426, 0x01f98bb0,
- 0x4fe8d5f5, 0x027f5194, 0x387accf4, 0x17c01e9b, 0x41fe8694, 0xfc85dfd0,
- 0xcfb82ca9, 0x12c3fb92, 0x5ad497a5, 0xf5a37fd6, 0x096ae35d, 0x927755fc,
- 0xe363294c, 0x98d7efc3, 0x93555fa9, 0xf508224c, 0xf8785eab, 0xc06be9fd,
- 0x09758e5f, 0xad287f70, 0xf7fa58d7, 0xf8debfdd, 0xb81afef0, 0x65fa946f,
- 0x7f2aaceb, 0x78fe37b7, 0x0b918c04, 0x3dba47f0, 0xa1f0237f, 0x8a68af12,
- 0x111f7ce0, 0x8068bba4, 0x57274297, 0x7e8f9b2f, 0xe725c445, 0x589e4087,
- 0x16ffc716, 0x46c38f2b, 0x129ff7b1, 0xbf905bdd, 0x023f3adf, 0x8cefcbe2,
- 0x5cfe8a3c, 0xe7c59593, 0xd04a79f7, 0xb9f0527e, 0x3f702acb, 0xf8103fc9,
- 0xcdf1daed, 0x6497e071, 0x43de02c9, 0x9efb24da, 0x7900cf4c, 0x82bedb34,
- 0xa26b296e, 0x6b13bf11, 0xbc0ff08a, 0x35a7655b, 0x9b4cfbf1, 0xa81deece,
- 0x661e63ce, 0x4565ddcd, 0x308bf3fa, 0xeec6567e, 0x7befa0c3, 0xfd212fd3,
- 0x7f4012e1, 0x13fbf390, 0x61a8fcf0, 0x42e20d8f, 0x827efc1d, 0x09cd0d33,
- 0xbe5969f3, 0xf0362fe5, 0x70e7ded7, 0xe2b52338, 0xdb654a3d, 0x83ffbc44,
- 0x0b709bce, 0x161ba7c4, 0xf7efb264, 0x8a6777d8, 0x67ff4cfe, 0x167cc0f3,
- 0xc8efc434, 0xb2727b14, 0xf583ebd9, 0x188b5535, 0xbbac9e2f, 0xbf0a6c37,
- 0x5f6f4c37, 0x712ab49e, 0x87cc04e9, 0xf3676a5a, 0x594fc6f4, 0x9f12c4df,
- 0x24b2df8a, 0xcfeb08bf, 0xc08126fa, 0x5a679715, 0x03c89e52, 0xcec89e3f,
- 0x44ac30e1, 0xcafda376, 0x6fe89fcf, 0xbe43dc37, 0x6cde5793, 0x4aeb3738,
- 0xfdfb6624, 0x77600997, 0xe0b1fbb9, 0x8a07d322, 0x1be5377d, 0x6f557c6d,
- 0x8d34e6e7, 0x41207fbd, 0xa77fb378, 0x55eec022, 0x06ff61eb, 0x7bb587a6,
- 0xe10c7909, 0xf52dbe90, 0x2947b81a, 0x3b068ffd, 0x7c02dbcc, 0x3cf80f11,
- 0x54fcf787, 0xd08dff10, 0xda20d15e, 0x927eb0fd, 0x95f01971, 0x70283762,
- 0x6cdf3c69, 0x91d7431e, 0x5f60d675, 0x3378874e, 0xcffa05f0, 0x2fbcfee3,
- 0x5357f40e, 0x8273c240, 0xa3bbb3ac, 0x60e4a816, 0x3e0379d3, 0x5bfcf37f,
- 0xd881e7da, 0x2dbde0cb, 0xef17e606, 0x28f7fbde, 0x9e6f4b90, 0x82f1c6ef,
- 0xbb4f4376, 0x6b91e118, 0x67718315, 0xc44c5db5, 0xb79003ac, 0xaa9a2d35,
- 0xbb77a131, 0x7213fb37, 0xb4f495bf, 0x1ec0721f, 0x11d8c311, 0x3e74ce1c,
- 0x6f48f809, 0xe36e5c57, 0x24c1e6f1, 0x6ca3ee1d, 0x18b71f3c, 0x8a6e1fbf,
- 0x7d472fb2, 0xaea5eccc, 0xbf1fa7dd, 0x13ef9e06, 0xe711fdd9, 0xb7a7e445,
- 0xda1e2e76, 0x2a5be2a6, 0x5f4f1139, 0xf9db3ff5, 0xd5ffed06, 0x4716489e,
- 0xa9979c97, 0xf50877bf, 0xf97871f7, 0x38f3b007, 0xd7b800ef, 0x2fdb07e9,
- 0xfafc3d1d, 0xc3da1b3c, 0x1ea0e981, 0x376bac46, 0xac5bfe02, 0x90d9d7f9,
- 0x00a3eadf, 0x33925e2e, 0xf3804c90, 0x7403927a, 0x7626a815, 0xb5b627f0,
- 0x97800c18, 0x98c98d8c, 0x9f89b3a7, 0xafaa2e57, 0xe8ab2635, 0xef3f1162,
- 0x877b293a, 0x1f9eaac4, 0x72f931b0, 0x6fe94f72, 0x43e34f30, 0xc61e1913,
- 0x31b06cde, 0xd18afb7d, 0xe866cd7b, 0xdf80c477, 0xfbdeed0d, 0xcfb85efa,
- 0xc761d178, 0x3dff8858, 0xbf607362, 0x6a9b7dc6, 0xf1b7cf20, 0x5452d013,
- 0x14286caf, 0x37de740d, 0xefc58388, 0x1fd0180e, 0x893dc60f, 0xf9f60e2b,
- 0x1bcf5f10, 0xf9cd062d, 0xdefc1bd8, 0x326d7bdd, 0x89b12fb6, 0x2dadc788,
- 0x37a07139, 0xbbeeac5a, 0x8e2fa06d, 0x12c0d5b5, 0x629f7894, 0xb03c4daf,
- 0xf4d19af5, 0x061d89cf, 0x71dba03b, 0xf61179e0, 0x484938eb, 0xd87a408c,
- 0x8f3c746f, 0x3a37bc7a, 0x1d7478d8, 0x2abf016f, 0xff9aa7f0, 0x7f5a34a1,
- 0x858a55a3, 0xfe052efc, 0xf9943eca, 0xb5c4f51d, 0xe4ac82de, 0xb8817ada,
- 0x3a5f92b3, 0x7f944ece, 0xd2e9012f, 0x6a3d7368, 0xda0ef663, 0x30f727d7,
- 0xae15e8bb, 0xe1524947, 0x829f8050, 0x8b1b7aa7, 0xe9eb2a33, 0xdbdffe6d,
- 0xca549e98, 0x9bd74bef, 0xe9178764, 0x0fcb1b66, 0xe6fd7877, 0x6b23c854,
- 0xcf7fc54c, 0xfb679549, 0x93e7a47b, 0x1b057bda, 0xf8060cdb, 0x8762ac0e,
- 0x6de68310, 0x20ebed1f, 0x48f5499d, 0x09878d7f, 0xdd6971f2, 0x48ee2c9d,
- 0x7fbf0de5, 0x81d1cf0d, 0x7a79f87f, 0x1396817f, 0x18afd69b, 0xdbf5f088,
- 0x7042af80, 0x65037ca2, 0xe811ad55, 0x5652d175, 0xe973f316, 0xc8dd6b45,
- 0x58eb459f, 0x5b1ee17e, 0x0ce7ae32, 0x886257a7, 0x27f9001c, 0x657f0e2e,
- 0x6e9c79dd, 0xd13c354f, 0xfa52f30c, 0x73e013fa, 0x4f63e352, 0x7a1572c3,
- 0xc641b53d, 0xb5224a71, 0x7cadf6e7, 0x18076dbc, 0x20dc4fbd, 0x5ffdc0e7,
- 0x0ec4bd13, 0x3637ec71, 0x7e41146c, 0x9cf401bf, 0xf41cf8cc, 0x0f3dc9ed,
- 0xf402fd46, 0x4081bb5c, 0x2315fcbc, 0xe2a2d929, 0x5febdd8b, 0x696ff0d5,
- 0x1835f55d, 0x158b6f97, 0x7c2bce40, 0x15fdc0ab, 0xe42af3a3, 0xfc74ebff,
- 0x2fbd953f, 0xdfb03b47, 0x9fff9c13, 0x9ff94198, 0x10d98a3e, 0xaf38c023,
- 0x07dfc318, 0xa40ff5f7, 0x6d5ca0bf, 0xbf5721eb, 0xcdb57266, 0xafe74a96,
- 0xe31bb6b8, 0x71f5c10c, 0xaa6279ba, 0x02c93742, 0x6296bfc0, 0x8bc01870,
- 0x99e815c2, 0xdfb7cdda, 0xd95c8690, 0x0f39e122, 0xf9e2473f, 0x0277ca1f,
- 0xe486bf0a, 0x6eb7c299, 0xd5d83473, 0x8056ab53, 0xe7971f5d, 0x253cfa45,
- 0x52c687b8, 0xf80a767d, 0x383c8c38, 0x57c7e5c1, 0xf762fbb2, 0x7a000fee,
- 0x221ea12e, 0x13ac87ec, 0xa51780ec, 0xdd8eb1dd, 0x5a3c3ac3, 0x2bbf9cd0,
- 0xef0c1ff5, 0x41fb8f40, 0x7c634787, 0x3c84603a, 0xa63e11d5, 0x839088c7,
- 0x570c40fc, 0x5b3e000f, 0xcdd7f544, 0x4a75fd2a, 0x553a45ae, 0x347970e0,
- 0xc55f5f93, 0x95ff7db0, 0xe21585d3, 0x2f73aa85, 0x024890ea, 0x605167e3,
- 0xf8c22e7c, 0xba4cf6a7, 0xdafde90a, 0x076ef4f0, 0xfe162aff, 0x48f5a73d,
- 0xec33319f, 0x13cb1df8, 0x46223392, 0xb0f91f63, 0x57f1bddc, 0xfd01d7e8,
- 0x46f7bf02, 0xff4025ff, 0xfbdd0c24, 0xf0abdd28, 0xa501d0a7, 0x55a26b8b,
- 0x174f41f2, 0x02a379ca, 0xe7745797, 0x33474f95, 0x9780b079, 0x66f25e8e,
- 0x60fcfd94, 0x81ec9f3c, 0xcf0cf9e7, 0x7c02be21, 0x67e1f22b, 0x3dafe117,
- 0xaf6c76d1, 0xe60174f9, 0x73f2d4a9, 0x9f3e7aab, 0xd1a5eeb2, 0x4b7ce682,
- 0xca34ee7f, 0x5a2bbee2, 0x48ea3e77, 0x34c7d10b, 0xd92ecf6e, 0xff73c268,
- 0x7802d02d, 0xbdfecddb, 0xbb3de56c, 0x0a4f0d44, 0x4cd115ea, 0xe1f42b8e,
- 0xc3246658, 0x55f2ffa8, 0xc86ee172, 0xab59f9ff, 0xdd346f37, 0x77a316c7,
- 0x07e8b5f6, 0xf182af38, 0xd833caaf, 0xc6241f21, 0xde201765, 0x7c0a2481,
- 0x33cd8fb8, 0x1979d52e, 0xe70ec9fa, 0x0f079038, 0xf8297c73, 0x9bd0e055,
- 0xaf0deb9e, 0xe27c387b, 0x8e5ebb79, 0x9efe7314, 0x5c5dfbc2, 0xe045788e,
- 0x2f711b27, 0x59fd6117, 0xe505fe4c, 0x73c11648, 0x727597c9, 0x5e9fe5e4,
- 0x91acbc8e, 0xc2da1323, 0x0bfa11ca, 0x1bf1ffcb, 0x4b1da216, 0x63b7870e,
- 0x3d334677, 0x93fa0f1c, 0xb2f78bf6, 0x3987def3, 0xc48a52dd, 0x0ddac9bc,
- 0x5713cc26, 0x366d90e4, 0xaf7f81c9, 0x16fa06d9, 0x1f76cd7a, 0xc5e70c9e,
- 0x9c074649, 0x03929f5f, 0xd453f788, 0xfa45af01, 0xc7fbc7c8, 0x0223c8c3,
- 0x47ef12f1, 0x9cefd083, 0x9f213626, 0x5046992c, 0x78deee7f, 0x4955d205,
- 0x74008a5e, 0x23175a5b, 0x54ec7b40, 0x94e401bb, 0x962b8fb2, 0x71b0c819,
- 0xd40707c8, 0x6f0ae472, 0xcdbbfe15, 0x49dce343, 0x47210c72, 0x33fb3d1f,
- 0x8da8bc75, 0x22f1d5d6, 0xfbe07f5a, 0x468e8bc4, 0x78801e07, 0xae6c3fd1,
- 0x94779876, 0xea28ff25, 0x912ac4b7, 0xc5d6e4a8, 0x4a1fb7ec, 0x2e3c952f,
- 0x34a95a45, 0x81c4d04e, 0x6073ab6f, 0x582bf81c, 0xe380c54f, 0x7870c34f,
- 0x7b5846af, 0x1fa3ad9b, 0x13e40b97, 0x97e8f882, 0xfc42255f, 0x063b9145,
- 0x2fe2ac7b, 0xa197900b, 0x037fdbf0, 0xd7b57d1c, 0x00008000, 0x00088b1f,
- 0x00000000, 0x7dcdff00, 0xd5947809, 0xe77df0d5, 0x24cb2d9d, 0x7642c993,
- 0x03bbec26, 0x4eb1ab09, 0x04906008, 0x8d441007, 0xb0900938, 0xd2910364,
- 0x208196d6, 0x2b188a06, 0x0eb154b5, 0x4551fa14, 0xdb1ab61b, 0x1a4013a0,
- 0xad563414, 0x61a5afd8, 0x80891d91, 0xe58ad3fd, 0x7bdce73b, 0x264ef333,
- 0xe79f6a02, 0xcdcf0f0f, 0xcf7bde5d, 0x773dfb3d, 0x79632d49, 0x9b19223b,
- 0xed50b390, 0xccc9a906, 0x831b163c, 0x43632f1f, 0x087a3e79, 0x6b9859e6,
- 0xf26b6320, 0x01de7975, 0x9fc75d8c, 0xa269fd3b, 0x678e3e15, 0x30d6fe6c,
- 0xb53349eb, 0x7fe1d767, 0x268c5d79, 0x649f595f, 0x9fc7d93d, 0x24bf8f9f,
- 0x4c33ffc1, 0x2b1812cf, 0xe1a7e263, 0x70ffdfcb, 0xdfc7b418, 0x54dec655,
- 0x805689dd, 0x12dcdca7, 0xd8ceddd5, 0x13c7f933, 0x52d491dc, 0x223ddf87,
- 0xb97178c6, 0x71debde3, 0x55de798c, 0x0fc816d9, 0x4a3d1936, 0x64e2fc34,
- 0xe8826b76, 0x06947e0f, 0x041967c5, 0x55437ff9, 0xfe97632c, 0xc5f4a3ad,
- 0x32f2b89f, 0x7a8afbe0, 0xb439639d, 0x185068ab, 0xd1cc62cb, 0x19cd7995,
- 0x4785d58c, 0x5fd0620d, 0xa748bece, 0x292fca01, 0x8329af66, 0x870800d1,
- 0xa23fc241, 0xd41b7d35, 0xd8983757, 0xca5ec86a, 0xe119ac61, 0xd9a23bd5,
- 0x077e3f00, 0x0fa67e1d, 0x6bca00cc, 0x630b2e1d, 0xff78c29b, 0x7b64c29b,
- 0xb483347b, 0xecd192db, 0xd7a7c004, 0xf40d1633, 0x6983c481, 0x036e92f6,
- 0x1f3099f4, 0x8018f33d, 0x3eadd94e, 0xadd2f115, 0x9163aed5, 0xadf471fe,
- 0x4ddbe68c, 0x6039d76f, 0xf7813afc, 0x543b4d9d, 0xd873e03d, 0x156ada98,
- 0xf728d2d2, 0xa8f3c458, 0x2c6aaaec, 0xa8f7cd8f, 0xa59f686e, 0x00b3ed54,
- 0xe678d85e, 0xcce502d8, 0x848f8307, 0x18d616fa, 0x2398d905, 0x2828ce2d,
- 0xd9c6751f, 0x1de60038, 0xf60a62ed, 0x1a32d8c7, 0xcba45fbf, 0x38b2fd85,
- 0xfd0052a7, 0x2307fb0c, 0x767ec8bc, 0xec568d36, 0xf35c6f00, 0xc01ec518,
- 0xe24d305f, 0xfeccf5ab, 0x73d7ec53, 0xba40e748, 0x7398ebda, 0xfaefb423,
- 0x2c31bf72, 0xd2bedfca, 0xb778d0aa, 0x46b9ddbb, 0xd879f346, 0x9c8fdf0a,
- 0x0067ddee, 0xf1cf8678, 0x03da33ec, 0x519733e6, 0x1e2d297f, 0x11d2479a,
- 0x8ba60e77, 0xcfd4312d, 0xc6be33a8, 0x4baed001, 0xca07cc15, 0x543f9ad3,
- 0x5569af10, 0x71d20acd, 0x825ed367, 0x3f79b537, 0xea11814f, 0x7201dd20,
- 0x8f301755, 0xcd1d16c5, 0xa145b163, 0x99c5e574, 0x7fa82e89, 0x6c5eeac4,
- 0xc79fea19, 0x62771cca, 0xbebff415, 0x7cfb5ba9, 0xb7bc027b, 0x278867c1,
- 0xab72dfd9, 0xb269fa91, 0xf3847fb8, 0x72de9cab, 0x476f7900, 0x48a39fd3,
- 0x88e21a2e, 0x8e8709be, 0x96123d13, 0x78a0ce00, 0x0a85a1fd, 0x85f5aa83,
- 0x23a53340, 0xddb8279e, 0x8899318e, 0xf89f806f, 0x09311ac7, 0x8c62f2f8,
- 0x91c706bb, 0xd91427ed, 0xb45f5022, 0xcf77c5e7, 0x598e652e, 0xfbcf003d,
- 0x6eb2778b, 0x12f77748, 0xbb7b7ba4, 0x21878f81, 0xb38b313f, 0xa4bbfb16,
- 0xce38e9b0, 0xf942984b, 0x979e064b, 0x95abfaf8, 0xeb11ebe3, 0x7896c5a4,
- 0xf02b278e, 0xbc614bf1, 0x7a1eb05d, 0xb3bfcad7, 0xcd617e0b, 0x1e705f9c,
- 0xbb64bfa8, 0xdbdfa2dd, 0x3d5cee9d, 0x08cd93e7, 0xde11c8e7, 0xc3b7c87d,
- 0x90fb3cf3, 0xe098d3ff, 0x27ce3c93, 0xcfbefcc1, 0x467ea36a, 0x8865699d,
- 0xb9852cf7, 0xd32ee902, 0xa1ae10d7, 0x89a3dfc8, 0xb61e407f, 0x52c378e3,
- 0x800354aa, 0x13acc712, 0xdec67758, 0x5da9dab6, 0x3ee708e6, 0xd3ab37e4,
- 0x207cf245, 0x2be54ac2, 0xc07f3833, 0xfc407ff7, 0x2ed3cb05, 0x7e01a394,
- 0x7e438a39, 0x8fc8ec8c, 0xbcf013bf, 0x63a5e42d, 0x613feeff, 0x3acd71ff,
- 0x0c9d02a7, 0x65e9123f, 0xa2f874d0, 0x8fe1152a, 0x00ffc063, 0x358e6da0,
- 0xa52ce507, 0x5d20a1cc, 0x875c229b, 0x230fd4ad, 0x4732b9bd, 0xef86ade7,
- 0x893b46e6, 0x3ed8df7e, 0x366667ec, 0xc01f6fcc, 0xe115fc1e, 0xb6b07b03,
- 0x6ff4f508, 0x3d4469ff, 0xd7f2976a, 0x38a22434, 0x48ae3f80, 0xf7a7e0bd,
- 0x410bd271, 0x73d60ef4, 0xebf6f4c1, 0x039ead05, 0xf4e05d7c, 0x9f226770,
- 0x522f35c5, 0xead07eb9, 0xd1e8ceb5, 0x3a083f41, 0x7e708a5c, 0x0c5cf881,
- 0x7ae38832, 0x583eb346, 0x0e1d99de, 0x76a4898b, 0x1c3b45ff, 0xd1df1316,
- 0xadcceb0e, 0x47c01507, 0x576a8379, 0x8fd50a61, 0xff489cd9, 0x8714eb17,
- 0x41a4e509, 0x71787e25, 0x4bd93865, 0xbb67ef09, 0xdbb107a3, 0xcff21520,
- 0x8ec9dddc, 0xf188c656, 0xf18790ed, 0xd679592f, 0xc5277568, 0x1793e804,
- 0x4308be1b, 0x644ff73c, 0x62c64e03, 0x0ed6a70b, 0xf0290883, 0x537f09bd,
- 0x6b83af10, 0x69ac1454, 0x95269dee, 0xfb1dd6e8, 0xfe5ace1b, 0xbd700d9c,
- 0xceb46dbc, 0xf537c81d, 0x05ec6757, 0xb8232bf8, 0xf7b4be5d, 0x33e42f5a,
- 0x92f77f59, 0x3f7bd262, 0x13192b07, 0xeedf1fa0, 0x61eb8273, 0xd53d6856,
- 0x2a76871f, 0x850023d7, 0x7a3ee651, 0x70d427f4, 0x27f5aa87, 0x7baa3988,
- 0x7f107e02, 0xbf84e18d, 0x77209eea, 0x48e70419, 0xc5bf7fec, 0xfca092c8,
- 0xb623c80a, 0x037f7093, 0xe2074778, 0xaa6f0fd1, 0xe08454f5, 0x5f0fd50b,
- 0x0e905d3b, 0xd16abfd0, 0xb12e3cd3, 0xb3d20770, 0x4864e8ce, 0xe151cf7f,
- 0x55ba081f, 0xd4bb9e08, 0x1b88f430, 0x91e2f7e6, 0x7f7e0754, 0x984afea9,
- 0x46fd122e, 0x979c14f7, 0x851ad69a, 0xc35f70f6, 0x032dbe95, 0xc54dbf48,
- 0x4e872bf2, 0xbe03dcd8, 0x8466fcd1, 0x7e7687a6, 0x9ac8fa95, 0x6150ff40,
- 0x7cc17e7c, 0xfe3434a4, 0xf244194b, 0x7a1f50c7, 0x1ab799d2, 0xa072bde6,
- 0x997ba7e0, 0x983ee51d, 0xabab46de, 0x6e402622, 0xaaed15ff, 0x9c70b842,
- 0xcf342194, 0x741f9885, 0x41a66678, 0xc31bf387, 0x7f4a6ed0, 0xb0effd0f,
- 0x4eff7e21, 0xfe7dafce, 0x3a0daf3d, 0x3fbe68c4, 0xf80071c6, 0xaf803ae5,
- 0xeac18c12, 0xfb79c08c, 0x62e51e88, 0x48e6e57e, 0x61f30a9f, 0x5a170cbb,
- 0xd6e81ea4, 0x4fa07e11, 0x19e7c20d, 0x46e238ed, 0xd235fefa, 0xd1f88d51,
- 0x5fd15b37, 0xc6acf985, 0x28a2367a, 0x2fdfe711, 0xf505b9d2, 0x18cb4bfc,
- 0x57a5f3f1, 0x4c137798, 0x1d7efb76, 0xd646cbf1, 0x9fbef88f, 0x570cf2ee,
- 0x3af3c924, 0xb9ab3b84, 0xb77a8756, 0x43aed7a7, 0xb9b7da7d, 0x3e23a74e,
- 0x8622ff70, 0x5799e4fc, 0xff5f00f4, 0x37ea556d, 0x686f07e4, 0xaf40ef7e,
- 0x92f481cd, 0x7c16cb78, 0x43788d90, 0xbfaad083, 0xe3f662d0, 0x52c3e80d,
- 0x63fb1d6c, 0xf11d25ac, 0xe9faf8d4, 0x5fd02d5e, 0x67a71bc5, 0xfe2a5e20,
- 0x18262260, 0xd1be87f3, 0xe59fefc8, 0x2e67f684, 0xe872ad2c, 0x257a9fc1,
- 0x85d91ba6, 0x446cd632, 0x6ebca13f, 0xa01f4381, 0x76ffa5cf, 0x8f9cd0c8,
- 0xaa1a1ffd, 0xe78065b2, 0x5de18e2b, 0xd13b0858, 0xbfa12fee, 0x472fb006,
- 0xafcf11d8, 0xff734567, 0x20f646d1, 0xa5a1fdb8, 0x7a631c73, 0xa1dfde74,
- 0xbdd361c1, 0x907e7df0, 0x8634741f, 0x18b6b5db, 0x2141876e, 0x8bce113b,
- 0x3d78b7bf, 0xc8717450, 0xfd0c5147, 0x641f5dcc, 0x2e8f807a, 0xfe47e6b2,
- 0x35767288, 0xf971d692, 0x5cca3f83, 0xe5cbf166, 0xdcf8231d, 0x70ed78ef,
- 0xe7da1d94, 0xe717df6f, 0x1ddfc009, 0x9db57f4c, 0x5c7033af, 0x7d33e346,
- 0x07a42f4b, 0x04d9e3fb, 0xaff9a43b, 0xf9c715bf, 0x74874120, 0xdbf4245e,
- 0xc028b0ef, 0x525fcedf, 0xf3247c41, 0xe6666de5, 0xebc80d8d, 0x04b88d9b,
- 0x648b6f2e, 0x37b7685e, 0x7a4712c6, 0xa3259926, 0x5f14e99e, 0xe0cf8937,
- 0x43cf8972, 0xa3a6cf83, 0x2759f15f, 0x1b6f70fe, 0xf7ced76f, 0xd74fc14b,
- 0x7ceff3fb, 0x0aec3ea5, 0x8d845df1, 0x638ae9d3, 0xf7f41764, 0x1ebe8df2,
- 0xe4ed10d6, 0x4f1832fa, 0x8d2b5f6f, 0xdf7f7ec0, 0x050bca66, 0xfba6de97,
- 0x21ca7e76, 0x1fc02a80, 0x53baa6dc, 0x9c1fc26d, 0xbe8af90c, 0xbad1c657,
- 0xd08bf25a, 0x4f30777b, 0x306fca23, 0xf77a487f, 0xfadd01b0, 0x296672a3,
- 0x318bb748, 0x4237ce76, 0x047ca41e, 0x9d3831e3, 0x50ee6460, 0x62af80eb,
- 0x98c35e24, 0x23e1f407, 0xdf640d1b, 0xf8fb5f0f, 0xf7e04cde, 0xd60c1bd3,
- 0x9ce430e5, 0x3ea5f617, 0x0673f503, 0xe40aac9b, 0x3d7ddb4f, 0x5f4bee50,
- 0x0fc85d50, 0x923c37a7, 0xf3d21330, 0x0065bf20, 0x0346e947, 0xf8d9cf95,
- 0x159f9528, 0x42fa5d72, 0x97d47f7c, 0x4eaff787, 0xf9ce3a40, 0x486989ea,
- 0x6b46ed97, 0x9690c1ff, 0x631c536d, 0x6f3df002, 0xbf269873, 0xe0e6c75d,
- 0x995d243c, 0x47af6ee2, 0xa6d53f13, 0x1f7176fb, 0x04dfd69f, 0xa0aa72ff,
- 0x3029c4e3, 0x57a18aef, 0x77dfafc8, 0xc9ec9c20, 0xf92a919b, 0xffc1be8f,
- 0x20db9def, 0xde95fb9f, 0xa09dbe41, 0x674158f3, 0xb7a45cb0, 0x9f3ccc4b,
- 0xfc9ebafb, 0x4a8b5ccf, 0x91f686f8, 0x7bfea163, 0xf40fbda2, 0x5321ca2c,
- 0x848dd7b3, 0x0da36376, 0xf7d0ed0c, 0x19f2f37c, 0xdb3bc9d8, 0x025bc7f4,
- 0xd59a33e6, 0x387f41f6, 0xca821987, 0xcf2c7a9d, 0xc7cb6b35, 0x2cfbb8f6,
- 0xad630ffa, 0x77c972da, 0xfab4d88f, 0x7381df62, 0xf3009b3f, 0x92a4392b,
- 0x7d237cff, 0xafc22efc, 0x5dbf3a47, 0x3bbe0db8, 0xf872b02c, 0x4915e9da,
- 0x142357c8, 0xd3acf186, 0xe3cb42d7, 0x665ea41f, 0x7e3edf40, 0xe63816fa,
- 0xdc51e7b6, 0xa0b119ef, 0xdff08f3d, 0x7afb1ebc, 0x8d9b753d, 0xed8233c7,
- 0xfcdcb046, 0xfe46ecb7, 0x3dd2b7e0, 0x837f4a16, 0x5ced85e9, 0x89eb06ef,
- 0xe1213b60, 0xbcb7860a, 0x0fb1a74d, 0x191ea15f, 0x8c27681a, 0xc3be2764,
- 0x6d8370f5, 0x30f5c768, 0x2f8431f8, 0xad3d30cf, 0x6adfc1c3, 0x220376c4,
- 0x0039b1ed, 0xb76b0ad2, 0x167fb208, 0x405b7ef7, 0xb6ffaa1c, 0x8dea1d5a,
- 0x418cf8f6, 0xeb91a71b, 0x9d8477d5, 0x1cfa13a8, 0xceb4abd6, 0x4eee18df,
- 0xc9b8e3d4, 0x8c96c746, 0x48f9f88e, 0xcfccefb4, 0xbeac7e95, 0x8fb1fb86,
- 0x389a5d58, 0xa893eb19, 0x5fa2fb89, 0xd9edf28e, 0xfcf34e1b, 0x420d7154,
- 0xe733d439, 0xf4016ddf, 0xf87036a9, 0x8f89e183, 0x319276e5, 0xb207f917,
- 0xd0e8f67c, 0xd5895c7a, 0x679cfb53, 0xff474fef, 0x07c6d3ed, 0x7ebf51d2,
- 0xede7141a, 0x169e1e4c, 0xb0a4faf2, 0x2e223123, 0x11ca14f0, 0x9dda41e4,
- 0x55fbe1db, 0x57245d4b, 0x9d3a5d3f, 0x2e9667d2, 0xb613faa1, 0x9adf1a0c,
- 0x775767f3, 0x35c9d3c0, 0xd989d92a, 0x18af5746, 0x59a4eef8, 0x1385f147,
- 0xbb799155, 0xd19cb122, 0xb3f6727a, 0x0278b613, 0x6c277ee2, 0x6743a27a,
- 0xfd8f8cf3, 0x9cbdfa66, 0xbda144b5, 0x23d7e76a, 0x2db5ec1d, 0xac7fe316,
- 0x55db0125, 0xb6bdcd2a, 0xb7c71d29, 0x2c7c6732, 0xf59197f2, 0x0ba9b947,
- 0xb828f6e7, 0xe72c4a5d, 0x1fa1bfc3, 0x8a7efd0b, 0x9e842b76, 0x2f3a0bb1,
- 0xb1ed38b4, 0xc922efa4, 0x81b8275f, 0x728cbe5f, 0x60b84776, 0xd313d65d,
- 0x7c785d61, 0x2ac5b16e, 0xf0a9c3f8, 0x5fab8e75, 0x5bf8886c, 0x609ef167,
- 0x7811de38, 0xc9038e0d, 0x8681c654, 0xbcf9f2c6, 0xe26ab36d, 0x0eff1842,
- 0x79f9ff15, 0x1ba3d72c, 0x2a3c5bc3, 0x7c03c3ca, 0xdb25de3d, 0x2b7c60a3,
- 0x0736bf25, 0xc5775fe3, 0x2da5b8f2, 0xeb889dcf, 0xa344e4f6, 0x3736e303,
- 0xea038f2b, 0xc05f7c9c, 0xd63823ad, 0x7ac27b37, 0xcd095c01, 0xa4231cee,
- 0x0d317153, 0xaac2edf8, 0xa0dd2196, 0x6b23211d, 0x9157b87f, 0x92686c8b,
- 0x4028f429, 0x6772861a, 0x454f728c, 0x559b0cba, 0xfa718d55, 0xffbe3294,
- 0x77715670, 0x9c9f01b5, 0xa43c2b7d, 0xe8225c3f, 0xc9d194cf, 0x36b3fa68,
- 0xacae081b, 0x819f3fcd, 0xf9b59f7c, 0xa012bd2e, 0x1ac79687, 0xdf67fe68,
- 0xe295d79a, 0x58989f16, 0xea7a10cf, 0x1e5f8287, 0x69d87410, 0x8b7fcd0c,
- 0xac6fbb45, 0x55405bcf, 0xe2f9f569, 0x5b3880d8, 0xd265f945, 0xed6393e7,
- 0xfaf3ce34, 0x80c903ba, 0x3167e7cf, 0xe68a0787, 0xf148dd6d, 0xbac69dd7,
- 0xe4efb8f1, 0xa431d0a9, 0x7f03fefb, 0x7e8c9038, 0x60fb2ce4, 0xbfda23f4,
- 0x4ad2f43f, 0x0e7e7f2c, 0x4ff88c1b, 0x60ad3ef2, 0x619fe63c, 0x7faf84b5,
- 0x65b1316e, 0xbf7db718, 0x210ffc6e, 0xc74cbebf, 0xcf04bf50, 0xe832461b,
- 0x19f53112, 0xfd382374, 0xba4a0f51, 0x91190303, 0x886e921e, 0xee90edbf,
- 0xc11af2df, 0x2a9ae12f, 0xb6f3dee2, 0x7c8f1f6e, 0x53665c92, 0xe1204e30,
- 0x793d91ba, 0xd9dbf631, 0x0ed0ef93, 0x221b12bf, 0x0ec21d2e, 0x610d88ef,
- 0x2fed8387, 0x637738b3, 0xe1d91bbb, 0x36ff82e1, 0x7fed06c6, 0x08597ee0,
- 0xed8d0dba, 0x1fdf0f10, 0xe3ff621b, 0xdef0f146, 0x43ff72b1, 0xc97f0f1b,
- 0xad6ff5c8, 0x293c3d8d, 0x1374bc84, 0xb5d6ebe3, 0xc67ed11a, 0xf5212835,
- 0x518b62d9, 0x1c7e1fee, 0x125fb01b, 0xe0438fac, 0xefb628f7, 0x17b7cdbb,
- 0xe9890d5b, 0x5bee8111, 0xdeb0ebbf, 0x29ce310d, 0x22fb3f81, 0xf6a6fb46,
- 0x0afa462a, 0x141e5ef2, 0x371429f4, 0x934f38b0, 0xbec1badd, 0x1cd69dd5,
- 0x3ee483f2, 0xd6ab54d5, 0x938b8c4f, 0x239f9ced, 0xd89d699c, 0x3c097f89,
- 0x70dbfcc1, 0x4c45b8dc, 0xf7231fb3, 0x3caae261, 0xcd0b318a, 0x6af8a311,
- 0x32f758d7, 0x1d6bb403, 0x209b1cc9, 0xcd685d1f, 0x9b6a7d41, 0xfdc468e3,
- 0x7917959a, 0x02e57e3c, 0xfd4e5de6, 0x7732f9f0, 0x17ca2f37, 0x2e302dd2,
- 0xe1c71110, 0x72e38888, 0x1cd27606, 0x8f0ae1c7, 0x9293b00b, 0x3e75ba1e,
- 0x1adae895, 0xd0054eda, 0x77df46d5, 0x50efd742, 0x3771ed2e, 0x8cf71fe7,
- 0x19be05bb, 0x7c737718, 0x4b4c14f3, 0x8f04dfec, 0x0ff38997, 0x2cf80f1e,
- 0xf826ee2b, 0xee2deaec, 0x50881e8f, 0xa5dc5dbe, 0xc4275e23, 0x6b77d085,
- 0x487d75f2, 0x4770b35f, 0x233abb28, 0x7dbff22e, 0xa086645e, 0x179d2df7,
- 0x2d27f179, 0xdcb3a446, 0x06f090f7, 0xe591139f, 0x264a0d15, 0xf6733fae,
- 0xc075a35d, 0xd37fc6a5, 0x79e3a03a, 0x42ee3e0f, 0x678003e4, 0xcea03aac,
- 0x7977f207, 0xea56919b, 0x22ffb32a, 0x4df6e31b, 0x53b5e606, 0xefb6337b,
- 0x7efb78c7, 0x633656db, 0xd31faadc, 0x547ac47b, 0xa8fdceb9, 0x7ee39468,
- 0x8d5b2a4d, 0xbebcadf9, 0x6197998a, 0x847a3a5c, 0xf003d98e, 0x670ce319,
- 0xc67c00f6, 0x7934d9e6, 0x2f9e4eb9, 0x25778dc6, 0x32efbe6b, 0x7da69bbd,
- 0xa69fbb92, 0x10ce653e, 0x6aad3e4d, 0x577da694, 0xf981cfb0, 0x9addcf0c,
- 0x266bddf6, 0x6b3df26b, 0x3fb4d01f, 0xcd9eaacd, 0x9c7a79c6, 0xce003dcd,
- 0xdece0259, 0xdf358beb, 0x0dd5d7f5, 0xf920a1f3, 0xffee1f14, 0x326c16cd,
- 0xfa73c44b, 0xfa69e77a, 0x5e6aff3d, 0x9df80293, 0x19386b5d, 0x7c219f18,
- 0xea4b7e00, 0x8c1cf615, 0x5b5eba5b, 0xe9e1a73f, 0xce902995, 0xe7cb6af5,
- 0x829cbee1, 0xdf2dadfc, 0x823d73ad, 0x71ed9deb, 0xe228ce22, 0x7f03ac3d,
- 0x97b8d244, 0x9778f037, 0xc41de9ea, 0xb13a5a1f, 0x762fc96f, 0x44a62fc1,
- 0xd984bf2d, 0x7a52fcb5, 0x1f30e770, 0x88ff88eb, 0xe47c413e, 0x78017f81,
- 0xf895f897, 0x7cb438b7, 0x9de15df5, 0xdb91af31, 0x3ff96d0d, 0xb5f1b4e2,
- 0xe3ee917e, 0xd4aeb7a8, 0xbf71522f, 0x7df1e58d, 0x57f52bfb, 0x6bb21d07,
- 0xdb3ad7f6, 0x17173a4f, 0xfb175718, 0x3f709749, 0x137636f1, 0xfefb89fb,
- 0xd900f885, 0x1f801b77, 0xb98708d8, 0xcc30ff7d, 0xac147fbf, 0x760a6537,
- 0xb238cbe3, 0xd77dfe27, 0x587af86a, 0x085c5ff4, 0x9387dcaf, 0xf9e472e7,
- 0xe7c91621, 0x3c01fb29, 0xf143f1a8, 0x022d9ffc, 0xf7dbadd7, 0x96f5a42f,
- 0xc4c43f3c, 0x7e10bfb9, 0x3aefe93f, 0xfc8935fc, 0x6e78f081, 0x6d3123cf,
- 0xf9c407f7, 0x3bcf692e, 0xb7ee47eb, 0x7b2a9675, 0x6c3fda55, 0x9b1dc255,
- 0x5e93d842, 0xfd72dff1, 0x1c43a675, 0xe07c57ba, 0x2bd1ebfa, 0x00aed007,
- 0xb962fbde, 0x5af602c5, 0x5febdbf1, 0xbf114444, 0xbd541eb6, 0xb2e0a1bd,
- 0x036d1ed9, 0x6984363c, 0xab4c88ed, 0xf403c9cc, 0x3daf58b1, 0x11f727e7,
- 0x6367db83, 0x27fd80fb, 0x8fe34ef8, 0xfdc21cac, 0x6e78ecb5, 0xe488bfdf,
- 0x9114c1fe, 0x175a0caf, 0xbf70d655, 0xe9f8236c, 0x4cfd010d, 0xfb50b789,
- 0x533911a5, 0xc08e29e2, 0x332bbbd7, 0x5627f214, 0x21f90a2a, 0x5347a267,
- 0x9cb8b5fd, 0x623fc4c9, 0xbbe8299c, 0x6edaffc1, 0x38bb1e1c, 0x37fb238f,
- 0xe6f6f3c7, 0x4e94d1f8, 0xb88ab789, 0xf21fb5b3, 0x93846547, 0xa1aa35fa,
- 0xc7a6a5f7, 0xb5ad79f3, 0x6a27e930, 0x84e3fee2, 0xbf38c4de, 0xf9a3fb89,
- 0x71fc1363, 0x7f66a67e, 0xf1138c68, 0x773e857d, 0x53ba9ea2, 0x78b3bdd0,
- 0x758fb3bf, 0x75276e3f, 0x12fbf78c, 0x1dfbc643, 0x0fde28e3, 0x5e71ea5f,
- 0xa47f71c1, 0x2fcd8443, 0xb7c48f3f, 0xd45483db, 0x7746f54f, 0x5abbae35,
- 0x0eff8377, 0x2dbc7dc5, 0xf0301fb4, 0xae077750, 0xb06656af, 0xb7e416bd,
- 0x7fa18c65, 0x5ba2df5f, 0x6bf5061e, 0xf58acc3c, 0x75f03723, 0xbb7ae95b,
- 0x8069a703, 0x8865b075, 0x8bac1f5f, 0xd7bc218f, 0xc46e4cb7, 0xf73581fd,
- 0xa19a1b32, 0x1b9b565a, 0x06d0fe85, 0xf8dd7216, 0x09b39094, 0xd4557b39,
- 0xdfe8f117, 0x53d3a087, 0x0fa04e82, 0x879d22d6, 0xf0afbab7, 0x4fae38fd,
- 0xfae22548, 0x1bcebf74, 0x373f3d6a, 0xf21d773a, 0xe86f40c1, 0x0b5ac3f5,
- 0x1175b7e7, 0xdda8e7ae, 0xb5ee7e2e, 0x59dfea54, 0xba07a63a, 0x9d74114f,
- 0xdf9f81b2, 0x5faed760, 0xc89fa557, 0x7a867fa8, 0x8b5ef4a5, 0xa543e317,
- 0x821e190d, 0x7a38a5cb, 0x7868bea2, 0xd2f985df, 0xc62b2cac, 0x657f9c23,
- 0xe43ea9ca, 0xbfae3262, 0xd494ecf4, 0xe3c76427, 0xb269df68, 0x16b5b7e0,
- 0x0d473f3b, 0xfc008e28, 0xb6586e97, 0x7cefcf17, 0xfb466bf4, 0xd6d4474b,
- 0x54d9d861, 0x2192ce40, 0x2159ea98, 0xfef82bc5, 0x1fa2bdd5, 0x5c61bfcf,
- 0xa9dc7fb3, 0x3e69070d, 0x63cc0c47, 0xb4ba3e06, 0xfa3b3ee7, 0xcde32bdb,
- 0xfb93c714, 0xf75547b2, 0xf48464e3, 0xda0815ad, 0x56110dfd, 0x43fc7f8c,
- 0x82465df0, 0xc7d21f7b, 0x057c7cbd, 0x6596c1da, 0xa3c474a6, 0x1a92797b,
- 0xd7ba7007, 0xd1ef342a, 0x788c93cb, 0x8ae6617e, 0x4f50e3c1, 0x95ce610d,
- 0x2879df18, 0xd3948596, 0x9d7cf1f3, 0x60655c58, 0x849a68c6, 0x172fe311,
- 0xbf8a146b, 0x015bfee0, 0x988e67d0, 0xf7aaf95f, 0xec3f88a3, 0x1e186ff0,
- 0x733fe5cb, 0x1e494aaa, 0xe46bcec1, 0x19d58ca7, 0x799fa093, 0xdb39606b,
- 0xf1fdec8d, 0xc043fe0e, 0x3af2ef79, 0x5b257d6d, 0x7f9d39f3, 0x5befe061,
- 0xeb682ed0, 0xe8f2953f, 0xaba40e60, 0x8cc5b17b, 0x0b4684e7, 0x51ad14bc,
- 0x665fa8ac, 0xbf8c68ae, 0x9b33f20f, 0xb4f20754, 0xe8eb0bc4, 0x8f39d3ef,
- 0x693d4dcb, 0x6ed9703d, 0xdced82ef, 0x2bff5c51, 0x2c70f77a, 0x3dd6287f,
- 0xadf1d71c, 0x9e18589f, 0x06d6399b, 0x1ec618fe, 0xc5106ccd, 0xd06cac1f,
- 0x5a3b00a4, 0x6026b064, 0x16c3dfbc, 0xb7be3226, 0x779c0e65, 0xf90d79a5,
- 0x07e89581, 0x1f91f9f2, 0x672c50f8, 0x15d7d6d5, 0xeac39f3a, 0x9a07e40d,
- 0xd6781f85, 0xae009b5e, 0x6e3d7317, 0xde2d3920, 0x687e4316, 0x235c8af1,
- 0xaef16ff2, 0xe043d218, 0x63d87e07, 0xc78e9f98, 0x481e6456, 0xeb8b7e84,
- 0x96aa1c32, 0xb8ff5a7e, 0x5ba498e6, 0x4b4fbf47, 0xe8a193b7, 0x94d2f406,
- 0xff0824a7, 0x3d8bd04e, 0x477e4b16, 0x7ab782e1, 0xcb9e019a, 0xee746155,
- 0x83ff33a8, 0xbed1c6a5, 0xe6175c9e, 0xdfafb725, 0xcafcdf68, 0xb744a19a,
- 0xfde57a60, 0xb470e667, 0x16afec27, 0xa1ec7a86, 0xc9e1ecee, 0xc2b0fe50,
- 0xeaa1ebe5, 0xa72879f1, 0x6f5c0959, 0x6614b7be, 0xfdec6468, 0xece666a5,
- 0x4b07d8c5, 0x68ff94ad, 0x3fe52269, 0xf4a76a5e, 0x287da593, 0x68e2293d,
- 0x0180ce52, 0x25475f88, 0x951af970, 0x6cdee220, 0x8caa2251, 0x307cffbc,
- 0xa1c56754, 0x4d8c27d2, 0x271eec63, 0xdfc02320, 0x046f7e99, 0xdf3db912,
- 0x4b8eb062, 0x9571ff44, 0xd8befa42, 0x3da6bb75, 0x3c4625f8, 0x64facdff,
- 0x9ce9cbfa, 0x1938dd98, 0xfcfef0f8, 0x69fb4d58, 0xfc9a2935, 0xcd3b04e4,
- 0x775e527b, 0x8503f94d, 0xa2f935fd, 0x9e024036, 0xf8db302f, 0xb7d8aafe,
- 0xd7c6cc67, 0xf6de56eb, 0x2ef0d56a, 0xaf7807df, 0x7d50321e, 0x5d243d30,
- 0x31d7ad67, 0x73368037, 0xfa0dcc3d, 0x933b593d, 0x11fceae4, 0x95fdd90b,
- 0x1ddf32db, 0xdb63f901, 0x7ebfb40c, 0x5aec456c, 0xb63e3fdc, 0x418a3e2d,
- 0x32a95eea, 0x7ac1fa1f, 0xe80591ab, 0xcb15dcb7, 0x9156fce8, 0xf940e4d7,
- 0xf9efda2f, 0xd1dbcc95, 0x5120441f, 0xbd543e3e, 0xe7e8853e, 0x14befc24,
- 0xf902dde6, 0xf1afa033, 0x16ccf8c8, 0x8519d70e, 0xd9fcc0ad, 0xfaf5bfb0,
- 0xb171c03e, 0x8744b6a0, 0x50f501eb, 0x1dcbe93c, 0x2dbe432a, 0xfda0605c,
- 0xa91fb9bb, 0x94cf311b, 0xde9c2921, 0x64479d2a, 0x7fa8992f, 0x021c0ad6,
- 0xd6fd16ed, 0x77d689b4, 0x0f77e44c, 0xfc16aef4, 0x26747c89, 0x08633986,
- 0x3de08558, 0x46fc7ef7, 0xd3e3f7ac, 0xfde7083b, 0x32b5dea5, 0x5cebf801,
- 0xe9107789, 0x49e2c7b5, 0x7ef182ae, 0x96f5c8d2, 0xf140e507, 0x9cbf4beb,
- 0x9d3e272d, 0x38247069, 0x25655f48, 0xb93abea1, 0x98e740c6, 0x3519de99,
- 0x3b3fd689, 0x38e58f88, 0x71f6f527, 0x9ac9df08, 0x96fb860c, 0xf2546bc5,
- 0x78ff9007, 0xffe72f7b, 0x1b3755a7, 0x28d6fd0e, 0x23a5d66e, 0x60b23cdf,
- 0x9a639d38, 0xc141d621, 0x9033e07a, 0x7f2f7755, 0x7e1ede7e, 0xb56586ce,
- 0x181defe8, 0x7c158f38, 0xbfde44bc, 0xd650073c, 0xd1474fed, 0xd4dcbee5,
- 0xf0ed1a3d, 0xe2550fd9, 0x6addb3b3, 0x3d022587, 0x0ef6e82f, 0xcfe43efb,
- 0xe94e7817, 0xb854ff21, 0xae02677b, 0xd26b7457, 0x3e786e95, 0xdbdac4f6,
- 0xaf73bbe1, 0xe6241c18, 0x7f49e24b, 0x6e697bcc, 0x8ef3c0d7, 0x2f97f51d,
- 0x38bfef99, 0xe7c01493, 0x38dd7b7c, 0x775c00eb, 0xe21d84bb, 0xe6e3b1f8,
- 0xbac5e02a, 0xc343c14e, 0xcb50c4ec, 0x3d773c6a, 0x3024c413, 0xec42784e,
- 0x7a101f8f, 0x1109fa45, 0xa67e785d, 0x7b37f38e, 0x0dbf2155, 0xbffa347e,
- 0x944f9c52, 0xebea5f7a, 0xfb4b5632, 0xf81247c1, 0x8ab9c639, 0xe055da97,
- 0xa8a82ece, 0x420f2b12, 0x79356d97, 0x97d419bd, 0x480fd035, 0xfbe762ee,
- 0x9e57c643, 0x652db645, 0x417e7ccd, 0xbc19ceed, 0x1d19cd25, 0x75894ded,
- 0xf51b0ae3, 0xfc60706f, 0x69c854a4, 0xf5e2ad79, 0xdd9079f1, 0xd98af194,
- 0xdb066ec2, 0x28f60ea7, 0x0ecd0ec8, 0x56acb3b2, 0xde01576b, 0xc2471c48,
- 0x2ba70c1b, 0x987842c2, 0xbda17007, 0x0f7b712d, 0x15b8244c, 0x03b25007,
- 0x35cca53c, 0x01e70626, 0x477b3ef5, 0xd5e782f8, 0xcf315e01, 0x1c4bb860,
- 0xff70fb9f, 0x5187cf18, 0x1e6829bc, 0xfec11e92, 0x894ba49a, 0xa4b7e387,
- 0x7e7a2141, 0x3207eeda, 0x7e491b8a, 0x9d500581, 0x44d77bf6, 0xeba567d4,
- 0xf866ff40, 0xd3f247f9, 0x8517563c, 0x7cc152fc, 0xbe50932b, 0x46d3757c,
- 0xe1bedfa2, 0x49ca237d, 0x53d7cda1, 0x5c288317, 0xb4bcd3fb, 0x1044f580,
- 0xd7446f9e, 0x9c378a6f, 0xbdc65e95, 0x37b34f00, 0x41b0ceab, 0x1ce2769a,
- 0x60e48791, 0xc463c78e, 0xb11cc6f8, 0x9c11bfee, 0x6e7e7a95, 0x76f086fc,
- 0x5b7d27e2, 0x68baf3b8, 0x9fbf62fd, 0x943a33d5, 0xaff76a9e, 0xdffaec82,
- 0x217e3c0c, 0xbd55f1f5, 0x5025e293, 0x2aaefc2e, 0x079b8f2b, 0x2cb4f1e9,
- 0xc225e3d2, 0x4e71cbae, 0xf149dfad, 0xf768d9b7, 0x5d3fca03, 0xfee293b7,
- 0x476657c6, 0x6a7dffa1, 0x78b5ccfd, 0xb6d4ebbe, 0x4be76499, 0xde76939f,
- 0x1ff40c6d, 0xbd17d772, 0xdfe463f8, 0x9f1461ad, 0x16efd92f, 0xabd01eeb,
- 0x9ebeced0, 0x8eb651eb, 0xb452d5eb, 0x1ec80387, 0x8b76c6f6, 0x51bddc4b,
- 0xc9ca020e, 0xe99e2e4e, 0xe81eddfe, 0x11cbf177, 0xc2a10f0e, 0xdf91d3ea,
- 0x3da1f56e, 0xf1f85f2c, 0x0ee73c51, 0x1fa3fff6, 0xd90ffb48, 0x92f77a8d,
- 0xc26f282e, 0x1bab97ee, 0x27e8add3, 0x5ff13b08, 0x3439bfc0, 0xfe1087fe,
- 0x01ff118b, 0x6bc720fb, 0x06679e38, 0x1ac4ffe1, 0xdb95974e, 0xfae147ba,
- 0x774d78f1, 0x6f8eb3f2, 0x9ff849eb, 0xcff01ab5, 0x3f5a5fe3, 0x8ff006ab,
- 0x3fc408eb, 0xdfbc5bc0, 0xe0eff02e, 0x78e1aff8, 0x3a786b67, 0x3d9e03ab,
- 0xf1618e74, 0xf40e4daf, 0xf984ce1b, 0xb33a9fc8, 0x01d5655d, 0x83f4987e,
- 0xbfb560be, 0xe24d7f42, 0xe6af6e7f, 0x0a7fa841, 0x1453fe9f, 0x76ee61d2,
- 0x80efa41e, 0x82ece67f, 0xfc7fb8fe, 0x95e9bf76, 0x7e01f12e, 0xa9d24dd3,
- 0xd918b982, 0x1d3f86c5, 0xe28375c1, 0x786d4f84, 0xd7dc468f, 0xd7ded7a8,
- 0x851933c0, 0x382f8c36, 0x278466cc, 0x8a1ef835, 0xf91c619b, 0x9f3f3d9f,
- 0xbce490b1, 0x6dbe7355, 0xba19f322, 0xa758ffa0, 0xf2c6fdd0, 0x39513945,
- 0x55d4e30c, 0x2ee9c704, 0x78fce68a, 0xff23aab9, 0xfdc8ccb1, 0xf93fb948,
- 0xde0ff0ae, 0x25d7c2ed, 0xd2b175ef, 0x18c29777, 0x164b81d9, 0x23ef17a3,
- 0x112a7ac0, 0x31ecf7c7, 0x228edd11, 0xd57f804c, 0x6036e228, 0x1f4f9102,
- 0x1f4f9c64, 0x38a26c8c, 0x5e54ac39, 0xd0f8bb40, 0xfc839312, 0x8a68b8da,
- 0xf4203ed7, 0x2b9183dd, 0x1e1f685d, 0x313a348a, 0x783d7e85, 0x1a30ce88,
- 0x0df18786, 0xafba46c9, 0x796e6853, 0x0fbe9705, 0xd4789e27, 0x06dea00c,
- 0x55c637ee, 0xd75dd7e0, 0xc5d23b63, 0x9c6d1f4f, 0x743c32a7, 0xe055a3dc,
- 0x293a714b, 0xbe82639e, 0x2b8e01c3, 0xdcb12f68, 0x9df1e56e, 0x8b27400d,
- 0xe5c1be9f, 0x03f7c3cc, 0xe35cf0ca, 0x6419c628, 0x935fe104, 0xfaf2332f,
- 0x26afc4f0, 0xec66cbac, 0x103ecccf, 0x3a8656e9, 0x45f7d704, 0x978c5ed1,
- 0x25f183df, 0xe27aa61b, 0xe67ac997, 0x26b4f1d1, 0x89cccf12, 0x8144d378,
- 0x9823a9cf, 0xeef01a2f, 0x778da83b, 0xf9d3e7dd, 0xef7e037a, 0x911afbd1,
- 0xbb66753f, 0xb8e30ac1, 0xb82194f2, 0x7e5b292e, 0x25a6f073, 0xa5d7f39a,
- 0xcfc75e42, 0x80feb585, 0x041e21c7, 0xcdbc4561, 0xeafdb3d0, 0x8807ce10,
- 0xdd9b4a97, 0x2816ed43, 0x71950f14, 0xc1ff4936, 0x1d207dd0, 0x41f0141f,
- 0xf851353f, 0xbd3431bd, 0xf5ca26fa, 0xabad1d73, 0x9bb90be7, 0x9b6de52f,
- 0x27c6de56, 0x82bda9da, 0xede0307e, 0x26769141, 0xff44e317, 0x5cb912e3,
- 0x78e2dd64, 0x9d35b22c, 0x7908b7ce, 0xfef13729, 0x88f7f8e5, 0x8da24c74,
- 0x00f095fa, 0x7ec71ebf, 0x9001a074, 0x56d64f5f, 0x87347f93, 0x33b5c405,
- 0x5f24edfc, 0xebb7cc77, 0x4c75dd11, 0x10b3ad8d, 0xc2f7caf5, 0x1f47a81c,
- 0xacf5d634, 0x4ed8ec8a, 0xb214dbee, 0x3d230366, 0xc261e229, 0x23558cfe,
- 0xa1407ce9, 0x5e0fefc2, 0x7478b1ca, 0x31a718d1, 0x630b6910, 0xf13f3a14,
- 0xf27fb137, 0x89e2f450, 0x5185d728, 0x33a63d46, 0xfbf52b58, 0xe8b76b77,
- 0x33de18fb, 0x0e763156, 0x77c88f03, 0xa8d5b8c2, 0x8d7e7877, 0x4aa29b33,
- 0x21c77f22, 0xdee1e027, 0xca7f406b, 0x09df2f7f, 0x4b7a5ffd, 0xe93bb3d4,
- 0x0b8f4bfb, 0xf2e4f63e, 0x7d65cffc, 0x92afcf1e, 0xff3cf9f5, 0xe45feca4,
- 0x5faa0e9f, 0x4bff5416, 0x3ebc5f9e, 0x7e83df3f, 0xd2ce68eb, 0xd214a385,
- 0xbe847b53, 0x23ee5c28, 0xf6ea16fc, 0xf33474f2, 0xdc6eb2e9, 0x6ba2536e,
- 0xd51fda0f, 0xf682d272, 0x2764d5f7, 0x704f9fe5, 0x75c44b2f, 0x63c524d4,
- 0xa1fb7d44, 0xc4c1ec97, 0xed1fce4e, 0xf8e3c2e9, 0xbfa0929b, 0x05fb7ea1,
- 0x8c4eacfd, 0x1c7ef5bf, 0x80ae1c49, 0x26f99e7e, 0x23a7fcf0, 0x49be1b3c,
- 0xb592b33f, 0x487f48fd, 0x86be7549, 0xe32763f3, 0xe645e734, 0x8d11c4ff,
- 0xe78627f1, 0xf3f50045, 0x67a5d797, 0x5ff3ff42, 0x04bd3d7d, 0xe76125fd,
- 0xcc74da2b, 0xdb34f789, 0x1be7a518, 0x7de2313f, 0x8d5d8ab3, 0xaed071c6,
- 0x00dcd212, 0x9c04cab8, 0x93f4e760, 0x8373ec03, 0x3d8c1bd0, 0x5f37f7cd,
- 0x7a47ab3d, 0x9dd5d7ce, 0xf6ed0e7a, 0x3ee42528, 0xddf166cd, 0x17ce4ed1,
- 0xe87a15ef, 0x11b39a6a, 0x8c6bf9e7, 0xb73e4021, 0x60fb93ba, 0x855f1c49,
- 0x1ccdeec2, 0x01db3166, 0xe43f43cf, 0x1b2554fb, 0x3c608632, 0xd184cdf8,
- 0x6d7e24ef, 0xc795b53c, 0x3c781b53, 0xbcd6d0b5, 0x33379408, 0x31ad9526,
- 0x84d8c1df, 0x0339485f, 0xf36f8591, 0x9d5f324c, 0xc79b263f, 0x767f30bb,
- 0x506b63fd, 0xb9c29a6e, 0xf0d0fb1f, 0x17a8e181, 0x7422325a, 0x37e79056,
- 0x498c8be3, 0x8efcb143, 0x639e5871, 0x222af4b2, 0x8be232fc, 0xc75de337,
- 0x3db05f90, 0x46dc41c6, 0x307dfc5f, 0x2adbf70f, 0x0f75a79d, 0xda87708a,
- 0xc087fa77, 0x4ac931ab, 0x19901369, 0x870917fd, 0xf9fc1f1c, 0xdfd0cd45,
- 0x8349e5c9, 0x9f71db57, 0x3490c725, 0x467e3fd4, 0xe072fb82, 0xac7527f8,
- 0x6e292e17, 0x024b8e16, 0x5dee030e, 0xd95dbe03, 0xac06732a, 0x898f26f3,
- 0xcdefe4d0, 0xc0ce658f, 0x29bded38, 0xc2f4fc9a, 0x0ff69aee, 0xa9afeacc,
- 0x6735302f, 0xb1f80555, 0x1e49fb9d, 0x62d2a782, 0xee7f4709, 0xfc5f0def,
- 0xfff441e5, 0xf40eab36, 0xd9eee755, 0xa1db97f2, 0x4e3c65d5, 0x3b47f145,
- 0xc9cecbc5, 0xa77a28f3, 0xe85f703e, 0xf3a66b22, 0x03ed9d3e, 0x7cee75c9,
- 0x773a7eeb, 0x03ef5df6, 0xeb124af5, 0x086c21dd, 0x55cbc3da, 0xaebc511f,
- 0xefcf9222, 0x8cc7ebe2, 0xfb8a0fb8, 0xdf81d78a, 0xd10fc2ef, 0x50f36c3f,
- 0xfeb73b3c, 0x1d9bed18, 0xba7ae448, 0x1e817522, 0x42551def, 0x1c68768a,
- 0xe068abe8, 0x3646e697, 0xbbee1770, 0x1fb85866, 0xb19936de, 0x1e2be458,
- 0x884a69df, 0xf3d77ba1, 0xbca8f26b, 0xfa9c2da2, 0x1e6d4f7f, 0x5f09e747,
- 0xa1ff6853, 0xe5a1e520, 0x29b87e78, 0x11e033dc, 0x77e0b718, 0xde21e577,
- 0xf3f1762a, 0x9fea05b5, 0x5a4016b3, 0xdf479b56, 0x49aca817, 0x42617f01,
- 0x05bfb72e, 0xaf21f368, 0x46acb30e, 0x7d1aabbb, 0x3d479ebd, 0x9e90b463,
- 0x807b6e89, 0x336cafc6, 0x24f7f7d3, 0xd0d77f71, 0xdb1ae1c2, 0xc972a2e6,
- 0xba93530f, 0x860fd669, 0x7c7acdf8, 0xc2d0c397, 0x6dddfda8, 0xf39528fd,
- 0xafcfbb7d, 0x21ae3ee9, 0x14b8eafe, 0x71dbf798, 0x90dc958a, 0xa57c3d20,
- 0x0b34786a, 0xc7daa7a1, 0xf4e7e369, 0xdcfc6d4c, 0x738a615e, 0x31c0127e,
- 0x3d16b1f1, 0x48b107ee, 0x35f115b3, 0x7b60c471, 0xa97c8049, 0x2237ef7b,
- 0xdeeb0c7d, 0x369da237, 0x501b9a41, 0x33ce2e5f, 0x05e9eb04, 0x2f4f5249,
- 0x1dda54a3, 0xf9067576, 0x82ac33a9, 0xccfc8501, 0x7e54fa10, 0x1a6b4cdf,
- 0x1e6ee3a0, 0xc5347fc7, 0x45f502bd, 0xbe9b0e73, 0x7366f483, 0x7cc3ee3a,
- 0x9d03f057, 0x89f90acd, 0x751e742d, 0x0ebb08e2, 0x04abffe3, 0x6f8e525c,
- 0xa2c58f34, 0x5b2a7bfd, 0x77befd82, 0x4ecd9de7, 0x47f1afe8, 0x0f689999,
- 0x25cfb8e4, 0xcc297bf1, 0xd70d7ada, 0x446f9583, 0x0bde51d8, 0xfb863170,
- 0xb44c7b9d, 0xda72814e, 0xc37ca8cf, 0x89ef09b4, 0x7ac14654, 0x7dcfc615,
- 0x7c87cc33, 0x9866f8dc, 0xef46ed1e, 0x4873f774, 0x7b37dccf, 0xa1f5c18f,
- 0x67a4c1b3, 0x9f38f7e4, 0x09db3d27, 0x5bd237bc, 0xe5267cc1, 0xe5c35dd3,
- 0x69f048a5, 0xb73f90b1, 0x552ba390, 0xaf0e485d, 0xe340063c, 0xca63e93e,
- 0x27e85dc0, 0x7ef42dd8, 0x02cb9493, 0x79410f5c, 0x3a18ff41, 0x8dfd2bff,
- 0x6b2c3960, 0xe5bf52b3, 0xef21766d, 0xb94bca36, 0x6372162b, 0x2cc67e12,
- 0x53bbe7c1, 0x5e20efdc, 0xee41aa0a, 0x3f1f68a3, 0xcfc9e50b, 0xf22b4637,
- 0x624df017, 0x54fc8049, 0xd0cfde37, 0xb9c5313f, 0x41666f88, 0xcc9fe81a,
- 0xac4ff76e, 0xfe0012e3, 0x74322b89, 0x9da9df78, 0xe6f9db7f, 0x8f7ff8e6,
- 0x48e29790, 0x67f44f5f, 0x0e61550d, 0x397e873c, 0x2cf7ef8e, 0xb8f1c55c,
- 0x45cae0d0, 0x2fe162ff, 0xa1978a15, 0x697a81df, 0x632a91d8, 0xfee51c60,
- 0x0ecc41b6, 0xd6d29878, 0x1337d283, 0x0f1147dc, 0x04d36d45, 0xa37d06be,
- 0x4ea1c5fd, 0x7832471e, 0x198d8e4d, 0xab724718, 0x6933e748, 0xe04cfacc,
- 0x1d7ade7e, 0xbee4c3c5, 0x992b8ca3, 0x807cbcf0, 0x5f42fd1d, 0x37ef4e9b,
- 0x7299c704, 0xb0bfddb8, 0xbf7640d9, 0xc3cff1ac, 0x2e7f5074, 0xed05d9c3,
- 0x777a97c9, 0xbcf5f21b, 0x0d57dec9, 0xe4ff9f90, 0x7691a8ce, 0xf4eb3e3f,
- 0x47689ebe, 0x188f00eb, 0xa35baaef, 0xbfb979e6, 0xc9f7c113, 0x7e4b7f38,
- 0x79f3e60e, 0x9f88dd6d, 0xc89954ae, 0xbe015d0e, 0x48760165, 0xe7a91dda,
- 0x7c91fda5, 0xfae7ae5d, 0xda323cab, 0xb408c9eb, 0x395c933b, 0xf87d77c8,
- 0xddbf1a79, 0x1476b4d9, 0x38a5c1ca, 0xed28b73a, 0xbc1cb046, 0xd31c14b6,
- 0x8eed1d5e, 0xcf52ebd4, 0xfa35bb4b, 0xfe772fe5, 0x8a55cd15, 0xe032407b,
- 0xb73d6eeb, 0x2deb775f, 0xe3633fc4, 0x6f91e926, 0x1e8f5e6e, 0x98f47a13,
- 0x74568f46, 0x27060762, 0x741c9adf, 0x4cf3ed15, 0x3d447fdc, 0xa3dfd81f,
- 0xe0c7a329, 0x7327c63c, 0xc15dfb3b, 0x1ffe99dd, 0xfa6b7c9f, 0x88b2587f,
- 0xff40ddf7, 0xfd732617, 0x99efac1f, 0x73a7bf95, 0x2f5f4f69, 0x0ca383da,
- 0xc1da03ec, 0x16fb0886, 0x5ec80f61, 0xbf7b4784, 0x4d5c1ece, 0x7888599b,
- 0x1e0f610a, 0xf616fe4a, 0x94a1f240, 0x5227291b, 0x48e5822e, 0x9f84c5ca,
- 0xe9113ac2, 0x57bf1ef4, 0x6cf7ae50, 0x7b46fda3, 0xcf9460c4, 0x976e3f76,
- 0xc1d6f242, 0xf1f9084e, 0x6ed68bcb, 0xf290b948, 0x5ca7e522, 0x20ecc5c8,
- 0xd6a7d8b9, 0xf70a333d, 0x6bdd92cb, 0x72fde393, 0xd823b652, 0x57ca743e,
- 0xb3645918, 0xf218aae3, 0x81a43955, 0x44ea657c, 0xbe499e1e, 0xd968bf35,
- 0x6fd3f24d, 0xf4fcfbfe, 0xe9f84e9b, 0x3f0dbe7f, 0x3f63f475, 0x3c03b2ce,
- 0xdf40b257, 0x6df9f866, 0xfb8c3bc2, 0x7af9dd0f, 0x0497d600, 0x8d319377,
- 0xae133ee2, 0x2f8a2ab3, 0x7494be0a, 0x6cc0fe96, 0x93387711, 0xe1077ae2,
- 0x82c0f5c5, 0x447bd39b, 0xb35c5367, 0xb327d711, 0x03f40d21, 0x9b7ff33a,
- 0xbdef516f, 0x3e749371, 0xfb9dfc96, 0x4392c78d, 0xb1c78dfb, 0xb5d29bfc,
- 0xf8899720, 0x300b8fde, 0x29e138de, 0x0acb6791, 0x46d38f10, 0x3c9ffac8,
- 0xfa81ece9, 0x38b8c981, 0x53de39c5, 0xf4b3de45, 0x3f6818f0, 0x8fe619e1,
- 0xd8fd439b, 0xb8f6e8ec, 0xedfcc288, 0x3b1fe795, 0x51e886bc, 0xddcce5cb,
- 0x3ffbe7a2, 0x79059f22, 0x447e404b, 0x6f037e50, 0x616fa51f, 0x9045e781,
- 0x9c21949f, 0xff00aece, 0x7fdf8601, 0x5585ed05, 0xa8d71861, 0xd6f8db8c,
- 0xf56bd415, 0xb545ed0a, 0x14d581e3, 0xfbc55338, 0x735f94b9, 0xc23e09d8,
- 0xbe78bb03, 0x93ed4a4f, 0x37e8bd1e, 0xa1bddce0, 0xb9d2714e, 0xb78a1183,
- 0x7c47465b, 0xdad149f7, 0x6bd1fc27, 0x1e7867bf, 0x6fbe56ef, 0x8dd6cfbf,
- 0x6e99f7be, 0xb2fbfc61, 0xfe7f9f43, 0xefe70a5e, 0x21d15931, 0xa8a5c7eb,
- 0x37111fbc, 0x68a1f1a0, 0x7be85d4a, 0xb8c513b0, 0x425fb8cd, 0x24f6dcf8,
- 0x28d9b7e2, 0x93f2fdf1, 0x196377c8, 0x60cfc4d3, 0x9fdfca7c, 0x8d4172f2,
- 0x19d74f9e, 0x9bafaf84, 0xa91480ef, 0xf2f8fdbf, 0xf4cbd104, 0x8476f835,
- 0xfb5db7c0, 0xe8ebefbd, 0xf7c3ac35, 0x48e76f82, 0xf86a763e, 0x22ef5a3d,
- 0x538e8cfe, 0x5747e8ac, 0xe0d6c2b8, 0x9f2fc17a, 0x6cbe27bf, 0x1d03fb96,
- 0x02b5efe4, 0x890abf94, 0x4febcf47, 0x74bafca2, 0x3cb9eded, 0x7335f3b6,
- 0x52bc01f6, 0x7fbe0fc8, 0x27faf9e4, 0x7c092e31, 0xd794f541, 0x2c1dc007,
- 0xf941758f, 0x15f920ec, 0x03fa47f2, 0xa9e001ed, 0xb8b7ea27, 0x007b4663,
- 0xd04cfc9f, 0x27b8a2e9, 0xfb9a3cda, 0x78ddcd93, 0xfb8523ba, 0x7c09cf8f,
- 0x9bed126e, 0x90f003c3, 0x1f1fe1aa, 0xe6025bae, 0x3fba784d, 0x93fbce4e,
- 0x63d07c82, 0xbf5e36cd, 0x27a3e52d, 0x7cfed93d, 0xa6af7f70, 0x7880527c,
- 0xf1fff7f1, 0xee23f461, 0x91db7817, 0x27b0e472, 0xc139d052, 0xf0214eff,
- 0x5163bd07, 0x74a1fc8e, 0x761f8fe4, 0xd04f4fe4, 0x774ef4f7, 0x3a7bdf67,
- 0xfa0cef7e, 0xea3de19e, 0xd05eff9b, 0xae883f2d, 0x1d744179, 0x942f9413,
- 0xff46af79, 0x5c5cbd4a, 0x09e3f4ff, 0x54df1871, 0x9fbf38e8, 0xbd934f9f,
- 0xfc956f99, 0xf230e67b, 0xcf9f9fab, 0xd7279e12, 0xce79ba09, 0x787a893d,
- 0x51e1ea12, 0xd414fcfe, 0x5f3f9443, 0x7e61fb80, 0xea81757b, 0xed91abef,
- 0x7afd922f, 0xefec8560, 0x3a4bca33, 0xb225cf32, 0xbd0bf777, 0xa4ad3cc3,
- 0xf035e7f7, 0xfe7d3fef, 0x2b5fc3f3, 0x7841b50f, 0xf79410d9, 0x775fb504,
- 0x22b6fb03, 0x82c7fbe8, 0xe504d7ea, 0x6be507d7, 0xcd17dfb4, 0x8b0e4852,
- 0xc9fdf046, 0xe60cb960, 0xda522f8f, 0xf6ed63e3, 0xff24895c, 0x1357234e,
- 0xfafe79aa, 0xa829fff3, 0xa7c80c89, 0xb21e89b0, 0xc05a30ef, 0xb9d041fd,
- 0xc1f8151e, 0xbcde89d0, 0xecde99d8, 0x79ef6c13, 0xd7f03ffd, 0xd22fda24,
- 0x54fb25f8, 0x9551be6d, 0xbbbd4770, 0x5f603228, 0xe2265995, 0xfdf3baba,
- 0x6389889b, 0x22fc0352, 0x6744f84f, 0xfb653cc0, 0x575d5f71, 0xd4f8bc71,
- 0x719b89f0, 0xd8b4687f, 0x14f1b4d7, 0xf68aa5ec, 0x6fc452ba, 0x5d39e1c6,
- 0xebee176c, 0x0fd030b9, 0x70bd7562, 0x523f8d9e, 0xd550bbf9, 0x53c01f40,
- 0x79d3b311, 0xea7899d3, 0x47d43bbe, 0x0df92f47, 0x47efb77c, 0xd3b412ea,
- 0xd2c49747, 0xa945a639, 0x17dcefdc, 0x366135dd, 0x1e231be4, 0xf8db7d26,
- 0xf74a58c4, 0xad95ceaa, 0x353ae856, 0x5f646279, 0x3c268fac, 0x4fc43639,
- 0x9dfc065c, 0x38276a99, 0x426b36dc, 0xabdbfa3d, 0x085fb40d, 0xfc457e2d,
- 0x3069a4f3, 0x968bb7ae, 0xb0fda7f5, 0x1a4f9fe2, 0x8ab0f787, 0x3ed0371f,
- 0x4ace8b49, 0xeaf72271, 0x6a2e74b1, 0x7a910ad6, 0xcdf4a2ee, 0x1abafcff,
- 0xbeb569ef, 0x0efbd0a0, 0x7bad5c77, 0x9b9e1067, 0xf74ee9ac, 0x7580de2e,
- 0x3efb9e00, 0x17b7bebe, 0x089f21cf, 0xa473a2ab, 0x8bee9ed0, 0xbfb35e95,
- 0xdb0b313b, 0xd0e5d6ab, 0xa39414fe, 0x956a7cff, 0x41ef09ba, 0xc2594515,
- 0xa9f6fcf1, 0x75c518af, 0xa26e3d4e, 0x478e2277, 0x8fac67ba, 0xe8b8fba3,
- 0x8a53b3e9, 0x3c014a3d, 0x67d0da4c, 0x96126262, 0xfb7d049b, 0x1e011544,
- 0xfced748a, 0x24a4f643, 0xa527e786, 0x05b899f6, 0x97ea71e6, 0xd87ce9bd,
- 0xe4e754c1, 0x2fd7c054, 0x52539cd2, 0x6e5e11e3, 0x0ffcdeb7, 0xe3fc8fdf,
- 0xe404e285, 0x395287af, 0x56d1bf5f, 0xbef8109c, 0x3d45c977, 0x469bc1f1,
- 0x277a22fb, 0xc14d3c30, 0x41f03675, 0x67cdc62c, 0xf00b7589, 0x219d92f3,
- 0xa9e1abfc, 0xf1abd12a, 0x48d9f1a7, 0x0f5f3f5f, 0x19f5177f, 0x5f2037ad,
- 0x2d7321b1, 0xa693b9da, 0x0f44ec25, 0x91fe7ed6, 0x3c230bed, 0x7985b619,
- 0x7e3032c3, 0xfc871cea, 0x7aeb12cd, 0xc804b64d, 0x77ff68a1, 0xfbe73f0f,
- 0xeb8f6877, 0xfe7bbfbe, 0x9fb812d7, 0x4697db21, 0x5ce83c59, 0xf458b69c,
- 0xfaa38f48, 0x3cf0a7a5, 0x060bc95a, 0x2f2503b2, 0x8ad63fc4, 0x06f807fa,
- 0xf3c16be3, 0x81aa63fa, 0x933a31c7, 0xad18cf4b, 0x1331b25c, 0xc99dbe71,
- 0xdc86cd65, 0x3b239b89, 0x2b52cb97, 0x5ee34fd7, 0x9651efe0, 0x71e8b50e,
- 0x0bf4737f, 0x7ba16d6f, 0x86c20b74, 0xd289bde0, 0xaf444c17, 0x63c58b16,
- 0x13ef0dbd, 0x9031f458, 0xedca9b3e, 0x9f90bd69, 0xcde9955c, 0x7ba52843,
- 0xf0df7212, 0x9e6792ec, 0xe797e3c5, 0x70da7798, 0x2765dfc0, 0xbbcbd3e7,
- 0x063f8a54, 0x1f9623ef, 0x61cc69dc, 0x788fb137, 0x32c3fd83, 0xdfde22d6,
- 0xf07dfd0d, 0xa9abe1fe, 0x0687fbc1, 0x2a5e4fba, 0x37730ff6, 0xe9770428,
- 0x3fcf7e12, 0x8dc79637, 0xfa052e4f, 0x1ede691b, 0x0f3c10eb, 0x294eedcd,
- 0xf866bc53, 0x0b0daef5, 0x13d98e28, 0x6e7184f1, 0x89e26ef1, 0xae3a4730,
- 0x085e4bf3, 0xfe96fc23, 0x7e5fee6a, 0xfaf78599, 0xd702e20a, 0x2f91fbd5,
- 0xde197e38, 0x9cfd941f, 0x7a63f65e, 0x45f731a7, 0x7cc31f58, 0xabd8634a,
- 0xbd2067f7, 0x9f71d292, 0x5d2bb653, 0xbc5ea3fe, 0x61afac1d, 0x4ab45d1d,
- 0xecc7efe5, 0x041d9136, 0x01644f59, 0xad672cf7, 0x72346838, 0x8712c63b,
- 0xeedaff09, 0x1c769fbf, 0x6eeaf1ea, 0x2687b8a5, 0x51ef27f1, 0xfbf8e915,
- 0x853a8574, 0x268157ee, 0x97497ba3, 0x7b5fb953, 0x679f953a, 0xd0774a28,
- 0xb5f29cfd, 0x0cf2c726, 0x7dfb4fde, 0x95df584f, 0x684b9aeb, 0x26f7f33f,
- 0xae54ab8a, 0x45867308, 0x3b17f3f1, 0x6af9d006, 0x51f011bd, 0xe2fae766,
- 0xa56f98b2, 0x745dd27d, 0x8ecf419f, 0xdcbea1e8, 0x7963f5c2, 0x923de00c,
- 0x186e8a33, 0xe8c767be, 0x9bf624dc, 0x7c602834, 0x3f439445, 0xbf7f28f6,
- 0x83563a4d, 0xdf6c1b71, 0x31e21077, 0x8474da76, 0xe49515ef, 0x76b49019,
- 0xaf7dfa04, 0xdeb899a8, 0x6fb55a2e, 0xf9dfea1c, 0x8de307db, 0xeaf45609,
- 0xe63f6407, 0x88b7fa0b, 0x90c56773, 0x22b677c7, 0xb93cb8d2, 0x8a2f1e55,
- 0xef345348, 0xf2fac910, 0xbf1e0655, 0x8a8f3d07, 0xc7d97ca5, 0xa5b96fd4,
- 0x6ff50139, 0x30c36ef9, 0x6951d3d4, 0x978b2e5c, 0x011f65a5, 0x44362abe,
- 0x6583bbd3, 0xe623029e, 0xca156acb, 0x4f8bbffb, 0xbf3d3e47, 0xe428b5e2,
- 0xbe61139f, 0x5a97689e, 0xe8398417, 0xc795a1de, 0xe8afceeb, 0x6695f749,
- 0xf82d9b59, 0x45acc19e, 0xbfa86ddd, 0x467d5a8f, 0x975a3fac, 0xd3bcc3a1,
- 0xbcc6cd6a, 0xe51b7f53, 0x2df38bcf, 0xa57c83f4, 0x6d973a70, 0xbfc467db,
- 0xcc44324f, 0x1f2be2f7, 0x4ff8c2f4, 0x2f737a79, 0x07c02bb4, 0xcf1052bd,
- 0x9764292f, 0xf3f1b62b, 0x2a0f92ee, 0xee400f90, 0xa83e09e6, 0xf7daf5d8,
- 0x902a1e51, 0xf23a43fe, 0x7ef3f011, 0x71b1df2a, 0xefdfe31c, 0x76913e47,
- 0x0c2bf20c, 0xf1df8c36, 0xa71a667c, 0xe18f943f, 0xfc019ee5, 0x39fb5d1c,
- 0x741c8d04, 0x1a575f46, 0xcbc587b7, 0x5d6fa44c, 0x5a1e5c69, 0x428eed56,
- 0x657c5dfa, 0x67dc01df, 0x5601df29, 0x1e421eda, 0x712a3e04, 0x3f0451fe,
- 0x389517f9, 0xfcff28df, 0xc85ef9db, 0xf3e32561, 0xd4adf393, 0x7acbf98b,
- 0xc124fdf1, 0xe04c652f, 0x2e6f576b, 0x50ce4277, 0x0ebde98e, 0x4db73f31,
- 0xf7e50efb, 0x22dcfcc5, 0x28bad665, 0x17d20fc4, 0x103e0ff5, 0x04fa9469,
- 0xbedc5c9a, 0x4bf1ce91, 0x57f8497a, 0xdf403809, 0x7e6c6339, 0xf274b63a,
- 0xe095644e, 0x778f639b, 0xfc07af49, 0xcf4adf9d, 0xeabf116c, 0x7c93c603,
- 0x7dcbc723, 0x38ddd279, 0x87dfe86f, 0x8f71cbfd, 0xd8f4227a, 0xe5c651cf,
- 0xe52fc243, 0xa1fab732, 0x614707bb, 0xee968bbb, 0x9cde7003, 0xacd2ab8e,
- 0xfd13bdf4, 0x59def805, 0xfadc50af, 0x1fe75898, 0xa8b5fc7b, 0x7e7e01e2,
- 0x277c427f, 0x307f0cf9, 0x6de1263e, 0x7038f1b2, 0x0f52dc30, 0x9f73b849,
- 0x2c6eefb8, 0xbee3f097, 0x4a9f2051, 0x957e4a3c, 0xf982f5f7, 0xda4e7896,
- 0xfe73b54f, 0x463d4cae, 0x943a77e7, 0xfc27f707, 0x5ce213a2, 0xe33c6b79,
- 0x8915ff71, 0x8af735fb, 0xb40c8b18, 0xc08ed23f, 0x807d1acf, 0xa7bf69fd,
- 0x8b3ce716, 0xd690bb74, 0xc73ffa8d, 0xd0398cea, 0xe699d96f, 0x9dcef871,
- 0xb8ef43f4, 0x31a353ea, 0x9f8bb55e, 0x52fc9377, 0xc93f6176, 0xffb8b941,
- 0x83eab454, 0xefc8e182, 0xbed035bf, 0x63e3d14e, 0xcfdfe88d, 0x187332dd,
- 0x41ef01a2, 0xbb3f5ea0, 0xbf266879, 0x984d6059, 0x3621f786, 0x01ed333f,
- 0xaf559f28, 0xd80dbbd2, 0xd16fca0f, 0x5f1499a3, 0x52d6113d, 0xf8fd0a30,
- 0xf456a81f, 0x32df6fe3, 0x7f6c31f4, 0x0c6ba5bb, 0x39b1b63d, 0x7d4ef296,
- 0xe907d934, 0x8073caf7, 0xc7dee2d5, 0x3fde845f, 0xe22a9edc, 0x2f755ffc,
- 0xdd6f8fdc, 0xacef4618, 0x75ed1a14, 0x4f6f1c3e, 0x54675a17, 0x23eaf11a,
- 0xbf255bdd, 0x99918e6c, 0xb9508693, 0x0fca0939, 0x451f9a1a, 0x51f0723b,
- 0x3f7c60cb, 0x86d7a992, 0x9a7f7315, 0x6ac63bef, 0x70912ddf, 0x0fc6247c,
- 0xdf7e4fee, 0x1b08eb84, 0xefa44fdd, 0xedf8aecf, 0x6783b434, 0xe1b4f6b7,
- 0x09ef4fbc, 0xa703fba3, 0xcf77da0d, 0x57def56e, 0x79297df0, 0x9a74f56f,
- 0xfc938fd6, 0x377bc37e, 0x839ed37f, 0xa5b9d1bc, 0xdd194b0b, 0x8d397efb,
- 0x2263f7d1, 0xe789dabe, 0x4d6a4b08, 0x7307bc56, 0xf71ef912, 0xfcab76b3,
- 0xcb99a5fe, 0x99ddc9c1, 0xe4b7bf74, 0x525f3c6f, 0x3ef178a7, 0x9fa7fef2,
- 0xb30af3a0, 0xabc4cfc1, 0xf3feed09, 0xa1a7a7ba, 0xb8765c38, 0xfe7de257,
- 0xf9f95bcb, 0x32ef0e8a, 0x2079dc1c, 0xdfb9dec9, 0xcbfb5dfc, 0x9f110e32,
- 0x2fcfbdae, 0x4fd72cf1, 0x8c3f026f, 0xdbc7e218, 0x90e74b67, 0xa9617cbf,
- 0xca4bd29b, 0x23b7b5b1, 0xe9a25b1f, 0xeb1fc0be, 0xbdf1519f, 0x835df2a8,
- 0x783ae1af, 0xbd346454, 0xd2d9f293, 0x7a8fb425, 0xa5156961, 0x0e32de92,
- 0x46aec777, 0xfab3eefa, 0x9fbc06cc, 0xb46446fb, 0x90b603b0, 0xdeeced74,
- 0xb9d79cb1, 0x4afa701f, 0x9d6dcfb8, 0x6af38519, 0x61b63e7c, 0x2235d224,
- 0x5f7e8ada, 0x724738a9, 0xabf73d6a, 0x7fa398cf, 0x3df40f93, 0x024a61b3,
- 0xbb3737be, 0x5869def1, 0xb147b25e, 0xb1c07ae2, 0xae145267, 0xb7d53edb,
- 0xa8fde144, 0x7bcbd74f, 0x3bfa5e55, 0xd8f2a354, 0xca3f6c14, 0x0cf667a7,
- 0x7c8d75be, 0x9e82f232, 0x879ebfee, 0x5c938a72, 0x0938a70b, 0xb9e2c4fc,
- 0xf3afd991, 0x3afb4af8, 0x6ef3ac57, 0x347ef317, 0x31f726dd, 0x04773ca8,
- 0x61bd3f2f, 0xefec44e7, 0x158366ec, 0xb36cfee1, 0x079ffa81, 0xc01d33eb,
- 0x5f2b667b, 0xd71e60f7, 0xf2b767cb, 0x3abccdf5, 0x5f29bebe, 0xfbf27060,
- 0xcc7e5aa2, 0xef47680d, 0x5ef274fb, 0x9f273cc8, 0x97b03cdf, 0xbe60df38,
- 0x7475618d, 0x9e9bec8f, 0xdbe60d17, 0x855f92f9, 0xd7e7687e, 0xe044f8ce,
- 0xf91de513, 0xbcc3f255, 0xdedf7cf5, 0x07383756, 0x47f24ef9, 0xd5593bf0,
- 0x57dfc646, 0x7bd385d4, 0xed2293b8, 0x530fb406, 0x20c65ae2, 0xe74e3e5a,
- 0xab9a807e, 0x37bde273, 0xf90a6d56, 0x748acece, 0x744557ee, 0xdeefc465,
- 0xcf3f2b74, 0xc97fee29, 0x86922614, 0x84527b76, 0x343b0bed, 0xaefd3a79,
- 0xcfc0f47b, 0x3db76e93, 0xd8c1ddda, 0xee0bd32f, 0x267cc3d1, 0x7776da65,
- 0xbff3fc83, 0xb7f3c09a, 0x201a86d9, 0x78994cbf, 0xd7c818cf, 0x4a9f3ba7,
- 0xece7180f, 0x38692e96, 0x19ff283f, 0xbbc5d796, 0xa5698e7f, 0x49760fb8,
- 0x24b41d69, 0xfdfedfc3, 0x7fa3963d, 0x2df3fbb4, 0x18ee9606, 0x7f097980,
- 0xdd25b4e8, 0xf8f4abf9, 0x8cc5e58e, 0xf5e74e3d, 0x0e1efc3c, 0x09ccb8fc,
- 0xf38a4f78, 0x97bcb15b, 0x2f741353, 0x9fefc1c7, 0xf252fbc9, 0xff5f543e,
- 0xb70db27d, 0x92ec9f72, 0x2a1dff81, 0x0fbda9c5, 0x89fc34a6, 0xf6a9f9de,
- 0xa23096b0, 0x4d9ef683, 0x7753be39, 0xa20bdd1b, 0x6f4c87fb, 0x57337d27,
- 0xac683bfa, 0x29dff987, 0xfcfc8960, 0x1f82a3c1, 0x3d652f4f, 0x9fe8807a,
- 0xca39b77f, 0x985c700e, 0xfa85ebe8, 0xfddc3220, 0xe9d7c427, 0x0ba9d50d,
- 0xaa1ef0e3, 0xed0f91c9, 0x7df978cf, 0xb7e132ce, 0x42f1cdb2, 0x3bbea82f,
- 0x46535da1, 0x87684ddf, 0x757c17de, 0xfe97c321, 0x192bd423, 0xed049d7c,
- 0xde5d3ce8, 0xb1e2bbf2, 0x4fed85dd, 0x700d98f4, 0xbc06009b, 0xfa1e35a7,
- 0xf7a3611c, 0xfb4a98aa, 0x7efe5ecf, 0xa2799e92, 0xd5eef86c, 0x3ee2e933,
- 0x9413dd11, 0xeff89274, 0x1a181740, 0x999d59fd, 0xbeee1019, 0xfdfd036c,
- 0xf91f492f, 0xddc2e2ce, 0x7742fe3c, 0xe31e4524, 0xe2cda748, 0xb0759fef,
- 0xbf916f8b, 0xd1e9620a, 0x330d9fe8, 0x11c9db43, 0xf5d88d1b, 0xff2f6d77,
- 0x92fc2e9d, 0xe0706cc1, 0xa2a5923b, 0xd0b558cd, 0x2d5bef8e, 0x7bd3378c,
- 0xe85f0b25, 0x96c1fc4e, 0xb60590fc, 0x89621b63, 0xa866565f, 0xf5b9ff84,
- 0x2a1dde8c, 0xf3a64fa8, 0x36f5f994, 0x12daa34a, 0x6fecfca9, 0x7ae2c9de,
- 0xe0a7d389, 0xa68cba7f, 0xd3ff4b73, 0xd9d6529b, 0x6691a77b, 0xf0bbcfba,
- 0x0b6bb720, 0xc7bfcaa7, 0xbbafefc2, 0xc8ae3804, 0xb90b8a1a, 0xe753dc3a,
- 0xf0ba57ef, 0xe77e00be, 0x677d5034, 0xfc4a57ef, 0x82dd049a, 0x7a9cb3df,
- 0xde913330, 0x59ef147f, 0x9aed174e, 0xceb3bdc5, 0x4fbcb5de, 0x6a227bb4,
- 0xddf2135c, 0xc8696774, 0x9ef52d77, 0xcffa0730, 0x7a48d486, 0x373ee147,
- 0xf59a97f8, 0xf11e8b4c, 0xbf9b2d30, 0xba753973, 0xfd90deb6, 0x4373e939,
- 0x92778776, 0x4d8fa80c, 0xecfb6d2e, 0xf50ec2ae, 0xf6bf7d65, 0x2354d15d,
- 0xbe3d4fd9, 0x69f90b3b, 0xf4515de2, 0xbfffd10f, 0xff10b4ec, 0xb83bc49b,
- 0x112b2ccd, 0xbeadc2f5, 0xdbfffb27, 0xefc1b1fb, 0x03bf06c4, 0x42eb7fdb,
- 0xdd607e4d, 0x6fed350f, 0xa9ae5fab, 0xad5bec1f, 0xfa6ccfa9, 0xb43f2699,
- 0xfb4d39f9, 0x693647e1, 0xbcb647ea, 0xfdbfa9a4, 0xfe4d0ecc, 0x683fd68e,
- 0xb6d9dfda, 0x61cf9357, 0xe7da68ef, 0xe4d03f9a, 0x57ff5ac7, 0xc4aefed3,
- 0xf1fa9a13, 0xfa9af3f6, 0x68ae7d09, 0x2f8e05f2, 0x373fed35, 0x457757ba,
- 0x0cea22bf, 0x433aadf1, 0xf944f861, 0x6629a6e5, 0xba6b07d4, 0xf8247d0a,
- 0xd3b0b96f, 0x7ba307ac, 0x6cd563ac, 0x3d5ff11f, 0xc1a0bbff, 0xde7f4f76,
- 0x1ff8c4e5, 0x6bdf8d7b, 0x527f068b, 0x8c7e301f, 0xff02ccd3, 0x9e6c5dee,
- 0x778f9355, 0x77da6a25, 0xd4d76e99, 0x68fbb927, 0x38e653ea, 0xaab4f934,
- 0x5df69a11, 0xf9353897, 0xa69e4f0c, 0x971af77d, 0x76b3df26, 0xef7da6ba,
- 0x7d4d6ef5, 0x4d1cef5f, 0x55adff7d, 0xbac0fc9a, 0xb7f69a25, 0xf5347bd5,
- 0x9a357d83, 0x5aa6ccfa, 0xf3687e4d, 0xe1fb4d7a, 0xfa9abc47, 0x355b2d91,
- 0xa99fb7f5, 0x68efe4d3, 0xbfb4d7ad, 0xc9a7cdb3, 0x9a83b0e7, 0xf7e6b9f6,
- 0xd6b1f935, 0xefed344f, 0xa9a63c4a, 0xab3f6f1f, 0xce7e97a9, 0x6b9f3e84,
- 0x53df85cb, 0xe697f8e0, 0x6ef7f6fb, 0x1f742877, 0x6ed75cea, 0x96c57df2,
- 0x24fd1530, 0x6c99c517, 0xf5111078, 0xb727de15, 0x8539f3f1, 0x238aaf14,
- 0x944c887f, 0x810bcf1d, 0xab8510df, 0xf40c8cb6, 0xfefc23ab, 0xccf5ea5b,
- 0xdadff79b, 0xd5dcff84, 0xf288beee, 0xfb6eaf31, 0x989f7a38, 0x1c225679,
- 0x77bffdf2, 0x956dde83, 0x19f378e9, 0x17f00fa6, 0xa6d5860f, 0x389af90e,
- 0x05f378c1, 0xb6c1ef86, 0x22e22bf7, 0x17bdc7f8, 0x16bff406, 0xf7f817d6,
- 0x9a976b23, 0xffc76fe9, 0xf295a96c, 0x522696eb, 0x3a00fffe, 0x0047bf29,
- 0x000047bf, 0x00088b1f, 0x00000000, 0x7dedff00, 0x4554780b, 0xeedd7096,
- 0x9d248fdb, 0x777579d0, 0x493cdc9e, 0xf09d0848, 0x3a3e00d8, 0xc0406021,
- 0x490435e6, 0x41a8c1a4, 0xf881ba43, 0xbb75744f, 0xb2021031, 0x10d191b3,
- 0x0186c195, 0x099d1964, 0x09d1a32e, 0xe09af09a, 0x1c604c3a, 0x3719d9c5,
- 0x8ee2a3a0, 0xcfe31e10, 0x7fc38fee, 0x937ba9ce, 0x380e9dbe, 0xf7ff3afe,
- 0xb4fbfa3f, 0xab755538, 0x739d554e, 0x2aaa3cea, 0x89895ead, 0xde6d6322,
- 0xf39f4a1c, 0xc99899da, 0x316f36d8, 0x0ebddbc1, 0x72defd82, 0x9d7a774a,
- 0x5bcbbf94, 0xaf1ef041, 0xdebdd28b, 0x79f74a1a, 0x92fe543d, 0x9fe081b7,
- 0xb6947d7a, 0xff299b7b, 0xc10b6f15, 0x046dbc07, 0x53f5eabf, 0x4bdde1da,
- 0x76de1be9, 0x76f4ef2a, 0xb7a6fc10, 0x6f2ee08b, 0xbc87c10f, 0xf11f04bd,
- 0x98f8269e, 0x1ed28fb7, 0xbe9467ef, 0xf2a7eded, 0x0957bc77, 0xdbbf8ebe,
- 0xcd2afc19, 0x2631e49f, 0x7ae69730, 0xc9ccc21e, 0x00f63226, 0xff824bfe,
- 0xcc8846e2, 0x8cfdd8c2, 0xb0d73eff, 0x9413769a, 0x3ff2fe77, 0x74c60285,
- 0x1f8d8ca5, 0xf662690f, 0xc634c6ce, 0xe675b026, 0xd318724f, 0x63d75740,
- 0x4e09fb07, 0xd6191319, 0x2d75dfc3, 0x58c7dffe, 0x94bffc3c, 0x834c78e5,
- 0x14095369, 0x55befb42, 0x1a777f82, 0x3e20d755, 0xbf1c8dab, 0x95135a69,
- 0xf82c3e57, 0x5563020d, 0x8be9f322, 0x587dfb18, 0xc11b0154, 0x2e8f25d8,
- 0x2172c447, 0x04830edc, 0x443a8ff8, 0x2c5d7e0e, 0x9da5b18e, 0xd29b1d86,
- 0x84aaf106, 0xfdf035ef, 0x0c1a562b, 0x3a3d64ab, 0x1df203c4, 0x9ec618da,
- 0x4ba6b8b7, 0x8a60ff90, 0xf687a7c6, 0xed9fc999, 0x2dec648c, 0xe6066b8b,
- 0x77dcf25f, 0xc07f1b0c, 0x7ec6cf6c, 0xe2ba1b66, 0xfdff4117, 0x9df6b5c7,
- 0xe1f3f0d2, 0x6c67296e, 0xdfca0ddc, 0x02ec973c, 0xa2ffca3c, 0x9ffce175,
- 0xf85645d0, 0x492f01f3, 0x1a4a78e0, 0xeadb3a55, 0x7cf8825a, 0x47b9e919,
- 0xe5f85303, 0xacf6ab6d, 0xae552181, 0x82e11aca, 0x2582eeef, 0xcd8c1963,
- 0x418e9265, 0x38e67cf9, 0x2d4d069a, 0x17822e64, 0x6fa51f31, 0xb1aabbc5,
- 0x4fccc59d, 0x21b26bb0, 0x82b8d435, 0x78cb72f1, 0x947c65b9, 0xabab71f4,
- 0x20e5e38e, 0xba4c4ebc, 0xa5c71b23, 0x5596f5e0, 0x58737aa2, 0xefc476ff,
- 0x3f1783cb, 0xd2863211, 0x174077c7, 0xeb1e6826, 0x73ac3d31, 0xf7d18ea3,
- 0x7e088f8d, 0x2e856ba4, 0xb791992a, 0x0be418fb, 0xf4027481, 0xd2fc8451,
- 0x92373a9f, 0x0949e4e8, 0x92707c1a, 0x0b1fa7d6, 0xb3f8d4e3, 0x87d12d05,
- 0x1efc005e, 0x48fa0388, 0xea0e9e1f, 0xe00d219a, 0x67afa01f, 0xaff3bdb0,
- 0xce0e5dff, 0x49cdfb97, 0xa357ce12, 0xe801d606, 0xd6b6f7d8, 0x99925bbe,
- 0x94ed6014, 0x6ba47e31, 0x73edda26, 0xb17ae0c7, 0xdfa84ea5, 0xfb0d65ad,
- 0xfbf687f3, 0xb417ae2a, 0x2ba6c27f, 0x9cbb53f7, 0x9ff295cf, 0x63c5fae2,
- 0x5eadebca, 0x16ad69f5, 0xe8713ff0, 0x131a5e9c, 0x6f0d1c62, 0xe00666e7,
- 0x3338eeef, 0xe44261dd, 0x45e7f2fa, 0x949fe60e, 0x1fa144e9, 0xb5d23ead,
- 0x178814c3, 0xf9e817ef, 0xd13744e7, 0x4419cf40, 0xe0f89fcf, 0x690639d3,
- 0xfb4822c4, 0x20ba6a60, 0xd660bd75, 0x672cdd23, 0x99ab4a76, 0x6007d293,
- 0x9d7e91f9, 0x38f4a7be, 0x76b20fef, 0xbe2bafca, 0x7cf482d7, 0x8a95c6bf,
- 0xa5eb2d70, 0x2feb377c, 0x2dfcc1b3, 0xd47b5e6c, 0x6fcf5806, 0x025a6a79,
- 0xff3cefcc, 0xce98a3b2, 0xe27c25dd, 0x7a3f8893, 0xc13eaf10, 0xfa113eb3,
- 0x92a5fbbf, 0x3f9049f5, 0x85d7cb47, 0x175f2bfd, 0x8f047e45, 0x97a1f81b,
- 0xe341cb8f, 0xab9546d2, 0x09f2a1f8, 0x9da010e6, 0xff0683fe, 0xfe00b4ce,
- 0xdfe87e28, 0x898e5093, 0x7ae0f7fd, 0xc434dfbb, 0x083f7ae0, 0x29c71be2,
- 0x806b1838, 0x2ad690fe, 0x882a8863, 0xe1621fde, 0xb9f7ac76, 0xa79fdf4c,
- 0xcfefa230, 0x4060e605, 0xa67417bf, 0x5ae50166, 0x0456cbaa, 0xbe60acf8,
- 0x6ee50626, 0x38054bcd, 0xd725234f, 0x1fd744a7, 0xa61537b5, 0xa7f7fca1,
- 0xf7ff280a, 0x698dec19, 0x5d84fdaa, 0xe321408f, 0x3f9f3861, 0x0ec776c0,
- 0x3e284bc5, 0x14429ff6, 0xf33d0663, 0xbf888b19, 0xebe444d9, 0x57f13d44,
- 0x066d4e23, 0x3c94e3f6, 0x9feda1a6, 0xf9edf190, 0xef744b4a, 0x16ecf183,
- 0xf7c3f542, 0x60f8432b, 0x2c3f243f, 0xa7d1fa8c, 0xfa563e71, 0x64bea663,
- 0x6a75d027, 0x86974b84, 0xc716c182, 0xcb998be5, 0x4fb49e97, 0xe67d7133,
- 0xc8a8de4c, 0xdd8f6a65, 0x09d1e5c6, 0xf843e49d, 0x1d9a4944, 0x9c80d724,
- 0x97f8abbd, 0xbb8f11a7, 0x2d2ea68c, 0xdd16eca4, 0x7d94fa9f, 0xff707d30,
- 0x7fd94bbd, 0xeffbe16f, 0xefb5991c, 0xf1babb12, 0x3aecc67b, 0xfd972fc4,
- 0x6d8f995e, 0xf22adfb8, 0x0b7ec871, 0xf9c5eb03, 0x832b2513, 0xc7c0b574,
- 0xdc253abf, 0x36c47c8f, 0xf4f8d2e7, 0xfe0cfcb2, 0x58c15ade, 0x13c651a6,
- 0x19704bfe, 0x20ce6659, 0x5663549c, 0x9b1e29c1, 0x06c8feaa, 0xe69e5549,
- 0x679551cb, 0x7055db34, 0xaab14b56, 0x8736a8fe, 0x97f5ce0a, 0xede7eaab,
- 0x31e0aa75, 0xfaaa15ed, 0xaa5c3b63, 0x1aaec2f2, 0x1eb8f955, 0xd09e0a8f,
- 0xffaaa0db, 0xaa7da777, 0xcd7d49f2, 0x9f29f2aa, 0x5be0a8b5, 0xf554dbfb,
- 0x57eabf6f, 0x7fb09795, 0x354f9556, 0xd3c157ee, 0xeaabafcc, 0x16fb80bf,
- 0xb61dcff0, 0x0cfe556e, 0xbbeab8e9, 0xaa4e733b, 0x75e417e0, 0x270e2df6,
- 0xe72d68be, 0xfb6cd1fb, 0x5876aa07, 0xfebe68e7, 0x7b6f3c61, 0x510b1fcf,
- 0xf4d76e4e, 0x4add21a7, 0xf222735a, 0xdcf16671, 0x2c664043, 0x14aab1db,
- 0xf94e5bc5, 0x1d308753, 0x8a5fdced, 0x715f926c, 0x05a610f2, 0xd0a58bae,
- 0x44d7b31c, 0xc8b4c61f, 0x8ad53853, 0x3dcc34a8, 0xdf44e98c, 0x5728a9aa,
- 0x3f5c785f, 0x2a28f91a, 0x074fa146, 0x827d67d1, 0x7eb9f886, 0xf28fc9b1,
- 0x24c532c7, 0x96139032, 0xb1d65a1f, 0x9a8b4c02, 0x1af66d31, 0xfa0f5f99,
- 0xba519780, 0xfe666bc9, 0xaf67206c, 0x93fae08d, 0x43a795f7, 0x44ab233b,
- 0xe699aa33, 0x48258f51, 0xe5f5bed0, 0x765d9c96, 0xb0edd6c6, 0x42e5d7cf,
- 0xc59e19ff, 0x4e01a23b, 0x30058e63, 0x2398167f, 0x25b19936, 0xfa76df3b,
- 0x97c287f2, 0x244d9d33, 0x5cf6c417, 0x7694ffd4, 0x6e7e9637, 0xdf2198d7,
- 0x11e74bf7, 0xf1adf798, 0xc21df4e1, 0xa75f9925, 0xb60b475d, 0xf69ef90b,
- 0x4cfc7c10, 0x977fdf1a, 0x0a7d73a4, 0x66eb8487, 0xacc6cbe5, 0x808ca7a0,
- 0xa93adcb9, 0xf0ea0ce1, 0xa027d9a2, 0xe0d7627c, 0x892b907b, 0xe0832958,
- 0x4e01c3db, 0x6c625840, 0xc7eb967f, 0xc5d5afd8, 0xfa00d9d8, 0xc351a849,
- 0xcf9e615b, 0xa3e20e66, 0x89f1aa5b, 0x8fdd0630, 0xf43b769d, 0xc60aadb3,
- 0x3d56f00b, 0x7a9437d7, 0xf68c34a3, 0xf8d32ff7, 0xcdaece7e, 0xf49ea3b7,
- 0xe79e3ca5, 0x3e8bfdbc, 0xeb7b44ce, 0x3589a52a, 0xf205c11e, 0xb4e95acd,
- 0xae9ea0fb, 0x8423e611, 0x348bf2de, 0x1dd7be91, 0xa090447e, 0x1269a7de,
- 0x7e9589c1, 0x0d52771a, 0xbf801bb4, 0x6609f44d, 0xe63db7c8, 0x9b3f1013,
- 0xf06769d9, 0x885a331d, 0x3cc8d7fe, 0xcbf86b61, 0x0f418fa2, 0x769d79d3,
- 0x13bba7ac, 0x271f33e8, 0xb86663d4, 0x47e3c94e, 0xa3eb10b0, 0x0d3e86a4,
- 0x9f40dc73, 0xd47d4a8f, 0xddc5fb43, 0xe80b2926, 0xa6c585fb, 0xda211d8a,
- 0x9f9e54fb, 0xfeea310d, 0x1f3e5a2d, 0x6cbedc8a, 0xf0a8ebe6, 0xa6689af1,
- 0x526be392, 0x846f5bc6, 0xc8cdb5af, 0x6ef8015c, 0xd0cc7e85, 0x55abe1be,
- 0xe83f1c66, 0x4fea4ed0, 0xc764f2e4, 0x6ec8728f, 0x21c75e0a, 0x3f9408f4,
- 0xa3e908a2, 0x7c08dfcf, 0xdbd2a868, 0xfeb26f51, 0x7b809343, 0x116b2273,
- 0x5358be50, 0xdc447aca, 0xae5744d7, 0x793e8433, 0xd654ba33, 0x839fd94f,
- 0x3d774bd7, 0x9c12fde3, 0x31d57fef, 0x1f56c7d4, 0x05718f8f, 0x3a4c53d0,
- 0xd662cba7, 0x98fe45a2, 0xbd29dacc, 0x7a52f585, 0xd4a7eb1b, 0xa622ccc1,
- 0x694ecca5, 0x3a527319, 0x2d28799d, 0xce942d67, 0xce94ed64, 0x8294bd62,
- 0x93a9433d, 0x9aeec999, 0xa637fb07, 0xd293980b, 0xa50f31ef, 0x7e9ce999,
- 0xc10b582b, 0x4a76b377, 0x24ef803b, 0x8c01fa3d, 0x9c827694, 0x904df4c3,
- 0x79769873, 0xa3652625, 0xd287201f, 0xa53b5e23, 0x94c5bcc7, 0x541d78f6,
- 0x396f6def, 0x9d78efa5, 0x56f09e94, 0x75ebda50, 0xde53bd51, 0xf5df4a1a,
- 0xcf7d287a, 0x69e940db, 0xdfd28faf, 0x1d299b79, 0xc67e07a5, 0x2be9cdf9,
- 0xf53e7d44, 0x0243bd23, 0xe591ecf9, 0xe68761d2, 0xb8f1dc99, 0x40661a6e,
- 0x235b283a, 0x7359fd20, 0xa43f0e34, 0x0b56729b, 0xe1ba42f7, 0x0cdfd704,
- 0x0fd248d6, 0x82f56dad, 0x0876ed04, 0x5808da7d, 0xa9e9e9cb, 0x9f208d73,
- 0xbad93a4b, 0x19c23b08, 0xee81194f, 0xfd3ce876, 0x64bca03b, 0x08d734a7,
- 0xc8e4d67b, 0x8fb1ff53, 0xe93e54c3, 0x03346b08, 0xfb3d2b3c, 0xe38138a9,
- 0x7befc281, 0xaee6733b, 0x253c44cd, 0x34c5f3c2, 0xbf512c30, 0xfa44c47e,
- 0xd9db6175, 0x93c00d42, 0x68454c1a, 0xebd40617, 0xae1fba42, 0xf2b9705e,
- 0x9655b6dd, 0x0d879c46, 0x0e5a809f, 0x7d19a959, 0xd5f3ab85, 0x5ebe6aed,
- 0x837b4cff, 0x09eb03fe, 0x7f6f6837, 0x7d32a396, 0x3a7effc2, 0xdd6fa60f,
- 0x6bf68ff5, 0x8e640fc8, 0x5774fdc1, 0xfd339734, 0x04ee9fa0, 0xc8c577bc,
- 0x1a4cc6f0, 0x5c43ca17, 0xd29b0db7, 0x77803efd, 0x1f573985, 0xd47ff2c7,
- 0xd14277d8, 0xa6d770ae, 0xc933825c, 0xc621b13f, 0x8f931393, 0x97df3cfa,
- 0x0d1f935a, 0xbff80293, 0xafcb9d39, 0xe95cb7ad, 0x447681dd, 0xc16586b3,
- 0x979b3b77, 0x7681cc6f, 0xf419bc7e, 0xdc478007, 0x0b31bd5a, 0x6a37d3ca,
- 0x19656a26, 0x78fc7887, 0x4d9ef573, 0x8f255fa8, 0x7686c98e, 0x99796433,
- 0xb857db1a, 0x55bce806, 0x95a7b6af, 0x7e649ff4, 0xce6686a9, 0x954d6c82,
- 0x3a1df4ed, 0xdfb81156, 0xefc64cfd, 0xd53c5957, 0x57fdcedd, 0xfee19186,
- 0x25fc6027, 0xc3bfb923, 0xfe48ceb2, 0x7ff24b0e, 0xca03bc9d, 0x7634db2d,
- 0x6b44e954, 0xea1d5aed, 0x3b598bfb, 0x810ee3f2, 0xe14bef7f, 0x0a28217a,
- 0xec0373e9, 0xd3deadf2, 0xfc03328b, 0x9f0ab684, 0xc97bf680, 0x0fa15ac8,
- 0x07e49ff7, 0x2dfbb405, 0x15c12e15, 0x8781f689, 0xb965cfca, 0xf80e927e,
- 0xfbe12ad9, 0xb992fd40, 0xa15d7012, 0xd2768adf, 0x605158f3, 0xf8b3a77f,
- 0x3b07ac3c, 0x75d5f499, 0x782bc27a, 0x97654ebe, 0x95f6c01e, 0xff2e0c75,
- 0xabb7067e, 0x5d013d77, 0xe24c1f20, 0xdd89f376, 0xce3fa489, 0xa0770d69,
- 0xa9e274fd, 0x6f0465d1, 0x3d40ec99, 0xc9eec4f2, 0xb39d31d3, 0x3bd52665,
- 0xb41eb021, 0xb96ce787, 0xd4fcc45b, 0xdb0bc00c, 0x7a27a33b, 0x41e5b39c,
- 0xcb47fbf9, 0xe358bcb0, 0x91da09fb, 0x22fb8dc5, 0x1c9e4ed0, 0xa6124af9,
- 0xf57d3427, 0x5dffd0dd, 0xdc2bf666, 0xe31b9d9e, 0xfe1cb1fe, 0x74a9f731,
- 0xbfd7ea1d, 0xf5a74f4b, 0xc41ccf9c, 0xec835007, 0xf6f65bba, 0x8a4d061e,
- 0x3fded6dd, 0xe65ccc15, 0xc11f30e8, 0x5ecbb4b4, 0xd657d386, 0xe9823ce3,
- 0x194f5ef4, 0xa7e52faa, 0xba608e5b, 0x3bf5d724, 0xff179f9c, 0xbcaf7be1,
- 0xc7c8f008, 0x07a8cdeb, 0x37d13e65, 0xebf92763, 0x21f90c74, 0x45a7926b,
- 0x746c048b, 0x787ca0c6, 0x835169f6, 0xad21b9fb, 0xc3610c25, 0xb41ae97d,
- 0xb745770b, 0xb3b8d0d4, 0xe3ce19c2, 0x210fb0db, 0x3b45645d, 0x809f9063,
- 0x3e1d692f, 0x10d3e993, 0x634731ed, 0x1fcf187e, 0xe1ce17a8, 0x5af503f3,
- 0x27ea04c2, 0x13fb2046, 0xbfdc06d4, 0xddfef26d, 0x38093cc6, 0xcf48d61f,
- 0x64ebf40e, 0x67fe7095, 0xb02e9c91, 0xfa44d37a, 0x96cd9c84, 0xb89dcf16,
- 0xe897560e, 0x3ba40beb, 0xf40706d8, 0x19827491, 0x055bd7da, 0x219c830e,
- 0x7e87f0bc, 0x42c98b0c, 0xbf828d7a, 0x0bda02b5, 0x1c7033d0, 0xdf834cf3,
- 0x9b177429, 0x4235c7c1, 0x65acbfa6, 0xdf053dbc, 0x9f2e0cb8, 0x83496f01,
- 0x7c6568f8, 0x009a1c60, 0xd1ea027c, 0x66f006f8, 0x05d21b76, 0xa7817a48,
- 0xc703124c, 0x8471ad5f, 0x7a645da1, 0x4fe8fbf5, 0x02394289, 0xf753fe78,
- 0x69f22324, 0x327238f0, 0x46df08d2, 0x6f5187d0, 0xfce2e99f, 0x11e958db,
- 0x18423ec8, 0x3a2c9fc7, 0x35681fd0, 0x017416ad, 0xf326b5e3, 0xa5667a7d,
- 0xcae51ba7, 0x3b08e2cc, 0xac9df7d2, 0xf3999d7d, 0xc04c91f7, 0xf81b146f,
- 0x41c4d899, 0x4f47f0bd, 0x97127bbf, 0x97b59934, 0xf9fee2e4, 0x70b3fdf8,
- 0x3a3eb6fd, 0x4ff107b3, 0x3baa79cc, 0x5e741a06, 0x197dd794, 0x6ca4ebf7,
- 0x1c0e3f13, 0xe0079247, 0x8d44bf40, 0x41e81cba, 0x65742b05, 0x71a21a13,
- 0xe444d1bf, 0x7a819ccf, 0xe486944a, 0x6129c83b, 0x33fd4841, 0xf9e4ae88,
- 0xaee7d657, 0x375a4c8c, 0x03af89ab, 0x171bb7eb, 0x5583ca46, 0x6dfa09d6,
- 0x011f3604, 0xa658df74, 0xd7680bf5, 0xac28fd62, 0x919de2cf, 0x8769d743,
- 0x03399a4e, 0x1ac3f4e5, 0x74366ef3, 0x7edc815e, 0xc3ed7a4b, 0xf90e5471,
- 0x7dfc91a2, 0x436af801, 0xb8f5eac1, 0xac6dfd59, 0xb48cee6b, 0xc989f9a1,
- 0x3ee2660b, 0x68cb589b, 0x47cb83fd, 0x575ea63d, 0xa3c737b2, 0xbbf988ff,
- 0xce7ac1be, 0x8655de4c, 0xbaf07cfa, 0x1a97742a, 0x105f7a1b, 0xa65f3933,
- 0x954fd846, 0x92215e93, 0x114ce09e, 0xa2ed03e3, 0x1f7c190d, 0x1335fdba,
- 0x23ec43ed, 0x5cb71fa3, 0x93ef577b, 0xa50eb0b9, 0xae683457, 0x1cefa3b0,
- 0x484ce1fa, 0xddeafda7, 0xf50affd5, 0x1a657da6, 0xb06ff987, 0x10e819be,
- 0x9d80f5f1, 0x2fdaf001, 0xa3a0b4f6, 0xd992b1a4, 0xfa55df71, 0xf3f723d9,
- 0x49df9d0b, 0x645735f2, 0x820e493b, 0x2f401e65, 0x7e896900, 0x56731978,
- 0x68dd90b6, 0x5907cccd, 0xf6bd6e8d, 0xfe5fb425, 0xefd0cf49, 0xd242af38,
- 0xe7f8c095, 0x65ba4a55, 0x5917c7e8, 0xf311ea39, 0x3f94ec2b, 0xf3ced2bf,
- 0x417f3c8d, 0x17f28385, 0xbe783a54, 0x3e61f209, 0x7bf85616, 0x42eed0bd,
- 0x41a48c53, 0x93a5783f, 0x50355f97, 0x0f603bf9, 0x87c90264, 0xde49f987,
- 0xe1a67cb7, 0xb84f12f1, 0x0d5c005f, 0x123d4591, 0x1a7ddfce, 0x8624167b,
- 0x01999114, 0xe9c2b67e, 0xf3f942d7, 0x13809fcc, 0x6af546f9, 0xbfe43667,
- 0x719a2c91, 0xc0386f7c, 0xabf9c66e, 0xe9de6915, 0x351bf007, 0xd8cf14c9,
- 0x7dadfb21, 0x67e48c2b, 0xfc875d05, 0xa2456cac, 0xf2f0c7ac, 0x7ecdcb6d,
- 0x0e40c7d4, 0xdff63ad2, 0x001e9227, 0x1cedf0f2, 0xca5e8bd4, 0x484987b4,
- 0xb37e6ab7, 0xa12f2f54, 0x19992af6, 0x9559f2ed, 0x97c6bdbc, 0xea0d7e34,
- 0x3379a655, 0xf71a0e91, 0xafda3b32, 0x2a9f56cf, 0x9b78458b, 0x87e5cedd,
- 0x56342e5a, 0xe12e396f, 0x731a3c78, 0x7ee7d516, 0xe94f46ad, 0xc830ad2e,
- 0xd2deb4cf, 0x2a18fca0, 0xd83dec6f, 0xa955424e, 0xb3d4137d, 0x8fd138c0,
- 0xf3cf4dbd, 0x1488f77d, 0x8b54b067, 0x4182e65d, 0xa7914efe, 0x187c82d0,
- 0xc545f245, 0x525fa35f, 0xf9923fc3, 0xc45df814, 0x3176f971, 0x5d95c93b,
- 0x27207aea, 0x52af2835, 0x67f9d4da, 0x2fc504b2, 0xe0879aa5, 0xb87ab679,
- 0xe71e0bdc, 0xc2bab8e0, 0x34b8d146, 0xd7285c7c, 0x74d73f20, 0x2b73f288,
- 0xa124bb45, 0x853f6bbc, 0x92f51fe3, 0x9e00bac8, 0x13345d55, 0x66d669e9,
- 0x6643b90d, 0x0b925eb3, 0xe2b71b37, 0x671e08df, 0x6436f8f0, 0x1cdf6968,
- 0x1bd707d0, 0x7d6c1f49, 0xb8c1a4c4, 0xe15be822, 0x973857e8, 0x099e1a55,
- 0x532230f3, 0x6bafd7d6, 0x34693cb9, 0xacea9d11, 0xfa04e58f, 0xa5d1841f,
- 0xeebeb023, 0x72bcec7a, 0x68e91b8a, 0xac72c1dc, 0x93639658, 0x2a7c60fa,
- 0x933873ff, 0xd6f7e602, 0x7c1518fe, 0x5544d5fb, 0x2e1012fd, 0x8d53e581,
- 0x69f2aa79, 0xf82a71e6, 0x5514db0e, 0x54d219fd, 0xce677c15, 0xb3faaa9d,
- 0xf055f3ed, 0x544bc55d, 0xee3ae7f5, 0x2fcf9555, 0xbe55487f, 0x0546b9d0,
- 0x7bf8aa2f, 0xaec5fd55, 0x92f95546, 0xe555279a, 0x9293f6c1, 0x3f726696,
- 0xe79b56cf, 0x8be483a4, 0x0e46704b, 0x14a967ad, 0x3dd703fb, 0x53eb822a,
- 0xe51af5c1, 0xe04178f5, 0x48feb1fd, 0xe29df20d, 0x91ed637f, 0xd75cff2a,
- 0x3ec6c9e4, 0xec72fa13, 0xb2dd23ef, 0xc51fdc13, 0xc53bfcfc, 0x04fdd57f,
- 0x56f683d4, 0x715ba647, 0xabbf43bf, 0xf9fd0f4b, 0xb7bfe435, 0xb40bd736,
- 0xe7ae6e0f, 0x7aab957e, 0xc00d8ae6, 0x7ef38583, 0x828e78e5, 0x70447327,
- 0xcf1860ff, 0x95fb26df, 0x52bf439e, 0xb03f6336, 0x17787e28, 0xac509bb5,
- 0x467fa1f7, 0x7a08f6a8, 0x662e5b94, 0x07284836, 0x97ff5397, 0x5823ec2b,
- 0xd2567988, 0x398daf56, 0xbd5b7da0, 0xc61ead6f, 0x69399756, 0xbcd0b3cb,
- 0x1fc8c3cd, 0x94e668f3, 0xe7816b2d, 0xa25321ff, 0xf9104975, 0xf75f3f3c,
- 0xd03db9c6, 0xa5956b5f, 0x706ae508, 0xf3bb9279, 0x941bb1e2, 0xd5f2bf3f,
- 0xd1bfee0f, 0x671d75f7, 0x87ca029a, 0x24568bf5, 0x1d004732, 0x7ed08648,
- 0x74c81ff9, 0x27ac9ee5, 0x5a33d63f, 0xcfc893d7, 0xd7ff2617, 0xddf0bdc4,
- 0x3dcae979, 0xfe43a7a8, 0xea1f300f, 0xcf9ebcd1, 0x29e744bc, 0xbf40f352,
- 0x2c3bfd47, 0x941edd34, 0x95ad17db, 0x5a07e8fd, 0xd097a91d, 0x7e324fce,
- 0x0eea7e46, 0x83abb71d, 0x07e7f7ed, 0xb276edec, 0xedcbf7bf, 0xad5396ec,
- 0x8ccf7f99, 0xe45a263e, 0xf98840f8, 0x09b546d0, 0xab12af28, 0xf9024fc5,
- 0x4f523ba2, 0x498b047e, 0x6a983bf6, 0xc5017e54, 0x791dd06f, 0x6f7480bf,
- 0x7e415ae9, 0x6017f47a, 0x75e5077b, 0x2417f609, 0xe8b4ff19, 0xb51bd8e3,
- 0x23f206cf, 0x04fd1084, 0x27f8a1e1, 0xa3f1fb82, 0xccfb813e, 0x27d270ca,
- 0x397dc782, 0x6650e4b3, 0xff48f23c, 0x7e503bc9, 0x7ed1d29f, 0x84bd1c38,
- 0x1fcce149, 0x266f7ed0, 0x7223efb7, 0x91f95462, 0x0fe644f6, 0x64b35ff4,
- 0x321127f3, 0x48cc5b0c, 0x51c6df7d, 0xbcdbdfd8, 0xbb3a13bf, 0xd841f48d,
- 0x7bfed0f6, 0xeee7e64f, 0xab69465c, 0x01b7976c, 0x9cfa631f, 0xd9fa4cd7,
- 0x843fe036, 0x4a257bb7, 0x4a1cdefd, 0x54ed7a77, 0x4c5bcbbe, 0x83af1ef0,
- 0x72debde0, 0x9d79f74a, 0xb792ff94, 0x7a9fe082, 0x7bb6945d, 0x15ff286b,
- 0x03e087af, 0x5f8206de, 0x44507d45, 0xa533753f, 0xa85b786f, 0x46dbd3bc,
- 0x3f5e9bf0, 0xbdde5da5, 0xdbc87f94, 0x6f11f04e, 0xbcc7c107, 0x78f7045d,
- 0xdb7d287b, 0xeff94bdb, 0xdc134f78, 0xb1938f2b, 0xfa2f5ee6, 0x84a25c2b,
- 0xaeb3ddfa, 0xd7ea336a, 0x331a65b6, 0x9736f38a, 0x39fa0566, 0x78f255b6,
- 0x86956d9f, 0x87a040fc, 0xb39f51fa, 0xf8fa7b2d, 0x405f2a34, 0x49b15be5,
- 0xabac4a30, 0x56cafeb8, 0x159ea9ea, 0x77c1020f, 0xfd2b6adb, 0xb25b805a,
- 0xbadca9c3, 0xedbb244a, 0x3a278d79, 0x245deb9b, 0xae3aadbf, 0x1074283f,
- 0x22e9fb21, 0x974a44b2, 0xa3fc7365, 0x23ef4232, 0xfc4a5919, 0xc707b9a4,
- 0xf182ab67, 0xf555be21, 0x5a5f8c46, 0x49f183ef, 0x3aae3fa4, 0xc3247804,
- 0xc07f1178, 0x6cc2fc87, 0xad97d719, 0xaf08eb55, 0x94f365e4, 0xda346778,
- 0xfa9e6de9, 0xa56f84b9, 0x36cd7e48, 0xfbe8a1d7, 0xe7ca4e50, 0xe1f1ac7c,
- 0x50fe7f4e, 0xf082327c, 0xddb8c6df, 0xd2fa0c90, 0x00e310fe, 0xc7a9478b,
- 0x198f78fd, 0x26f1fa43, 0xb2627acb, 0x3d8ff9c0, 0x6dff122c, 0xc1f7a067,
- 0x7e81cf77, 0x503943e7, 0xfa156fba, 0x72cd1eab, 0x3c02cc4d, 0x3f8d247e,
- 0x531c0224, 0xaf4fdbce, 0x1ea0f717, 0xae7deb0d, 0x3e37f209, 0xb689d9b8,
- 0x6966ec71, 0xdb5bb22d, 0xd01357b2, 0xa82c95ff, 0xcb4947d7, 0x3bb63c65,
- 0xd5cf7b78, 0xb64fe48b, 0x76903aae, 0x865bf784, 0xfa8e26fd, 0x61ba187d,
- 0x1a481632, 0x55c91914, 0x2fec45e2, 0xe5cda1ec, 0x66fc5fd8, 0x215fd287,
- 0xe775f7f6, 0x65e3e469, 0xbc085756, 0x37279386, 0xb38b2393, 0x8e48e322,
- 0x9424b124, 0xb8ebcf23, 0xe49df2dc, 0x861d24fa, 0x1fb43499, 0xc4ae7e25,
- 0xe8e383d3, 0x243d3235, 0x61c74219, 0xfde80d57, 0xddb7aa3e, 0xe749c9b1,
- 0x0b3e304b, 0x6c75ab45, 0xeaf3ae05, 0xdaf37092, 0xa4a0f410, 0x018e505b,
- 0x468bdfdf, 0xb9b3b523, 0xe1a3b79c, 0x56cadced, 0x32625c11, 0x6bc842fb,
- 0x6e5a7d25, 0x4e2c81e7, 0xbe0f49b7, 0xae18f1b4, 0x3a3adbef, 0xc69cf413,
- 0x04ed11bf, 0xc92d09df, 0xfb6d44d7, 0x78013d8e, 0x79e3cb35, 0xb5cfef4e,
- 0x7b40ff23, 0x915728f9, 0x7fc9f25f, 0xcc0566c1, 0x5addf2bb, 0xa3fd8fd9,
- 0x29a21b6b, 0x2eb55cbe, 0x36a3f50c, 0xb07a2466, 0x85d13cea, 0x4560f401,
- 0x1f410cba, 0x4af4b2fb, 0x3254d53c, 0x7c32e311, 0x728a9e5f, 0x583ef009,
- 0xe1fb451d, 0xdeef65d4, 0x5be01639, 0xd47688ae, 0xe5ab9ecb, 0xfd2713e7,
- 0x26e74351, 0xdb9c7cde, 0xb7fdb77d, 0x7bf41eb2, 0xb3e9c827, 0x7a41e768,
- 0x77b3334b, 0x52dcbac1, 0xcdff226d, 0xb3c557ad, 0xb91a7681, 0x7da3c7a4,
- 0x5335fdc1, 0x803ca1fa, 0xa67d26fe, 0xaa330fae, 0xa1233d45, 0xab6f9d4f,
- 0x1a66703a, 0xcb56d3f4, 0xf6bb6e3f, 0x7d8471fe, 0x93f21af5, 0xf429f500,
- 0x4dfe4093, 0xe78097d1, 0x191a3716, 0x32eb73c9, 0x41e519a3, 0xe49c25b7,
- 0x1362db5f, 0x321ba1e9, 0x9ea18757, 0x8faaa86c, 0xdea474c6, 0xa77d03b7,
- 0x7dffbbdd, 0xe4812d9e, 0x817f3f2d, 0xfa0c5984, 0xae7abdc0, 0xb6faf8e4,
- 0x7944cb4c, 0xc3f2a1a9, 0x8b7dffbb, 0xac077d0f, 0x3490f085, 0x7e0f912c,
- 0xe29bbe00, 0x2fdf02d4, 0x444e6740, 0xabae74f8, 0x4243e507, 0x8b1baf9c,
- 0x56ce9ab6, 0xcae2f9d2, 0x5d33e238, 0x31e987b5, 0x18c8b2bf, 0x9f0ae7c8,
- 0xfffcb5fc, 0xbbe71cb4, 0x59b81c99, 0xf7e337bb, 0xbe73a59f, 0x369ece19,
- 0x154f230c, 0x9acf18fb, 0x4b6c8a63, 0x7d59eafb, 0xf6eafd48, 0xc567ce6c,
- 0x643e7e7a, 0x72f4c54e, 0xfaf8c38a, 0x96c73c44, 0xa9f9cd93, 0x714912cd,
- 0xd674b6e2, 0xdf037185, 0xf7f70d72, 0xdafff1c4, 0x3fc9d32a, 0xa2782ad4,
- 0x3e78197d, 0xeb8695c2, 0x147306d7, 0xa6b7fd09, 0xfcceb972, 0xabc6331e,
- 0x409a9da1, 0xf3dec1fc, 0x9198e9a9, 0x0bfe4c3e, 0xa49ef12d, 0xa3b7f00f,
- 0x17fd1c5f, 0xdadddfc1, 0xbf6f86af, 0x984b86aa, 0x354f054e, 0x6669e1aa,
- 0xe6c96c35, 0x361dfa7a, 0x490cfe75, 0x1ca7270d, 0x73f0d309, 0x7f01a6ed,
- 0xbbf044b3, 0xa07e0199, 0x01769a0d, 0xafa525e7, 0xadb2fc96, 0x93dfdca9,
- 0x73f6af5c, 0xb596b224, 0x6df90231, 0xfcb6f954, 0x73fa0255, 0x7cead56c,
- 0x8c150798, 0xbff48acb, 0x9f95d724, 0x02e9718d, 0x4b3aee7e, 0xc5cde9eb,
- 0x238b6875, 0xcf934a3e, 0x1fdd0d05, 0x95b8d0b7, 0x7c0f9076, 0xfa45e301,
- 0xe62f840f, 0xc76726ba, 0x05f03e73, 0x7df997ee, 0xa503e43a, 0x41f8e1bf,
- 0x3962c7e1, 0xab9ca26e, 0xa5b722b9, 0x97a9ab9c, 0x0475c7cf, 0x92b9c79d,
- 0x81e7465c, 0x09aef4ae, 0xc877c50f, 0xce6cbe67, 0x946e9877, 0xdf20d7cf,
- 0xef9cf4f9, 0xd5f0df30, 0xfd28672a, 0xafbcbcf0, 0xcc37b43c, 0xf8c071fc,
- 0xab47b656, 0x82477760, 0xd3bcf039, 0x740ff843, 0x3a3337ba, 0x0f2b5a47,
- 0xbf338be7, 0xe908d3db, 0x0b975a5b, 0xd66567d7, 0x338f3d59, 0xfe51ebf5,
- 0xdff7979e, 0x38dd820d, 0xdb94c05a, 0xbb668da5, 0xccbdfd11, 0x57f2a19f,
- 0xd5877e28, 0x31acd22b, 0x0188ff80, 0x4cd3823f, 0x33e34de7, 0x35118fc9,
- 0x2b3771d5, 0xccf73c04, 0xa2046f98, 0x554e85dc, 0x658fc790, 0x97d0fd97,
- 0x035e383c, 0xce02abfa, 0x0f441923, 0x3573b923, 0xe7014995, 0xff655bca,
- 0x9b1f00c5, 0x7f609796, 0x7896cc3f, 0xd679863c, 0xda9fff72, 0x6ab8665f,
- 0xd833b553, 0xdfaab27e, 0x722fd956, 0xfed5f6f3, 0xf4d5c337, 0x0ecfda61,
- 0xb21cdf6a, 0xd576c1fd, 0x11afbc7e, 0x3e436f1f, 0xb5ffce18, 0x1ba7965f,
- 0xf45e9e6c, 0xd818e97f, 0x06071495, 0x6a8898fa, 0xc369ff23, 0x5d5379f9,
- 0xa60fdab2, 0x1f927e63, 0x90d647cf, 0x3e6048fc, 0x9859df8a, 0x47d7f287,
- 0xbbf1e74d, 0x1371b960, 0x8798c179, 0xfd00dea1, 0x3f57f2a9, 0x46d3f7c2,
- 0x3c42eec1, 0xfff3c783, 0x89abdd8a, 0xfa4bdf1c, 0x64b84a73, 0xdbde81b8,
- 0xe32575ea, 0x3dc21bf7, 0xfeeb1835, 0x762ebb3c, 0x1b3de83d, 0x7c08c630,
- 0x71bb3576, 0xfb84cfbe, 0xf58fa724, 0x27a21a71, 0x1d96ddcb, 0xb27a00da,
- 0xa8695de8, 0xf2345af7, 0xa1fc2f39, 0x65bd6cbf, 0xfd10a6e7, 0x029bfa2b,
- 0x8f002b5b, 0x956dba00, 0xfe81e6f5, 0xd0ee2496, 0x3163b406, 0x3fa90ab8,
- 0xd2a35ce5, 0xeb37d35f, 0xf7ecab6f, 0xdeb3fa52, 0x559f1ea3, 0x59f1a1ef,
- 0xe947fde5, 0x2f8e2b6f, 0xb4dd5f04, 0x1e8ed93f, 0x7aa96fe8, 0x8783567c,
- 0x72d567c6, 0x7f40e1ff, 0xbfacdf4d, 0x931ef936, 0xe1d3e64d, 0x0e37fdce,
- 0x1a76ab9c, 0x29b4ae51, 0x7f7940fe, 0xbfb414bb, 0x37f796ad, 0x714bfbe5,
- 0xbddfe4e9, 0x18df33d4, 0xfdc35f6a, 0x247ac98c, 0x2648f593, 0xcf0891eb,
- 0x3ea67a99, 0xf0b0e81e, 0x22f9b6c5, 0x1e73e3ec, 0x153e333a, 0xf62f19e0,
- 0x5f6117cf, 0x99e2f39a, 0xc9f04903, 0xccbe2fcb, 0xe6787fcb, 0x9b94324a,
- 0x2fcdef7c, 0x962a3803, 0xde0ac7ef, 0x8db7bf4a, 0xbba37ae2, 0xbfee73e1,
- 0xfb8af904, 0x87aa6356, 0x42f17fa1, 0x32d47f72, 0xe94eefa8, 0x310f2cb7,
- 0x6eea4a2f, 0x467e4f38, 0xff287914, 0x40bfe1e6, 0xee53cfb4, 0xefab9467,
- 0x6d454467, 0x8c2ffd22, 0xef28cdf9, 0xba0e8c22, 0x28d6f84f, 0x642c1fbe,
- 0x376e0af6, 0x39f25948, 0x31cfba0d, 0xd76e58bf, 0xb1cfcb7c, 0xb1c6a17c,
- 0xdfd9ed1e, 0x478aaa4e, 0x173958f5, 0x7f783797, 0x1bf5d772, 0xbe0e1f9c,
- 0x23e7393f, 0x23c2eb81, 0x3ba5bfb8, 0xb9f7e257, 0xa886fc02, 0x9f370ef7,
- 0x7db8a3b5, 0x0e9f383f, 0x0e319f3e, 0xfee69f3e, 0xfeb0b5a8, 0xcb7ee8ee,
- 0x5d9fc413, 0xc86be721, 0x5fcd06bc, 0xd8a628fd, 0xb7a45a79, 0x32b7cd9b,
- 0xc1f9caaf, 0xa2ca4146, 0x794feafd, 0x3183fd2a, 0x8e2a14bb, 0xb819f483,
- 0x4e6deabf, 0x5d19fe86, 0xcf073d9c, 0x45fe3795, 0xde5cf21b, 0xd63e796e,
- 0xb9d38546, 0x3d28c6ce, 0x51dddbd9, 0x97fa1933, 0x9a74d345, 0x72a8b297,
- 0x8da96f3a, 0x8f68ed65, 0xd7239f06, 0xce9bb88e, 0x68ad6901, 0x703a4041,
- 0xa461d92e, 0xe8b989f8, 0xc5c8e786, 0x8f239d9b, 0x91cfc999, 0x7425e947,
- 0xea45b459, 0x7f239e43, 0xf7df146c, 0x713c71bb, 0x278c3f88, 0xa21c706d,
- 0x31d1c799, 0xf5f2023f, 0x7f231766, 0xc7de3cba, 0xea5075e4, 0x861ecc1b,
- 0xb7ab40f2, 0x68a7a84b, 0x613ef9c3, 0x4e5869b0, 0xf7c8bf08, 0xfbe8e947,
- 0x34cd724f, 0xd7231aaf, 0x5afce7cb, 0x7a4fe908, 0x4fe29475, 0xc3674d0a,
- 0x0d3cc9d1, 0xf0a7473f, 0x9e9302e1, 0x302df7ce, 0x0fd14ad9, 0xef0800b2,
- 0xfa8098b3, 0xf7e22db7, 0x0dbb4581, 0x5337e7e9, 0x6ff9ff6e, 0xb9f9ba18,
- 0x43353e7c, 0x4ee3f747, 0x8f61cc09, 0xd57e7a19, 0x869e8ce9, 0x66bb9a6e,
- 0xec87599d, 0xeff2e2f7, 0x867b6115, 0x167553e3, 0x779fec89, 0xa85ca146,
- 0x0f1f5b4e, 0x42caa2f0, 0x94dfdd1d, 0x08ee44e3, 0xd19fc72e, 0xa28e4eba,
- 0x51e7d178, 0x624748a5, 0xa3e22a7f, 0xea0289c4, 0x9e2a37bd, 0xd7e1cdea,
- 0x18dea0c5, 0x7f67d394, 0x1eb462ef, 0x127a50b6, 0x302c4fda, 0x07cb236e,
- 0xf302a3b4, 0x01627ed1, 0x2f2c27eb, 0x9085f6b6, 0x609a4a17, 0x0d5292db,
- 0xd0909e7c, 0xff92a942, 0xee5b43ac, 0x57aeb10f, 0xc6fd75e5, 0x601b4c76,
- 0x8ed0713b, 0x2ae5fb01, 0xd517dbce, 0x61e32ca7, 0x17657548, 0xe9b18ec9,
- 0x88933e15, 0x1e6106bf, 0x45fb04af, 0xd5b0de75, 0xfba14beb, 0x6d38f2fe,
- 0xa346d62b, 0x1c55031d, 0xbcdb9f48, 0x9965296d, 0xcec8e383, 0x8d13e991,
- 0x17a889b6, 0x5c725ff3, 0x97f40ccb, 0x74349b24, 0x5326013e, 0x6e612f75,
- 0x38b4f459, 0xccdd4534, 0x2ed0926e, 0x3f3d25ef, 0xf896bae1, 0x62f0e120,
- 0xa4ab7186, 0xef0176b8, 0x23f40d03, 0x97ae6fdf, 0x5c57b9e3, 0x048e3465,
- 0xcefec0eb, 0xf38d0ec8, 0x747945cd, 0x518e69e5, 0xe5d58fc2, 0xdcfc71c9,
- 0xe1d5fdc2, 0x3ae8097e, 0x4057b6a9, 0x380c0138, 0x5c27c5f4, 0x426b4c6f,
- 0x045af279, 0x6db58bf9, 0xf207cc99, 0x45745527, 0xfb3ce0e5, 0xc9a6ffa5,
- 0xdf0b0790, 0x9c207cad, 0xa136b3f4, 0x25d90665, 0x285869f7, 0x1c98cf3f,
- 0xc828c7ee, 0x609ffce1, 0x1ea94d6b, 0x44d3e987, 0xcf975f37, 0x1db39067,
- 0x9f11d9f4, 0x1c58fa2d, 0x759a7bd4, 0x9b73e9a1, 0x7ec0efdc, 0x185fcf21,
- 0x7f911973, 0x3b9382b5, 0xdbeef739, 0xce82cfb7, 0x55e74613, 0x8d7ac936,
- 0x4e444ed2, 0xd846153b, 0x45cf0c1d, 0xdf07660a, 0x9b3ecc07, 0xf9abd60f,
- 0x7b486d2b, 0x791cc1eb, 0xb26b491f, 0x4cb2fd61, 0x94fd0dbb, 0x1a55f7c1,
- 0x70da26d3, 0x0c671a7d, 0x7031a9d0, 0xcb4ee85f, 0x53cf1f7e, 0x2c747a99,
- 0x70591cf0, 0x2173c7aa, 0x972837b1, 0x1d3797cf, 0x9b42e7e2, 0x78bd454c,
- 0x14c9a10e, 0xfec74457, 0xa99cfc4c, 0x3a64df52, 0x64def246, 0x1356f1e7,
- 0xa2020fee, 0x3ba1e7c7, 0x83cd18ed, 0x0e5a6f52, 0x7b26ab97, 0x5bfbc317,
- 0xd53f76e1, 0x3e9d130b, 0x161fe00d, 0x4ffee8c7, 0x55f39198, 0x318fac04,
- 0x7e95ef80, 0xd1d1cb6f, 0x172535bc, 0x7e1096f5, 0x6704de22, 0x1b22b64d,
- 0xdf38dbed, 0xb4636fd0, 0xaf9cdf42, 0x5be7971f, 0x3e51a769, 0x434f7aff,
- 0x58b2fcce, 0xd73913f4, 0xa6bb60e4, 0x83b446e5, 0x6fe391b4, 0x6186ded8,
- 0x285e6bdb, 0xf238f7b7, 0xc8b23685, 0x50e9ed8c, 0xc3a0845e, 0xfe76e467,
- 0x30ede357, 0x97df74b3, 0x9f305a60, 0xa3de942d, 0xa38c46a4, 0xddfa1b8f,
- 0xebbf9637, 0x90247ed4, 0xfc717bbf, 0x1ecf932b, 0xee1ca12b, 0xdb2eda3f,
- 0x619d8a27, 0x2ededb91, 0x3ee87bf0, 0xef4edc21, 0x8776c836, 0x0f3d4c25,
- 0xf941f783, 0xe0ae5c3a, 0xc72ee6e7, 0x046b8a31, 0x77e5f3f3, 0xb40e8a3e,
- 0x73ef504f, 0x04bb7364, 0x1c4bb453, 0x610d9fb2, 0x9da01bf4, 0x80fdf0a2,
- 0xfa42b75f, 0x3f005ba7, 0x0d6fc803, 0x7b242bb4, 0xc90dbe88, 0xe7c8697d,
- 0x053bf2a9, 0x5cd7f643, 0x4785a72e, 0xfe434b3f, 0x4feb8b2e, 0xf982efc0,
- 0xae4785fc, 0x5e78e026, 0xce703198, 0xab43e286, 0x7bf3a717, 0x1cffc7d9,
- 0xfed10aed, 0x457feecd, 0x86b4dd9d, 0x5ce5c0f4, 0xdf5bfc0f, 0x8cbedb07,
- 0x821d9deb, 0xcda4efda, 0x5fe77ae5, 0x7acc7de4, 0x2df7a455, 0x2eb965ce,
- 0x0ab61f20, 0x7f28e5e6, 0xe7e11f53, 0x5e3f56e6, 0x2103d9ff, 0xed1841f8,
- 0x804e73fa, 0xacdc5c3d, 0xa35a3f27, 0x8dc47d29, 0xafc31ce2, 0x71cb87b3,
- 0x1e4b7d79, 0x24f3f235, 0x5b17ae2e, 0x39d3f75c, 0x23f3e095, 0x243bd5c3,
- 0xbea53dcb, 0x7947db01, 0xfe479a62, 0x23684b80, 0x964dbfa0, 0x7678c17b,
- 0xf3c864e2, 0x12b90463, 0x18456875, 0xed93abb6, 0x3f8aedb1, 0xe8c8a2a3,
- 0xb75ef808, 0x1a58c8b8, 0x8c8d2f40, 0x6e0ddf9f, 0x01dcceff, 0xafa55a7d,
- 0x459f70e8, 0xf89c50df, 0x433901a7, 0xcab8658a, 0x0ffa518e, 0x70163f3e,
- 0xf38c2c5e, 0x5a67b729, 0xe818dcf1, 0x962b6bb7, 0x6df9c48f, 0x582f5d15,
- 0x3ffa1e61, 0xe739d030, 0xecbe650f, 0xb872f993, 0x43b1f3f5, 0xf6318ca0,
- 0x97823b04, 0xc64e80d6, 0x68fe408f, 0xfb94d4cc, 0x5cb38c43, 0xfd08671e,
- 0xafdcd6fa, 0xe6975fa7, 0x51afd086, 0xc504767f, 0xd461021f, 0xf4211d9b,
- 0xec8213eb, 0xedcf900f, 0x1d49d09c, 0x270f307d, 0x6f611d6e, 0x919ee894,
- 0xf6045ec3, 0x32678bc3, 0x239f6f51, 0x23c7bc0c, 0x608c31db, 0x221623b0,
- 0x6799735e, 0xc50203df, 0x48ee5a51, 0x5c04eea3, 0xa7ad9b8f, 0x3711fb24,
- 0xdc613ac2, 0xb2daf5a1, 0x0ce2a119, 0x274038ff, 0xef02ba28, 0x042ac007,
- 0xc48695c4, 0x63e282cb, 0x38194e18, 0x5a1dabff, 0x7562aeff, 0x35e36afc,
- 0xac30bfee, 0x0427fe60, 0x2eaa1f3c, 0x0bae5f9f, 0xe2a9cf8e, 0xba9d0b5a,
- 0x887c7c60, 0x6f8cb26f, 0x2907b6ca, 0x452d3e0e, 0x64acfde4, 0xc707cf64,
- 0xbd850cbd, 0xc3ea2d0e, 0xf7f48c15, 0x9e363f60, 0x5eff2517, 0x09cf6305,
- 0x7d5ade74, 0x59e9e4df, 0x1cfbf8e7, 0x8fd8e52d, 0x50c3532d, 0xafbe0e3f,
- 0xf09bc4a0, 0x7de04c98, 0x22dde569, 0xe10d62cb, 0x53b77cc7, 0x8797e2b9,
- 0x4b12a6fa, 0x55eeb9c0, 0xdd3ea06c, 0x1e85f2a3, 0x59d6d6f7, 0x1c4fef14,
- 0x82ec29ef, 0xa33b24a2, 0x66aa4879, 0x3cc00764, 0x86fae2a8, 0xce345d94,
- 0xc58c354b, 0xaaa038f2, 0x7076013c, 0xbf184fa4, 0xe30fce2a, 0x76c1c154,
- 0x4deccde7, 0x0de64a43, 0xfccdf9e5, 0x5e39068d, 0x646e46f8, 0x633be91c,
- 0x77d418d8, 0xa69f8b2c, 0xeb04b8f5, 0x34597e81, 0x03c54284, 0x68fb4337,
- 0x5f90ba07, 0xc4dfd1e2, 0x30caef54, 0xc9f74887, 0xb38e6284, 0xf1e4eb10,
- 0xfc467ce1, 0x9507086d, 0x9859f80b, 0xbce0706c, 0xc3000c1b, 0x333d0590,
- 0x56be4026, 0x15af37f6, 0x33308898, 0x4fdc8ddb, 0xe36bbca8, 0x866d77a7,
- 0xff7407eb, 0xcfec30be, 0xfa53bfc7, 0xdb8ef219, 0xfb27be0d, 0x7dfc1ccd,
- 0x951df919, 0xff9b87fe, 0xfb6ddee1, 0x2777d4c3, 0x3267bf70, 0x20e56bd1,
- 0x4cbc12bd, 0x1efc47a6, 0x4abdc2e5, 0x0c77adb1, 0xfb3c37de, 0xfd1d8470,
- 0xf0e303e0, 0xefe5a9dd, 0xed75fdd1, 0x9361e00d, 0x8c0fbe48, 0xafef6e4b,
- 0x02fd171d, 0xbc06dae4, 0x4fe78434, 0x279d192a, 0xcf4ab8b0, 0x000e7489,
- 0x1392a0c6, 0x4013ef01, 0xf10e1b7b, 0xf15baf73, 0xb0710b9d, 0xd02bd45f,
- 0x4255b06e, 0x483b087e, 0xbf19ab49, 0xd5e0ac1f, 0x1a3d07a8, 0xf5c352e9,
- 0x3ea6d9e8, 0xe935cf11, 0xe445fae2, 0x2e68e71f, 0x37e807c7, 0x0bf9d19e,
- 0xce7c926d, 0xdfc4a471, 0xfbe4cb4d, 0x84cfd29b, 0xfe591ad1, 0x47fbd2f7,
- 0xd54e23b3, 0xf2c6764b, 0x442fc5f6, 0x11ecfcff, 0x00d3eaa7, 0xe167d82e,
- 0x2ba9d270, 0xecc66669, 0xd10bacfb, 0xef3b3f9f, 0x807495d4, 0x78d9f68b,
- 0x464614f9, 0x097df8ce, 0x319fd10b, 0xd559b461, 0xd7385bfe, 0xd53cdff1,
- 0xcf21341a, 0x5a36df63, 0xe8c94f39, 0xf3b3ad3e, 0x2e31a797, 0x47f654e9,
- 0xdf482e87, 0xde0b2281, 0x717f9323, 0x9d0f1451, 0x9dd9d329, 0x1452eef8,
- 0x68bb2dfa, 0xfa0d477e, 0x6bfe9fe9, 0x4382f4fc, 0xccca9779, 0x1bff812a,
- 0x2c2b981b, 0x99ee8023, 0x9f9d7343, 0x81b8a603, 0xffd28f82, 0x6960bc10,
- 0xbc4098c5, 0x0a3b51b6, 0x0d0a175e, 0xc70587a4, 0xfd082e87, 0x549cf1db,
- 0x2fd6cfc4, 0x10ba75c2, 0x002a9fd9, 0x9eb79e1c, 0x7c42edd6, 0x1ec176ff,
- 0x3af8eb00, 0xa22bef56, 0xd6a3fc75, 0x027a3d51, 0xdfc5dbbe, 0xe396686f,
- 0xbbc64f50, 0x019f687c, 0x32b9d1dd, 0xfc9e8a5f, 0x05e36548, 0xb03fa047,
- 0xcbf7346e, 0x69d3925c, 0x49cf1686, 0x01f74ba0, 0xfa85ad81, 0xf5976bee,
- 0xeecc9fa8, 0x3d47a33c, 0x19c0eeba, 0xad4bde3d, 0xa9da1843, 0x8477a6db,
- 0x32feffd2, 0x97f2ab5a, 0xd1d77629, 0xe8f5ec94, 0x16abab77, 0xeade1ee8,
- 0x6e1fb9d7, 0x251c32f5, 0xb2df7763, 0x55b8fc9f, 0x98f5eece, 0x477d652e,
- 0xc588ddf1, 0xdceaad2e, 0x089a92c0, 0xcabe3c55, 0x9782ab13, 0xc0eac0b6,
- 0x21b4bb3e, 0xc31df549, 0xef82cf5d, 0xd0fe0e28, 0xd790affe, 0x736db171,
- 0x16bbfa2f, 0xcc7ad4bb, 0x62b5ceec, 0x11ede20c, 0xfece1aec, 0x84b77e12,
- 0x00d2108f, 0x7de60abd, 0xa3d7075a, 0x648c2aea, 0x0c22549f, 0xab595af3,
- 0x7393e3f5, 0x54f45347, 0xa810eeee, 0xbb972ddc, 0x576e046b, 0xa975f2cb,
- 0x8392e38c, 0x75d1a727, 0x37a39f52, 0xa5df0033, 0x88e7e515, 0x437d651e,
- 0xc4855719, 0x290d8df5, 0xddb0e9ef, 0x5817dfa5, 0x4b8d1a6c, 0xa92d47a5,
- 0x1e55c351, 0xd59e905d, 0xbdf943a7, 0xff9d41b4, 0xbef2d1f3, 0x90f2c79e,
- 0x2d18de9f, 0x07189f88, 0xbca53fe1, 0x81ef0277, 0x0f3ad25d, 0xead67d22,
- 0xdf700abb, 0x1175a4bb, 0x7e4394ac, 0xb8afdf1d, 0xce01a2be, 0x751befc3,
- 0xa7de330e, 0x8814adf5, 0x00b0976e, 0xb06d27bd, 0xa1dac13e, 0x7722bf70,
- 0xe4f59cc3, 0x98283d0f, 0x13286f51, 0x83de221d, 0x8fc61c6f, 0x83e6517e,
- 0x1f2fac13, 0x2246caf1, 0x9eca7585, 0x99f6823f, 0xf996b7ec, 0x3d948e30,
- 0xc4bf204e, 0x4371809d, 0xc922a611, 0x37b03991, 0xad9a4184, 0xf920af6d,
- 0xe66f563e, 0x58da62ef, 0xfc70bca0, 0xbe701333, 0x0bb27510, 0xfde87b93,
- 0x9b6d39bd, 0xcc5ca22f, 0x3d1470cc, 0x193df805, 0xf27ffbc6, 0x16bfc175,
- 0x3fcba9da, 0x0ad3f246, 0xd6fd81e4, 0xda3964d9, 0x5acff6a1, 0xc121ae51,
- 0x7ea7cacc, 0x32f89413, 0xc3ed15d0, 0x9fa4a55d, 0x9f7ee558, 0xddb8942d,
- 0x2e7ca0fc, 0xe2d6f98d, 0xd1befaf9, 0xf495f28c, 0xcaabfb1b, 0x5e283104,
- 0xe61a3750, 0x4fada579, 0x5be9de75, 0xe901bf6c, 0x187db82c, 0x395e2abe,
- 0x8a2d7b4d, 0xcc1d77ee, 0xfee8deb0, 0x3ea8d694, 0x8733a4b7, 0x53bbdd07,
- 0xf6d99fcb, 0x777ba0a4, 0xeef74119, 0xddee82f2, 0x2df9efa9, 0xba094e74,
- 0xe7bea777, 0x54cdb067, 0xe6930fd5, 0x9c88e0a9, 0x23f555bb, 0xe7d5cbed,
- 0xbcff8eae, 0x77c74842, 0x2e7d7d06, 0xe0668798, 0xc198e28d, 0x0a2f247d,
- 0x3e1a432a, 0x6984cc2e, 0x0ba1a173, 0x9139a4e9, 0xe386e7db, 0xa0badb0f,
- 0x9788e31d, 0xfc6fe88c, 0x452fe089, 0x9f28c4fb, 0x18fd1953, 0xaf33ed53,
- 0x52be7015, 0x5cf2dbd2, 0x7d61f3b3, 0x494af7f2, 0xdee01dfc, 0x463eb8d1,
- 0xf9036c7c, 0xaf7e55e6, 0x476cac78, 0x5f3ced28, 0x0f353258, 0xcc7fcfbe,
- 0xece28331, 0xf07efc1d, 0xa78f3d4e, 0xe7e55ef8, 0xfa3bf35b, 0xfe008e34,
- 0xf5c7993e, 0xa59c6790, 0xeba91f14, 0xf9165d84, 0x1eaceda9, 0x75d465ef,
- 0x7ee14776, 0xab3ce056, 0x60c9bf47, 0x89cfbcbe, 0xaf68e1fd, 0x743dacff,
- 0x9e6d6d3c, 0x98e3f89e, 0x1eabd72c, 0x91bb72d6, 0xb9e16639, 0x575e4571,
- 0xabe3e7ed, 0xe7e7a85a, 0x1d1a3160, 0x9c836e42, 0xc396ab3e, 0x707ef50e,
- 0xca3d7f8b, 0xaadf900e, 0x4c174b7a, 0x12b7bb27, 0x31f236e4, 0x797573c8,
- 0x17c91372, 0x7caae790, 0x3c80de77, 0xdf0ebfcf, 0x426a769d, 0x8170f38e,
- 0xda78f348, 0xffe69535, 0xf4479819, 0x64333da7, 0xde7cf8de, 0xc65ebe6c,
- 0xb7580fb5, 0x2ebf7ae0, 0xf2f6ebe0, 0x7dfaf230, 0x0a775d79, 0x4c2845bd,
- 0xa270cedd, 0x634625db, 0x387b9e09, 0x1365f296, 0x7eaae1c6, 0xfd3dd02e,
- 0x6e3eeb7f, 0xbf5ffd41, 0xfd05a8ff, 0xa3f6ee61, 0x594db016, 0x8b5a4ead,
- 0x85d03c7a, 0xba9ef51d, 0x7fc22e8e, 0x6eb8fb65, 0x21d95fcc, 0xee3dfbd0,
- 0xd3a71703, 0x135f5938, 0x0e770bc6, 0xf28fd783, 0x37befeb8, 0x307ee24f,
- 0xfb89f417, 0xdf8301fd, 0x801d202f, 0x5ebc425c, 0x35e5f017, 0xb1a373b6,
- 0xf51e9422, 0x1f7cf26f, 0xe867a8d9, 0xef85afaf, 0x52c71c71, 0x488de98e,
- 0xb205fb47, 0x27edddb5, 0xfb604617, 0xfa863af5, 0x17df8285, 0xe21fbd29,
- 0xd6a83ff8, 0x3580a7a1, 0xbe696b56, 0x52d7a83f, 0x74fbda3b, 0xc15e2f04,
- 0xae1c55cf, 0x0929a8fe, 0x56a0fdda, 0x530c7ba0, 0x31f3fbef, 0xe0af1784,
- 0x3d305afa, 0x4c1af42b, 0x3bf4c19f, 0xbe6b4e84, 0xc91e9d19, 0xe4d5ef93,
- 0xe7dc02b1, 0x59a7dd61, 0xe11e7e91, 0xae2be3f7, 0x7fa1d61d, 0x6cc9bd33,
- 0x31e0027f, 0x0b7aff5a, 0xbcc389ca, 0x8776b0bc, 0x748de5c0, 0x5261f237,
- 0xbda19eb3, 0x971e7efb, 0x7ae3ef4b, 0xfad0e3c5, 0x31af8c05, 0xe51d37b1,
- 0x4f1c9a52, 0x2ac7457a, 0x905c53f6, 0xaf319bcb, 0x96ef54d9, 0xbd71e537,
- 0x40839143, 0xe4fdaee6, 0xc44f6d97, 0xcb2f147b, 0xe55341e7, 0xfa32b2f6,
- 0xf485cfa7, 0x672f4caa, 0xf8143c64, 0x6cff4cb2, 0x1f68cfdb, 0x59c72d9f,
- 0xd1743666, 0x833ccc79, 0x879453eb, 0xabdf52b3, 0x39ae7dc5, 0x3a7cedfd,
- 0x25378d67, 0xc9fbe226, 0xd27877fc, 0x60d6dba7, 0x9c372fdc, 0xe0ec31d6,
- 0x381e7453, 0x35bc6b2c, 0x49439c54, 0x7a2557dd, 0x6aeeb08f, 0x3c0aa53a,
- 0x7d39d0f7, 0x1701d91f, 0x5c9f13a7, 0x2ddea9b5, 0x7bc654fc, 0x5d3ef28c,
- 0x80f3f727, 0x8b8b169c, 0xf329eb06, 0x1c659e80, 0x2ed6586f, 0xab35af5a,
- 0x75a92158, 0xcefe29ec, 0x0149ed66, 0xa458bddf, 0x304ce873, 0x608defdf,
- 0xfc8b1f25, 0x3657241d, 0x748c4dc6, 0xd784fb2f, 0xd7af704c, 0xaf29f046,
- 0x61ade944, 0x687c88ce, 0x4f11e167, 0xe1dbce16, 0xde275694, 0x8ef0bc57,
- 0x336ba64e, 0xd32e2fbf, 0x2d4ee5da, 0xeb9c6233, 0xc2e3e800, 0x5cf7fe20,
- 0xddfba44d, 0xa0fec3bf, 0xbf0d959f, 0xaf677921, 0xed1d38b9, 0x33dac2a2,
- 0x1bbb084d, 0xf51d3cfe, 0xff610f89, 0xf41ebd20, 0x72809b7b, 0xd3bd24e4,
- 0x8635795d, 0xd35979da, 0xcbf91d3f, 0xf740a6f7, 0xb8ec3e6f, 0xfdf2b7a8,
- 0x7873dc89, 0xf2fd1c2f, 0xb9a3f2b3, 0xd42ce91c, 0x243afad0, 0xddeb3bd5,
- 0x0a2bffa3, 0x20d8c3d7, 0x7e0a7afd, 0xc865a3df, 0xfb4a9bbf, 0xe421cca3,
- 0xdff469ef, 0xb071f365, 0x15e5a1ec, 0x9e165f7a, 0xe990ac93, 0x3cbcb838,
- 0xa13fc07f, 0xebefca73, 0xa1fe0108, 0x3fdfc62a, 0x2ba7bb05, 0xaab8f81c,
- 0x67f92a73, 0x0dc23caa, 0xd1c333fd, 0xeb4dd7e1, 0x28cff718, 0x818dda30,
- 0x1bb44d7e, 0x1f7faa99, 0x252b077f, 0x74f786f3, 0x14897ddc, 0x666bafcf,
- 0x795aef14, 0xe7a53475, 0x2120df5f, 0xfbc318ff, 0x6b7ee95b, 0x8cec86b6,
- 0xfeb53e95, 0xcb80a533, 0x7c052985, 0x60f95cde, 0x01b0e52f, 0xa2ec097b,
- 0x5db9f37b, 0xa9887514, 0x7ce0a5ec, 0xf28c97b2, 0x13101d3d, 0xe04257ae,
- 0x6941477d, 0xca977e0d, 0xd9ce885a, 0x72fefc3b, 0xe4d738f0, 0xf8553e73,
- 0x35f2317a, 0xe7076fd2, 0xe776e0eb, 0x41ac9415, 0x4c38da3e, 0xe65cab7c,
- 0x8c6d95fb, 0x16ddcbe6, 0x05f4f343, 0x0296736b, 0x78017e5d, 0x0bd23de0,
- 0x3444674e, 0xe5c17f7c, 0x3df3c08c, 0x6ba81c8a, 0x36efa70b, 0xc58bce66,
- 0x48cda373, 0xf9ded0f7, 0x9c46a98e, 0x38da7be7, 0x7dfd29ff, 0x1638b5d8,
- 0xae8269f9, 0xf2876f5f, 0x5133cee4, 0x784df7a8, 0xf22c7e7d, 0xfe7870e1,
- 0xcf1918fd, 0x1e12c486, 0x70bd8797, 0x004f6ca2, 0xba27ee7e, 0x87fa9de8,
- 0x6fd1181a, 0x56ffabf7, 0xbe7c7c87, 0xfb8cc233, 0x230717e6, 0x0bcabde8,
- 0x3de81a6f, 0x7df95a9a, 0x7d742fd5, 0x7cbf4873, 0x22f74b5d, 0x47fe6fdd,
- 0xfba3f22b, 0x3b9d0355, 0xc373a87c, 0x6af7dc45, 0xc39c673b, 0x5f6b5677,
- 0xc3f2dbfa, 0xd25486ca, 0x3ff8148b, 0xbe2746bc, 0xe45e7bf3, 0x8ea1e272,
- 0xf77d217f, 0x0b976ba1, 0x17ca7cf0, 0x44c7ff07, 0xb7ee6b94, 0x79444f2e,
- 0xe5c5fee6, 0x7eee5889, 0x4a13c22d, 0xc05eb95f, 0x7eca3efd, 0xa8aef699,
- 0x90ad0ff2, 0x5d6d23e9, 0x3d07bd0b, 0x7b02e4e1, 0x130fbbe0, 0xac4e34b2,
- 0x65b7e13f, 0x7c05f7b1, 0xa457aeb7, 0x93f8e338, 0x01d51165, 0x814f7974,
- 0x7e2ff14e, 0x930ebf23, 0xf019c7df, 0x77f2f4e3, 0x8af6367f, 0x1aa37dfc,
- 0x83a1ee81, 0x5ee432fe, 0x8affad1a, 0x88df7a58, 0xc73bce89, 0x8b38478c,
- 0x3e6205de, 0x00ccd1e3, 0xaf71693d, 0x7400cba6, 0xe869d154, 0x57befd22,
- 0xacb0433c, 0xf173dd3f, 0x2134c8d3, 0xe7267f84, 0xe39434d4, 0xf81a7ec1,
- 0x8ade2245, 0x71e955be, 0xc1fe20a5, 0x15a59bfe, 0x287f9077, 0xd6937fd8,
- 0x8f666a2b, 0xe9dff7c7, 0xf78c2f3a, 0x8bf22369, 0xfae287a2, 0xffc1081d,
- 0x3970c66b, 0xbad5f0a6, 0x5dff1e5e, 0xcc6a5bd7, 0xe656b484, 0x9db003ab,
- 0x75fda0fa, 0xa377f39d, 0xb5dd611f, 0x60631145, 0x3bbdd6be, 0xfc813d8f,
- 0x66352e6f, 0xeed777e1, 0x1fcc2e30, 0xfee097a4, 0xf2e18ca6, 0x184f4072,
- 0x97cbdf66, 0xed5bfaf1, 0xe463397f, 0x87ff6cf3, 0x87607fef, 0xedc31d8f,
- 0x4fdc25f0, 0xe0f0edc2, 0xc791437d, 0x792ebb4a, 0x63ca879d, 0xc04877fe,
- 0xec79265e, 0xbd51231a, 0xb1b9cee4, 0xbbbf4764, 0x0d325620, 0xb4433f6d,
- 0x87f2626b, 0x71e8afb6, 0xa8e39f6e, 0x871ced11, 0x1749fb96, 0x99bef408,
- 0x9db9f7a2, 0xeee3e902, 0xeb1f9d4a, 0x2ef57829, 0x85d57ee0, 0x4c3f9d0e,
- 0x150fd418, 0xdca071fd, 0xa2b9502e, 0x637a2a4f, 0x71fb93af, 0xe5e78c17,
- 0x16b986b7, 0xd87d7ce1, 0x13f94615, 0xc67cf126, 0x0093479c, 0x813df45e,
- 0xfacbff11, 0xc1a742a4, 0xcea5e6fa, 0xd7be1b8c, 0x4fa64db3, 0x8352cf85,
- 0xbfd943f8, 0xdd39f39a, 0x1dfee1d7, 0x7ff7fb8b, 0xe0f2f4aa, 0x7eff6176,
- 0x466ff108, 0x1fbe121d, 0x19d15bff, 0x4aff3eca, 0x5efe0bd6, 0x23debf59,
- 0x72af8825, 0x7db8764e, 0x6fd64eb5, 0xce6f2b86, 0xbcfc7aff, 0xdfdf1e47,
- 0x8e779f8a, 0x9f43bff9, 0xf50bd01d, 0x4779c7a1, 0xc64fc941, 0x6b86bcc0,
- 0x739e743d, 0x1ecdf7b8, 0xb055f595, 0x7c745573, 0x41af4534, 0xc35dc8bb,
- 0xd1cd03fd, 0x7ec9afd2, 0xf7a5ae39, 0xef921e57, 0xd5783e73, 0xea2d694c,
- 0xd92e90c9, 0xd9de927b, 0xc6a3525d, 0xb77d19bf, 0x34aafdf8, 0xb157eb8a,
- 0x552bf232, 0xf19b4675, 0x7c737fbc, 0x2be431fb, 0xb4ad6edf, 0xc6feb03b,
- 0x237d72d1, 0x44d5b7f7, 0x618fdfd3, 0x95407a41, 0x57df5827, 0x645305eb,
- 0xfa70d13f, 0xc3ba2fc1, 0xd1e95cb8, 0x39d79f12, 0xd055dff9, 0xe0b97277,
- 0xbf23086e, 0x886bda09, 0x820d67d7, 0x5f3ddf1f, 0x4cfbd729, 0x13ff25ec,
- 0xcaa0d3c5, 0x2ca7ceb9, 0xd4dfb20e, 0xbb95a3f1, 0x33724b7e, 0x73148e38,
- 0x0d0b8e40, 0xd2268dc4, 0x60959079, 0xbc9fe24f, 0x5dd24b72, 0x1f80ff38,
- 0x71dc93f3, 0x9730fca8, 0xfb223e7a, 0x3cebc973, 0x7e2433fe, 0xc7933cd4,
- 0x95ddf08f, 0xa5c87e10, 0xc51d8f23, 0xb374a3bf, 0xc75d51b8, 0x3247ba49,
- 0xd208ff44, 0x518dae3b, 0x8a4719fb, 0xb23b8fdc, 0x7fa33053, 0x8f3ca46a,
- 0x9c31b77f, 0x7fe9eaf4, 0x79458ea8, 0xf9d3aca0, 0xcf5e7cb9, 0x04a5707f,
- 0x07f89bbf, 0xe3061cd1, 0xf507c5fa, 0xb0e249bf, 0xbbf09464, 0x63b408fa,
- 0x7561ffce, 0x2febce04, 0x2fbfc520, 0x3169daf1, 0x2bd23fa4, 0x0fd82dcb,
- 0xbfc80ba3, 0x45a5fb2c, 0x07230fd8, 0xdfc139fd, 0x6bbf976d, 0xfc853306,
- 0xf8f3af98, 0x6b82737e, 0xa6cfc126, 0xa61efe33, 0xffcefc83, 0xfe8d7402,
- 0x2c183ca2, 0x1a7f9fc6, 0xbc61d6ce, 0xf5de39a8, 0xb3d1f136, 0x08f9091a,
- 0x9338a7be, 0xfb44bf6f, 0xc6194e23, 0xfcf40a73, 0x0cea465d, 0xbcb46bd6,
- 0xc760098e, 0xb0093c62, 0xe6f18059, 0x53ae393c, 0x6c44ce10, 0x6b9d49ff,
- 0xf997be13, 0x5f68b764, 0x8f604c4b, 0x83bf77c5, 0x83824be3, 0x3895c5c7,
- 0x1f1f1293, 0x6024ce2e, 0xee9c053f, 0x8715b9f8, 0x25737180, 0xe7bec49e,
- 0x635720a4, 0xf7ce87b1, 0x48c8533f, 0x718b7fae, 0x21f9259e, 0xc83548e2,
- 0xd5cf2463, 0x394dc571, 0xfe9d10af, 0x3dc4f1b5, 0x1cb7d863, 0x13f3e2ff,
- 0xe8f8f78c, 0xb7b2164b, 0x51effabe, 0x5e76cfb4, 0x42f0fda6, 0x8fbe41bf,
- 0xecfdc7d0, 0x2ff23a9d, 0x2dbb005c, 0x3d9f603e, 0x3ddbcf9a, 0xe89539d4,
- 0x596f40ff, 0x2f3fd604, 0x777c6fe7, 0x48d9fcc1, 0xbd22bd97, 0xe3e78b07,
- 0xd03b0ed0, 0xbd404e2b, 0x975c5be5, 0xb1098fef, 0xd0f0c62e, 0xcbe44cef,
- 0xc05f947c, 0x07ea63e9, 0xd772fedc, 0x598a38f3, 0x72ee0b96, 0x63c1c93d,
- 0xf1411629, 0xc5435b9f, 0xa7ef5e59, 0x856aa37d, 0xbe1cf740, 0xa3a59c71,
- 0x82b7de5b, 0xd3e5d3fc, 0xe70e6e49, 0x9b880eb7, 0x15b7caab, 0x23879c0c,
- 0x815475ff, 0xe31dc699, 0xb3c12c29, 0xbff8ca87, 0x73b875c5, 0xfb3a086c,
- 0x695fdb16, 0x9fdb6eff, 0xb6ddf792, 0x6e3be6bf, 0x77de6d7f, 0xf1dee71b,
- 0xf57fe31d, 0xccff6e3b, 0xaf3f3c77, 0x73ffffe5, 0x70700300, 0x5cf83f9c,
- 0xdfbc7040, 0x1f3efc70, 0x36106d96, 0x6a4177f7, 0x42b57a8c, 0x462d5100,
- 0x0877a2ef, 0x71e24d66, 0x46658db0, 0xf0610eff, 0x5f32807c, 0x1db90b4b,
- 0xe8bfce61, 0x4e79858b, 0xc596f475, 0x126c9fa2, 0x82fd877f, 0x132acefc,
- 0x18cef4cd, 0xfbc04cd4, 0xa161cdf1, 0x7261aae3, 0x23edc37b, 0xdc9617cf,
- 0xfe9e3631, 0xfbc8436c, 0xfec82f1d, 0x23077347, 0xa51324bf, 0xafd47984,
- 0xd0fa8094, 0x3f3c2388, 0x76398baa, 0xda525e10, 0xa507b23c, 0x8b6fc434,
- 0x998def1c, 0xfe869d99, 0x0bd018e8, 0x14f81e31, 0x8e2905c6, 0x4a7aa665,
- 0xe58c1f7f, 0x31d16dfd, 0xe55bee81, 0xac4cf3f2, 0x9e2aa0f9, 0xebae8ef7,
- 0xc50265e3, 0xfe2396f3, 0xe574d2bf, 0x89934cef, 0xff37e618, 0x8ce29980,
- 0x48bd2627, 0x8956777f, 0xf331adef, 0x6ed1872a, 0x1cd63c06, 0xbbf4471c,
- 0xf7a4d0e4, 0x7733e9f1, 0x750f68a6, 0x17f1514f, 0x1dfd969c, 0x8940bf8a,
- 0xf65efd6b, 0xfe887c93, 0x221fba17, 0xab1dea51, 0x27f7b6f9, 0xfc10d8ef,
- 0xfee045bf, 0xb8afdf21, 0xde9c687f, 0x6e78119e, 0xaf3cb372, 0xdc78bacb,
- 0xecf7f142, 0xee33c793, 0x01976d11, 0x4d71d2f6, 0xcfb8f463, 0x094a6b8f,
- 0xe1c0b4c7, 0xf07de0d7, 0x35fbd5c5, 0xa285faca, 0xb2b1d6a3, 0x9fa7a31f,
- 0x12ff7ae2, 0x60ffe714, 0x30bf3f2c, 0xf1e390af, 0x0824d801, 0x1b12c9af,
- 0x711c7d51, 0x2a1b598b, 0x7605549e, 0xacb9e231, 0xccade399, 0x34975577,
- 0x7339fb15, 0xd309bfb4, 0xa9b49aa2, 0xbdaf6fe4, 0x9bfa84d8, 0x63e5dafb,
- 0x4cbf93b7, 0x713da12f, 0xefda9f4f, 0xa5a30ab6, 0xfd2784f1, 0x0cdf5a9d,
- 0x71e3ec91, 0x9fa24433, 0xb230aa98, 0x4c74635f, 0x2e78426b, 0xca8a8bd7,
- 0xcc22a6e3, 0x3e934416, 0x4523d458, 0xe83f97df, 0x51998b07, 0x74f38f1f,
- 0xe2aaf8b3, 0xcc35bb4f, 0xe7ae1af1, 0x5d5f1b5f, 0x74bbcef9, 0x971954ae,
- 0x9c4a2f32, 0xaaf8b874, 0x5dc1ce72, 0x2e75457e, 0x4ff62dc3, 0xb8e3ff47,
- 0xf2f46783, 0xfe334b39, 0xfe25611d, 0x8bf5ee3a, 0xe2557714, 0x45cf6eac,
- 0x3be1abd2, 0x0e3f7e3d, 0x06213f96, 0xf1e217df, 0x9ef157d7, 0xffef1e94,
- 0xd4bee999, 0xc5fdf21b, 0xe63f184e, 0xa1cde9bf, 0xa76bcbb4, 0x98b790f4,
- 0x45e77752, 0x387ed78a, 0x53ef1d56, 0xb49779e2, 0xd56333ce, 0x0e0923e7,
- 0xc369f78e, 0xddc6bfb9, 0x97bfa3a3, 0x48c77ee1, 0x73a4bbf2, 0xfaebdd19,
- 0x246ba4f2, 0xf1875de2, 0x38ba00b6, 0xe187b0ef, 0x9de7613b, 0xb38c30f6,
- 0xa73eeb8d, 0x752ff3c7, 0xfd1eaf62, 0x12718061, 0x1f744d1e, 0xf7cfc8b8,
- 0xdfd09676, 0x5c69bae3, 0x136fe3ac, 0xe59ffb17, 0x00210141, 0x00002101,
- 0x00088b1f, 0x00000000, 0x17b5ff00, 0x67534c5d, 0xb7b77cf4, 0x0bdf96e5,
- 0x72223f2a, 0xa29862c1, 0xa740c2dc, 0xac741631, 0x4a8a5c13, 0x66b50102,
- 0x2d09922e, 0xcbc2ccd9, 0x01893ad2, 0xb8b2c3dd, 0x26a9f364, 0x87b6e883,
- 0x6ead93fa, 0x840b0b55, 0xc3e22e25, 0x52c9719c, 0xba33330d, 0xd8dc6281,
- 0xdf39d85c, 0xd8bdb5bd, 0xa4da2cbd, 0xdf3f3d39, 0xfff9df39, 0x0730000a,
- 0xb956e7da, 0xf84ce706, 0xffc6cfa5, 0x4fa43d0f, 0xbddde38c, 0x1726eb4b,
- 0x3ebbf1c4, 0x036935c9, 0xce9c5df8, 0xf6002b94, 0x1c5ace87, 0xaccf1f04,
- 0xedfc2176, 0x4ab5dfc2, 0xd2f7803a, 0xee202d4c, 0x96a666fd, 0xd2afdef8,
- 0x4fe9027a, 0x8ed77bdb, 0x70045e97, 0x106b4196, 0xc12e55f9, 0xb8e08271,
- 0x4546fac3, 0x25c06e5c, 0x80fce938, 0xe89b34ad, 0xd9a55cc7, 0xf5f4137b,
- 0x00674539, 0xdaaf39e9, 0x09f489ac, 0x06a019bb, 0xc15c0ce9, 0x556bf624,
- 0x7fdfdb81, 0x4a4f2ad2, 0xdbf11c7a, 0xe036cc1d, 0x3c8150de, 0xf7c71e59,
- 0xfc028fd3, 0xd422666e, 0xb9e97402, 0xd77264b8, 0x3bafa8aa, 0x52816a3f,
- 0x5c5b4ca2, 0xdf5e30ab, 0x12acfd4b, 0xbefcf860, 0x170568e2, 0xa0172095,
- 0xe0373f4d, 0xb19c5bdc, 0x3d7fc010, 0x4698ca05, 0x4adf9113, 0x2a8e143f,
- 0xa769da22, 0xb6e5785f, 0x4c27f7fc, 0xcdba11ab, 0xbdc268fe, 0xc3829dda,
- 0x2eedc99a, 0x7920ce6d, 0x212fce31, 0xb74bd3a5, 0x51cc22ad, 0xf413e428,
- 0x025ac217, 0x36ada8d2, 0x0406ef6e, 0x7ca1b07e, 0xa488539b, 0x70d69da0,
- 0x6f50044a, 0xdf045395, 0xcd7b088b, 0x7c461281, 0x2be726f1, 0xbf11366f,
- 0x042aae4f, 0xcbe7e3f4, 0x09417916, 0x3464dfbf, 0xf3aa8e21, 0x3c52fed3,
- 0x953176af, 0x34ef6adc, 0x4193f1f2, 0xe3d6ee7e, 0xfc3433b2, 0x5ff72172,
- 0xcb9e0136, 0x8e38031d, 0x18f67776, 0x756eedcf, 0x3f7461de, 0x337fa0f8,
- 0x904d81ca, 0x6bde8907, 0x3b3aa394, 0x001ff18d, 0x43d62670, 0x0d41d537,
- 0xe7e1c641, 0x45d513e8, 0x582a0615, 0xbf373f11, 0xf974467e, 0xf062faf9,
- 0x5117f10c, 0xd80d567d, 0x024dbf28, 0xf5e10194, 0x9f412d92, 0x9eb9155f,
- 0xfc01650f, 0xde17d728, 0x7e30c83e, 0x915f8f7d, 0x4a6e505a, 0xd2ca97ae,
- 0x32f7b8e3, 0x401653d6, 0x036cf0f5, 0x9858fbc5, 0x794d1581, 0x28bef1f3,
- 0x6eb17d57, 0xbc4ead9c, 0x31dfe6a7, 0x3a44f9cc, 0x0d9a81d5, 0x61205f9a,
- 0x5817fcbc, 0x55ed1060, 0x491c3d35, 0xb2b9f8a3, 0xec8532d5, 0x23a50ed8,
- 0x6b126dee, 0x3c2ee118, 0x160ef840, 0xf6e7f090, 0x005b9d2b, 0xd8b754ed,
- 0x5bdc52af, 0x15aacc3a, 0x40dade88, 0x50596bf4, 0xff122937, 0xc4a97bc4,
- 0x55aa672f, 0x9eb3be21, 0x445f8df8, 0xade7aa44, 0x7865a514, 0x8d28cbb7,
- 0xeac1b37d, 0x551f500e, 0xf411a337, 0x3587476f, 0x84b5fe40, 0xce90cd9b,
- 0xbea041eb, 0xedcf5b7b, 0x328f45b7, 0x099f48a3, 0x5f916757, 0x16d3cc0b,
- 0xea356115, 0x7841c82e, 0xb005bee1, 0xb4e2bc1f, 0x73b94645, 0x05ac4c3e,
- 0xc49f4be0, 0x8327c861, 0xd7c03963, 0xc30e7cbe, 0x2fd3853e, 0x8c39cafa,
- 0x470e54f8, 0xa8356b7c, 0x959e3cca, 0xdd02fbe1, 0x7059a727, 0x7e6f9b25,
- 0xf9623ebd, 0x29ef0baa, 0xba3e7ba6, 0x93962eea, 0x5a20c7c8, 0x6ad6142c,
- 0x6730c9fd, 0x06c3e75e, 0xe881e3b2, 0x60a73a61, 0x460d61be, 0xef308421,
- 0xaa6febbf, 0xd96f9b52, 0xf193b802, 0x04faf467, 0x3cd02287, 0xfad24b7a,
- 0x5fc5787f, 0x48529e3c, 0xf31eb2b9, 0x413719e6, 0xd48fd20a, 0xbe7f736b,
- 0x4f18eb9e, 0xc0ddb8c0, 0xcf9c1278, 0xcbf8b56f, 0x74ad1f28, 0xa7e7248f,
- 0x0ac4faf4, 0xb432bb30, 0x4fbc329c, 0x600e6c47, 0x8f30b220, 0x4916211d,
- 0x19df3ec5, 0x244774de, 0x96e0c3d8, 0xd73c7e71, 0x46e6d87d, 0xb6f389a5,
- 0xf9268d33, 0xd54a5c13, 0x34592ce2, 0xf6d56fd8, 0x8b5d935a, 0xb56e0c73,
- 0x9471756b, 0xfbeb059a, 0x381679e8, 0xa9e7fd88, 0x734ebb18, 0xd001cf2c,
- 0x93c7c38b, 0xd1311e9f, 0xef990f3c, 0xd8e3993d, 0x0c8a791f, 0x3794391d,
- 0x41f6260c, 0x24077e81, 0x63946dc0, 0x6e611c91, 0x192dca25, 0x9f7d259f,
- 0x2f6e15d8, 0x01905777, 0xfe0450ba, 0x465f3483, 0x1a77502d, 0x639d77ed,
- 0x3bfa9070, 0xf70502e0, 0x1bf1e8fd, 0xdd214f87, 0xb4c98e73, 0x5783ba8e,
- 0x16ef9ef9, 0x78ff7827, 0xbc2d77c2, 0x3537831e, 0x0239887a, 0x403af249,
- 0x6eed1dfb, 0x6e687f46, 0x05301f74, 0xc36ed052, 0xbdafad39, 0x41404b0e,
- 0x1de8ac7c, 0xe79df091, 0x1cd1e419, 0xa5162653, 0x1980ff11, 0xafdc2502,
- 0xfd84baa6, 0xfc855f84, 0xd8cfed8e, 0xf4c0f1fe, 0x6bd52158, 0x0a235327,
- 0x8cb73fdf, 0x922f05fb, 0xed2fdf1b, 0xcd3361a1, 0x0643dc1b, 0x868eddb9,
- 0x713f343b, 0x4be918cf, 0xf9e7df0e, 0x53af2880, 0x7e062fdc, 0xe1633d8d,
- 0x58092c6d, 0x38731509, 0xca5536cf, 0x6eaddf3c, 0x1f18dcc6, 0x91757049,
- 0xc991709f, 0xc7e76f34, 0xf5aed1ab, 0x419fa341, 0xc877e62f, 0xd0c7d5a2,
- 0xa3f0163a, 0x94a2237c, 0x7b8ba1f7, 0x1cfd0cfc, 0x40aa62aa, 0x8c2120f1,
- 0x3e3d16c7, 0x6e1f802f, 0x70a9fc4b, 0xe01aae6c, 0x2b61ac35, 0x5ea353d6,
- 0x6e01000f, 0xd4e3f9a7, 0x8e23bd08, 0x2af9839a, 0xf9f8977f, 0xe055677d,
- 0xe814d4fc, 0x6bafd649, 0x6ab375ec, 0xf33dc90d, 0x7b2ed3f7, 0x47d3f792,
- 0x3b2276f8, 0x244ced7b, 0x2bbe30bf, 0x15efbfa9, 0x411ccb5d, 0xb5c981f4,
- 0x5975ce8f, 0xbea9ab22, 0x1cdc981f, 0xee91f18f, 0x8b82fda1, 0x91f516ef,
- 0x87cf8c00, 0xcc67e523, 0xa2769794, 0x125beec7, 0xe9b8e397, 0x0aa1fc69,
- 0xa1efdacf, 0xfda79aca, 0x17fa867e, 0x7f57cfab, 0x1dbcb26e, 0xa497f9a2,
- 0xe7d27e7e, 0x9912c01f, 0x3893cbf7, 0x6487b683, 0xaa3c75e0, 0xa67ef5ef,
- 0xc87b48fc, 0x06199dff, 0xed5cf895, 0x7ff4d0cf, 0xc18beba6, 0x9bf61d51,
- 0xf6f9b935, 0xfc39f427, 0x8a71c98b, 0xa4f2bdee, 0xdf824a00, 0xa0a982ab,
- 0x195df824, 0xf6e031ca, 0x7c8362c8, 0x81a978f5, 0xc2b1335f, 0xbd735fc0,
- 0x14bf80ca, 0x5f90675d, 0x01bd6bff, 0xc5bd30df, 0xcff1bf20, 0xd63c066d,
- 0xb95875bf, 0x4936e789, 0x0ae41baf, 0x157e8d3b, 0x2afd18f5, 0x15fa35ee,
- 0x37e25bd3, 0xdfacb7fa, 0xf64e5fe8, 0xde855c83, 0x91fcffa1, 0x2060fb49,
- 0x34f3c33c, 0x13029d35, 0xa8c44734, 0x66c21fb6, 0xf0a617be, 0x84a2e2ff,
- 0xd7a72c3c, 0x0919da3f, 0xb9d2b32f, 0x2b369d0f, 0x512edbbd, 0xfe3e600d,
- 0x2e76d705, 0x000ee017, 0x00000000
-};
-
-static const u32 csem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0xe3e3ff00, 0x51f86066, 0xb8d3c10f, 0x72361818,
- 0x0143f821, 0x684333b7, 0x0606163e, 0xc77e2001, 0x9ef0c0c8, 0x38330491,
- 0x207eec10, 0x27880abb, 0x7dcf5071, 0xe52f1143, 0x5f5d9fa1, 0x153d76a0,
- 0x837f7818, 0x031083b0, 0x03309b83, 0x8408b483, 0x55045fbf, 0xc10851de,
- 0x99412e7e, 0xfa819f5d, 0xbbeb8d01, 0x00038031, 0x00000000
-};
-
-static const u32 csem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c0b, 0x733ef7b5, 0x9993331e,
- 0x420f264c, 0x084f0042, 0x21842a20, 0x38880840, 0x8d069009, 0x8808089a,
- 0x420100ca, 0xa9113248, 0x676d5e97, 0x6ad11422, 0xa36d2d1b, 0x4101da97,
- 0x180d45a3, 0x1d0340e8, 0x5abc414c, 0x5b4a0a8d, 0x3c3141b5, 0xe878490a,
- 0xef5bd6c5, 0x33ef6b5e, 0x42667399, 0xfddfb6a2, 0x7f17dfbe, 0xecfb36fe,
- 0x7b5ef673, 0x7b5affad, 0x231fb5ed, 0xd313c659, 0x057c8415, 0x7213d77f,
- 0xf4842448, 0x0b3b4eeb, 0x108e3a68, 0xb0398e7f, 0xb4242055, 0x24edefef,
- 0x4db39085, 0x267355b3, 0x98c7fb21, 0xf2d3d743, 0x80fc81b3, 0xdd4f9699,
- 0xd121c479, 0x514ed57c, 0x3ed37282, 0xb1df7e2b, 0xde400851, 0xf1fd6e6b,
- 0xb5df34b5, 0x699b2453, 0x376424d5, 0xda425491, 0xa9fd842d, 0x6a5f98f1,
- 0x4daad965, 0xf682effb, 0x626683ca, 0x37b7dfa5, 0xafc86e89, 0x08042adc,
- 0xf76aaf6d, 0x5a00ca83, 0xd080b2df, 0x7e695568, 0x1a8a63eb, 0xfb03c84f,
- 0xb368ecfe, 0x67da7213, 0xfd82aa21, 0x491c6f28, 0x7b604548, 0x7dfa00e1,
- 0x65c136c5, 0x6c57f5a2, 0xf401d73c, 0xc3c93455, 0x8adf5a44, 0x47511b06,
- 0x22bfb6b0, 0x07cb5ed0, 0x794eded8, 0xfe57b428, 0x110a3de5, 0x1bb29fa1,
- 0x74a2abbe, 0x76b5bf40, 0xb1eafb4f, 0x559f8d3d, 0xe8f6d1cf, 0x0a2fd57b,
- 0xb562e82e, 0x8e807889, 0xb9d6dd8e, 0x7fa1db4f, 0xf8f0cab5, 0xdc2c7ec8,
- 0x08a8fd05, 0xed0a526c, 0x6526df40, 0xfaeec8e9, 0x87fc3456, 0xacfabe9e,
- 0x72889efe, 0x47da7a63, 0x3bbc3a59, 0xbb88415f, 0xa44bd691, 0xaa3a5280,
- 0x4207f9fb, 0xa1e32122, 0x96a8917e, 0xe4a9faee, 0x23fe0711, 0x0f949ff4,
- 0x81f1bdfe, 0x72dd99ad, 0x9904e95b, 0xbcedcb75, 0xea51cb93, 0x5fac8dca,
- 0xf20c7f4b, 0xf9d4f4a0, 0xee3e989c, 0x8374c34b, 0xfdbe454f, 0xd30237dc,
- 0x9f0b9f7a, 0xc3cbe93f, 0x8dcfa374, 0x22be53e9, 0x12be034c, 0x6fb36f7c,
- 0x7c5ba62e, 0x8cfe7c1e, 0x06d31caf, 0x7f3e0d5f, 0xd31ab7de, 0x3e3f3e6d,
- 0x1eb7d17f, 0x1d5f46d3, 0x5e403ba6, 0x05f26d34, 0xbe5dbdf0, 0xbe834c06,
- 0xc7be7c46, 0x11f4c417, 0x64c747ce, 0x3e512f92, 0x49c4dc38, 0x8a924ec5,
- 0xcd32f9dd, 0x7cb09527, 0x7cfe1dea, 0x3d53e685, 0x32f94f34, 0x6f9432a0,
- 0x3501f9a6, 0xfdf07cac, 0xf342c0a4, 0x7cacfd83, 0x02ee23c8, 0xa90fcd2b,
- 0x37c3e563, 0x68e20bfa, 0x9580787e, 0x542dbd5f, 0xabf9a360, 0x7679591b,
- 0xa76a9933, 0xcb10ecf9, 0x9ee1bce7, 0x39f34f1a, 0xfb9f2cad, 0x83aa7f81,
- 0xd8db73e6, 0x04ce93f7, 0x2d1ed544, 0xbab21d87, 0x6d595098, 0x4b70cff4,
- 0x515e6913, 0xca2e21ef, 0x6eadff1f, 0x43f29d29, 0xc8796376, 0x9bcb1f3f,
- 0xbf963714, 0xfcc32fe3, 0xe583d92e, 0x2c55fdc7, 0xfcb078af, 0x98bdff73,
- 0x2c7eca0f, 0x58fad4b7, 0xf963f15e, 0x58f5da80, 0x80391eff, 0x1f6b23e5,
- 0x4a3df2c3, 0x5f1fcb00, 0x1a7ba4fb, 0x3c11afcd, 0xd23c073f, 0x01649cb4,
- 0x4ad31a9e, 0x09d69e28, 0xf7e02e64, 0x8a3a0007, 0x0ae975cb, 0x3f8ee1ea,
- 0xfa0d3ee4, 0x90297f8b, 0xc3ccfa5f, 0xaffdf899, 0xd6991eb0, 0x4f5ef623,
- 0xba799bce, 0x2cde727a, 0x8069ead7, 0xfb58d6f7, 0x378ecf56, 0x79e9e927,
- 0x67ab42b3, 0xdf13d23b, 0xbce57eb7, 0xcf4f5935, 0x3d5a955b, 0xc49e907b,
- 0x74d3d1be, 0xa69fcf44, 0xb4fe6123, 0xfafd3d20, 0xf7b8cf46, 0xf719fcf4,
- 0x6f3f985e, 0x7de93d60, 0x3de9a7ab, 0xde9a7f3d, 0x08e7f30b, 0xdf506bf6,
- 0x7dee35fa, 0xbdc67f3d, 0x47cfe61f, 0xdf664f48, 0xa1f5d9ea, 0x3ebb3f9e,
- 0x04e7f30c, 0x6fac33d6, 0x48fdcafd, 0x8fdc9fcf, 0xc2e9fcc2, 0x5beaae7a,
- 0xd23ebb3d, 0x47d767f3, 0x817cfe61, 0x5bea8cf5, 0xa2ff72bf, 0x5fee4fe7,
- 0x0931fcc2, 0xbe98cf50, 0x54fc13d1, 0xa7e09fcf, 0xb0d8fe61, 0xa37df19e,
- 0xcf5daf27, 0x30f6bc9f, 0x9004527f, 0xd5bec4fb, 0xf3d76c13, 0xe61ed827,
- 0xe7ac20cf, 0x2bf5beba, 0x3f9e84ef, 0xfcc22779, 0xcafd8e19, 0xf40f7aa7,
- 0x7c4f5a10, 0x39ecf5cf, 0x9ecfe7ab, 0x8cfe61b3, 0xd3a67ac6, 0xaf7ab27a,
- 0x9e875267, 0xc23a933f, 0x7ac3c9fc, 0x9eadf466, 0xfe7a1d3d, 0xf308e9ec,
- 0x73f91f27, 0x35fadf53, 0x9fcf53a9, 0x3f8c9d49, 0x4cd70f63, 0x3a72d075,
- 0xfa44ba16, 0xdc67b5c9, 0x45e6816e, 0x4e8bcb27, 0x44bf0117, 0xd20dfcd4,
- 0xf7e916ea, 0x39896df6, 0xbf48930f, 0xfa14a0a3, 0xb1bd4f15, 0x2123bf48,
- 0xe7e74e2f, 0x7493ba24, 0x01a2e4f9, 0x95fbf7ba, 0xf795d10c, 0xaeb57b9f,
- 0xa393dd3c, 0x4f9467cb, 0xa83fbdd2, 0xbf9740a6, 0xba0df562, 0xb7fd33f7,
- 0xeb59f2ea, 0x3fbdd76f, 0xae916eac, 0x0afacafc, 0x8155f95d, 0x35fcba95,
- 0x7baeff0d, 0x03e3547f, 0xc1d1f2ba, 0x63e57587, 0xf2eb8f42, 0xa93d0f63,
- 0xeb7c7f7b, 0x84f95d66, 0xcaebcfa3, 0xd0edb627, 0xb93dafe5, 0xd9e7e0c7,
- 0xf0d7ed9d, 0x27b808bc, 0x574fefcc, 0xc50bdfd0, 0x0657982b, 0xdf8fd1d8,
- 0x3d54bf1f, 0xbcabe54e, 0xa14d58b2, 0x129905f2, 0x0fe7ae3a, 0x8db2bf28,
- 0x9277bf3e, 0x7d274ae7, 0x19e2af7e, 0x9fe18ced, 0x24083c52, 0x04d5520d,
- 0x41fcb1a9, 0x20b1e199, 0xc7e1cbe3, 0x535ef7e8, 0x9a44f0d7, 0xd7e62fef,
- 0x129e5e03, 0x38d3884c, 0x7bc0d491, 0xf3826671, 0x73330782, 0xe047f69f,
- 0xaa20fd75, 0xbd774287, 0x1a4f65eb, 0x6b9b19f8, 0x1f83f6df, 0xed106eb2,
- 0x9e4200d7, 0xf90ede16, 0x07efd287, 0xd0f34d2d, 0xf50accfa, 0x57db23d3,
- 0xb123fb68, 0xff6806fd, 0x37da1ec5, 0xb5d3c90f, 0xae5c196f, 0xd0a2df6b,
- 0x1fd49df6, 0x6f23fda8, 0x12610a9f, 0x7f0b2f21, 0x83cdf6c4, 0x07fdb1cb,
- 0x895f3a15, 0xdc2e3f6c, 0x77f4107e, 0x3e3fb41f, 0x4c87ff46, 0x707ff7d2,
- 0x0affbe85, 0xb52bffeb, 0x71fb78c7, 0xe116ffd8, 0xe0ffeb18, 0x337fd60a,
- 0xbedc37ab, 0x43ffcc23, 0x7b37ffd0, 0x64d67fea, 0xa8afff7d, 0xccdff7d4,
- 0xf6a77fda, 0x8edf6f14, 0x9c2bbfed, 0xa2bffd62, 0xcc57db12, 0x47e0171e,
- 0x09ab88c9, 0x40c9f6d0, 0x03fa986a, 0x903b685c, 0xa0a2488e, 0x6151e426,
- 0x6f71d208, 0xe7dbc31c, 0x686f1471, 0x9cf8fc6f, 0xcb65a804, 0x8e2ef3a5,
- 0xf2db15f5, 0x584bb015, 0x4b2be74e, 0x4165a938, 0x364df111, 0x28c30398,
- 0xd1411dbd, 0x0db2f90f, 0xfec005d7, 0x4164cd79, 0x91277c09, 0xf4ff3c10,
- 0x4736a367, 0x2e98cbf6, 0xdbdb93a9, 0x3c2df422, 0x23202a8f, 0xd37d286a,
- 0xbbe30401, 0x79d31ff3, 0x8bf3a110, 0x833ce80f, 0x227e4850, 0xa23ef6b3,
- 0xb7c825f3, 0x9412f9d1, 0xdf8b5213, 0xa70eead1, 0x384bfa51, 0x4c4b1ffd,
- 0x43be3f5f, 0x7ea9f808, 0x31bdfe7e, 0xb05d4f38, 0xde9946da, 0x7f42c74d,
- 0xfb4f2eb2, 0x753907e5, 0x360736ed, 0x155fc80b, 0xaa8a55f8, 0xf5e2c849,
- 0xddd79419, 0xc54fbfef, 0x7f594e9e, 0xfdcb711b, 0xae77fbe9, 0x69390612,
- 0xe6ddb3bb, 0xb84e361c, 0xd7a84c33, 0x4794c324, 0x634dadc8, 0x29035a64,
- 0xb71fcb75, 0xb33bb445, 0x5d9f9f48, 0xc877cfa2, 0xe944d96e, 0xc81528ea,
- 0x9cef5a26, 0xad72fab9, 0x8929bb1d, 0x57b799c9, 0x9be8ca92, 0x3c0e6903,
- 0xe79ca276, 0x1ab7d93a, 0x32c5de3d, 0x3c82c29d, 0xc808fdfd, 0xef829fd5,
- 0xfd64eedd, 0x573bd236, 0x684bb8b6, 0x142ee73f, 0x236f8003, 0x67da7ffd,
- 0x69b29b73, 0x32a7feba, 0xc7f74531, 0x8f3cff48, 0x328d3fb1, 0xcbf3c38c,
- 0x6e19cf8d, 0x3ffcb9da, 0xf4d07c06, 0xd283e004, 0xa3e39c7f, 0x7c32aedb,
- 0x9b9ecd78, 0x4f5d0f01, 0xcae50488, 0xc71b72f1, 0x3d3a92cb, 0xc8f1082e,
- 0x7365c720, 0x23879c85, 0xe3873070, 0x1ebd5960, 0xbf127737, 0x2e431e9c,
- 0xfa6c36f3, 0xdd1a9a61, 0x6e390fbf, 0x1fb23fe6, 0x4fdd13f9, 0xb8bba726,
- 0xd1acee9c, 0xe5c6df97, 0xeb97277a, 0x0ec7fadc, 0x6e41f350, 0xe8320357,
- 0x4d3ef7bb, 0x793a6d9e, 0x8d3cb87a, 0xe5c5de74, 0x98f7d779, 0xb6f48d3c,
- 0xd5b67971, 0x90c9905f, 0xf48d7a68, 0xd51d582d, 0xb9e4051f, 0x9e5b1fd0,
- 0xf27e60de, 0x55e788f1, 0x8f92338d, 0x8ad9e847, 0x7e5d5286, 0xee9e6079,
- 0x0bf565fd, 0xea4be575, 0x17caeb96, 0x975bbfaf, 0x9effe85f, 0xab05fdee,
- 0x77e5756b, 0x2ba43cd6, 0x98fe5f9f, 0xf3cf3f2e, 0x39fdee84, 0xcae93773,
- 0xa73c9767, 0xb4599f2b, 0x752f975d, 0x6fbdd6ef, 0x2dd577da, 0x8e37cf80,
- 0x89fc0488, 0x30275ccf, 0x4b99f82e, 0xc73bc176, 0xbae22a7d, 0xd30237dd,
- 0xe2173e93, 0x0f2fb4fe, 0x8b608ed3, 0x3a09c61d, 0x89252e2e, 0x6e9bccd4,
- 0x103f5dae, 0xe38269c6, 0xacd316e9, 0x4264ff5a, 0x91526d7e, 0x0af5c5df,
- 0x44258d09, 0xd386c180, 0x944625d1, 0x5e52f5b7, 0x727f0d4f, 0x5b717974,
- 0xc7dee7ec, 0x8ce15e17, 0xd6e97711, 0x7e019253, 0xbbf7274f, 0x0295e58d,
- 0x4e7c8929, 0xd7a803c8, 0x5bb8f8e7, 0xaffd30a9, 0x405e91dc, 0x0d0f901c,
- 0x7b5cb9af, 0xfde4148d, 0x3a592701, 0x7f565e3d, 0x13bece8d, 0x03f6ca88,
- 0x3dd58dbc, 0xad70d15f, 0xfb33bbee, 0x1abba445, 0x1844c56c, 0x375e4b16,
- 0xb50e1d81, 0x0a399e0c, 0x61bf74e8, 0xd82a7182, 0x33c2fd0f, 0xe3e4a2be,
- 0x04afc812, 0xb9be93d3, 0x3cfbb698, 0x95f71e98, 0xafb1fa63, 0xdf36d306,
- 0xf23f4c6a, 0xc0fd31f9, 0x3fd31eb7, 0x3d30eaf9, 0xf4c7abea, 0xd3005f3d,
- 0x4c06bec3, 0x6235f1df, 0x620beada, 0x6373e1da, 0x6f5de9aa, 0xc7c93bb8,
- 0xbf80d3e1, 0x78eb3818, 0xfaed5560, 0x3b38ddc9, 0xd6afba6f, 0xcf9bb03f,
- 0x8e66f5c5, 0x1e1d5487, 0x336080be, 0xf297ace2, 0xb0e3997a, 0x9763efa7,
- 0x6bff377b, 0xc4de36f0, 0x8a6fccfc, 0x653c6eb7, 0xd594f018, 0x89fa9e1b,
- 0x34f1bbe3, 0x7e64e4de, 0x8fd3c70f, 0xe6311fa0, 0x84e00515, 0xd7f08bf4,
- 0xa71636dc, 0xd409ebe6, 0x6a716553, 0xfa1af6de, 0x75fa2b6e, 0x6e301181,
- 0xb7f11f9c, 0x3f8710e1, 0x274cd47f, 0xcff73d7d, 0xf99e9388, 0xcdf9c6ee,
- 0xbc1d00d2, 0x5b9746c6, 0xad5f18e3, 0xe8445226, 0xb0d0f6b8, 0x468b5c67,
- 0x49225e62, 0x55c07df0, 0x5ea31f1a, 0x7f032bea, 0x9aebe37b, 0xa1b3cff8,
- 0xff27f6be, 0x78e90b9e, 0xe397f313, 0xdbf4445a, 0x1769e849, 0x2e3c37f0,
- 0x10695d99, 0xa61aeedf, 0x086fd138, 0xf3fcf5d8, 0x376e7cd3, 0x3ca21eff,
- 0xb771c56a, 0x37f90d2e, 0xe9e1f3f4, 0x6f5fe07d, 0x7e37bdf6, 0xf80c0a2e,
- 0x37b3f097, 0x5d9bd8fb, 0xc5f56e24, 0xe77fed20, 0x0f3951be, 0x870760ab,
- 0x0f5a79b0, 0xa5d6d6fc, 0xff7cf48c, 0x33b8e26b, 0xeb71c355, 0xf9db4260,
- 0xf9cbeb88, 0x40132ba6, 0x9c1eb42e, 0xe4ed741f, 0x722f7e7e, 0xafa99b3d,
- 0x2fac6bcf, 0x68c22141, 0xa2bc6eda, 0x6a420490, 0x22a3cf44, 0x6d5c6fce,
- 0xec1b887e, 0xa8d6b9b3, 0xfd3c6f30, 0x1a854866, 0xf385f1f5, 0xc0769e87,
- 0x9a656c3c, 0x863c79c9, 0xaab4b51c, 0x8f69d331, 0xf504af9c, 0x4275f3f9,
- 0xe7ce2351, 0xa35984d4, 0x3a719c60, 0xbb050f8f, 0x56a9869f, 0xc534cacf,
- 0xddda9c79, 0x09590dd3, 0x6017fe6c, 0x225b64f6, 0x3ed39bda, 0xcfffbe0b,
- 0x7aa7a7a6, 0x69087a34, 0xc0589f22, 0xacb2d39e, 0x51efdf9e, 0x0a8ba41f,
- 0xb34937c4, 0x37cc39fc, 0xaffff4ad, 0x12bd4086, 0xbd7ab5e6, 0x3cdfa28d,
- 0xd36f9e1a, 0x53bf47b5, 0xf857b5b5, 0x93bd67ae, 0x7b86bb48, 0xf957bf2a,
- 0x068af0fa, 0xc7ef53ab, 0xdef2ea26, 0xe753ba60, 0xc03fc2d7, 0x2411af71,
- 0x87255fc0, 0x5f64a75f, 0x0cda780f, 0xbf9843c1, 0x2abdec08, 0x51e29b4b,
- 0x015a5d51, 0x34f28b9f, 0xfe73abfc, 0xa9d4ed4c, 0x7a0265d7, 0x54a4be46,
- 0x20a9f2e5, 0x4c44cde2, 0xbf98bf34, 0x4569a8bd, 0xa75b8c31, 0x50fe6c4c,
- 0x301c4a46, 0x75272e3f, 0x3d4f10b9, 0xa0454c4b, 0x3bc9679f, 0xfa11b18e,
- 0xb0544e78, 0xf5ebc5d2, 0xdf9d3c7e, 0xeacbf2eb, 0xe4a5f9f5, 0x075854d6,
- 0x2641ba5f, 0x86ec0101, 0xe898fcbe, 0x91977ac4, 0x6e30759a, 0xbbc79cff,
- 0x94893916, 0xfaabe941, 0x17732fcd, 0x892e3a52, 0xd6d5fc6c, 0x31279771,
- 0x05662bfa, 0xff7d3714, 0xb7b1a693, 0xbf440b51, 0x7583ac0f, 0x71297f6d,
- 0xf2d1256d, 0x1bf4bafb, 0x81fcd5e9, 0x4e64f5a8, 0xe0834a47, 0x63b0c40e,
- 0x3d30248a, 0x6aeef6e3, 0x838ba9c9, 0x223e42e4, 0xf18df20e, 0x78744294,
- 0x067a2cda, 0x7e19e34b, 0xd4820f00, 0x4dbe78a5, 0xf55169fd, 0xfbf52d5f,
- 0x903fd627, 0xabab9fd6, 0x4a9ff73f, 0xfa28d0ff, 0x5fd5620b, 0x76179bf5,
- 0xa93da9f9, 0x0e67e978, 0x53c9c742, 0x8baa5d52, 0xeb72b5ca, 0x9a6e1d0f,
- 0x0efc949e, 0x80a9ebc0, 0xde4b1458, 0x76f2c3ab, 0xbb8805db, 0xfd693fc1,
- 0x11ff9fa7, 0xdf3e23c6, 0x9e313b2a, 0x990e60d6, 0x37563ea9, 0xd9262f2d,
- 0xf2c63f98, 0x21139e0f, 0xafe3d41f, 0xa59fd9e2, 0x8a0afec2, 0x0a5f1e14,
- 0xbd5b3fa1, 0x1c42d3e5, 0xea17489f, 0x683bf191, 0xda1252ff, 0x424a85bf,
- 0x13a53974, 0xce5e04e3, 0x8fd36f17, 0xf80e89ce, 0xdfce1b57, 0x7397ef8d,
- 0x14b974ff, 0xa36ed29f, 0x26409eff, 0xf8d43d80, 0x3fcc0241, 0x2fdcf35d,
- 0x7a518fb2, 0xdd796cce, 0x49f04421, 0x8df3a3d3, 0x47b57f8b, 0x76ded9ed,
- 0xf48b3d50, 0x4af1b483, 0xbabf720d, 0x7295a599, 0xd52d71c8, 0xb24dcafb,
- 0x571f4fcb, 0x33f4f0be, 0xf31c424f, 0x30d7668f, 0x178aff5a, 0x8937bc0e,
- 0x976c57e6, 0x37598a53, 0xb76a42ec, 0xfff4bc5c, 0x72dd39d5, 0x80f978a8,
- 0xcf628ea2, 0x96ea4fef, 0xfbed8ac7, 0x9a2a3215, 0xf71b531f, 0x18f66d2b,
- 0x563c6972, 0x9ac27e08, 0x814bfee7, 0x7da9e2f8, 0x199fe902, 0x0e9b9f83,
- 0x7c001fa0, 0x39723942, 0x7866e585, 0x02e54bdf, 0x93935af6, 0x6e46fcb1,
- 0x753ea04f, 0xc5f9e224, 0xf2fdb43d, 0xd05d993f, 0xef17f2ff, 0x4e3f4071,
- 0xd70c3548, 0x2a61fcbf, 0xd972afd8, 0x94c4ea9f, 0xea7f2f3d, 0x65b788bb,
- 0x15377f6f, 0x9dc449e3, 0xc7b1c26e, 0x5bfd0e9f, 0xf63671b2, 0x20f1296f,
- 0x297fcaee, 0xfa680496, 0xb68a4499, 0x0e8bd0c7, 0x362717ae, 0xf68c4753,
- 0x1fcc04ef, 0x23bf5ec1, 0x422abee2, 0xffa026ee, 0xa17de5df, 0x3fe6021e,
- 0x1d3930b3, 0xaf5c4c90, 0x8919b7a8, 0xb60f2dd7, 0x0f4e7c82, 0x7587f772,
- 0xfc912f16, 0x57c21f9c, 0xedf15eb4, 0x7c99fde9, 0xf2e52a88, 0x3f38e8ef,
- 0xfbc39e15, 0x9adbb2ad, 0x7c8efbad, 0xfeddd995, 0xa53ede2a, 0xe7c60e3b,
- 0xfdb1a913, 0xa6b201d5, 0x8e9c74f7, 0x7e8457c0, 0xf2df7d33, 0x4d6fd310,
- 0x45a503df, 0x30f17e50, 0x0ef81fd3, 0x574a3fc6, 0xef963fa8, 0x3da0259f,
- 0x58e6f3a0, 0xe645bd7a, 0xd72fad7a, 0x96e94270, 0xbc088484, 0xc849fd40,
- 0x595f5c7f, 0x177e81ba, 0xd0bd2f61, 0x3eba239e, 0x71976f4d, 0xfa053ffd,
- 0xfeb74d7f, 0xef4c8d93, 0xfc9ff67b, 0x07236e2c, 0xf412799e, 0x5fa7ea95,
- 0x4b957d05, 0xdd7fdfa0, 0xeddef2d6, 0xdaff4f54, 0xdea9e9a8, 0xb4f51a7e,
- 0x1278c77c, 0x6aff4f4b, 0x7a989177, 0xd4c79f4a, 0xe21b7b53, 0xfd94fff8,
- 0x2897f8d4, 0xd9a7f9eb, 0x68f89ec3, 0x4a2f87b4, 0x68d3f22a, 0x61dfe90f,
- 0x3f8d1b92, 0xde1a770d, 0x755d7e2a, 0x309dd805, 0x85dc352e, 0x2ee1a971,
- 0xe3ab7e2a, 0xcffcb19f, 0x74a26b10, 0x4fd4b7cd, 0xa5847981, 0x2bbce08b,
- 0xeb88967f, 0x048b96a6, 0xc880bef5, 0x7df06fb8, 0xf078cd53, 0xfdfca743,
- 0x52f7b3b6, 0xbf13e77a, 0xebe5d6cc, 0xbfebf464, 0xc9abeafc, 0x73b73fb4,
- 0xeca7cefe, 0x63ca89be, 0xe28424ae, 0x24f39d28, 0x82484fe2, 0x3e40acf8,
- 0x7e63a08e, 0x7f0f3eb9, 0xebbb5253, 0xaffdede9, 0xa6f90f3b, 0xb63edbe9,
- 0xa42ef576, 0x2979b143, 0x20a54f12, 0xef3fca57, 0x04302138, 0x549b52ed,
- 0x7aaf3112, 0xb79ddb9c, 0x0f1ccda7, 0x9cfe4bfe, 0xe70c0951, 0xeb7e7183,
- 0xbcebf6e5, 0xbb004d5f, 0x0b39be7e, 0x0fe7afe7, 0xb58f8e2d, 0xe385b26f,
- 0x575f00ec, 0x750bb4e9, 0x277dc522, 0xc5ff42e9, 0xad92b76f, 0xbefdd631,
- 0xe4f89b2f, 0xfe8dcb83, 0x736e5489, 0xd1e70e39, 0x2272134f, 0xa6eb36e4,
- 0x5a239253, 0x71f7f00e, 0xdbeb3cc4, 0x0d7017f2, 0xb6b16dfc, 0x88c49615,
- 0xf384fdd7, 0x5f2bca6f, 0x69d5fee0, 0xf012f9cd, 0xd45d9a71, 0xd41e39c5,
- 0x192475f4, 0x794d7409, 0xe3a3f965, 0x87bd8e29, 0x57ec1744, 0x539f36f5,
- 0xbbe6313c, 0xfd427e46, 0x901e47e0, 0x23afc89d, 0xe012c972, 0x56d991eb,
- 0xef96eb02, 0x58aaae2a, 0xb3374e74, 0x523cc878, 0xe138d9f2, 0xe6fe3eff,
- 0x150f89cf, 0xb79c7e50, 0xd1c0fdb3, 0x7f7a63f8, 0x6a0429de, 0xc8a1c005,
- 0x004229f2, 0xc48564e2, 0x0164e8f3, 0x48fafdf5, 0x2c1f95fb, 0xd5f6017d,
- 0x4e0b3754, 0x96af2d13, 0xb1c014da, 0x025db837, 0x9546fcff, 0x20de31b8,
- 0x159a8cd5, 0x203ad711, 0x96afc84b, 0x277eddbf, 0x2cc2f7f0, 0xdcba0133,
- 0x6039cf23, 0x3cd0bfdc, 0xa7a0f516, 0x47c1fd7e, 0xa0934ca6, 0x30f8821e,
- 0xc530a1e2, 0x9ecfcba6, 0xa8ba064a, 0xdb98a6dc, 0x90c571ee, 0xe18532df,
- 0xcdf6cfac, 0x7d99fff2, 0x1bed4c9b, 0x691cb5c3, 0x512b46df, 0x2c7fadf6,
- 0x56b2b6fb, 0x58b80fed, 0x3fab37b9, 0x6be575c8, 0xb2c5fa4b, 0xd8faaf6f,
- 0xbe35fdfc, 0x2073bb0f, 0x23a36fb5, 0x6a40dbec, 0x6dc462df, 0xffcd15d3,
- 0x59bec5ec, 0xeff477fe, 0x316fb055, 0xd1523bfa, 0xe6a2b7db, 0x456fb45a,
- 0x7edd4503, 0xcf852ca8, 0x6fb47ae7, 0x1b367f0b, 0x16cbb2f3, 0x57c03f03,
- 0x71af6fb0, 0x80ed073b, 0x38a45b9d, 0xdabefdb1, 0xdabed2b9, 0x3e25ffb9,
- 0xe56e766b, 0x239e7620, 0xcecc871a, 0x7664ccad, 0x665ee56e, 0x630e56e7,
- 0xdf68ce76, 0x1beca20a, 0x047abefb, 0x8be71efd, 0x83b8bf99, 0x95cf1796,
- 0x7efa165d, 0x5f9daab1, 0x691f19a8, 0x122916ef, 0xdeca39f2, 0x39e1ceb9,
- 0xddecde90, 0x86ef605b, 0x0a1b1da2, 0xc7c4647a, 0xba6d430d, 0xbe4772fd,
- 0x4bf5ff68, 0x107f2fa0, 0xbefd9e71, 0xf68bcd89, 0x163ed17d, 0xa7376ef4,
- 0xc98551e7, 0x47e7c3b3, 0x24753a7b, 0x43aaf7d3, 0x544e3871, 0xbfac0937,
- 0x15010bf7, 0x5dbf81c6, 0x9df2f9c2, 0x797cd97b, 0x83f1998e, 0xcec89bfc,
- 0x2c16505d, 0xdcc3c08c, 0xd718154b, 0x0b112b9c, 0x0e0baff8, 0xfc0a70dd,
- 0xd69705d6, 0x00bbbfa3, 0x89bec39e, 0x32eb6ded, 0x2e77bb68, 0xa1de7017,
- 0x1798efed, 0x3f7a97b6, 0xec737e76, 0x38531a7d, 0x13ee533d, 0xa72fb002,
- 0x2f107db7, 0x239bfd72, 0xc8bf21b6, 0xf8cc625b, 0x985ef6a4, 0x97c62e4f,
- 0x6fcc55aa, 0xf289f30e, 0xf9a2154d, 0xbc5d2544, 0x2f9bb530, 0xfda4ee77,
- 0xbfb9e94d, 0xf7a2df1a, 0x3e71b8e1, 0xd7bf80b3, 0x3e341f13, 0xf39ff547,
- 0xb8a9fa9d, 0x8fc8c79f, 0x5ccecd46, 0x5e814643, 0x3cf26fbe, 0xf4701e3a,
- 0x942f949f, 0x0de6dbce, 0xd9e79dd3, 0x9372f9c5, 0x54b4d8e7, 0x6a48f815,
- 0x97b76700, 0x4a903f6f, 0x3b8b77fb, 0xe6420733, 0x78a6ffb3, 0x62d0fe20,
- 0xa83b42ed, 0xcccd30e1, 0x8e57f870, 0x9c0323c3, 0x09bc70d3, 0xafd44e0a,
- 0xf1cec190, 0xca5e647d, 0x6f5fd067, 0x144f8f90, 0x859fa09f, 0x720578da,
- 0xa9bcffa1, 0x5bc5c999, 0x6e5ca023, 0x81075d26, 0x8229d5ef, 0x2aab442b,
- 0x21ff6e0c, 0xd57ab7ec, 0x9e839f4a, 0xcdae0b97, 0xf4f61d8c, 0x963898d4,
- 0x3718e162, 0x9b8c4609, 0x24bde00b, 0xc668b7d8, 0x1efceff6, 0x3f4647b3,
- 0xf5b98a65, 0xe533d008, 0x09b264df, 0x7fe8061e, 0xfa303811, 0xf07a5131,
- 0xa4fdf735, 0x2afdfb72, 0xfc0ec1c8, 0x1fc052ee, 0xf8d886f2, 0x257b95a3,
- 0x4df21a75, 0x8e904393, 0x1c98e32f, 0xc8dfa960, 0x3cb45be7, 0x6fde1fe0,
- 0x7ef86416, 0x324f9506, 0xfa6a9a2d, 0x7786a0e2, 0x2fcd1ab3, 0x47a42788,
- 0x6fb00dd8, 0xd596eb91, 0x4f91b7c1, 0xeea2ac37, 0x27cd1a99, 0x07603e4d,
- 0x28afc72f, 0x8fee09fd, 0x9bea7fb9, 0x599a4fea, 0xacfb3faf, 0x868faf5d,
- 0x015eda38, 0x4e690aed, 0xf20fc5d4, 0xd65e6ccc, 0xce20f562, 0x5d935ebb,
- 0xfb68d59b, 0x0b971573, 0xcf2257cc, 0x0e854def, 0xd3b1bac1, 0xfad13e4a,
- 0x2ce1843d, 0xd5783c72, 0xf5f941ea, 0x5e04ff54, 0x98fe4f7f, 0xb40eff96,
- 0x5516fb07, 0xf1c67b7d, 0xf5278b48, 0x6669afd6, 0x69be3f66, 0xbe76b4bf,
- 0x9783baee, 0x4dfc62b4, 0x2cd87f5b, 0xc32e7e7a, 0xd048b8fc, 0xca5073ad,
- 0x9ff2fd71, 0xe558ff50, 0xfc43f532, 0xfcf94428, 0x31a7b6ea, 0xf9f67d5e,
- 0xfe833763, 0x48adf8ac, 0x3a9f542c, 0x1093c5b6, 0x80a207db, 0x24d1509f,
- 0x91167ae2, 0x2333b942, 0xd6420cfc, 0x14bc7e30, 0x62a7768f, 0x4c503987,
- 0xf5d8afbf, 0xddc43649, 0xf6601e3a, 0xc73cffcf, 0x1b2dbfa3, 0x242bfbd6,
- 0x946f8eb6, 0x9f1cbdcf, 0xe6db7667, 0x1a16fd82, 0x8ad779d8, 0x39b239c6,
- 0x6550ce22, 0x7b5c5996, 0x59f70db7, 0x70139ffb, 0x17d0329f, 0xdb52ce79,
- 0x39e679ff, 0x822b9766, 0xcdce0072, 0xef6c3456, 0xc5783880, 0xaffa3351,
- 0x0a7386de, 0x5f53a7f8, 0x23fd017a, 0xc5d4506f, 0x8fe2a341, 0x0cc8620d,
- 0x2aa6b3f1, 0x7f3403b4, 0xb18df30c, 0xc5bdf0e3, 0xb4bc56c9, 0xb29f9777,
- 0xcfcbc570, 0x6cdcf03a, 0xc60756eb, 0x1f2e1b21, 0x378a8fff, 0xd9743e36,
- 0x8e69e378, 0xf5995f8f, 0x21a435eb, 0x9490e319, 0x1892dcbe, 0xee308b71,
- 0x29ecf85f, 0xb33b0f58, 0x014fafe3, 0xb8ff95bd, 0xe07dd4f0, 0x3ab3ed8f,
- 0x3ef6bc61, 0x13d7047f, 0x7376efb4, 0xee78ef3d, 0xe9875c59, 0x05d9a3f8,
- 0x3dec75b5, 0x23d61831, 0x917fb63a, 0x55db710a, 0x3ce3a77b, 0xa9ced56d,
- 0x798c49fd, 0x6e029680, 0x07587d03, 0xa5abca32, 0xd03065a9, 0x1bca9679,
- 0xfc70b65c, 0xc58ab1b8, 0x371e55e3, 0xbd7b16de, 0xdc4e2a2d, 0xeb96f334,
- 0x926efc60, 0x43e92a5d, 0x9530f8bc, 0xc83ee8e3, 0x9a43db6f, 0xbf298fbd,
- 0x2a0ff0b3, 0xf20df7a7, 0xc969acfb, 0xb2849eaf, 0xe31ee4a6, 0xf03ea1c5,
- 0xdbcf5b4d, 0x6c7f7662, 0xf1d9bd06, 0x83cf8c6b, 0x835ce8dc, 0xd9f0bc74,
- 0x9cb38860, 0xc2eebb94, 0xcd7b33fd, 0x62aa2fb8, 0x3fa8fbef, 0xc6df3b1d,
- 0xd7c232f5, 0xf8483ad5, 0xf083ad8f, 0x4b779c39, 0x73338b3c, 0x5a1c43fe,
- 0x1e73e075, 0xd638666f, 0xc53dd0e2, 0x6c2dd39f, 0xceb6913f, 0xcfe5b558,
- 0xf5c4310a, 0xd3903c85, 0x8baecbb1, 0x02707c6a, 0xae44261f, 0xf38ec4a7,
- 0xb8ddd787, 0xe07e40bc, 0x4bd7857f, 0xc4207e68, 0xfbc203cf, 0xe83d8624,
- 0x61d6c4d8, 0xfbd8e43a, 0x95f5b50f, 0x4f418b14, 0x575b7d03, 0xaffe8de9,
- 0x26191fcb, 0xf9a3e39b, 0xd8cbe674, 0x45827c76, 0x61fb76f8, 0xf5a8852a,
- 0xcfac0b7f, 0x60531d37, 0x638da1fe, 0xf0cf7f5a, 0xe799f279, 0xb1ef3c45,
- 0xed05b1ae, 0x545ed1b8, 0x341f1613, 0xd3833bd2, 0xe3641d5b, 0xf11d99c4,
- 0xe7ad3b01, 0x11bb2bcc, 0x8edbd5cf, 0xdf5a7e29, 0x959786c1, 0x52fd88b6,
- 0x22044e30, 0xe2f33fe8, 0x7eb66cfe, 0xc6e5e6c4, 0x76f0e676, 0xdbb1cdbc,
- 0xa73b6ef1, 0xbf85676b, 0x77e76151, 0x69dedf2e, 0xea073dc9, 0x132add3b,
- 0xba7fbfd8, 0xc40a2c51, 0x45927f68, 0x4cf2e2d6, 0x8978e86f, 0xd9e31de7,
- 0x493146f9, 0x557aff41, 0x84d1de7c, 0x15154814, 0x6a6b14e2, 0x35d2fed9,
- 0x81a577df, 0xde24d7bc, 0x756deb86, 0x533afe06, 0xbf10f99c, 0x192b4e70,
- 0xda357007, 0x49b7449b, 0xf8aaff47, 0x1e70fea2, 0xc7f72d7f, 0xf3c2e488,
- 0xb0a3a297, 0x3a23fa08, 0x8c6b4e4d, 0x5ed905f5, 0x7c113c42, 0xf3fa9d91,
- 0xb1cbe492, 0xeda3d42a, 0xb4b4a9a3, 0xa742c41e, 0x4b0ab71b, 0xfcddec79,
- 0x77ec4e59, 0x4f3e36e7, 0x99d51370, 0xc183f6ca, 0x23b9d1b8, 0xc68c9b21,
- 0xe29b890f, 0x0b9fc6d1, 0x07eff6db, 0x41d6b47b, 0xcf5489dc, 0x31555728,
- 0x8e8dce0b, 0x805908b1, 0xfe6f73d3, 0x6d6bd696, 0xd0fe7116, 0x85f6d769,
- 0xcf4113ba, 0xdc11e46c, 0xfe5007ff, 0x4e9bb92a, 0x0240bee3, 0xdf76a4af,
- 0xb45d312b, 0xfce7bce3, 0x10071646, 0x98bfd5c9, 0x2470e2cc, 0xf1f3f400,
- 0xf3a70564, 0x7ef0a43c, 0x3ae78299, 0x72f6bd96, 0x3930886e, 0xb92bf244,
- 0xb4be7f48, 0x86c8eade, 0x77e27975, 0x9939c2b7, 0xbf5f5e32, 0x53b9fd12,
- 0xd07e7eaa, 0x4f5c25d3, 0xf0b4baff, 0x32bfd810, 0xebb452cf, 0xcfeae7fd,
- 0x59f71aa5, 0x2fb0bd21, 0x93ddea8c, 0xabbef442, 0xd6c7e6f2, 0x7a397cc1,
- 0x011915ff, 0x482ac9fb, 0xe7ce0b9c, 0x97d068ac, 0x79bb03ef, 0xd893b015,
- 0xebef172f, 0xc36dbf95, 0xdc79317f, 0x0aebf965, 0xe2dbfbc1, 0xecb2ae31,
- 0x9f68c5b5, 0xfe7a69cc, 0x7f3d555a, 0x7c8c236d, 0xde39f3d4, 0x369be7a5,
- 0xcf89ecff, 0xf3fa7909, 0x4b3e46be, 0x021bc784, 0xb5110e2c, 0x09b82dbf,
- 0xd9f236e9, 0x0b76d7c8, 0x7ce2f75f, 0x96257fa5, 0x81b26654, 0x842974ee,
- 0xa3d4617a, 0x80487b0c, 0x094a0f7f, 0xae57e2d4, 0x69efb478, 0x19423fbc,
- 0x7a06cefb, 0x2ebd0224, 0xd13823d4, 0x46de7607, 0x5bb6703e, 0x909f5841,
- 0x59e9aeaf, 0xfe94f79e, 0xfa22d8fe, 0xefc046d5, 0x762bd468, 0x0489376e,
- 0x9e8264d6, 0x6e309cba, 0x6a2cfa37, 0x9ff70499, 0x286cb510, 0xc4e27bdc,
- 0x1f7cc7f4, 0x8248e74a, 0x431b82fb, 0x3ec15317, 0xeba738fd, 0xde7bb066,
- 0xec04a425, 0x6c71cde0, 0xa798b29e, 0xdc2ab77f, 0xed7b4eae, 0x59bef87a,
- 0x785ce156, 0xcb56f367, 0x4507c830, 0x9bc47fbc, 0xb4157758, 0x332cd1df,
- 0x812ccaba, 0xd8bf1061, 0x1dbb632b, 0x7cf19365, 0x6b6fd865, 0x3a40fb66,
- 0x2c713f9b, 0x1de7b08e, 0x055e9fc1, 0x4c27acf1, 0x0c9ff7b1, 0xfdf89ab7,
- 0xfc70df35, 0x7fda8c6d, 0xf6cadc37, 0x0878fdc7, 0xe97547ed, 0x330e3e79,
- 0xcb96b87d, 0x6f4bf7f9, 0x6ceffec0, 0x47185416, 0x6e3bc50a, 0x39fb451c,
- 0xe3c488f1, 0x392e2c30, 0x9bbfbf8e, 0x1f80d2b8, 0x0223af13, 0x3fc4f3e8,
- 0x35b7dc12, 0xce2966ae, 0xa0eb7eab, 0x7586cf38, 0xb05b8a52, 0xe8ec6773,
- 0x956f8fbf, 0x9c4cb874, 0x798169e6, 0x04a384e6, 0xa384eded, 0x123cf2fa,
- 0x369db110, 0x4f6bf3fd, 0x5605f3ea, 0x49076f8e, 0xf86f7c05, 0x3aba4452,
- 0x01eb88bb, 0xd9676f5a, 0xa6efbc00, 0xda9c22f3, 0x6297e9a5, 0x7e71ac51,
- 0xf281e026, 0xe08509eb, 0x52c4f2f8, 0x5fefc63b, 0x05715a59, 0x7f9feb8c,
- 0xac4573cf, 0x7611e073, 0xafed8129, 0xe2502772, 0x0ad7ae29, 0xe975df8c,
- 0xebf63125, 0x70d6386b, 0x7d39e1ad, 0xd6279c69, 0xad0fc4be, 0x58290fcc,
- 0x6050423a, 0x204fb65e, 0x078ed7c0, 0x373d973c, 0x640f27e3, 0xe0de3d00,
- 0x2db3f405, 0x963b82cd, 0xeacab19f, 0x07bef360, 0x1fb0b5fc, 0x94aa5eef,
- 0xae7b1f60, 0xabce0377, 0x2ba0876e, 0x5ba9677c, 0x9770e788, 0x8866c858,
- 0xe9754b67, 0xee03c6b7, 0x4758cea7, 0xc4b27de9, 0x427e7284, 0xfefd2176,
- 0xbe30422a, 0x03b5e3c0, 0x229b266f, 0xc0ff23cf, 0x95b0ff9a, 0xd5b0fbd6,
- 0xf6497289, 0xdfa004b8, 0xe5ffdff5, 0xbceebd00, 0x0e394664, 0xed1ff3e0,
- 0x4f9cadbb, 0x6bdce3a3, 0x3ca4ff01, 0xe5c3f505, 0xc965a871, 0xe5012f70,
- 0x54758c7b, 0xf24d2fcd, 0xe946db50, 0xf09bb249, 0x76e22e7e, 0xdf6d4eab,
- 0x45efe119, 0x090903e8, 0x69a5f604, 0x166854f6, 0xff14f142, 0x10f62ce3,
- 0xca9233cc, 0x0929bf69, 0xf5616256, 0xc2674ab5, 0x9f71aae7, 0x2e65c53b,
- 0xb8226e1c, 0xd2360daf, 0x9d9afd42, 0xdaf3ecd5, 0x66f68244, 0x605263ed,
- 0xa367ad0d, 0xf88566d4, 0x2d5ba649, 0x4944ad80, 0xbde78a92, 0x7d339507,
- 0x32fd65b4, 0x50afec31, 0x0ff31f65, 0xf5ac4171, 0xfcc38fba, 0xfc00bcf2,
- 0xf5d43eca, 0x2e35b80a, 0x75cf6b2b, 0x79fe82c0, 0x3f706ed8, 0xbb8f90ac,
- 0xb1353f13, 0xeba102fd, 0xb69dbf71, 0x1bb4668e, 0x15de0f54, 0x953eaf41,
- 0x75cf9e08, 0xb572ffd3, 0xf611772d, 0xb9938f83, 0xf4169ac1, 0x2d91c4dd,
- 0x5f6bc780, 0xa238bbc7, 0x3784c8ec, 0xde806b3c, 0x8c3f6a6f, 0xa2131878,
- 0x33e5c8fa, 0x2a7b8552, 0x943ce19c, 0xfcf95ab7, 0x949bdb8e, 0xd1fd71d2,
- 0x3338e5af, 0x6bd357f2, 0xace7bea3, 0xb198b576, 0xc13200d6, 0xba110ed8,
- 0xc0b350e9, 0x8221bd1e, 0x4f99df7f, 0xbae942f1, 0xfc0ef417, 0x19818bf3,
- 0xcd0d9b80, 0x7e82b1df, 0xa3f1e37c, 0xb11d7e99, 0xa227fabf, 0xf6cac3a7,
- 0x0f803b87, 0xf22ffbd5, 0x728423f1, 0xea95cb0e, 0x443c6447, 0xe711bdc3,
- 0x81ac5e9a, 0xf0b2330b, 0xf9011c7c, 0x0a234288, 0x3a364cd6, 0x7f9aaf81,
- 0xcfec26bd, 0x9eb9e226, 0xded64e55, 0xcbf3591a, 0xefe8165d, 0xfe82f8aa,
- 0xf5175b97, 0x97f3a25e, 0x5e30f388, 0x67e70ba9, 0x090a4bde, 0x7e0b7f24,
- 0xb9eb6905, 0xc4a57e3a, 0x0757e0c5, 0xfff8d1e8, 0x6d93fb27, 0x6a83cfec,
- 0x25ae7f77, 0x51b6df9e, 0x4f7b90bb, 0x05c33a7d, 0x89169c39, 0xd95ebe0b,
- 0x51e77e93, 0x2dd706fd, 0x7a0d9f4a, 0xea99b13c, 0x8f5a29b1, 0xde09725d,
- 0x6bdae75b, 0xd4677b43, 0x5fbc8beb, 0x7be31b5e, 0x1199e88d, 0x5371f307,
- 0x5dc060d7, 0x8b924ab6, 0x41d9b129, 0xb6afad91, 0x91c6eb26, 0x8fddf1e8,
- 0x2ff35276, 0xf8d2bf35, 0xe4afd85e, 0xcf1686e3, 0xff148214, 0xc7f7dfb4,
- 0x5f01e679, 0xfcd938d7, 0x829a0e13, 0xab03fcbf, 0xcfa00ee7, 0x0710fb46,
- 0x42231aeb, 0x125e2c99, 0x4f5be9d2, 0xe83365fa, 0xc248634f, 0xc74fcc71,
- 0xcf4261b1, 0x4b8bf4f4, 0xab52f464, 0xc0ca7e02, 0xab1ac25c, 0x7bafb826,
- 0x47bb3660, 0xbb0e6066, 0xe3dff1f7, 0x7dcc7ad8, 0xd0dc6c71, 0x4b581fd2,
- 0xc97e81ee, 0x739bf112, 0x40dd39be, 0xef0fc42a, 0x0ddf738f, 0xb914b0fc,
- 0x4e191fb1, 0xde2812e2, 0x0146a432, 0x552437f6, 0x1b8b02aa, 0x40ee3612,
- 0x28cbeb4a, 0xdc61f356, 0x16b6a0ca, 0xcd1920e2, 0x6cf5cfb1, 0x5dbf9388,
- 0xea29abbc, 0x3886ca3c, 0x541f6fe6, 0x8b937f68, 0x709479d9, 0x0f9286dc,
- 0xbf88edfc, 0xf1db3b0d, 0xf50f5b19, 0x1b3e3227, 0x30205fe7, 0xf3c497e8,
- 0x6488543f, 0x91f9c24d, 0x99df04df, 0xb23f382c, 0xd8235711, 0x58e297cf,
- 0xe09d755c, 0x9ff90f5a, 0xb8165d48, 0xffc3476f, 0xeadf278f, 0x8e2be892,
- 0xc367ceeb, 0xc3ea959c, 0x8eaf20f3, 0xaf87e7c9, 0x0d741ec5, 0x8b737866,
- 0x9aeffdba, 0x4eb282dc, 0x8788566e, 0x78ebda44, 0x1df7e705, 0xe60b9c42,
- 0x05cb1d43, 0xe160a746, 0x7d2403e7, 0x43db869c, 0x27781c6d, 0xb7e9132e,
- 0xbc18ff11, 0xb2e2cc1f, 0xfd1a3d00, 0x86a473e1, 0x73c69e73, 0xe15969a0,
- 0xee3a4db8, 0xe0512d93, 0xbe722f8e, 0x97fe86d9, 0xdff4c1d7, 0x60fe8788,
- 0x6e732e3c, 0x15abf292, 0xae5fdbe4, 0xdb7b0449, 0x0ee3ceff, 0x0f91af90,
- 0xcc7f829d, 0xfadf5841, 0x9f731c83, 0xa5a69688, 0x7f05280d, 0x0d3d2d34,
- 0xbd79ed53, 0x07198a5d, 0xeef5cd3c, 0x9eb5e31b, 0xc3f30c58, 0xb39fd0d3,
- 0x73de779e, 0x6177baa3, 0x8e3ebc7c, 0xd15ebbf1, 0x8026a8f8, 0x5de7759e,
- 0x927eec09, 0x90ff7644, 0x8373c993, 0x492a52cf, 0xd1b9ef91, 0xdc47e91f,
- 0x1181e633, 0xad9320d8, 0xbf166b88, 0x5065ced1, 0x97e4c743, 0xb9fae8c8,
- 0xec294c6f, 0xcc6d919f, 0x30dc5d2e, 0x254bdb1d, 0x5387580f, 0x312d2ebe,
- 0x73ae20b9, 0x1c9fd176, 0x517c1470, 0xe02e6b46, 0x91e888fd, 0xd431e36d,
- 0x65b7f38d, 0x88409573, 0x9ea52a42, 0x9726241a, 0xb8eeb819, 0xff7314d0,
- 0xe6c6ddb3, 0x4e71cddf, 0x06d2d34c, 0x8d8d9697, 0x39440fcc, 0x7aa47869,
- 0xae365e98, 0xc5309cfb, 0x6fb40a47, 0x994ea7d4, 0x40dd6104, 0x9c2987b3,
- 0xd63d9aff, 0xf40521f4, 0x4b01d60c, 0xe4d47da8, 0x9abf8439, 0xfc4af18a,
- 0xfd5f9a13, 0x8e03e602, 0xded00aeb, 0x8f5ffd51, 0xd98232fa, 0xd3d82b6f,
- 0xe7653888, 0xc107f7de, 0xdf87dffa, 0xeb0f10bf, 0xba917f40, 0x9e7ec1e2,
- 0x78ddffbc, 0xe1f43738, 0x715e2cfd, 0x351e6197, 0xfaecc6c1, 0x6c92b6a3,
- 0xdf02d7e8, 0x227ae77f, 0xb3564970, 0x01e58d75, 0x5c9e70d1, 0x554f2f7f,
- 0x9ee1b263, 0x5bd63f1e, 0x32e7efc5, 0xcb92a1ca, 0x4db6f961, 0xed0a864a,
- 0x7eb6dc7b, 0xa08f6e70, 0x14d93cbd, 0x8d11f38f, 0xc6db459e, 0xfa773028,
- 0xaf99b34b, 0x6ccab77f, 0xc317705c, 0xf387967a, 0xc1e748cd, 0x6fac367d,
- 0xfed8cfc9, 0xadb48594, 0x7abed4d5, 0x0b79d99a, 0x7c963f63, 0xa7f616a8,
- 0x90f25bc2, 0x7862f380, 0x4e3a7eff, 0x883f5679, 0x7ec65eeb, 0x31cdef1a,
- 0xe6d55f9e, 0xfcb8cb53, 0xf50788cb, 0x6b5cea2f, 0x369f5b33, 0x1fceffc6,
- 0xff61b2ca, 0x91fe3c6d, 0x79c0264b, 0x86871de8, 0x3eee5c24, 0x1efc33e5,
- 0x1a57b826, 0x823e93d2, 0x654db669, 0xbf3464f7, 0xaae02f7d, 0xef1db83a,
- 0xf6bafb19, 0x94f9aaa6, 0x6b30f603, 0x91fa8776, 0xa43f01ab, 0x97f9d04c,
- 0x282e9bd5, 0xf8cbbe6c, 0x7e7f0770, 0x1b37f407, 0x3fab59f6, 0x7ce54c9a,
- 0x317ca547, 0xbf321ef2, 0xa6ee7f4d, 0xfad5fdaf, 0x2b5bf5a9, 0xd1fbe2af,
- 0xf869df8c, 0x2c78e6cf, 0x6eba52db, 0x9ad16500, 0xf30627bd, 0x4e7868f3,
- 0x1197c347, 0x4948cb3f, 0x8110ba61, 0xb147e693, 0xcb3c9a5f, 0xfef216ea,
- 0xbaf8d3fb, 0x8fc41a5e, 0x118dc37a, 0xdb721d1f, 0x2367d060, 0xb87a3a3e,
- 0x3627e45f, 0xa99427e6, 0x678842ee, 0x9d763751, 0x394fc233, 0xbc1dd529,
- 0x0b6cf40f, 0xf8c479c3, 0xd7b99ccb, 0x57cf1c65, 0xe1fdabc6, 0xdb943d3e,
- 0x6017d844, 0x5a7bc3f6, 0xb73eed3b, 0x7c04a86b, 0xb4f4c22f, 0x7435c4af,
- 0xd2f97768, 0xc0382e27, 0x411cee8f, 0x11d38e30, 0x77f7a7af, 0xf9e91136,
- 0xa543971d, 0x3f8ffad4, 0xd2da8d83, 0xda1dfb8a, 0xa071e4bf, 0xb145cd2f,
- 0xfe27f9fa, 0x86f7e11d, 0x4cf5c5dd, 0xe02c979b, 0x99abbb72, 0xda2f67ad,
- 0x30f28a58, 0x437ad7ee, 0xd0661670, 0x638d3caa, 0x51bf9014, 0xdf5c4b3e,
- 0x51607dc1, 0xf08f2272, 0xdc1e017d, 0x2f5653a7, 0x28c3dc62, 0x93bb7cbf,
- 0x6b57a39d, 0x42b71e70, 0x790ebd8a, 0xb5f4dda5, 0xc7ec63fa, 0xed0126c2,
- 0x65fe91a4, 0x0dd76a5b, 0xd67fd020, 0x847ee8bf, 0xe25da206, 0x55fad4fd,
- 0xff785c46, 0x50fad440, 0x7224f5db, 0xe6f2f53f, 0xbf2fb8c5, 0xb09ff69a,
- 0x85c61238, 0x7a35fa34, 0x1428fd8d, 0x8816c8cf, 0x5c16aee3, 0xefa39f60,
- 0xeeeb7327, 0xb0d85c3f, 0xafc8207f, 0x66fb625d, 0xce02fddb, 0x203f3b0b,
- 0xbd607d6c, 0x3d69eb80, 0xed99afca, 0x8e59ea07, 0xe7dc0a35, 0x8851b657,
- 0xf565c729, 0x11a1aef9, 0x60796a76, 0x8ea86b86, 0x1fdc46de, 0x54a1a2b2,
- 0x9d807cf7, 0xfdb893c7, 0x48df4dee, 0x38cc624d, 0x9a5fa693, 0x97fa69be,
- 0x3cd9576f, 0xcc1c0a47, 0xfebb04c8, 0xa84bce18, 0xcedabe5d, 0xd1e607d7,
- 0xb89faa57, 0x581f5ba0, 0xb3e4c792, 0xe7c62c44, 0xca57d93d, 0x1e7d9d07,
- 0x7fefd767, 0xd1fdb6f8, 0x85e9a1fa, 0x5ea33fd6, 0xc5aff918, 0x30728cd5,
- 0x82e81ff2, 0x7b1bc1f9, 0x0407816d, 0xa74677d0, 0xe915af7f, 0x702b48ec,
- 0x3fc839c1, 0xce9407c0, 0x31dbf4ea, 0x9496235f, 0xc75e71da, 0xfae34de7,
- 0xe1c83f16, 0xab4ed67e, 0x473b2c7b, 0xb80c9254, 0x36db5298, 0xf8a4e2d3,
- 0x2174647c, 0xe53a2bdc, 0x1099b6b1, 0xc8f25efa, 0x5fb84298, 0xb6d6ca7e,
- 0xea2e2d77, 0x2d8ed5d7, 0x57e5fb84, 0xf680dd80, 0x10db9607, 0x89e53d57,
- 0x9579f2e7, 0x5cce3fbd, 0xcbdd9f32, 0x292bcacc, 0x3c742d8f, 0xfc3c3cab,
- 0x959fa0f7, 0x1045c5ad, 0x8884a9b7, 0xaacf1d37, 0x2d908edc, 0x93e78d9b,
- 0x6cdb7be8, 0xf076559e, 0xc5ad2eeb, 0xb0f2adf1, 0x0e44fa84, 0x44a8b8b1,
- 0xdfa56afb, 0x7ea38dad, 0xdaefe52f, 0xe60b8b24, 0x1fb9f4af, 0x936bb5e6,
- 0xf11aaadc, 0x7c1f935c, 0x35ac7407, 0xfdfb75b1, 0x684f0daf, 0xbf78ccbb,
- 0xc32647df, 0x67c5a43c, 0x9e58d4c1, 0x7cf138af, 0xc589be44, 0xbfe58c35,
- 0x512cecd2, 0xd5170033, 0xaf161487, 0x4fe07fa6, 0x17a61156, 0xeb9d84d5,
- 0xf04c3aaa, 0xa1f54b1c, 0x02c73c42, 0xd63ffcfb, 0x735ff0e1, 0x571ba58e,
- 0x92054f8c, 0xc08a5930, 0x55bb34f5, 0x9bfb1797, 0x887f4046, 0x7382e718,
- 0xa9866218, 0xbfed0766, 0x294d0578, 0x4ba7243f, 0xea5afb84, 0xe1114ea6,
- 0x3235a9be, 0x62623fdf, 0xf6b5cce7, 0xb47f389a, 0x64bdb4f4, 0xecfdc807,
- 0x36b9ad5b, 0xf3817eb6, 0x6bbfad61, 0x60113704, 0xe08075de, 0x149c80f9,
- 0xb3fc02d2, 0xe01e7711, 0x127b3ded, 0x375b37e7, 0x90197fa6, 0x97a6ccba,
- 0x57f78a55, 0xfa84591f, 0xdd304ae0, 0x6ff34993, 0x7cb197d9, 0x2642e986,
- 0xf6dbf085, 0xc6bf9672, 0xcd086174, 0xce5f6bbf, 0x49c0b0f2, 0xf623b607,
- 0x48ff428a, 0x7de38768, 0xc01afb9b, 0xf16264b7, 0x0515e917, 0x7db453d7,
- 0x44e96b21, 0x1ef8f00b, 0xa7884dd8, 0xdafc16d4, 0x02eaf106, 0x3dfb0ab7,
- 0x837bf336, 0xf1aa69be, 0x7099b455, 0xf02903fe, 0x4fce43ff, 0xc9a42e4d,
- 0x8bec0d7d, 0x6bee8d25, 0xb4ed1d60, 0xf606d3dd, 0xad1bec66, 0x377ec053,
- 0x5ca7f3bd, 0x0afc9fbc, 0x37d8cf56, 0xf6909ce8, 0x066fece7, 0x8f5c8a6d,
- 0xffcf6d3e, 0x62a3be14, 0x5054ff40, 0xaa0ee49d, 0x44dc6b87, 0xbe60b255,
- 0x362f9fac, 0xb69f6611, 0x82ce4ad9, 0x10c0c95c, 0xf6455b8e, 0x6bc84e92,
- 0x26b49cf6, 0x9b5f69f5, 0x845abd92, 0x23293971, 0xd8117478, 0x7bb1dfff,
- 0x1bb7043d, 0x14be73f7, 0xed8cd7be, 0xfec1b10f, 0x177fd010, 0xf2a7f349,
- 0x2f8b17f8, 0x88dc9493, 0x07ef3079, 0xec1a7efd, 0x63609f37, 0xbf6807fb,
- 0x63abb044, 0x58e98a88, 0x81656788, 0xdf983d28, 0xde8f1a43, 0xdc7feb47,
- 0x9649e2ca, 0x0f8ba206, 0x38b3c766, 0x8b074ccb, 0x8dc9c60f, 0x10ff82b7,
- 0xc1388e77, 0xa5fce87f, 0x22fee122, 0xae2379c9, 0x11341d8f, 0x3959f7a0,
- 0x99f584e0, 0x7524abae, 0xafaee933, 0xab5bcb93, 0xbd4571f7, 0x7372e20a,
- 0x7d3fcc1d, 0x7ee09f36, 0x4a53aee8, 0x934dd600, 0x91352c32, 0xf92b9ff1,
- 0x0b390f77, 0xfe21e332, 0x408e37bc, 0xc5f613fb, 0xbf0e4099, 0x056396de,
- 0x3c04bc3c, 0x32487ca2, 0xfa86ef3b, 0x7a502e92, 0xdb39f133, 0x63a92f27,
- 0x277f2812, 0xe15760dd, 0xad67a9be, 0x7ee0378d, 0x784c17d0, 0x8a4beebf,
- 0x2ff214ab, 0x609d579d, 0x6ccd9f7f, 0xbcfec38c, 0xbcfec260, 0xf575d714,
- 0xc3f74a4a, 0x4a7c5823, 0xec0911b2, 0x502a64b2, 0x73cfa6ef, 0x493cd9e3,
- 0xe3cbd3b3, 0x2e3cfe99, 0x200f3c10, 0x7f51f299, 0x9d3afdb4, 0xebf7045d,
- 0x2ad59bf4, 0x4ae38e02, 0x4851b8b5, 0xe4cf7884, 0xdb7e8212, 0xe78cbb64,
- 0x307f6072, 0xc29b1b9c, 0x0f94efed, 0x813d712a, 0xdc30e04a, 0xe762d97f,
- 0x75f168f7, 0x4e39ebc5, 0x226d23ae, 0x5dd791f8, 0x07882e22, 0x8a497f5d,
- 0xe74e47e9, 0x10233ef5, 0x97be8129, 0x0095517f, 0xef44f977, 0x2faf4de7,
- 0xe0e3053c, 0x39e18b54, 0x8f4889f8, 0x4ff7cf1b, 0x4fee1a77, 0xd6f3e78e,
- 0xe47064c1, 0x1d6d313e, 0xf238ba68, 0x8b53f409, 0x65f01714, 0x3efdddbb,
- 0x5bfa7bac, 0x38b97265, 0xb63e33e2, 0xa5c46f9f, 0xa1ff5c38, 0x2e03b4f8,
- 0xf3afaeae, 0xafbf695b, 0x07eaca1e, 0xb95d821c, 0xc92997f2, 0xf1cde760,
- 0xa968decc, 0x97c03b86, 0xcbe18133, 0x3f5bba39, 0xe267c557, 0x01be9a7b,
- 0x3d9ea0ee, 0xac7e6072, 0xd78a6575, 0xedd78055, 0xb3f38276, 0xe65ba51f,
- 0xed699e82, 0xf86789ec, 0x6aeba637, 0x7587ee57, 0x6c67ff1d, 0xe03698bc,
- 0xde391292, 0x3864e87f, 0x3375aaf3, 0xf3fda66f, 0xbf5c65da, 0x8be7e549,
- 0x1e92f122, 0x770d1781, 0xef16761d, 0x7533f0d1, 0x3c22bbf7, 0x2119fa9f,
- 0x9e124cce, 0x99f86887, 0x9c3867e2, 0x138d8872, 0xddc7e1bd, 0xe6069ce5,
- 0x87370a31, 0x280a6e18, 0xb7f7f03e, 0x118fc07a, 0x8af54f37, 0x3cf12f9b,
- 0x53bdaafc, 0x186ebb2f, 0x7df7e9f4, 0xb689d31a, 0x8f82fbd8, 0x56ef7e72,
- 0x06cc6eea, 0x8993717b, 0x48937f9d, 0xe714adc6, 0x7bb4e3bb, 0x20b26be5,
- 0xf6625dbf, 0x19b37b67, 0xbb76cfed, 0xd77183c7, 0xcb9e0b34, 0x0da79226,
- 0x06bbf5f6, 0xdfc8d458, 0xc72ef8d1, 0x9a1ca361, 0xeffc0278, 0xf3fc98d7,
- 0x1b81ca6e, 0x197a48ec, 0x93b8c393, 0xe21126ca, 0xfdfc8e42, 0xe04faf80,
- 0xc3c02d4e, 0x25ef0571, 0xa0ae3eaa, 0xbecdfc5d, 0xbe210bb7, 0x9e1feda9,
- 0xc2ede7b0, 0x3ef09182, 0xdc6bd9c3, 0x3c796aae, 0xd276014a, 0xc4fd2f70,
- 0xfd2679f0, 0x8025f2bd, 0x72eeec9f, 0x73eb7de3, 0x1d1784e0, 0x736d6e77,
- 0x60b3074d, 0x4e7d6fbc, 0x9b1f9d88, 0x1d3dd47d, 0x7dd4654c, 0xb70f1ceb,
- 0x715dd691, 0xdffdf462, 0x163e7c74, 0xd7fbf10f, 0xc1c40a43, 0x6b9a951b,
- 0x26a27cd8, 0xa68fec0b, 0xf947f877, 0x08e1f8d6, 0xc3ff7ddd, 0x88f3f8f8,
- 0x38f7624b, 0x4eb829b5, 0xdf6128f8, 0xeb71f235, 0x39f7ae2b, 0x0f9c5eab,
- 0xb96c70f6, 0x576dd71b, 0xfe7c4539, 0x64b21213, 0x125cbc81, 0xca3477ae,
- 0x4213d4ea, 0x2a447bf7, 0xe5a76119, 0x8dc5fa7b, 0x70eff685, 0xf00e4c78,
- 0x43aea42b, 0x4984ddf0, 0x6ec16339, 0x4dacc7db, 0xa34c7186, 0xb455d29b,
- 0x874dded5, 0xc7275746, 0x858e1dc9, 0xf678c726, 0xe0a1d81d, 0x7c0b76b1,
- 0x71a0e1af, 0xff2639ef, 0xfc803c08, 0x2c20f1bb, 0x07c6bc80, 0xfcb54f1b,
- 0xa10f1f3f, 0x1e9f2081, 0x087100f1, 0x43c2b7c7, 0xc355f016, 0xaed7f503,
- 0xfe68fe02, 0xf6c2a35a, 0x0d796a1d, 0x7cf64507, 0x10a5cf7c, 0xf6443fdc,
- 0x6d39d959, 0x57ae224f, 0x6d64ecbc, 0x3ed87e74, 0x6498ba98, 0xebf983b2,
- 0x8c89efda, 0x57e80909, 0xe106a18e, 0x06e3f40e, 0x71743da2, 0x4176917e,
- 0x71377b80, 0xf806796f, 0xd064a197, 0xe2e6318b, 0x877fe010, 0xf8064a6d,
- 0xc9b63987, 0x5daf8059, 0x0ebd5623, 0x01aed643, 0x516f2fe5, 0xcd27fdbb,
- 0x6af0b5ee, 0x746ff6b5, 0xbd74fb30, 0x020f9d9b, 0x87491dbb, 0x2c41ff66,
- 0x9a108740, 0x86cafa63, 0x0db9baf6, 0x41d039ec, 0x205fbaf9, 0xe41fe04d,
- 0x5329dc9b, 0x17ebcfc1, 0xcece8092, 0x860c5fbd, 0xf3716538, 0xde8147ab,
- 0xd43d6d62, 0x350f5fa5, 0xbf9ad1fa, 0x342bcda3, 0xcf9b487f, 0xe504df82,
- 0xd3b9fcd9, 0x26add6cc, 0x6e782c87, 0xeaf3f1f9, 0xbfae6e55, 0x3147ed12,
- 0xa42dc7ef, 0xeed2e915, 0xf399b91d, 0x9d10f8a3, 0x39436687, 0x3e513721,
- 0x1defc4dc, 0xbfa5c9b9, 0xbc96e157, 0x688ef7d8, 0xbef6f4f5, 0xd6b87c71,
- 0x6df46eb0, 0x763e43d3, 0xfa7fc8cf, 0xd2773cd8, 0xc12fd110, 0xce979a80,
- 0x327069ee, 0x62521c3e, 0xb9fb578f, 0xb5324efe, 0xe5b9c365, 0x8efe7bfd,
- 0x7b2be3e3, 0xf81efefe, 0x494f1389, 0x4eb5f604, 0x012e353a, 0xd2f3e7d7,
- 0xab593d70, 0x9369fbd7, 0x88e7b08d, 0x5777ed1f, 0xdc7a520e, 0xc167d00a,
- 0x1e67b7f4, 0x77d429ff, 0x2244b8f1, 0x2a144dcf, 0xc710a19e, 0xbfbfe42d,
- 0xfe605073, 0x907e5692, 0xf3c5eeff, 0x21b0b71c, 0xc48fbb42, 0x9be7211c,
- 0x9a193df8, 0x593a6f5c, 0x8eca4a74, 0xfdfc0f96, 0x5a0be233, 0xf399a15c,
- 0x11fcb48f, 0xa77cb7cf, 0xfc096ee9, 0x89a4eff3, 0xeed11dc4, 0xe0ce950c,
- 0x2f1ce223, 0x4a7e0c3b, 0xbd3f73cb, 0xde2b8e99, 0x4adc4437, 0xfede6de8,
- 0x5be4367a, 0x8ff798c5, 0x9dfbf918, 0xfef1bbe6, 0x2a092191, 0xfb5bd3d2,
- 0x38a6ae93, 0x27720d19, 0x65cbcfcc, 0xe51877f7, 0xff9ecafb, 0xd91b6e48,
- 0x927bbf33, 0xbf0e51bf, 0xeb80533d, 0xc3c9bd4e, 0xb47ddb88, 0xbfda7e9f,
- 0x9fa7ed10, 0xf8af63fa, 0xbdff989c, 0x1af30d2f, 0x9f7bbd5e, 0x4e7f064e,
- 0x64f4e9c3, 0xbb899b86, 0xec4c9a7f, 0xf232f2dd, 0xf30773ed, 0xd710e66b,
- 0x3fe99bec, 0x78ae0a77, 0xd27e17b4, 0x4ab3fb0a, 0x0e738d38, 0x41ffa217,
- 0xe31079f8, 0x1c473638, 0x7bdee789, 0xa19bddfd, 0x5b9832f9, 0xbf0578e3,
- 0x36b802c7, 0x6f45538e, 0xb2e049d4, 0x98ab4a15, 0xba7ee31d, 0xce519746,
- 0xf6094847, 0x8d3a27a3, 0xabd23038, 0xefdae7f9, 0x4c7e50c0, 0xddf5a24f,
- 0xff63e6aa, 0xce61c6a2, 0xdfc69e97, 0x9c95fa9e, 0x1cdee3c0, 0x4e4e17ff,
- 0xdbd80b7b, 0xe519be93, 0xecd72c66, 0x90342147, 0xfc1fa983, 0xa9092191,
- 0x97850fa8, 0xe3a6e214, 0x3fa8190c, 0xaf8a4eff, 0xe3ddbc40, 0xc27acf64,
- 0x1325f55b, 0xe37724f1, 0x663e0e4e, 0x96eddc03, 0x1f106cea, 0xba5ecebd,
- 0xda6f5406, 0xf0b305a7, 0x1336879e, 0xf4d99081, 0x102d73e6, 0x251ef047,
- 0xa0a03e78, 0xc054ff79, 0x56a5efe9, 0x5e75479c, 0x08b1e424, 0xbcd8333f,
- 0x587e06c6, 0x6f9d8530, 0x7448983b, 0x27f790fb, 0x8f06bc30, 0x1dd9bf9f,
- 0x2f12fca3, 0x29dc499f, 0xc72e38d9, 0x70a3fc63, 0x3ffb09bd, 0x481d704d,
- 0x9e65bf01, 0xce85f380, 0xa40e13bd, 0xee3b7a50, 0x333b444c, 0xdde0f83d,
- 0xc6882a4e, 0xcf8b1eff, 0x780a16bb, 0xeaa140cf, 0x59617cc2, 0x98dfee26,
- 0x99e48ff0, 0x433e50c5, 0x74cdf9c6, 0x788252b1, 0x2134d9d4, 0x7b8be607,
- 0xf85ab684, 0x297f5c1d, 0xfd38876b, 0x7cff30c9, 0x0c7938a7, 0xaa9c76fe,
- 0xefe187e5, 0x3cc31203, 0x0bced56d, 0x7cb4cdfb, 0xf7016cd5, 0x66774eef,
- 0x7e047f10, 0x7953d70a, 0x6cb8a58e, 0xb8005fee, 0x3fa4599e, 0xc4bb3837,
- 0xeb910246, 0xef138216, 0xf7c83b21, 0xfc097769, 0xe7ae7c5e, 0xcfbc7037,
- 0xfbac9b99, 0x3f3094ae, 0x6453bbd3, 0xb3e471f7, 0xf4d6a1df, 0x87ae46eb,
- 0xf1f9f037, 0x8e864f3c, 0xd288628e, 0x5b3f4088, 0x62e5be47, 0xa5cf0e1b,
- 0xe78707e2, 0x1c6ef6d3, 0x8ad79861, 0x17116b95, 0x6f1d6c69, 0x1382ec36,
- 0xdfea6ec1, 0x9f4f25bb, 0x97c7a18f, 0x3d9a13b5, 0xc457bd98, 0xf9d9c375,
- 0x8902cf94, 0xaebfd3f2, 0x726098bd, 0xd078801d, 0x78dc97ad, 0xbd944e8f,
- 0x1be8a0f8, 0x50df8bd9, 0x7aa3cc1d, 0x1f0264fd, 0x41910737, 0x8ba63760,
- 0x380a7edb, 0xa6e3a4ea, 0xb48e0639, 0xef9b4771, 0x063d5217, 0x6c3390dc,
- 0xa5fa659d, 0xa4efdc34, 0x76c3f7cd, 0xae25fa84, 0x6fd2fe18, 0xf774b212,
- 0x4aed847a, 0xe7225f84, 0x64bf7b7e, 0x9547f53a, 0x206fa01c, 0x7b458ff1,
- 0x42c97186, 0xf10518d8, 0x1873b4c1, 0x744af1e7, 0xf3e38afe, 0xb02f88d3,
- 0xb752427f, 0x15fd187e, 0xd63cce2d, 0x7a53f9a9, 0x8de3849c, 0xa57dd8b3,
- 0x810a4e1a, 0xb3ffa09f, 0xf4eb8c44, 0xfdad1b86, 0xa212f0de, 0x564c08f6,
- 0xfae1788f, 0xf2f175f7, 0x197c6d17, 0x05f6864a, 0x343e1a27, 0x9bc718bc,
- 0x83c434ff, 0xba6f1a7a, 0x0e6f197a, 0xaed1908c, 0x7cd7e6f7, 0xeaf3e4ea,
- 0x37a62704, 0x7f1b355c, 0xd82c6897, 0xf937f011, 0x6b8e15b8, 0x1c9c33d5,
- 0xc1245b68, 0xec1791fa, 0x1cb76647, 0xfff078b4, 0x81c4c600, 0x008000d5,
- 0x00000000, 0x00088b1f, 0x00000000, 0x7cbdff00, 0xd5547c0b, 0x67b7efb9,
- 0x332479ef, 0x49926649, 0x1d843c32, 0x09212108, 0x11bc210e, 0x11084937,
- 0x88a80ca2, 0x1f01d68f, 0x4d092060, 0x6f53d5ad, 0x52812133, 0xbd583d6c,
- 0xf4f47bd6, 0x41ed5837, 0x0108750d, 0x26702783, 0xd0f098a0, 0x7ac0f820,
- 0x452968da, 0x5a18921b, 0xf5cf6a0f, 0xf6b7df7c, 0x8326664e, 0x73def7a5,
- 0xd62e9f87, 0xf5af6b5e, 0x5ff9efad, 0x4a9b5adf, 0x500a9fc0, 0x982015b3,
- 0xe1f95006, 0x06484a86, 0x01203be8, 0x96d40314, 0xfe1b41c9, 0xb1fdb4b5,
- 0x0cdd45c7, 0x51df8956, 0xf5c02661, 0x950b7e20, 0x06e6c50e, 0xbc95e658,
- 0xd6801672, 0xe1bfde2e, 0x62a82592, 0xf9af7afd, 0xe89b1ee3, 0x5fff35fb,
- 0xb800c803, 0x197f7f51, 0x2ffb0ffd, 0x1860a4d3, 0x3b365d5f, 0x978dffba,
- 0xa6913fca, 0x62d72c02, 0x3e4fc39e, 0x22f2a793, 0xac24becc, 0x8fb74457,
- 0xcfb92673, 0xe32ff1d9, 0x32d7fc61, 0x65f3c5c0, 0xaff7516f, 0xc8ed77e9,
- 0x523d48f2, 0xace80166, 0xdb1971b7, 0x7f016e5e, 0x4d2581c8, 0x0065c450,
- 0x9d0a0152, 0x581998b8, 0x0d0164bf, 0x136308f9, 0x3ab9f7e0, 0xdf86131d,
- 0x07e3883f, 0x8e30dc70, 0x3801c81f, 0xfae4ef54, 0xae1ef56b, 0x2f82935f,
- 0x877fe3a4, 0xb8a8b0bf, 0xdfedc59e, 0xdf38fc51, 0x8f0a4be2, 0x93d69b3b,
- 0x71830b4f, 0xf73f9eb4, 0x0de3fd16, 0xb6bfdc30, 0xbf8b33fd, 0xf9ebf2f0,
- 0xa7e7f35b, 0xcd3f3ca8, 0xcf0c15ab, 0x180144bb, 0x9a5ceb83, 0x635fcd1b,
- 0xc6f9589e, 0xfeb96fca, 0x56fcac7e, 0x90c7acc4, 0x32a2f40f, 0xffc38a8d,
- 0xa6d0264b, 0x437e5e5f, 0xb3f8b1f2, 0xdb2305bd, 0x72c97e01, 0x974f1e1a,
- 0xbe2b7417, 0x19974142, 0xb752baf5, 0x40efd40b, 0xb2b9ca0a, 0x4889c213,
- 0x2be7f5d8, 0xf4a8513e, 0x9471f04a, 0x6c7c033e, 0x1e1e5bc8, 0xe425d17f,
- 0xbcf0da6b, 0x7764148b, 0x0b1f3d11, 0xa8eb3881, 0xea1471a1, 0x6c39601f,
- 0x155a61d9, 0x635c75c2, 0x547d3b81, 0xe0328a26, 0x937db894, 0xf6e3c4d3,
- 0x8266c5ff, 0x3e5e01ab, 0x48025998, 0x3cead79f, 0x42011306, 0xbff7e066,
- 0xdfb9524e, 0x240824e6, 0x74a0fce0, 0x945ec8db, 0xb45c8012, 0x25b4653b,
- 0x364388d8, 0xd91f612b, 0x8157bf61, 0x2fdbb406, 0x050ef78d, 0xc914076e,
- 0x4c738fe6, 0x7ef4598d, 0xf61e7bb8, 0xa8a4559b, 0xcb8bb0db, 0xda877eaa,
- 0x9d580efb, 0xfeff5ef4, 0x699877ef, 0x1780bf9c, 0x0ed78429, 0xe7da8158,
- 0xf241cc3b, 0xe3e48b1f, 0xfdeb09b2, 0xec560003, 0xb8557f3f, 0xd76e5014,
- 0x13a37740, 0xc724b9cb, 0x8d7bf238, 0xfece9bd6, 0xe50a31c3, 0xd39740b4,
- 0x956fdd02, 0x8fd9901e, 0x41c92694, 0x53f61ac8, 0x5a32ead7, 0x3a256c80,
- 0x7ae1b416, 0x4bdafdb1, 0xb4bf5c4a, 0xe1771f48, 0x9321419f, 0x7ad1085c,
- 0xf84da8bb, 0x14d012a3, 0x6d4b29c0, 0x97e4ed31, 0xce459e90, 0xc973e7e8,
- 0xef5ea277, 0xf84bf18e, 0xf7bcd133, 0x8bbcc53b, 0xf726bfe4, 0xb65ffae0,
- 0x43cdef68, 0x9a4e077a, 0x0e7c59e1, 0x6732b1e7, 0xd0da5f24, 0x973983ae,
- 0x07fd8bb7, 0xe9153513, 0xc7f49979, 0x9ad1f541, 0xfdf2f53a, 0x940cf6a7,
- 0xb9787760, 0x13028579, 0x7b4f1d58, 0x3df98632, 0xff3aaf82, 0x22d9f963,
- 0xf91d9341, 0x5bddb0bc, 0x0465ae46, 0x8f913b1f, 0x80c95ef8, 0x295cf3c6,
- 0x78fb0d1f, 0x46a25cf9, 0xb9f2fefa, 0xffcd1ad1, 0xfa6be92a, 0x3feffeb0,
- 0xfe48983b, 0x2aa8f913, 0x2e0317a8, 0xd659f79b, 0xa1f7a15f, 0x6dc13951,
- 0xf5d16f58, 0x81c4e5fc, 0xefc4f9a3, 0x67de4deb, 0xe3651a69, 0xe48515c4,
- 0x9c96b737, 0x0d2477c5, 0x7ed107a4, 0x7709d524, 0xfb401960, 0xa40b7d21,
- 0x1993eb02, 0x36f34042, 0x9534f06a, 0x29abe60b, 0x1c41efc4, 0xe341dbb3,
- 0xe7a429a9, 0x338bd7f0, 0xf923857d, 0x0a8f52de, 0xd6b4f385, 0x1b2534db,
- 0x93bd5f60, 0x1ef56deb, 0x57ad5f2e, 0x2c74dcb9, 0x8e20c1f9, 0x3459ab53,
- 0x7df86d25, 0x8fb0aa57, 0x8867e805, 0x052005ae, 0x0b73a803, 0x5ef5d61e,
- 0x249b8291, 0x27ae1392, 0x97289f82, 0x08dc9ec1, 0x4d2936fe, 0x35b26693,
- 0xf28bbcb0, 0x063efc4d, 0x59f3e0ff, 0xdca3fb23, 0x4baaeaa3, 0xbae67e62,
- 0x961724b4, 0x52f8743f, 0x6e916ca8, 0xb8017c39, 0x5bf512ee, 0xfe380be5,
- 0x7842f0f4, 0x74c3e310, 0x15f10c14, 0xfd13b77f, 0x402c3a33, 0xca80c1f2,
- 0xd3a45976, 0x492e7da3, 0x323e70e7, 0xe0c7af9d, 0x30cad67b, 0xe83ed1e9,
- 0x17be2349, 0xb4767cdb, 0xc843a428, 0xf66e9355, 0x9cde3848, 0x26578b74,
- 0xa6fa26d2, 0x75fe446f, 0xd884e3a4, 0x6323a3bf, 0xa6f68aac, 0x4fbc6f29,
- 0x1cd9ad76, 0xcc2b8161, 0x71113dbd, 0x719e133c, 0x9f22bc52, 0xbdf235f6,
- 0x01c977f3, 0x73886bf6, 0x9e758fc8, 0x7186f64a, 0xd92e6b9e, 0x7fd256bc,
- 0xf5ed117a, 0x54f26260, 0x5dd0cff2, 0xd6b8ebc6, 0x6f91d626, 0xd8bb17f6,
- 0x9f0f859f, 0x6dfef7c0, 0xe9fc8010, 0xca1fdd35, 0x9a94f480, 0x907b32f2,
- 0xe4d2c3ce, 0xfc9f2a14, 0x9701725d, 0x897b92a7, 0x764d073f, 0xa77de695,
- 0x46ce2d5e, 0x72ded17d, 0xd61d0098, 0x0a1cb782, 0xa1ea2795, 0xe5f51b38,
- 0x971b7aad, 0x5c9deb27, 0x70f7aa9e, 0x49db1879, 0x76c75e9f, 0xb037b7d2,
- 0xd85dea9d, 0x1c31e54e, 0xdba2ca97, 0x96bc7893, 0xb42c92db, 0xd0c9838e,
- 0xfa4fcc6c, 0xb70c4e14, 0x3fe01782, 0xab6afb1e, 0x978c2aed, 0x34a17f56,
- 0xb3f4f90d, 0xac142aaf, 0xee3c5b1f, 0xbb60bfa1, 0x1fa667f9, 0x9bde90db,
- 0x8f5a394e, 0xaa9edd63, 0xfa41d8fc, 0x9d112c79, 0xb9b59923, 0xa63a434b,
- 0xcd1c6f93, 0x3660d76c, 0x7af4d3d6, 0xd95d7cc0, 0xa595807c, 0x42e0f93d,
- 0xaf597125, 0x577f21b3, 0xa3dffdda, 0xabb025ba, 0xaa2aeca2, 0x7b248863,
- 0xb641cc97, 0x7b92b1f7, 0x95bbc605, 0x127fff0e, 0xd17b0dbf, 0x91a43fa4,
- 0x49a9987f, 0xbcb372e0, 0xe1a49383, 0x95bf46e7, 0x49ff458e, 0x25debafa,
- 0x98cd7db3, 0xc741692f, 0xfa35fb48, 0x96ab38cd, 0x9e66fc91, 0x72a26f2f,
- 0xeb8b8559, 0x9ab355be, 0x1ccbfec8, 0x94bf7b97, 0x65d07fdf, 0x512dbd66,
- 0x389c5fb0, 0x8e9bf468, 0x7bb8464a, 0xf8312ba0, 0x69f5e92c, 0xd612637f,
- 0x8ab27917, 0x0337dd64, 0xb63b5dd7, 0xebe57b51, 0xde576cad, 0xf2e12f24,
- 0x6990a899, 0x21d0bed8, 0x2a64c379, 0x4a6a3ff3, 0xe4a776a3, 0xd42db625,
- 0xa6289da6, 0xbbd96cf6, 0xd5a7ea90, 0xa7510a32, 0x2ef38594, 0xb9c5bf60,
- 0xbe1b5e29, 0xd0fc2a77, 0x85dfd245, 0x04de49b9, 0xf04af3f2, 0x7baa1ae9,
- 0x9506dead, 0x6958f1d6, 0x4aa38d32, 0x5bd6135e, 0x1ffd286e, 0x2f894744,
- 0xda892405, 0xd7e10a5d, 0xc3f77f27, 0x6bf62732, 0xd9012719, 0xde70a9cf,
- 0x85fe889f, 0x026a899d, 0xb38b69f9, 0xb16bde8c, 0x5c4dce48, 0xff5295f7,
- 0x7d598e40, 0x7e3dc71e, 0x41e39d9b, 0x8c055be5, 0x36df8e83, 0xe542e386,
- 0xa84bf35b, 0x78126e3c, 0xcaadf2bd, 0x41376e0a, 0xe54a9c98, 0xf7e2dfed,
- 0xb0fe97b6, 0x1fe38dcc, 0xdf62ef1b, 0x562a7282, 0xf624fc22, 0xbfde8907,
- 0x77fb9abd, 0x9d0f9948, 0x0b17fec5, 0x38ac8a52, 0x213bb97f, 0x58c57faa,
- 0x497d5457, 0x2562a8f6, 0x16564fc2, 0x6fd54564, 0xb38a9628, 0xe6fbfa23,
- 0x57d54427, 0xb38ab994, 0x54dffa23, 0xbeaa2a39, 0xa8aca6f2, 0x1cd342fa,
- 0x61ea3fe1, 0xf3b0997e, 0x20d965f9, 0xa9fc898c, 0x037df453, 0x3b26efdb,
- 0xa9f812ef, 0x09f885c8, 0x55d652e5, 0xd8b971cc, 0x00affbae, 0x92667b74,
- 0x2ebf17ff, 0x83de8f1c, 0x4999fe20, 0x16fc4878, 0x201e2376, 0xdc60a47c,
- 0xcca7a08e, 0x2bc71d11, 0xff27cd40, 0x84b9d15b, 0x67b954f1, 0x319a1979,
- 0xbdfa31f2, 0x8161f90a, 0x2ee86243, 0xa5c732ea, 0xf46c62b7, 0xabae06fb,
- 0x316be9d0, 0x09529bf9, 0x6eb4058b, 0x7ac635c2, 0xb72e3a0c, 0x8ef90a9e,
- 0xdfff1432, 0xfd2c575c, 0x7f791b00, 0xa0d74b11, 0x8881c74b, 0x760718a7,
- 0xc43e32a6, 0x3e1e3b9f, 0x254f7030, 0xa45737fa, 0xee48737f, 0xf79785e5,
- 0x97b8c66f, 0xb8c67bc3, 0x2cd0fbc6, 0xfbc6fcf3, 0x2955cf43, 0xd89df3fe,
- 0x73ce293f, 0xf9ff14b7, 0x17fdd173, 0x03a36a28, 0x4828f8ed, 0xfbf100de,
- 0x2410aab8, 0x35ad3d2b, 0x43e8b951, 0x747842bf, 0x1340d9f1, 0x837af395,
- 0xfeb8adc7, 0x956572eb, 0x1e060df2, 0x8cd75d8a, 0x3a4fb154, 0xabb5497a,
- 0x5012ded8, 0x68bfb4ed, 0xd3b55879, 0x8345aa3e, 0x6a2fda0a, 0x691b4d13,
- 0x63e5a1bf, 0x549cf589, 0x52f3e7e1, 0xca318e05, 0x5e7f6567, 0xb6d5962a,
- 0x8b09479e, 0x60317cd4, 0x94703021, 0x48c15e70, 0x0954779c, 0xa3be683a,
- 0xbe1d070f, 0xa57e3f08, 0x29146f38, 0xa7e93a5b, 0x91fa45a4, 0x16825b52,
- 0x391637e9, 0xaff5515d, 0xc7d8aa9c, 0xbd45467b, 0x159a9d77, 0x6bf10fd5,
- 0x46a0e12e, 0xe42ae40b, 0x5e894d47, 0x7cb177c2, 0xfd7d17fc, 0xe093875e,
- 0xaadd9813, 0x97138fec, 0x7f82a5bc, 0xa457cfb1, 0x6fea7d8a, 0x6e583d68,
- 0x35f4154f, 0xe2013ec9, 0x3e933710, 0x4f71d6c4, 0xc3c68aba, 0x77a43d91,
- 0x22e9bb5e, 0x4ef86f42, 0x29d7d5ea, 0xe9decfa8, 0xc44eefa6, 0x8ba923fa,
- 0x699e7d44, 0xffac04cf, 0xd45cb534, 0x374d36af, 0x057e017b, 0xc32baf8b,
- 0xe7dbba7a, 0xfb79c54f, 0x12ad8ecd, 0x24c519e2, 0x787b9141, 0x0588fbff,
- 0x160a29e3, 0x21734c95, 0xd8ab76ad, 0xa024d72f, 0x25fea3ff, 0xaafc4a9a,
- 0xdce43049, 0x1d714193, 0x9134ceee, 0x6ff630bf, 0x87be0b76, 0xfcd8e7ef,
- 0xc25f42b5, 0xa5fa2ac9, 0xca2ff7fb, 0x9ed8bd24, 0xe7f5e4ea, 0x21e799ef,
- 0x7d74857f, 0x7ffdfa97, 0x3c536ba4, 0x62cc9aba, 0xfc96de9e, 0xf9bb8a52,
- 0xd21c51e3, 0xbb70bcb0, 0x4213cfcf, 0xcb8c2ba8, 0xf5848f35, 0x4bc59746,
- 0x90fb7d38, 0x6cacaf7c, 0xb213f3d4, 0x9c8de85d, 0x1bb8da62, 0xfaeb9fcb,
- 0x3bcd14f2, 0x1819e683, 0x01f51cb7, 0x56e3039c, 0xe93a8a14, 0x0d172c83,
- 0xf81ede10, 0xf7979256, 0x7e0763c7, 0xbfac03fb, 0x97be4777, 0x8907f470,
- 0x82ab3f82, 0xb07b1a13, 0xbc1acd3e, 0x3e748c2a, 0x967fe694, 0x6b36e0f4,
- 0x9beb1270, 0x8d126363, 0xfbc0692f, 0x877f6310, 0x32d538fb, 0x1fee2471,
- 0x88d82f39, 0x11ccb7cf, 0x45e6367c, 0xee28da9e, 0x3c5b37bc, 0xf9c0e837,
- 0x06ff885b, 0xc074433d, 0x03c72758, 0x45a47910, 0x61e443b2, 0xbce260ff,
- 0x1f192d49, 0x359cf7d6, 0xcfaebef1, 0xe68057d8, 0x9b933d58, 0x27399e78,
- 0x6c4cc936, 0xd4ccff00, 0xb6af4859, 0xfa7de7ad, 0x7de8ee8c, 0x7f4eacfa,
- 0x9bdf03a9, 0x7cfc7ef5, 0xdc7d3cc8, 0x299410d9, 0x89e9cf5e, 0xdf4f37ee,
- 0x1f3bcfa7, 0x54cdfcfd, 0x868dbe3d, 0x8e7991d1, 0x33ff7d3a, 0x0a427c78,
- 0x3af929e9, 0x516ef919, 0x3a9d9865, 0xeb5a37ec, 0xf90e5fb1, 0x85971b47,
- 0x11779da7, 0xa8f56dfd, 0x93f216d0, 0x7b0d2e1e, 0x770d3c2a, 0x7988d4c2,
- 0xf837bd74, 0xe0bef838, 0xdc9eb4e3, 0xbac7cf9f, 0x410cd3b9, 0x739d7875,
- 0x820d3e75, 0xd3a0f3e0, 0xd99e7cc2, 0x61e9cbf5, 0x98f5647c, 0x5f588d40,
- 0x6a089a82, 0xe7b53f84, 0x65d546a6, 0xce3a3e43, 0x9f8fae98, 0x351d1de4,
- 0x0c37818e, 0x5a9abdf9, 0x643849de, 0xe31d63ba, 0x13d9948e, 0x3e2dc6a2,
- 0x64272b1e, 0x2476e11c, 0xd7089ff2, 0x70a2569f, 0x80772cc6, 0x3fb30038,
- 0xc9706254, 0x68ec9976, 0xe7e8d9ee, 0xc8cbb4e6, 0x84fc72ed, 0xef9f3fa9,
- 0xe9f9fbfe, 0x99f9a2d2, 0xcfcd1156, 0x3f345f74, 0xf3455733, 0x9a3f946d,
- 0x4dd6632f, 0x6abf6a89, 0x7d545163, 0xa37383fc, 0x006167fa, 0xdc4fac8c,
- 0xffaa24ba, 0xa22beda4, 0xba9f93ea, 0x5e7faa2d, 0x7b544d70, 0x2baacefe,
- 0xa8617f92, 0xb11faa2e, 0xf20df4d7, 0x1fedbabf, 0xeff9e6a2, 0x34a2ff96,
- 0xcbaf2f3d, 0x438e997f, 0xc7fa1a5c, 0x4538e1a2, 0x93f215e9, 0xbe37f6ae,
- 0xa04bfca0, 0x53bce544, 0x1b780960, 0xd909edb1, 0x1b5f9127, 0xa136ac83,
- 0xc13268df, 0x8ff7f23a, 0x879c4c9a, 0x2abcec34, 0xaa8be04d, 0x9ff7e134,
- 0xf8a69b46, 0xeccff066, 0x78449ede, 0xa0993643, 0xe29ae29b, 0xc671bf65,
- 0x716be101, 0x7034793e, 0x7934ab5e, 0xa899b2f6, 0x329bf287, 0xd1e51fef,
- 0x7d71507e, 0x3f1fc78d, 0x8b9ff941, 0xfa4a9b0e, 0x03faa72a, 0x7d70b714,
- 0x2461e7a1, 0x3eaf795e, 0x49f6893c, 0x67957d46, 0xbfea66e3, 0x93858eea,
- 0xf43aff68, 0x498e8efc, 0x88721165, 0x388adf5c, 0x697be8f8, 0xc4673f22,
- 0x6aacdb87, 0x6bca0f63, 0x3ffc2c9a, 0xa5ef85c6, 0x903ffae1, 0x9c0b361e,
- 0xbad33015, 0xde724e31, 0xba8085df, 0xe194cb0e, 0x8d7ea478, 0x84c1f54a,
- 0x26f9dc68, 0x08fb4411, 0xffc72a5b, 0xbb7f0d5b, 0x36f98f2e, 0x3fee88e8,
- 0xc144f778, 0xd7236fcf, 0x2c67df90, 0xdd061d62, 0xfc3f75e7, 0x7b87eea9,
- 0xe446ffc9, 0x78edd79b, 0xf5f0893c, 0xa7815c99, 0xe8cfe78d, 0x4d267d72,
- 0x3bf5e9e0, 0x79919c13, 0x2b90eac7, 0x36db5eaa, 0x423679ca, 0xeb1bd70f,
- 0xad0a4bf0, 0x3f6e8363, 0xc93d9dd5, 0xf1e301b7, 0xdc70d3a7, 0xbf171d9a,
- 0x37de8fbd, 0x3888640d, 0x6ef9e01a, 0xd7180f79, 0x4415f2df, 0xd297d2e1,
- 0x25e57e44, 0x95cb0ba2, 0xdf513858, 0x776c6256, 0xfcc6f951, 0x7c3bb272,
- 0xbeb0961e, 0x84cc13ac, 0xb3fb96d3, 0x53f4c4cc, 0x2f677de0, 0x9a5f6d2e,
- 0x04dcf3ca, 0xc5c5333e, 0x9d5dbf77, 0xc686fd44, 0x4319c633, 0x2bd459b9,
- 0x419cc057, 0x246b9af9, 0x9f380dc6, 0xeefb9e8d, 0xe299b318, 0xbbdf31af,
- 0x0ef0bfe0, 0xf00ac5ea, 0xf8c6b8f2, 0x7e51a900, 0x90cb03f8, 0xbf24ed1c,
- 0x98532eba, 0x677539f2, 0xd1fe7cac, 0xebf030df, 0xdfce9007, 0x57b17d55,
- 0xbb7fba42, 0xfb57e07a, 0x4fadf9f0, 0xb5c5dfa1, 0x87fddb66, 0xc3ce22d3,
- 0x917ddcce, 0xc8f10ced, 0x33924ff3, 0x25eac97a, 0xeaa0f8fb, 0xbc489ca5,
- 0x616d227f, 0xb307bd27, 0x479ee2d3, 0xab2beec4, 0x6ed93f48, 0x8699c655,
- 0xeba7de5e, 0x930bdd65, 0xd25d79f9, 0xfd447ad0, 0x57f39979, 0xbcac0775,
- 0xd7477fbf, 0xbf17aa87, 0x9f991998, 0x54bd416b, 0x7274a873, 0x2a9ce749,
- 0xf1cf66f2, 0x6fd4a9c1, 0x21efeca3, 0xe978393d, 0xefaa64e3, 0x5e4bf379,
- 0x6574dc0f, 0xf323f7f4, 0x9b5cf922, 0xf92ef034, 0x567dea93, 0xa550f295,
- 0xdd8ef2fb, 0x4e9af58e, 0x9eb83bf4, 0x239eae0b, 0x6a7ed34f, 0x979404bf,
- 0xb02709aa, 0x9569af73, 0xaac79482, 0x65bddb6a, 0x9aabd60c, 0xba931797,
- 0x3f0b26d6, 0x0522d356, 0xa7f03c69, 0x748a7f31, 0x357d28db, 0xb00b1fef,
- 0x18a8efbd, 0x787d5cff, 0x4ff459ea, 0x9d9f2d7d, 0xb4363a23, 0x763f3959,
- 0x196c292e, 0xd85ef383, 0xea02852d, 0xb9f6ddb0, 0x5d6a3ec4, 0xcd0b31e8,
- 0xe5b9eebb, 0xfb0f04d9, 0x90b49df6, 0xfad75c7f, 0xbcfeb958, 0x20fb8458,
- 0x9dfac5db, 0xf322931d, 0xfc21f749, 0x81f8c883, 0xf70805f4, 0x09e39082,
- 0xdaab3e5d, 0xbb123627, 0x7dedafd0, 0xe6bf625a, 0x3bdf9374, 0xffdfebb8,
- 0xffdde695, 0xff98932f, 0x7fc657c5, 0x4f1805f0, 0xc0f3e8d4, 0xda1653f9,
- 0x9ab4d61f, 0x173bc5cf, 0x77dbbefa, 0xf0c67b95, 0x571636fe, 0x3880b16f,
- 0xc10099b7, 0x381e29e7, 0x91ab2c06, 0x07511f9e, 0x0e7147a4, 0xdd60d658,
- 0x71467646, 0xc608e3c2, 0xb9d717db, 0xf70f9e15, 0x9de31b08, 0xedead657,
- 0x858f6aa5, 0x9e3570f2, 0x75e90b5e, 0x7113f84d, 0x51f6df5e, 0xbf6716b9,
- 0x7e16ed5c, 0xc303d0d3, 0xa7d2ebde, 0x87985db0, 0xc6c860e2, 0x66b85f76,
- 0xdd53e280, 0xda0ed47e, 0x03fcb817, 0x6f607744, 0x2beb4a82, 0xccc9f7dd,
- 0xfe79889e, 0x5187dba4, 0xa3f979af, 0xe7e266a9, 0x2aa68f9e, 0xfbcfc349,
- 0xe2eb1c32, 0xddaa55e5, 0x4e6f4e22, 0xb68f9df6, 0x186f0483, 0xb769ade7,
- 0xda07f9f3, 0xe28e96c1, 0x75b83b48, 0xf3d20edd, 0x168bd976, 0xcb6d3501,
- 0x3fdc0dfd, 0x91e24bc9, 0x480616db, 0x8fa7650f, 0x8afe13f5, 0xcfd4cdf3,
- 0xae52267d, 0xe91b7fdb, 0x4f08e291, 0xd46bcc8a, 0xd17e7a98, 0xb75c9121,
- 0xaf9a266b, 0xc96fd808, 0xef0f5f0e, 0x54338a9f, 0x9e1ec7da, 0xa7c40e51,
- 0x38901e9f, 0xf54e6b5f, 0xf922cd6f, 0xbfb9951e, 0x010bf0e5, 0x9bee973a,
- 0x9f44c506, 0x4e9fdeb1, 0xe38c830b, 0x2f042e6c, 0xff79bb4d, 0xdfd21e2d,
- 0x611fa69f, 0x86f7617c, 0x234afc80, 0xe7ca06e2, 0x61420bd8, 0xd721271a,
- 0x3ce32c57, 0xf3276e79, 0x7bf562cb, 0x4d941f29, 0x4d875c75, 0xfa23adf1,
- 0xb144ee6c, 0x657b1e9f, 0xb23eba79, 0x1bce857f, 0xe92f9cfd, 0xed3d0b33,
- 0x5f180abb, 0x399d1df3, 0xbe09a4d4, 0x6b2e76c1, 0x46a63adb, 0xf044dbc6,
- 0xdf79e8db, 0x44bc5bfe, 0xd75139bf, 0xb6448cf7, 0xfff9d88b, 0xe499f499,
- 0x35b35a6e, 0x7c4cf88b, 0x7bf64753, 0xf067ef5a, 0x2e7f1403, 0xaa922bd9,
- 0x8d0fcbc5, 0x4e3c9777, 0xea9cdd72, 0xf01575cb, 0xc300acf1, 0x76b8c49e,
- 0x57fffd87, 0xe91fff64, 0xf8a2dcfc, 0x4ddfc46d, 0xf16cdd7a, 0x7fb64ea9,
- 0x0ff34a9f, 0xfc746fad, 0xf6e9b5f5, 0xff8265ba, 0x4fb7d71b, 0x15399f5f,
- 0x4bc68df5, 0x4e67ee06, 0xff48060e, 0x78a0929a, 0xec3e3e13, 0xdd90f72a,
- 0xc5f4396d, 0xa6f7b238, 0x2807af24, 0xd66075af, 0x2dfbb22a, 0xfd636fa3,
- 0xbc85f4ff, 0x9e623922, 0xad256913, 0x697ebfe4, 0xcfe2cbac, 0x42fc75a5,
- 0x5d6323d7, 0xabdf6ee9, 0x11bc88ee, 0x915f758c, 0x9fbe80fe, 0x17f1eaf3,
- 0xff9c73f7, 0x2f4487eb, 0xd6ee279d, 0x3e02b771, 0x783b1bd6, 0x1a55c655,
- 0x1f7ba31c, 0xd8261d8d, 0xe4a6cb46, 0x5d39c454, 0x36326cb2, 0xb70d9a7d,
- 0x4c6c74e6, 0xebba6fed, 0xbd213496, 0x0b2021fb, 0xaf9d167c, 0xa4d24d00,
- 0x6bc53cc8, 0x14f3f155, 0xc91bf8cf, 0x9e56ff2e, 0xb4d84e62, 0xf7f292da,
- 0xbace2be7, 0x9f3df7a3, 0x2a2655ba, 0x31f42b94, 0x8a0c4e14, 0xa74c17bc,
- 0xf133537d, 0x067bff12, 0x2df6cad7, 0x5cdae5f5, 0xfbee4f68, 0x8b1d6db7,
- 0xd62d9776, 0xfa46f54f, 0x3dc0a77b, 0xd78ff943, 0x46ee30a6, 0xfef3273f,
- 0x12d3a9df, 0xc462b723, 0x88f7c06b, 0x27f2a352, 0x265f23e1, 0x4aed7e93,
- 0xb922df55, 0x7cc9740c, 0xe941244f, 0xd8e2b8b1, 0x03c23ed9, 0xd38bf7e8,
- 0xd6c43ec5, 0x6d17ce26, 0x317ec6aa, 0x269ce9c1, 0x79c5d847, 0x579fc8b7,
- 0x9c60f91f, 0x05dc3105, 0x02e4f1d3, 0xdec37f1c, 0xc34a6496, 0xf6f33fad,
- 0x5392ba4c, 0xe91df8a2, 0xa54ffeb8, 0xc236391d, 0x53835ba9, 0xf0a13f89,
- 0x93f21484, 0x94040a85, 0xf1f138a2, 0x14de22a9, 0x87c53cd7, 0x3ed850ff,
- 0xe5e12d7d, 0x2f58b0da, 0xa6c661cd, 0x7ae036bc, 0x2a635b5f, 0x6ffb578d,
- 0xbf934607, 0xe05d297a, 0x4d2f179a, 0xa02bef11, 0x74acff50, 0x41e7ae97,
- 0x5f0be513, 0x7d8cf3d2, 0xcfdc4c97, 0x6db0bf98, 0x3d44eca1, 0x3f6f0828,
- 0x76cd79c4, 0x4df24aab, 0x3f040e78, 0x771813da, 0x0c5c1ed6, 0x5dfae714,
- 0x7db095e0, 0x6fc0e257, 0x0e061f49, 0x773a5558, 0x876e704d, 0x977f1c54,
- 0x0f2b4f7e, 0x31c5b215, 0x2f98dcfc, 0x94e7fda1, 0xe0bd2413, 0x6504dff3,
- 0x88e35c3b, 0xd31277e4, 0xd5eba25d, 0x89b0c4ae, 0x260645ce, 0xe9875ee1,
- 0x7813a61a, 0x3cce835e, 0x2cbbfbf6, 0xe07ee703, 0xa49cba66, 0xe8207907,
- 0x2ac9f684, 0xa704d1f9, 0x7048ebc6, 0x3480deaa, 0xa9daae92, 0x6ed0fc08,
- 0x35e7251e, 0x6baed877, 0x36eb8713, 0x135d85b4, 0xff8f3f40, 0x8f3a36d5,
- 0x8393aa1f, 0xfefc3d99, 0x6c2fe92d, 0xf9cb1a6b, 0xa28c80bd, 0x949963b6,
- 0x7954eb4a, 0xb545e87d, 0x07c122f4, 0xb767afba, 0xfea1f689, 0xaa0ee7a8,
- 0xaf3f443b, 0x925f69d5, 0x8742f6c5, 0xf07843d7, 0xee7c297e, 0xded7b45a,
- 0x05297cc7, 0xd35eaeb8, 0xb19a07a1, 0x87569fdf, 0xe93ee872, 0x1aff5673,
- 0x3e57cfd2, 0x2148f35c, 0x665ddbf9, 0x9df9256f, 0x18cfc09e, 0x5668bf87,
- 0x1dd845b7, 0xe0c81d8c, 0xf33180fb, 0xf4d99ed4, 0xfdd7c233, 0xce9525fb,
- 0x03cdfbbd, 0x9aee88e3, 0xe85a3ff6, 0xfeed64be, 0x4b4f188f, 0x9a1afe19,
- 0x035b766f, 0x039b6bdf, 0x1b5ef9db, 0x9fbe43fa, 0x7f08f218, 0xe73a7832,
- 0x390886d9, 0xec2e913c, 0xe3fc060d, 0xebb55e29, 0xf6907af6, 0xedee58dd,
- 0x8d2275b8, 0x07cf57bf, 0xc035ef18, 0xf7c431a1, 0x971af04d, 0xa0fef3c6,
- 0x967a4152, 0x4eedaeff, 0xa3ffa22d, 0x3dbf02e9, 0x66702e9a, 0x89bf8676,
- 0xf1df5de8, 0xd69925b1, 0x8e343679, 0x4521b9f6, 0xf1c6714d, 0x1bf64323,
- 0xcab54f63, 0xd7fa8580, 0x2bf6079e, 0x14a6ef28, 0xef4bdf94, 0x8d594db6,
- 0x4ca2f7cf, 0xe2ae2852, 0xefe294fe, 0x0c6fb35e, 0xe7786ff5, 0xc7e4a9f3,
- 0xe74f481e, 0x607e7ff5, 0x1be278fd, 0x22497fea, 0x606ed9d9, 0x69d866bf,
- 0xbe29d901, 0x5ffa405f, 0xf63cf54c, 0xdd2cbbcb, 0xf72ed84b, 0x12ec809a,
- 0x01ed9ff5, 0xf849dff5, 0xf689c0ae, 0x664fefc0, 0x6dd5df3b, 0xa32718d2,
- 0xf5c49f5f, 0xbea91b92, 0xc9ccbbab, 0x05f74e76, 0xc35ec88a, 0x109c7887,
- 0x9d1224c0, 0xfca8be04, 0xe9993b88, 0xe7e5fc36, 0x86e3d06e, 0x75c5e29a,
- 0xca3965d8, 0xa4e2223e, 0xf4711ba8, 0x9edb33c9, 0xee817b40, 0x0fdc28d4,
- 0xffbf0bef, 0xd5563d5d, 0x59773ebd, 0xeeb3ae33, 0x07edcc84, 0x585e7df5,
- 0x7a4393d7, 0x86e2867e, 0xefdc5d3a, 0xb033e7a5, 0x675df74e, 0x094b1b6a,
- 0xd8aecd63, 0xb9ca987e, 0x412950be, 0xbaabf9c8, 0x99859b0f, 0xb5fe93e7,
- 0x9f2eba1e, 0x9ff5cdee, 0x920242b1, 0xc0e5fad8, 0xb5c45f6f, 0xf910703d,
- 0xe14e271f, 0x10ff5872, 0xcf018d6f, 0xc97ef6c8, 0x4bbd23f0, 0x5afb1f48,
- 0x123ae1e5, 0x4d8a8352, 0x3fd277f5, 0xbac016dd, 0x9f7b433f, 0x99c7e254,
- 0x3f49f7fe, 0x997e4ffb, 0xf7b96641, 0xb7c7d8b4, 0xd27cb45a, 0xb809d69f,
- 0xa7a38db5, 0x3c8ba5af, 0xe215b14f, 0xa57e4b9e, 0x009cc1c7, 0xfef1223c,
- 0x5106765c, 0x655a17ee, 0xe7f882cd, 0xce56043c, 0xe7a37f23, 0xfd01ef6f,
- 0x941fe1a7, 0xf57abdcf, 0x182bc21e, 0x627deeb7, 0x89bfb9c4, 0xbb6d69f4,
- 0x6b84ff04, 0xfc4cf75f, 0x5e46097b, 0x1db6beeb, 0x3ca0c647, 0xee8b9eab,
- 0x9ee861b7, 0xbdf7887b, 0xefa39a1b, 0xae957c1b, 0x308996e3, 0xea0b7091,
- 0xb307fb13, 0xd4569d02, 0xfd3257df, 0x7e5e109f, 0x84f824c9, 0xf2ed957e,
- 0x671eb713, 0x1a3f844a, 0x8f7c00b8, 0xe8676f28, 0x99d7dd30, 0xa5e59cdb,
- 0xa22ae639, 0x165b6e7d, 0x825019c7, 0x9837dd32, 0x19cbf9ad, 0xd3b4075f,
- 0x9d642f74, 0x89c127ee, 0xa3bf287f, 0x8e9d6baf, 0x460beee7, 0x82073dd3,
- 0xdacf348d, 0xd1fee29d, 0xbff19dfa, 0xc7d5a813, 0xc9d4f0d9, 0xac0e9423,
- 0xabf7450e, 0xdb53f9d5, 0x05bcfd16, 0x9f181278, 0xfccf7d11, 0xfc43ef4a,
- 0xc5f02cc9, 0x4638fadb, 0xc219b5fb, 0x7920d67f, 0x410ddf24, 0xb37a4839,
- 0x0b240a4e, 0xd58e0b7c, 0x865df748, 0x65f7e8be, 0x73f9d6ef, 0xbc2fae97,
- 0xfabf7c2e, 0xe7482919, 0x24ff7780, 0x427bfe9a, 0x1f49cbab, 0x5d6af562,
- 0x6df199b3, 0x10b46c15, 0xabd58dbe, 0xd97d21aa, 0x1638a16e, 0x7e354fab,
- 0x0b7432e9, 0x4b7ffe5c, 0x98737af7, 0xffeb4cf3, 0x3ca5e4a7, 0xdfadbdd4,
- 0x745e50b1, 0xf9087da4, 0xa27a1956, 0x5defebaf, 0x7c86edcf, 0x9614c0a7,
- 0x15da456f, 0xf1a283ee, 0x50cb6ef4, 0x7cf3929e, 0x38139d83, 0x51e86e3f,
- 0x3ae538ec, 0x14fc5f2e, 0xada17970, 0xa2f84ed4, 0x2bc9b8ff, 0x4c7f9ca9,
- 0x4c3e442e, 0xe103203f, 0x89f6fe8d, 0xfe90078f, 0x37c513a2, 0xfa7cbe52,
- 0xd83f8c09, 0xf8b3a7be, 0x115fe457, 0x7d91a4e1, 0x4ecaec2f, 0xc783bdfb,
- 0x7fddf8e1, 0x4af1e8bc, 0xcbc7c3f2, 0x095c698a, 0x787ee9db, 0x1a871e91,
- 0x7bd9178e, 0xfdd1e222, 0xbedf2219, 0x47fbf3c5, 0x78b05f69, 0xf94bd9b7,
- 0xff66c58e, 0xafa404a6, 0xdbc905e8, 0xe91db380, 0x8d24f43e, 0x52a4f68b,
- 0xeef166be, 0xf6a21def, 0xd3125dda, 0x28bedfdf, 0xc7c5177f, 0xb8a5eca0,
- 0x577edfd7, 0x7384bdc1, 0x7053dc0e, 0x477cc457, 0x595f8552, 0xe399957c,
- 0xfb68ef71, 0xcf292b2f, 0xff60eda9, 0x1eeafbd0, 0xb0577f0b, 0xae0f024b,
- 0xf0e788f3, 0xbd0f89af, 0x085a4efb, 0x9eb697e4, 0xf1c4f4b4, 0x017946cf,
- 0xce6171b7, 0xf0b76ebf, 0x7fbdca3d, 0x6b7ad0b0, 0xf388fb9e, 0x126d5569,
- 0x67aaa7fb, 0x794aa0e4, 0x58af039e, 0x9a6b3f48, 0x8accc825, 0x3b73376c,
- 0xffaa51f9, 0x65f859b1, 0xe8d7ef43, 0xbde86e7a, 0x746b0761, 0xd6d775ff,
- 0x17bf3d68, 0xf1a32db4, 0x579a7bfd, 0x7ba03df3, 0x5ff7c7b6, 0x4b5c1f86,
- 0x2b8c52fb, 0xee8a9f6b, 0x7e90df77, 0xc7bfd807, 0x3257c9fa, 0x3cd8f3f4,
- 0x1efd23c8, 0xaf19af0c, 0x7e7d3da0, 0xc43c6ab2, 0xd71e3bc9, 0x8f1180f1,
- 0x8e26c307, 0xfafdb167, 0x285a2eda, 0xfe76d68e, 0x796bf199, 0x872c67fb,
- 0xbe0ef6ca, 0xf83d7aaf, 0xaf1f1037, 0x093bb76f, 0x08f65747, 0x6ed25fbb,
- 0x6a25060d, 0x7c91350f, 0xef8a0ffb, 0x4aaf023b, 0xf740a38c, 0x7e756b7f,
- 0xb7f9d5ae, 0x6367f716, 0xbe8adee8, 0x772fbeff, 0xe2ba11c7, 0xdf3fa351,
- 0x993875d0, 0x8404b8f8, 0x12125a7f, 0x8790c9fe, 0xc6465f11, 0x936f81d1,
- 0x5bb7d73c, 0x52f8bef9, 0x6d2d3fdd, 0xc593df16, 0x51fe8bfa, 0xddff9176,
- 0x8d8de82b, 0xd1ad35a7, 0xd232bbfd, 0xea0fdfd9, 0xc313f878, 0xa8f2e8df,
- 0xe53b001c, 0xb2a897e7, 0x756fc837, 0xe77f342b, 0x63cf8954, 0x2989d53b,
- 0x194beef1, 0xce3a9be5, 0x28cbea37, 0x43fd864f, 0xc88eedce, 0x998dfc7d,
- 0xcd54af02, 0xcf240391, 0xb2cf7d88, 0xfbb8aca2, 0xba44c81e, 0xd77b18df,
- 0xee45a64f, 0x391db47b, 0xf23f67a4, 0xf7495e3c, 0x859b6a8c, 0x8d9be87f,
- 0x8e10a6e3, 0xb5c5c607, 0xed20d6cd, 0x4f516a4f, 0xd2307bf8, 0x76bfb20f,
- 0x07e91169, 0x991c1bee, 0x3a72cf48, 0x2ff5c4aa, 0x8e38c36f, 0xfb2f2fc3,
- 0x2baaf58c, 0xf91bac5b, 0x1f6f1996, 0x6a1fec61, 0x6a9c092e, 0x7a51af3c,
- 0xd3511f78, 0xb749ee2e, 0x5c62fa1e, 0x7fdbd216, 0xadc63fe0, 0xa64172c6,
- 0x25adbf88, 0xbee98fa1, 0x6cbbe7cf, 0x90e8f171, 0xd89a97bf, 0x3dcc6a0e,
- 0xf6578c19, 0x859c2e23, 0x4fedf37e, 0x7ad1df79, 0xca4ee128, 0xf1adf5c7,
- 0x837e778f, 0x13601a9c, 0xd04ddae3, 0x9ee125c4, 0xd6b81c48, 0xdd0fee29,
- 0xaa49c7ab, 0x7d7a8c3f, 0x505df62f, 0x03eecf14, 0x2349e65b, 0x1bf0dded,
- 0xafbebad5, 0x85b1d82f, 0xf163e08e, 0x476eb551, 0x2e39fc88, 0x1ba2e2c6,
- 0xb4f5a333, 0xc644ede1, 0xb25dfdb9, 0xc8c47293, 0x268c5fd7, 0x7ef887dc,
- 0xeb3c9c42, 0xf65ebaa7, 0x0dbee7ea, 0x9be665b3, 0x0d288e69, 0x63fc851c,
- 0xe93fe97d, 0xcb1c5208, 0x04caf83f, 0x9dfaff92, 0x2445e7d1, 0xdfdf3f3f,
- 0xaafcb20a, 0x433e7643, 0x3a5fda32, 0xd214caf8, 0xbfb786b3, 0xf97211cc,
- 0xbee2c722, 0x29467d3c, 0x6bff6249, 0x77fec492, 0x4c93d2af, 0xfddaaefb,
- 0xfef22fb2, 0xbbe721bc, 0x4501fd75, 0x65d7f3ec, 0x686f5caa, 0x3a617a17,
- 0x7f9c4a20, 0x98f3c8a5, 0xed11fe79, 0xdf2fa825, 0xe880b710, 0x9ad7d942,
- 0x6aef5807, 0x9e989a4f, 0x198393da, 0x05ef11d9, 0xf24cdc68, 0x801b0d7b,
- 0xc81d88fd, 0xefa52ebf, 0xf4beb10f, 0x59c604fd, 0x523c2647, 0x64adce29,
- 0xc0f5bf20, 0x239355db, 0x3d05fffd, 0xc1f103ee, 0x09e72843, 0x87cebf31,
- 0xcf42b04d, 0xae3d0813, 0xee2c71d2, 0x8ec89aaf, 0x5757f763, 0x0e1b938a,
- 0xc7f28158, 0xf9581fb5, 0x07e7d03e, 0x1dfef2d6, 0x9327f92e, 0xffbf019f,
- 0x381f2a6a, 0x3d3276b8, 0x7de0fcff, 0x53de7357, 0xaf9514da, 0x1e7d1008,
- 0x797f51c2, 0x97c276f7, 0x90e30a5d, 0xefd3aea2, 0x9eeaf9d2, 0x9b7f3356,
- 0xc677bd59, 0xc22481e3, 0xe94b454f, 0x9d3d9dbb, 0xe21feb0a, 0xd947032a,
- 0x289d4719, 0xe3851c66, 0x165c82f8, 0x71a4ab1f, 0x5314944f, 0xc9db0937,
- 0x1c274d9f, 0x55c618e5, 0x9cff3d06, 0xdfd9f829, 0x13f9c091, 0x3d082609,
- 0xba28ec83, 0xcebeb437, 0x9b436438, 0x86bdf51c, 0x4ceedef1, 0xd7b0ae71,
- 0xa490b3d0, 0x16ed1eb1, 0x3db686e5, 0xf58eb419, 0x49eb10e6, 0xb459b343,
- 0xd02512ef, 0xfe0ccdf9, 0xfc4038d8, 0x508f4639, 0xc12c4b2e, 0x77db84b1,
- 0xea079d0f, 0xe28239f7, 0xe7635d5e, 0x686efe44, 0x3b8f73b0, 0x4e39fc5e,
- 0xda4833e7, 0xcfb12cd1, 0xf3af6d89, 0xd1c67c88, 0x1e2fc233, 0x1c9fe85d,
- 0xa0063fcf, 0x25fbec44, 0xe6ad7e5d, 0x86e7788a, 0xdf223d1b, 0xe06c73b4,
- 0xef71e928, 0x373e04ee, 0xfc8975ec, 0x974b696c, 0xac9fdf42, 0x5066956f,
- 0xfb9f5a3c, 0x829f7f1e, 0x83f662f5, 0x6e7cfde1, 0xbbbcdd5a, 0xc7438b5c,
- 0x1f111eb5, 0x01dfe897, 0xbd57d08f, 0xd37814fd, 0x23da7df5, 0xaa735e74,
- 0xdf14ecd2, 0x4aef8999, 0xf9fdd06f, 0x199bd78d, 0xd5029d37, 0xc43fce2c,
- 0xdd32c539, 0xfba0df2f, 0x3bdf11f9, 0xe99b033f, 0x7bf6229c, 0xdfafc367,
- 0x02bf8fac, 0xf6371e34, 0x759bf5bb, 0x2fb3783c, 0x4ca5f9fa, 0x40e6071d,
- 0x10f3f90e, 0x1fbe17c6, 0x71c09791, 0xa4e1697a, 0xbe8338b8, 0xeff55703,
- 0xe434a9c0, 0x1ef790de, 0x1da3bfc7, 0xdfcd7e67, 0x80499c13, 0xc5ce7109,
- 0xe19fe386, 0xf2126e3f, 0xaa2dcfd6, 0x4346829d, 0x077017ee, 0x331f9916,
- 0xe7463ee4, 0x3df1ffff, 0x22505ca0, 0xcacf25f3, 0x3a1e31fe, 0x32f5b09f,
- 0x7015c6fe, 0x8d75c41c, 0xce35d7d3, 0x2edf111a, 0x571d5a8c, 0x97d7877f,
- 0xc471101a, 0x9e4765cd, 0x75627195, 0xfbefe248, 0x5f62c3aa, 0xf6265d5b,
- 0x02ad39b5, 0x49bcaea7, 0xbb126a0a, 0x9f44d3c3, 0x6ccb3fa1, 0x7a180f02,
- 0x5d2fc432, 0xf09da87f, 0x3e3a0dc1, 0xc9a3d588, 0xf94e5dd0, 0xc9345be6,
- 0x472af74b, 0x6abf3f7c, 0xeee4ebda, 0xa83fa72f, 0x22effc6f, 0xf7d1eac4,
- 0x0f12fe3d, 0x07bad3e5, 0xb8e21657, 0x38fef347, 0xe6a6f48e, 0x2df37632,
- 0x3b13888f, 0x7ca3811d, 0x3f45a4df, 0x6bc96fef, 0x747e21eb, 0x5ec7e302,
- 0x3a96f757, 0xbcf9ab81, 0xc09c3abf, 0xb75643df, 0xb0bbf9db, 0xc486d6ea,
- 0xdb7fe429, 0xeb1daf65, 0xcb27ad95, 0xc5959f88, 0xad4a3ee2, 0xb38bdc5d,
- 0x10b7fdb9, 0x3b7bd77d, 0x2df9cfa2, 0xfba8bf3d, 0xf58f3d06, 0xa3091b6b,
- 0xf9f7ffa5, 0x5f3a8d9b, 0x662ebaea, 0xfea9c14c, 0x26afe690, 0xfd7fec7d,
- 0xd71d0b45, 0xa5794ed5, 0x6d88ae9c, 0xefdca8f4, 0x268ee6fa, 0xf41af34a,
- 0xf93a6477, 0x707351f9, 0x82d2e32c, 0xd30fbb2b, 0xa98dffb0, 0x3afaa714,
- 0x225aa6ba, 0x0eb7bbf4, 0xf91c73fd, 0xb7498035, 0x494b855b, 0x25e3a15a,
- 0x07b5c761, 0x3e50670e, 0xb7ec97a2, 0x9277ca80, 0xdeacb1b3, 0x12792a7d,
- 0xa2bd96e1, 0xed19c21c, 0xa503f732, 0xa4e6e727, 0x3336fa48, 0x6242177d,
- 0x9c9e801c, 0xdb230b1b, 0xdb5fff1b, 0x27a4d3ff, 0x289eb6d5, 0x84f837fb,
- 0x3efe7cbb, 0xcad07037, 0xbce808f7, 0xc72115c6, 0x347f7457, 0x644b370b,
- 0x7ce873a7, 0x3b41227a, 0xbaa0ee05, 0x95256102, 0xb2c38bce, 0x96377fb8,
- 0x7d4cf7fd, 0xb84a59fe, 0xcee9ee83, 0xe737cfd1, 0x5bf73742, 0x6a5c0300,
- 0x8befe4e0, 0xe5cbc04b, 0x29785b6c, 0x5082f1c1, 0x099fbf88, 0x73ae2867,
- 0xe63bfd36, 0xe61ef238, 0x0ce7029b, 0x0e74c87e, 0xc51bee26, 0xd75ba7ae,
- 0xf09a59c7, 0xe81d043b, 0x086cee7e, 0x35fbb9f1, 0xbf9fa3d0, 0x3cc75fc7,
- 0xb9d1f7dc, 0x3b6835db, 0x208fcc89, 0xeb4f9ff7, 0xa7ade391, 0x198b2967,
- 0x9f449cca, 0x7d30ce14, 0x75f2bf6d, 0x4d6dd3f4, 0x35df57ca, 0xe283f7d0,
- 0x6f4b73e1, 0xd3ef1bfb, 0xd349627d, 0x97b1bef8, 0x7da6c7be, 0x1de9584e,
- 0x001363f2, 0xe6b3ddfe, 0xc66f6437, 0x07e01af7, 0xfb11e7be, 0xf72d06bd,
- 0x3df0c67c, 0xedfee335, 0x950ae0ce, 0x72ac6fee, 0xaddff8db, 0x9b8db229,
- 0x87ca794e, 0x21bffcd2, 0x6a40fabd, 0x2883c49e, 0x638c19c1, 0x83b2bd75,
- 0x2fd69b36, 0x22f7c669, 0xf432fac0, 0x006401ef, 0xb763b77f, 0x1e69ef8a,
- 0xa5b43d41, 0x74abf6b2, 0x2e1e1a0f, 0x6f2f0955, 0xf4bcd971, 0xe895ae5d,
- 0xdbd30fb5, 0x2ff71368, 0xb16bfb8c, 0x19b46c7c, 0x8daf4a79, 0x77cc7671,
- 0xfcda773e, 0xbfe89bff, 0x9324a93f, 0xcbfe6070, 0x3f7c3df3, 0x7758c129,
- 0xc3eb8d89, 0x37191af7, 0x6a7dd136, 0x1d31aba4, 0xe1e21ef8, 0xba149ca4,
- 0x25d8d51f, 0xa63753ee, 0x9b7fd807, 0xf3fb12fd, 0x4ed2cec6, 0x0e83078a,
- 0x6eabdf0b, 0xaa34f974, 0x4421d207, 0x3ef89ffe, 0x69bbe0df, 0xfd21ef98,
- 0xed91505e, 0xde5157d7, 0x4a1b9a7f, 0x6169bde9, 0xc0f1126d, 0xe5061ef8,
- 0x4e9519e0, 0x7befa3cf, 0xfbe4e281, 0x501c8617, 0x9d995831, 0xb90d7cba,
- 0xf8ef8d38, 0x3bea2535, 0x8f5e437e, 0x98b90a24, 0x44cc26e9, 0x71a5577e,
- 0xf061e563, 0x8f00bffd, 0x30b1ae40, 0x0030b1ae
-};
-
-static const u32 xsem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x243bff00, 0xa3f0c0c3, 0x4aef811e, 0xf1303031,
- 0x12d18aa2, 0x6064e3ef, 0x6062e010, 0xfbe20530, 0x330c0c3c, 0x204cf480,
- 0x6066e516, 0x1ae20310, 0xc40dde20, 0x19f8807b, 0x1039fc50, 0x1be200ef,
- 0xbefd103c, 0xfe0c0c4c, 0xc4081c40, 0x95fc40c1, 0x1be18181, 0x73f6f103,
- 0x4c30330a, 0x2ff04715, 0x249fd903, 0xc1ffe7e9, 0xe90c4386, 0xa071df6b,
- 0x10acf37d, 0x7b20467c, 0x9aaa15be, 0xcdf85605, 0xbf268858, 0x18bf8d08,
- 0x0372fe8f, 0x4d5afe54, 0x81b5b334, 0xcd4909e9, 0x6efc4d3a, 0x40aac741,
- 0x3101a9ff, 0x5ff1ad00, 0x000368ca, 0x00000000
-};
-
-static const u32 xsem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5947809, 0xe77df0d5, 0x9926665d,
- 0x6c81bc99, 0x44d84eac, 0x4242740b, 0x61db101a, 0x8311688b, 0x9817054b,
- 0x264f6408, 0xdac7f520, 0x0040cfef, 0x8b435151, 0x03b45a35, 0x341b0504,
- 0x024180d8, 0x2d82e00e, 0x5d6ad8d5, 0xc8a0d2da, 0x1b80931a, 0xcefc5dfe,
- 0xc9bef739, 0x82264efb, 0xf5ffffb5, 0xf8f8fefb, 0xf77bee5c, 0xce73ddb3,
- 0xe28ef73d, 0x8b94c718, 0xff12fb18, 0xdd98c7be, 0xd71b18c6, 0x2356329d,
- 0xcf2d4ad2, 0x03d058cd, 0xac62ccff, 0x9785addc, 0x653633a7, 0x5ef91a87,
- 0x4837e412, 0x6de43b61, 0xde549d7b, 0x23e79ebe, 0xa0cfcd6e, 0xc83aa3fc,
- 0xdeded04b, 0x5065c0f2, 0x6643b9de, 0x91dbb11b, 0xc2963671, 0xe30731d8,
- 0xcf90597f, 0xc9c0ac66, 0xf61be5b3, 0x45f6c5cd, 0x84e6764d, 0x1577cafe,
- 0xf20cbcce, 0x86550785, 0x2f37ca55, 0xbe43fad3, 0x60352c38, 0x9f3263be,
- 0x1ca7685f, 0x3bf50cde, 0x37292d3c, 0x553b18b8, 0x8d5e60e5, 0x4b776ab1,
- 0x18a3f5ca, 0xcf6f092b, 0xf52576c5, 0x3a970f92, 0x97e6c765, 0xb6bae1fb,
- 0x97bb3e4a, 0xf12dd2b1, 0xcf923bcc, 0xfff84be1, 0xf91ca358, 0x862f941e,
- 0xb7e83275, 0x32e4d590, 0xab5fc719, 0xf0dddd79, 0xd3a5553b, 0x7cbe4638,
- 0xed038c2b, 0x7c969e2a, 0x1b0ac4b8, 0xf8c0340b, 0xb39cbbed, 0x7d70b937,
- 0x6e11b4cb, 0x1addd75c, 0xe70c2bd6, 0x717a74ef, 0x5cb41b7e, 0xbf592f28,
- 0xd5182b41, 0x96e95fdd, 0xd579d6be, 0x980d4d0e, 0x53d3a3ca, 0x47798c55,
- 0x184be774, 0xbf4037f3, 0xb36b094c, 0xff7f7746, 0x96322580, 0xcccbfd8c,
- 0x1feee8eb, 0x43df4920, 0x013fc16f, 0x6e3da15e, 0xb781ab82, 0xdbfc3ac5,
- 0xb3b78ddb, 0xd2a3c0ba, 0xdfee6d99, 0x3c401f48, 0x106a7cc0, 0x11ae904e,
- 0x644cf3f3, 0xdfe81493, 0xc4ba67e3, 0x918f5f7a, 0x9f2ca8d6, 0x420b58c1,
- 0x78cafda3, 0x116c6bc8, 0x93f631f3, 0xa9fed915, 0x059fbf90, 0x57bce2e6,
- 0xc4228148, 0x690d6313, 0x24abbf48, 0xffd71b36, 0x94349c03, 0xf407eaaf,
- 0x99af7009, 0x9649bd96, 0x3093dcc4, 0xbdc4f05f, 0x214fd4e9, 0x3f42a3f5,
- 0x8fdfcf43, 0xe9639b9e, 0x322dcf47, 0x7ea4a9fa, 0x4fd6179c, 0xeb04ee4d,
- 0x8c4b727c, 0x7ea4ee7e, 0x2eb617dc, 0xd6898afd, 0x46515cf9, 0xf54e24fd,
- 0x97d400b1, 0x2d607a0d, 0x5dca197e, 0xef6389f5, 0x98ba6665, 0xdff912bc,
- 0xa6625c0d, 0x389c848b, 0xfa261d0b, 0xd0f258fb, 0x5bec7e93, 0x44830f22,
- 0x5f1a3512, 0x5c91afeb, 0x41dfd498, 0xbbfa3bf9, 0x31dc2e48, 0x0eb17021,
- 0x59b1c0f3, 0x816bc83f, 0xe831eb6f, 0xb129e61a, 0x36bd4c34, 0xefcba34c,
- 0x261c3956, 0x88dbf80f, 0x683ed023, 0x08911ceb, 0xa4d2f5f9, 0x365c205f,
- 0x27c11b33, 0x5895664e, 0x48cece2f, 0x9e9ddd3e, 0x826429bd, 0x8041ead3,
- 0xdfbba97f, 0x0d206ad5, 0xbb2b6be9, 0xb6f48421, 0xa7ac106a, 0x854f633f,
- 0x14848fae, 0x20a83f68, 0xd769e10d, 0xe3cdbf80, 0x28fe306b, 0x1c19ff1a,
- 0x3f8e0777, 0xf6f8e7ae, 0xf1963921, 0x2c8b831d, 0x18343be3, 0x177de81f,
- 0x0f8c55bb, 0xd8c09bf0, 0x685ba1f3, 0x22e0fb7c, 0x8d6eff1a, 0x8fc65915,
- 0x05ff1aeb, 0xdea5f71c, 0x82643fd6, 0x4b83fd75, 0xf8d7ebac, 0x0b655ffa,
- 0xb471f8c5, 0x16875ffe, 0x2e0ff5f0, 0xf3b7ebe1, 0xf7c6bb7e, 0x75ffc174,
- 0xdeadf71c, 0xa2743fd6, 0x9517fd75, 0xe76fd759, 0xcacbbfe3, 0x1a2ef8c5,
- 0x1950bdff, 0x6545ff5f, 0x0f66be34, 0xb48e90f8, 0x61957101, 0x040d9f18,
- 0x19254886, 0x6474a7e5, 0xfda0c61f, 0xe084363a, 0xa71c4770, 0x80e2cfbb,
- 0xf2dd5cde, 0xa381858e, 0x08559e40, 0x9fad2f9a, 0xa59ca1a4, 0x0b7b9072,
- 0x341754c5, 0xb0dfb4c9, 0x70f0f675, 0x937b6f98, 0x82fcc21c, 0x65879775,
- 0xbcd8efda, 0xb0a76c3c, 0xf0ff7e08, 0xcd1bd1a1, 0x174e8aeb, 0x5ac7a8d6,
- 0xe7c47c2d, 0x46cc9a13, 0xa6fcc256, 0xeb8c1121, 0x39031fce, 0xbe7e40ca,
- 0xd314720f, 0x078c2ae3, 0x9c828fdf, 0x6f999a65, 0x3c7df196, 0x991cdec4,
- 0xff827282, 0xbc38531d, 0xc2912d8f, 0xd6cfff08, 0x3e50d22e, 0x0789ac2d,
- 0x23cf77a0, 0xb9d4f028, 0x28de1ecb, 0x08bd3c11, 0x15891b9f, 0xa033fb19,
- 0xb6801fb5, 0xa5afb6b0, 0xbc2c2ddd, 0xcfea0d32, 0x483f935f, 0x3cdff587,
- 0xc6563edb, 0x07f983fd, 0xd98f88d8, 0x630e5b00, 0xaad71bb3, 0xe3732003,
- 0x56fdf56c, 0x0139fb53, 0x22e6fe6b, 0x0d5dbe6b, 0x37d436ab, 0x01b6258a,
- 0xd2b5bdfa, 0x938c6e5a, 0x78e1f528, 0x20fde315, 0x56f7cf85, 0x67e2c74c,
- 0x573af09d, 0xf98d6de7, 0x5952ef04, 0xd6cbf684, 0x4ff84664, 0x9d017aa6,
- 0xbe7a3baf, 0x3f875573, 0xf733e60f, 0x19e0994e, 0xbdd6ff3d, 0x18db7ef1,
- 0x563f6b48, 0xd7a30491, 0x79ff3d13, 0xa3d7a34b, 0x1f961e93, 0xe9cefe8a,
- 0x829e9a24, 0x1efa934d, 0x6f2bd535, 0x51efb2b8, 0x6e957d13, 0x17c96599,
- 0xea58e787, 0x5be6d617, 0x14d617ca, 0xafe7ca5b, 0xe7c9645e, 0xd4b4ee87,
- 0x9974b79f, 0xcad6fca5, 0x37e52c7b, 0xe4b5ad17, 0xb11e04e7, 0xf671bfd4,
- 0x6db94b06, 0x20d725ef, 0x25bf551f, 0x3e37dc33, 0x007b1d75, 0x5d4fc1f5,
- 0x71f10f8a, 0xf88d2aa2, 0x979554e0, 0x4ca6f6d2, 0xc1cb8047, 0x16715402,
- 0xad086b2e, 0x9972889e, 0x5e2cfc91, 0x1a1433b6, 0xe4adda08, 0xb5c9f825,
- 0x09008b1a, 0x174fac4b, 0xa6ca771d, 0x94f3d6f2, 0x67a302d7, 0x5b972cf6,
- 0x6e0f7f63, 0xe508bfcc, 0x00f26f4e, 0x3ee006fe, 0xf7f621d7, 0x8932f2e8,
- 0x33bf99e5, 0xfcf89cb6, 0x65b3909c, 0x6507971a, 0xcc9bf6cf, 0x8c8f983c,
- 0xf1aafca8, 0x28a8001a, 0x4f3b5127, 0x2e007a46, 0x50cbd0b0, 0xedb77f0b,
- 0x155e6993, 0xa3c61328, 0x235bc9c8, 0x1c899ca1, 0x68dd7c18, 0x7eff879c,
- 0x29aef909, 0xb6f5f699, 0x8f7de9aa, 0x3c9f882a, 0xcd544f4a, 0x5558f4a6,
- 0x55a3d280, 0x5fbe9445, 0x6b694955, 0x0f4a52d5, 0xfd288557, 0x4a6ad553,
- 0xa1aaabdf, 0x5aaa9df4, 0x1550ff4a, 0xcabdb4a6, 0x0fc1a94f, 0x4937f25d,
- 0xaec2abe8, 0xf2879d80, 0x565ac567, 0xe216dd40, 0xf21a5f73, 0x67d759f9,
- 0x3f1f5023, 0xa19d8efb, 0xbc1bdfbe, 0x77ade9a2, 0x5f49fa3c, 0xfe030829,
- 0x3b967b33, 0x9c9e38e3, 0x819d3636, 0xf867ba3c, 0x46dbbe13, 0x92415e51,
- 0x37c90d81, 0xdfa31dcb, 0x75f08c61, 0x7f313c3e, 0x016b98e7, 0xfd1ec71f,
- 0x7bf6366b, 0x717fec4e, 0x87da6407, 0x0f936459, 0x1b8265f1, 0x3b9d6bed,
- 0x0f3fbc84, 0x82ea3efc, 0x0660cb5f, 0x274904e9, 0x68db3bfa, 0xb1c20a67,
- 0xc40c3e39, 0xdc1ececf, 0x5c7e41e4, 0x8fd3669c, 0x918380c6, 0xeba43796,
- 0xd3fef32e, 0xad9fcd64, 0x9037a691, 0x5c26f63c, 0x4ae91a3f, 0x430e8fd7,
- 0x6a51a7fc, 0x4d38b3f4, 0xbf028fd3, 0x3432da9e, 0x61dfef81, 0x27d60fbe,
- 0x5d82bd12, 0xd5fff548, 0x1fade9f3, 0x358c3e63, 0x281c0fb2, 0xe86ca00f,
- 0x1e9dedf9, 0xd13e5778, 0xcd5f10f2, 0x2fa867ea, 0x5fffc1c4, 0x157ec10e,
- 0x06fd1bca, 0xfd90e41b, 0xdebdf8db, 0xf3b41e32, 0xb637361a, 0x156e9deb,
- 0x2ba0cc76, 0x1a1a5790, 0x3a2764cb, 0x92beeb75, 0x9b07c968, 0x7d96e9fa,
- 0xfc01ff06, 0x4152820f, 0x541329ba, 0x56b8a1d4, 0x23bf304b, 0x2f013f28,
- 0x2bd78941, 0x016ab477, 0x0b63912f, 0xe5b719ea, 0xbde77418, 0xef208ff1,
- 0x6546fe4f, 0xdff962f7, 0xae505660, 0xf720c51a, 0x2f9f906c, 0x9635b772,
- 0x77b940ce, 0xf9f7c6d2, 0x83cf2c05, 0xab114f46, 0xe73d46c9, 0x8e9b6623,
- 0xfb11fff4, 0x64d3279d, 0x1a6cf86f, 0x6afe73ad, 0xfa0b3eeb, 0x585f2599,
- 0xb017cd6b, 0xde90536b, 0x2ca9d60b, 0x5a5f212c, 0x9d36bdcb, 0x95642dfa,
- 0x41dec8ab, 0xbdc6057b, 0x00ca674d, 0x73f95f98, 0x43e7658f, 0xae363bfe,
- 0x7bf61ba7, 0xff3e1f71, 0xe6b0a492, 0x1a0ff287, 0x19707f33, 0x55e1f6c3,
- 0x6e42a728, 0x7accdbe6, 0xceebefe2, 0xc6be7a3f, 0x8fc3d27e, 0x6f21e620,
- 0x18e1fc91, 0x9b34da76, 0x10adf424, 0xbae037a5, 0xbe6b7a4d, 0x2f918380,
- 0x19dfca8f, 0xe9a7ff95, 0xe859892d, 0xc81488ed, 0xfa7325b7, 0x52417d42,
- 0x37c0b53a, 0x47ad3fe9, 0xd2ffe5ff, 0xff4207fe, 0xeffe96d9, 0x3ff697fc,
- 0x57fcc7ac, 0xfcbfeac6, 0x433b6db9, 0x9e4a6f20, 0x60c3c879, 0xd4a93a1f,
- 0xef00f8a4, 0x7a579b65, 0x284e0e90, 0xf3d20f21, 0x3d3cb0c9, 0x46ec3d16,
- 0xa23f207a, 0x5da125df, 0xfe84ff85, 0xdf753d4f, 0x3e67dc4c, 0x64eaacdb,
- 0x47b16d2f, 0x15afc0ec, 0xd833c58d, 0xe11fca18, 0xc8cfbbf9, 0xd2b26f98,
- 0x0f93c967, 0x0dffa0a5, 0x13d84528, 0x2a97d211, 0xc5cc3eea, 0x3ac8287d,
- 0xdba2cf89, 0xfae7f8e1, 0xd7cc7c90, 0xc3967a12, 0x0fcf493c, 0x1b04b80a,
- 0xa3233bef, 0x72b593ef, 0xfd54683f, 0xd4ffa122, 0xc749dcdb, 0xdf6274c0,
- 0x7941df61, 0x8583c069, 0xbd53feb9, 0x4731e1f5, 0x756d3e60, 0x2648f1bf,
- 0x767c1938, 0x2ffe61b6, 0x2ef6f79e, 0x9d85db8f, 0x4c2eddd7, 0x424dbced,
- 0x69e66b6f, 0xa0f11a99, 0x41b65c5e, 0x73e085f5, 0x4f4db6d9, 0xea768a3c,
- 0x70df76bb, 0xdb74bfe8, 0x00987f4b, 0x6aedd2f9, 0x0cbe0cd2, 0x8dd29497,
- 0xbffc2097, 0x1e376c74, 0x92f57e4a, 0xbfcd1de6, 0x374fb8ff, 0xefb74a3e,
- 0x9ee8d8d3, 0xb0d298f0, 0xc5756b4f, 0x91c34bc0, 0xaaafd45c, 0xa1ae7eb7,
- 0xaf72793d, 0x63d352c4, 0x4bc373c0, 0x9c2027a4, 0x4f028f08, 0xaa8b785d,
- 0xa0bc041f, 0x14f0373c, 0x9080fe5d, 0x779fd83f, 0xd3f3d114, 0xf95fa3cf,
- 0xd70fbb3d, 0xedf4f45f, 0x71c75c1e, 0xf5d392a5, 0xfc532b63, 0x1a916e30,
- 0xe529d14a, 0xff1e8bdf, 0xe15bd121, 0xe14c3f1b, 0x9fbfa0f6, 0x50a6f68d,
- 0xc2df5c3f, 0xfad037f5, 0xe880580a, 0x3931e8ae, 0xa7e90c2f, 0x3dbe9b0a,
- 0xc8645f06, 0x6f8e2f9c, 0xd60b8504, 0x12ed1c77, 0x4efeb3f4, 0x7f266f0e,
- 0xfc8622c8, 0x3fc343ff, 0xfe5316ce, 0x93c70753, 0xbe09b643, 0x4ccf6d02,
- 0xb77775af, 0x0d4e7e20, 0x1fa2a7f2, 0x9094c82d, 0x25f48780, 0x31bf2bf4,
- 0x87e3952d, 0xd16c9579, 0x2980f40e, 0xb7eb1df8, 0x18e77ea8, 0x65f63b4b,
- 0x4bf8f77a, 0xef30f8c4, 0x8fbfdc38, 0x86a2b0a7, 0x55bbeb18, 0xf61ef836,
- 0x997d1371, 0x7bf39bf8, 0xbf9c3ddd, 0xcf0f7e0d, 0x9fe58e9a, 0x07f9c9bc,
- 0x08fee1db, 0x52a48af3, 0x25ebbef9, 0x16760792, 0x75d7c589, 0x6b6be0aa,
- 0x302741b9, 0x304a456f, 0xdff60bd1, 0xfe4fe087, 0xd07582b3, 0x832f24ce,
- 0x67a79e38, 0x16df067f, 0x251ffe0a, 0xad9ff95b, 0xbbdf7ce7, 0x7da2157e,
- 0x3f0d4cae, 0x2bf228f1, 0x8bc867f0, 0xe1e6aafc, 0x1fd74fba, 0xc04dc3f8,
- 0x0c1ba7a7, 0xcfcab53e, 0x7a2d3e68, 0xf484b376, 0xa7a7cd19, 0x891b408b,
- 0x3df0a7c5, 0xb5169f26, 0x9f953ffe, 0x8faefc06, 0x0f219f82, 0xb463837b,
- 0xf3633c3c, 0xe5a33c12, 0xc9bdfc21, 0x9fd27bb2, 0xbd067741, 0xfcb2fc95,
- 0x1817f222, 0x5dd06974, 0x741a5d17, 0x62ffc3d7, 0xf9745f81, 0xa005a460,
- 0x2a5dbc93, 0xcd6555d9, 0xda0c3cfc, 0x8b203cbd, 0x6da7e4e0, 0x3cbcd58c,
- 0x0f9cc920, 0xa21be547, 0xf2a3fbea, 0x03f55179, 0x4b4af951, 0x03a6b2fd,
- 0x47fc231a, 0x4becf52c, 0xc41f651f, 0xfd8c87b0, 0x4678d826, 0x0c5d210b,
- 0xde50d4ec, 0x0541cba9, 0x1ee0ff45, 0x0ec5ec99, 0x182af180, 0x3d3ea3a7,
- 0xb1b9021c, 0xf0edc9d2, 0xd3d3bd0e, 0x8995d207, 0xac99df3c, 0x67b942ad,
- 0x7274ef7c, 0x5e47473f, 0xe4d127a7, 0x2cd238a7, 0x0d6edc93, 0xfcb1e9b3,
- 0x10a3b020, 0x6f595bde, 0x39ffdce5, 0x5e0d764d, 0x8d68f68a, 0x771343ec,
- 0x3d1bb2c1, 0x68e92ae8, 0x6ccd7a1e, 0x55f0bef8, 0x3a558e99, 0x70633ce2,
- 0x57e42c5e, 0x89ec99fa, 0xb3f42c13, 0x6ccfe889, 0x82c576e6, 0x08fa5135,
- 0x54f4435b, 0xa1a25ae0, 0xe03b053c, 0x973fab7d, 0xe88945f3, 0xb5bd68af,
- 0x278f68dc, 0x95df685a, 0x03cb59d4, 0x65da3ec2, 0xcb0649f0, 0x86833920,
- 0x42e7da0f, 0x47934f2e, 0xf01b335d, 0x665071d1, 0xb6799e78, 0x9c7c2659,
- 0x97e7e7ad, 0xfc4c942c, 0x493ac156, 0x6a701a1e, 0x7ad27e43, 0x3b6d5797,
- 0x177d9cfe, 0x3fcecdd2, 0xa439f98e, 0x1ddf3b6d, 0xcff31bb1, 0x8ff83dbd,
- 0x29fd67ac, 0x37e49d7b, 0x26ebd8ee, 0xf3d8ef7a, 0x6177c1db, 0xfc9d977e,
- 0x3f7b1d75, 0xd7f4831f, 0x845edcb1, 0x1063aef2, 0xf7aa87b7, 0x95a63e7c,
- 0x8415d7f6, 0xc6b2a3b7, 0xbfe6a3f5, 0x3092961e, 0xdea15585, 0xf89e37b0,
- 0x93bcf829, 0x7b1d0bfc, 0xb80ecf3e, 0xa9eb75fe, 0x1d39e710, 0x59fb366e,
- 0xf7225f9c, 0x8f770783, 0xcf0cb4df, 0x69f71ba3, 0xca7ca1f3, 0x831f7f0b,
- 0x59e3b472, 0xabb50fae, 0x79e38fad, 0xe1fc8745, 0xdce01532, 0x9fd54c8e,
- 0x1194fbb1, 0x62a34393, 0xe4efe5c1, 0x7850b937, 0x4fb70a68, 0x21e1fdff,
- 0x73bcb9f9, 0xae121d87, 0x7fc38bfb, 0xd7b0b944, 0xac69744e, 0x32c374f7,
- 0xb7ce57d2, 0x7fcae1ee, 0xd0b83a17, 0x0b914b75, 0x7fd4f759, 0x5aff7c73,
- 0xa2fcd2f6, 0x9d27a0f9, 0xf283b9ef, 0x9a3edcdb, 0xfbd205ef, 0x7869ff82,
- 0xeef0167f, 0xabbaff39, 0xddd7cdff, 0x9d5fde3b, 0xe3aef02b, 0x85f07f79,
- 0xbefcd3bf, 0xf4db9cae, 0x0dee94df, 0x9b15febd, 0xa80ccdf7, 0xb8d59d3f,
- 0xb2b8b150, 0x19abff7c, 0xc0cafa50, 0xdf388903, 0x37e751c9, 0xc2a6fa46,
- 0x92c9a6ed, 0x9641ec8d, 0x907b0928, 0x840351db, 0x496030fe, 0x0321e901,
- 0xf5cfde06, 0x0ebbc506, 0x195f1fcf, 0xb147df3c, 0x3bec6c14, 0x97ebcc01,
- 0x9ed5bc8b, 0xfcc4b9fc, 0x603a3478, 0xa20ff7f0, 0xa0703b5e, 0xa42f7a4c,
- 0xe8beefa4, 0x97bfce99, 0xe7bb1669, 0x0ed5af4a, 0xdab24dca, 0x7f45534b,
- 0xff9f18d3, 0x0e149734, 0x0f261c03, 0xfa1269fa, 0x570f2747, 0x5cf90499,
- 0xf6815816, 0xb59754c5, 0xc33c06bf, 0xe1cdf719, 0x380d5768, 0x8797590e,
- 0x93241c70, 0x70bcf49f, 0xdc1379c4, 0x2f18c232, 0x871f14c3, 0x1f729f63,
- 0xbd859df9, 0x904d474d, 0x5aab5c57, 0xb4159f90, 0xc81c3997, 0xe5ec36ce,
- 0x84cde0de, 0x2188adfd, 0x032bf80d, 0xdad3bf65, 0x06dfd91f, 0x3e2ebe5e,
- 0x537e3c0c, 0x851bbcbc, 0x45ae8197, 0x74ebf20a, 0x62fa17b4, 0x1f9e0cfd,
- 0xdce85218, 0x570bd84d, 0xa4291778, 0x50cc0cf7, 0x8e855f10, 0x1cf0aba6,
- 0x6893e1c4, 0xd9b7171e, 0x64707f68, 0x91f70449, 0xdfe50ab5, 0x10e3e9b0,
- 0x7b2f33df, 0x0c9df4ee, 0x8d7ee6fd, 0xf1e53dc7, 0x7dbf8ff3, 0x8c44e5f9,
- 0x2c781417, 0x46afff84, 0x167aff3f, 0x2d380389, 0xa1285854, 0x25bdfa0f,
- 0xefc5bef6, 0xdfe3cd6d, 0xfbba5377, 0xdefd5f39, 0x3abfcae4, 0xd8e40e7d,
- 0x5df300fb, 0xe1a30e98, 0xfd5db315, 0xaf0e669d, 0x1e1621e0, 0xe42ae3c2,
- 0xe139d33c, 0x9ffe821d, 0x99b3d3fb, 0xea4ed768, 0xe5c09518, 0x17b230eb,
- 0x385ec282, 0x3e09bccb, 0xa1d7ca17, 0x79fe7409, 0x8ac77650, 0xec2adc2b,
- 0x7c625fed, 0x751da409, 0xfb4646ac, 0x1f92758d, 0x60e75437, 0xb7c4639b,
- 0x9f86abe4, 0xfe0de04a, 0x8f3c6ce4, 0x842fe3e1, 0xbc6609a6, 0xa938cdb5,
- 0x0789e98c, 0x74df7bfc, 0xe14df51e, 0xc23df68b, 0x35b3ab77, 0xfc862f37,
- 0x6fc05db8, 0xc82ffee6, 0xf36979ff, 0xefd21b06, 0xcb3675a5, 0x2aa96af9,
- 0x6cb1b1ec, 0xe66bce2c, 0x0b3ba77e, 0xf65072f1, 0xb0673c61, 0x88168cf9,
- 0x0d182e71, 0xfd1fec4f, 0x9d555be9, 0xdab76bf8, 0xbae11f30, 0x430723fb,
- 0x56977a3b, 0x9e6b1a53, 0x9e7cec03, 0xedc3590b, 0xfdffd263, 0xc3a93be0,
- 0xf68c9915, 0x7e131d67, 0x63fa688f, 0xb767c744, 0xafee30b0, 0x5ca2af68,
- 0x68cf5b38, 0xdc90077f, 0xf037768f, 0x7eccf7fb, 0xb69b8b9c, 0x82f512ff,
- 0xc749668a, 0xa50a8623, 0x6d3f4355, 0xc65129b0, 0x6bc3387d, 0xa3eabbc4,
- 0xc5f137af, 0xf8215556, 0xfbb0981e, 0xe3f71c66, 0x9ea18d36, 0xd3b17fe2,
- 0xc7f8fb83, 0x07c499cd, 0x57ebadbd, 0xa9aaec55, 0x972a3748, 0x30f4d187,
- 0x92ce3eaa, 0xf40e4cbf, 0x699afe47, 0x8be25d6f, 0x6befbf81, 0xbc173892,
- 0xfe16f940, 0xbdbe4cff, 0x80b7c869, 0xa3e2679c, 0xf90f5abe, 0xbe4b1a96,
- 0xa9bc962d, 0x7bc5f708, 0x5e22a686, 0x26aabf17, 0xdb6f92c7, 0xe739f8aa,
- 0xb94e2233, 0xdbe411a3, 0xadf24db7, 0x8c5be411, 0x5fbf9078, 0xff0b7ca8,
- 0x36dff0d7, 0xd6316f94, 0xf9566bab, 0x08f9a636, 0x8d31b7c9, 0xaf3c4b36,
- 0x7c9f3b5d, 0x47af9293, 0xeaa0f8fd, 0x3f418f8b, 0xfe3e84db, 0xc44b888c,
- 0xe5ce5071, 0x7f8d3a6a, 0xe2ee72a1, 0xff73950b, 0xe4367045, 0x8c1de2dc,
- 0xd27b9ce2, 0x8b739721, 0x939c8177, 0x9cb91e90, 0x7187bc5b, 0x7c945cbf,
- 0xbe43d91b, 0x115faa31, 0x4d83ede1, 0x02df0fe9, 0xabf58dfd, 0x1fd4073e,
- 0xc6ef2ddb, 0xae5de599, 0x7adc10a6, 0x1783bbc8, 0x0876ef26, 0x6c720779,
- 0x68d7ca08, 0x5b35f0fa, 0x8f77c1e3, 0x2bff5e3f, 0xcadf97e4, 0x86f8de74,
- 0xbd0f9f8d, 0x1678fe36, 0x6263d7d2, 0xdc848b3e, 0x510aaf6b, 0xe45e53ff,
- 0xf1772beb, 0x468af138, 0xd4561fae, 0xfc2f614b, 0x17c27733, 0x78bfce1a,
- 0x2152c48f, 0xebcecb3f, 0xf38d27b3, 0xc3233632, 0x720b0f44, 0xbfcfc94a,
- 0xf40e6140, 0x72ba97e3, 0x5bfea24f, 0xfefdc39a, 0xf17be2a5, 0xd0abadab,
- 0x88fc5dff, 0x46a5e744, 0xe711ab7c, 0xa26e23db, 0x77f91979, 0x6627e3a3,
- 0x99a9b88a, 0x1bc294bf, 0x947fc462, 0x7fe6b16e, 0x966ff822, 0x62f04adc,
- 0xe331cbaf, 0x5d7a8c38, 0xe0283a70, 0x7ed32754, 0x802705da, 0x27bd379b,
- 0x33d3009c, 0xe1ba5232, 0x585bfc52, 0xebef566f, 0xbd16e035, 0x5d7fc36e,
- 0x0de9fa2a, 0x7b9c060e, 0x1dc05fac, 0x939202ec, 0xa758f0d1, 0x33b5f975,
- 0xe8094e31, 0xe84ce486, 0x181700d7, 0x70d26f2f, 0x47977dcb, 0xd664fd05,
- 0xe1829a4c, 0xae30b30c, 0x6a0bca1c, 0x0fdcbd17, 0x1dee31e0, 0x4edc58ef,
- 0x0f609b2f, 0x56ec39e0, 0x41c92767, 0x35db0e83, 0x141c07ae, 0xbfddddf0,
- 0xf9d93272, 0x7a8e924d, 0x24e23048, 0xae0106b8, 0xa828ff78, 0x8106fc70,
- 0x0eff911e, 0x8719f23c, 0x8bc91ee3, 0x635c9dfe, 0x40bc42bf, 0x8e66ccfd,
- 0x22586097, 0x4eb164bc, 0xa8a97f3a, 0x84117c95, 0x8206d35f, 0xe19f219f,
- 0x93c665cf, 0x58957e89, 0x4c954bf4, 0xa8a965fb, 0xf35ed337, 0x99e7a407,
- 0x036caa4f, 0xfbfe1b81, 0x4f3e7a2a, 0x9e34501c, 0xb6bc04da, 0x085d3c21,
- 0x77ae4eb7, 0xfba0be45, 0x50794650, 0x39e05909, 0x5f73d1e5, 0x0671af09,
- 0x518e90bc, 0xcbe735be, 0x92682f98, 0x9ef4df58, 0x50f3c5eb, 0xef17bf33,
- 0x7ffbc239, 0x18b1f24c, 0xba60beeb, 0x8b9e85ee, 0xbcf16e80, 0x8eba37a4,
- 0xd23b5386, 0xe9bab7f3, 0xe76735f9, 0xe7a44ca1, 0x43f7123d, 0xce5a2734,
- 0x1e763d35, 0x09d5b5f7, 0xeeeb0f74, 0x6df5557c, 0xcb90c6f4, 0x7ed1ee82,
- 0xbb37df30, 0xf1821704, 0x141c5ba2, 0x18f347ef, 0xb353f5c2, 0x64e6de7c,
- 0xf567d7c9, 0x2edbbfde, 0x37278cc5, 0x3f2323f4, 0xf8c3c71a, 0x6f1826f9,
- 0xd178f764, 0x2fe183fb, 0xfabadf38, 0xbad9bfdb, 0x6ebe718c, 0xb590543c,
- 0xb88d5e10, 0xe05223a8, 0x73ea2a47, 0xfc4b25d3, 0xc85ccc15, 0x7fdc6fad,
- 0x7bdc96aa, 0xa74d2cff, 0xebb774fb, 0xe89d77c6, 0xe2674f33, 0xdbe26f7c,
- 0xec7fefb8, 0x5998e7e7, 0x44d6f636, 0xab263fdc, 0xe3eae90c, 0xa1f92a43,
- 0xe3ca9e3f, 0xedf9af6e, 0x3e5d0501, 0x3898f0d7, 0x8938cd76, 0xb037acec,
- 0x87a8f1eb, 0x047f983b, 0xef132fc1, 0xd5d465ed, 0x5f02f14c, 0xae12dd8f,
- 0xa537d4c6, 0xc435e933, 0x219924db, 0x7dfc5ade, 0x7f20b8a7, 0x032c87fb,
- 0x1fa0a05d, 0x07b1fb50, 0x9bd63259, 0x33264fe0, 0x27e37c66, 0xf3075e6f,
- 0xf6487f18, 0xacdea179, 0x03172e03, 0x7ae47a7d, 0xe0980b1b, 0xab858135,
- 0xfe34dfd1, 0x9c3affa8, 0x3be81177, 0xa8a44f78, 0x07b54379, 0x6a25ebf3,
- 0x72050c1f, 0x6d9eb03d, 0xbf7267b5, 0xea017285, 0xf5c13761, 0x4eb05ebc,
- 0x728861f2, 0x8a5af341, 0x93a82a2f, 0xb6e142e8, 0xbc1cc4b0, 0xfa03b0df,
- 0xda1eb6dd, 0x05fee167, 0xbadfb1ed, 0x875e6f33, 0x49e60772, 0xb9f9ebed,
- 0xf3b4017c, 0x2dd4bf22, 0xd78afea2, 0xb3ef0c4b, 0x7df3d514, 0xea90e8a9,
- 0x7dc6f2c3, 0x3b7ed08f, 0x97ebc603, 0x6450fb8e, 0xca0bdd2a, 0x2fba7494,
- 0xf84c1a19, 0x7f1c60eb, 0xf220fa6c, 0xabbc520b, 0x98a0c097, 0x64fe63e3,
- 0xb3f2421f, 0xeb4cb7c0, 0x96bcfd0b, 0x236e9c93, 0xe7433aba, 0xde0147ed,
- 0x1bf78001, 0x40e55e22, 0xab5a07ce, 0xc2fc5f69, 0x9b9f943e, 0x38a24d34,
- 0x8f2c858e, 0x8e6638e2, 0xebe6fae7, 0xe8c33b97, 0xed5d7be7, 0x0fdf881c,
- 0xefa76e5c, 0x1cb8dbed, 0x4ad41f6e, 0xebe3f6fe, 0x58f78655, 0x24cbd7aa,
- 0xabd78e2f, 0x7e563f74, 0x1431c78c, 0xc7fae36e, 0xdfbcf581, 0xe1b7a8e3,
- 0x439607b9, 0x11ab70be, 0xb4e5c0e7, 0xe8167f61, 0x90c2fe3c, 0xdd62e5bb,
- 0x75a1f63d, 0xd92434cb, 0x2e5b7968, 0x8b0971e4, 0x2d1cbd90, 0x1cf1cb77,
- 0x197c83dd, 0xeae6271d, 0x0e9063b6, 0x5d105f22, 0x19521c57, 0x07d231da,
- 0x9714b96d, 0x73a247b6, 0x92cdf18b, 0x8a1ae31f, 0x4987b1de, 0xcfe70eff,
- 0x2fee11fb, 0x8619daef, 0x3c431f2c, 0xb1ca9c80, 0xa7e9fe77, 0x1be4fdf0,
- 0x02088c0e, 0xb827c9ba, 0x59be711b, 0x4f3c799b, 0x52eb1bd6, 0x9b2f3ef0,
- 0x40e497da, 0x02ccad61, 0x52713926, 0x13775ff2, 0xd4741fdf, 0x667c0c77,
- 0xb8053569, 0xc1cb7ebf, 0x66ef55f7, 0xd8646315, 0x043d84ef, 0xf51f81f6,
- 0x6b5de29b, 0x1d133453, 0x9b59ef14, 0x55f7c322, 0x1aa61e22, 0x576857f7,
- 0x8a71f1ac, 0x06fa4af7, 0x3f4638d3, 0x2edabf46, 0x1ee86ede, 0x7fd6f69e,
- 0xd68fce31, 0xf286a9f9, 0x1e9fba22, 0x4fd2f7e3, 0xadcfefce, 0x395e6093,
- 0xac14cbaf, 0x8cc1f39e, 0x1d73e6a1, 0xcafc3523, 0x98da6fd9, 0x9cbf04df,
- 0xbf31c53f, 0xe38ddf09, 0x7f01ef80, 0x61493757, 0x23f984a7, 0xe516795a,
- 0x0af3e475, 0x98ae7fe1, 0x1aebcfca, 0x8158de33, 0x4b233f7c, 0xa1607a22,
- 0x8937d680, 0xfa2f35f4, 0x78b30bfd, 0x8f6842fb, 0x08f8d8fc, 0x13904fe7,
- 0x1523945e, 0x52e6d7eb, 0x8bc93afd, 0xc86e37fd, 0x28a47d27, 0x5e546647,
- 0xa3f48477, 0x4923a6a2, 0xb7c0c7c8, 0xa81f50eb, 0x51d76898, 0x68fc1b8e,
- 0xe2ebf7f0, 0xe8732b3e, 0xc67ef1a3, 0x8be646ff, 0x21f2d7c1, 0xf583d72e,
- 0x39831f9c, 0xdf5f5f9c, 0x2f0ae2a6, 0x9f89bf84, 0xfce16f8f, 0x43763f2a,
- 0x2f87de2e, 0xc3efccdc, 0x453f581f, 0x78fa7d43, 0xa6fda258, 0xbd737f27,
- 0xabbf9a35, 0x7defbe25, 0xe0d2fd5d, 0xe18f836f, 0xaf1c6aef, 0xef14f80c,
- 0xf5f3464f, 0x0fe1b54c, 0xaf7cc3b7, 0x03d61a79, 0xddf29df3, 0x26ad3d3b,
- 0x14f90939, 0x3c2817cc, 0x2b90cb9e, 0xfb8f0ae5, 0x8bf3dafb, 0xb76c3f1a,
- 0x677e47fa, 0xebf1e44f, 0xfdd12a75, 0x07b3f8f9, 0x7f205d9f, 0x9d5f285e,
- 0xf18d3f8f, 0x7ed63de5, 0x2de8277e, 0x8076bfba, 0xfae0046b, 0x8a26fd4a,
- 0xa9e8fdf3, 0x3f113323, 0xce81bba5, 0xddeabe91, 0x4e72822c, 0x557ed309,
- 0x3dd328d2, 0xb244a601, 0xf99b73af, 0x956dc798, 0x7a26e33e, 0x1ed6792a,
- 0x4bed019e, 0x86307e76, 0x779668e2, 0xe85a5c52, 0x872fa129, 0x1f20c75a,
- 0x7e3c2894, 0x042e5a2c, 0xd70fdc1c, 0x367e2bb6, 0xc2da4fae, 0x69288fdf,
- 0x9bb551b8, 0x746e25ce, 0x3a3d46a8, 0x1d010dd7, 0x9c5dfde3, 0x02ddf99f,
- 0x6dac6e23, 0x2513972b, 0x81d92a4d, 0xb7b65b25, 0xc970fc63, 0x77f2763b,
- 0xa19cb705, 0x9e5310fb, 0x94fe46d9, 0x396c9360, 0xb711eb7f, 0xd88e45b9,
- 0xb1b0ee31, 0x211dce9c, 0x0df2847f, 0xcf97e3b1, 0xfa585f17, 0x219d9ecc,
- 0xafe96100, 0x7ca0f49e, 0xd9b2d539, 0x7e877083, 0xba6e32bf, 0xc3669c47,
- 0xa7195f3d, 0x01ff0a79, 0x438f738c, 0x9c4635d8, 0xa4be96eb, 0xb2fcc247,
- 0x739c62f3, 0xdbe5e974, 0xef1c7d3e, 0x7b3db411, 0x6f9c71fa, 0x7e3e3fd9,
- 0xd8c1e31c, 0x77ed275e, 0xa2dea7c1, 0xdda36c38, 0xb5dfb126, 0xe2927d6f,
- 0xb5dfdbd7, 0xf6b7b0fb, 0x6307c73d, 0xf6fb603c, 0x6fd0522f, 0x34cf64b9,
- 0xd92eebf2, 0xc5952531, 0x148c2fd8, 0x017c36e9, 0xf8d1f3f1, 0x8078d03a,
- 0x023ed6e2, 0xebfca37c, 0x286dbb8a, 0x5ecc71e7, 0x1f5b6f11, 0x8f429efb,
- 0xebc6daf8, 0xe51cb9ae, 0x1fd7237e, 0xfb671bcf, 0xdbf1e026, 0x7abf8017,
- 0x1b102fc3, 0x3fe11f7f, 0xa2fb4f00, 0xe369f7f0, 0x8a3c5fc2, 0x7b7d8d65,
- 0x5c8db38d, 0x7b8cdc00, 0xfc380f10, 0x88c91c87, 0x5c525fe7, 0x866de233,
- 0x4f9ff717, 0x91fde307, 0x5ce76a13, 0xc7b85fba, 0x68bc63ae, 0x89b79ec9,
- 0xbc77da7f, 0x26687e41, 0xb3b423ee, 0x3f1e3fae, 0xd675892e, 0xae7c79b9,
- 0xefc63f80, 0x5df43d7a, 0x3a72e9c4, 0x7b77e236, 0x9d95db8b, 0xee36cf5c,
- 0xfdd79467, 0x76c3c451, 0x41ca4be3, 0xcaf91d3c, 0x0e036878, 0xddc390ba,
- 0xe3b1e871, 0x2beebba3, 0xfe217c08, 0x8aea1f70, 0xc0fc8733, 0x7a37e4b1,
- 0x0790c59b, 0xfc781bed, 0xfb1abb7a, 0x9711b05e, 0x3e688ffe, 0x3c585f0d,
- 0xffe6f9fa, 0x81d3e175, 0x4f724fca, 0x2dfdb538, 0x774f1cb6, 0x9eecdf4a,
- 0x7d149961, 0x1cebca6f, 0x473b7187, 0xbb83b434, 0xdeb16cec, 0x6f57e136,
- 0x78a64a7b, 0x070d55e5, 0xcb478e48, 0x2f7c0a8b, 0x337cc625, 0x9a2b7cc5,
- 0xf6d13ef8, 0x82ec3bac, 0xeff6da7e, 0xa8ae7a22, 0xd2f1423f, 0x95f96f2f,
- 0x8b8a6ad6, 0x6c227dc0, 0xd3db7f9a, 0xdc90c6fb, 0x44b2ef16, 0x8c49338f,
- 0x3d8e6c13, 0x8cfeb04e, 0x50d29c65, 0xcebba683, 0xc529de3f, 0x77f6237f,
- 0x83eb85aa, 0xe9e41aa7, 0x0fe318e1, 0x77d6aa73, 0xa4bf60a1, 0xfcdc67f7,
- 0x13d919bd, 0x12e5fa47, 0x093bce77, 0x146a9849, 0x4cbd55af, 0x87fd77c4,
- 0x5df10d2f, 0xe18abeed, 0x7c22577c, 0x551e7e4d, 0x4bd4300f, 0x2cbcb4d5,
- 0xcb442bf4, 0xc6c92d1b, 0x2ffc26c2, 0xf54f4f71, 0x644779d2, 0x70f3e220,
- 0xfb1571c6, 0x9f944bfd, 0x5b0a2fea, 0xfbf30a95, 0x2df2484b, 0xdfd97e83,
- 0xe794183e, 0x977fd9ee, 0xd963f11e, 0xb0aa57e2, 0xbb461e77, 0xa4e0bd84,
- 0xaf7906f8, 0x08f9de93, 0xf5a4ee3e, 0xf9f1d81e, 0xff5fa413, 0xb9f8cec2,
- 0x202f580f, 0xde750aaf, 0x9f1df1c7, 0xd457fe3f, 0x8c31b19f, 0xd438f85f,
- 0x3ea1bb47, 0x8e9cec9e, 0xa0c61367, 0x85f0a45f, 0x3ca266bb, 0xf4e78c2b,
- 0x6a4cf858, 0x3bfa1ab8, 0xc7f3cc96, 0x77a20db6, 0x759f4a25, 0x81e8dc53,
- 0xe055cf1d, 0x4cfed4be, 0xa97dc33c, 0xe7a105fd, 0x53bc52ff, 0xcd7aab55,
- 0x4cc5e3f1, 0xf3ef9af1, 0x12de6294, 0x2fc8c4af, 0xfe847c41, 0xba04a6aa,
- 0xaffa0407, 0xd48f9fa5, 0x447c3bce, 0xfcfea1c7, 0x3fa453fe, 0x7ae883ca,
- 0xcebdf946, 0x395ee221, 0xd77573b4, 0x059d6a0f, 0x9fd35f3c, 0xaa1693cb,
- 0xf853b0ff, 0xcf79458f, 0x87fd797e, 0xeeeefc84, 0x10afb787, 0xd344d0ef,
- 0x6fd146ef, 0x5fbf96e9, 0x959deb1c, 0xefa7f318, 0xc858943f, 0x76ca7a86,
- 0x857fbd27, 0x7de028ef, 0x3f1a9d85, 0x44f32ad7, 0xdd9b9de8, 0xc5971e42,
- 0x9ddde845, 0x581e62fe, 0xd1ccf31f, 0x9fbd34fa, 0x61939cf6, 0x0bf9595c,
- 0xbbe23f6e, 0xc7e7e77c, 0x71859e7e, 0x1714f189, 0xffc2fe5f, 0xb7283a22,
- 0x3f22e647, 0xb3b76e74, 0xdbe7c88d, 0xfc8c1d5f, 0x0646a6da, 0xf38af9f7,
- 0xbb06f2ba, 0x58bffef5, 0xdaaaa9c7, 0xbbbef0cb, 0xa4b6af71, 0x57f33917,
- 0x5fa3d727, 0x725ffa71, 0xdf5bbf12, 0x35553a73, 0x59df133b, 0x3897ea30,
- 0x77c5cb62, 0x137c5e51, 0x71eaee39, 0x9c5df53f, 0x25ac47cf, 0x153efd05,
- 0x3ca377a0, 0x3e92d92f, 0xfb04fd10, 0x043bc69d, 0x8fdc04de, 0xb25eabf6,
- 0xef3531a7, 0x7caa2733, 0xf430ca99, 0x54cc8cdf, 0x1b1d1d60, 0x67f414ce,
- 0x9cea4718, 0x9dee4b1d, 0x3ad3c676, 0x98f61c4a, 0x09cf9df7, 0x8d0f7aba,
- 0x1e3e64fe, 0xee3187f2, 0x724c357e, 0x2f388ef8, 0xbb012bd5, 0x6e97bf08,
- 0x79699399, 0xa1a9457f, 0x04a7c07a, 0x4eb662cf, 0x6fc932cb, 0xa5e2bc63,
- 0x264a9959, 0x4ffe577e, 0xddcabd17, 0x24a16678, 0x01150bd2, 0x9faeb663,
- 0xa2887ee5, 0x7e1039e6, 0x15d3cb1a, 0x86a54919, 0x358e3df8, 0x7502ea50,
- 0x5653bf8b, 0x9e4e50c9, 0xe8f6e710, 0x1bb4c2ef, 0xdc92775e, 0x6c620d0f,
- 0x07be3a78, 0x4dd04de1, 0x10f153f0, 0x5763e61e, 0x1797192a, 0x93b47433,
- 0x7d8050a5, 0x5d54f409, 0xe9133d35, 0x18fcfe11, 0x07a64907, 0xbfa3cfcc,
- 0x41ea05fc, 0x3dfca740, 0x70b2efbf, 0xc3188035, 0x3aafc981, 0xe877f199,
- 0xccc3bf56, 0x71a5c6f6, 0x68e77892, 0x1731c91f, 0x84ebfeeb, 0x94558a3c,
- 0xff09d5b7, 0x4473c1c8, 0xa822ce97, 0x58bbc617, 0xd7521e24, 0x9994e528,
- 0x90593dff, 0x3ea9d137, 0xcd1e5ad1, 0xa2d72017, 0xf8206dc6, 0x449fbf41,
- 0x5449fbf5, 0x557c9fbf, 0x829c06bf, 0x7c3e8d8e, 0x556562a7, 0x1f1b809e,
- 0x06e021cf, 0xef8919f0, 0x9c5b31e8, 0x13879c4f, 0x6cc4e35c, 0xf01f58ec,
- 0x4e971e5a, 0x612fb978, 0x41c6276f, 0x865aa4b3, 0x890aef76, 0x97f0d3ef,
- 0x63b532e7, 0xf0f883ba, 0xb94e311e, 0xc30af380, 0xbea3d53f, 0x1eaff493,
- 0xd5bd9df5, 0xdf5d8b8f, 0xe27cdbdd, 0xb127cf63, 0xe26bfe97, 0x75fff663,
- 0x0bc552e5, 0xe786bf6f, 0x49f25db6, 0xf55bd007, 0xd438f2cc, 0xfd8f1333,
- 0x70be95a3, 0xd031d33d, 0xa438ef8a, 0xb8b7a06f, 0xd1efd661, 0x7d1bd274,
- 0x40758be5, 0xe00fd5de, 0x7f189370, 0xf73f1d6a, 0xf70965be, 0xe87981d3,
- 0x8b37fac7, 0x0a3937fa, 0xc470dfc9, 0xbabfdfc6, 0x91eb96a5, 0xa658fcb7,
- 0xef1ee9f3, 0x803fe151, 0x2a5d6edf, 0xb1e92385, 0x7562d7de, 0x9e6e3f78,
- 0xbdfa3f18, 0xe6f300aa, 0xbd6396ae, 0xd2e9c557, 0xfd1757b8, 0x9602c54e,
- 0xb321de27, 0xd4eb3f7e, 0xcd67e4bb, 0x2c7deea8, 0x1ee816b4, 0x7ba04ff5,
- 0xebc7973c, 0xe2171462, 0x485c78d1, 0x4f3a20cb, 0xd9dfe433, 0xdc04de91,
- 0x307f99af, 0xeff3aeff, 0xa6f4af8b, 0x2a1def9a, 0xef2ce2e7, 0xbeab54f5,
- 0xea6f9434, 0xc15fd039, 0x0dced654, 0x39535e61, 0xfcc4ade8, 0x7249be18,
- 0xa3094d2a, 0x3cf4545c, 0xaf7a8856, 0xa8c3ef78, 0xd55d25af, 0x0ebe67a5,
- 0x4b8e6fff, 0xbc5cbe26, 0xb6f74bd6, 0xdbcf8b3f, 0x7b24f489, 0x57017c72,
- 0xed087a4f, 0xc6aeebe0, 0x5cf7a775, 0xf3e6b54f, 0x157dbe91, 0x6ffc8080,
- 0x4fce073e, 0xf6df7bb6, 0xa37efce2, 0xf4bbf432, 0x44ef8f84, 0x86cfca18,
- 0x887c5007, 0x0463309c, 0xbc46bf8e, 0x6ababa6f, 0xaa2ba524, 0xbc794898,
- 0xaf2a8adc, 0xea447348, 0xaa74e917, 0x1a556f77, 0xf95557e5, 0xebe03528,
- 0xfbd0d5f0, 0x7c618e93, 0xf02e877c, 0xf0136497, 0xe5fe900b, 0x73a4ab48,
- 0x195ea745, 0xd8df77c1, 0x7077d840, 0xc10d7a59, 0xf919d357, 0xe53ea135,
- 0x548798ed, 0xf8419dad, 0x564af452, 0xc56fe508, 0x5c228e07, 0x2d4bde9d,
- 0xd3da5aef, 0x7fbd46c6, 0x836f051a, 0xb871b6de, 0x7a712fdf, 0xfdfb868b,
- 0xe3178b6a, 0xb2bfee22, 0x82295deb, 0x1c43983b, 0xe7e6bfee, 0xdee13db4,
- 0x09be7b32, 0xe9eceeee, 0x04fbf704, 0x7016ef9c, 0xa87816ad, 0x46acf016,
- 0xa47e53b8, 0x3a44fbc8, 0xc47bd29d, 0x112bb7fb, 0x08ca901f, 0x7d878077,
- 0x30c98854, 0xf179ba1e, 0x7412eecf, 0x1fc8dbab, 0xfcf2bb2a, 0x127b7708,
- 0x05c3bb87, 0x06ba2078, 0x3cb17bb8, 0x5d54f044, 0x9f50ce1c, 0x15e441e3,
- 0x7e267b84, 0xb800f8e7, 0x871f8df7, 0x058270f2, 0xe4d25ace, 0x23fb830b,
- 0x124b7f7c, 0xbf0d1e7c, 0xafbf8d24, 0x6f77f06b, 0x88b571fa, 0xef16aeb7,
- 0x511c2227, 0xe00879af, 0x4f0e34c3, 0xc8a47dfe, 0x164d28fb, 0xe0357ff6,
- 0x161fcb01, 0x19c210fa, 0x73c51fd3, 0x56c93cfb, 0x38454fb9, 0xf2efe1f5,
- 0x1b10a4b0, 0x6878cd98, 0x85a5fe2f, 0xc6f31798, 0x4ad7aff9, 0x44aeb23f,
- 0x7de903bd, 0xdd6de918, 0xcf0daaab, 0x57a5e43f, 0xcb67ee59, 0x5e89fdb3,
- 0x42407f82, 0xc13ee6bd, 0x5e916b87, 0x1edc7e68, 0xe0e8295e, 0xeefef16e,
- 0xee7e823d, 0xa0fcfc17, 0x7e3e3741, 0x74cd643f, 0x9498c71e, 0x20ef1361,
- 0x4e399846, 0xc0d7d130, 0xd9179834, 0xe94a5e36, 0x8ef64b9d, 0x7e36f89d,
- 0x7d23f314, 0x6773be25, 0x9b43bf98, 0xa1f50fd7, 0xd9dde344, 0x39c4de89,
- 0xa23d3174, 0x6520f788, 0xc4b64f6e, 0xdab5df7c, 0x7e81dfb7, 0x13e6de99,
- 0xafa7f3ef, 0x6be2f184, 0xf54764dd, 0x59cde40d, 0x2d577908, 0xcb0c55d8,
- 0xc1707cb9, 0xf44d0bbc, 0x5f8bdf11, 0x595d7547, 0xf64af480, 0xa93fa438,
- 0xf844ea1d, 0xe8bdac02, 0xcd487abf, 0xc1fb87eb, 0xfdb18943, 0xb9e2b370,
- 0x7593c4bf, 0xb09fc5a9, 0x3b53f54e, 0xde55a27d, 0x43fb13ac, 0xfe56a99f,
- 0xcb83f630, 0xc59f7f44, 0x0f147e07, 0x6e729674, 0xa4cfc92a, 0x0fef636b,
- 0xc216aad5, 0x47aa39f7, 0xe50ebe73, 0xee6f5c6b, 0x9d187721, 0x8c0d9c83,
- 0x2ffe88d8, 0x3396be83, 0x8c42e72e, 0xbac693eb, 0x3ef4867e, 0x9d01f702,
- 0x01f71ee8, 0x34c3cbcc, 0x5b949ba2, 0x587fe46c, 0x5eecf825, 0x046b5fc1,
- 0x7c803d5f, 0x81df0235, 0x13fa51f6, 0x90eb4fc1, 0x12dd20ff, 0x78f5ce9f,
- 0x6197bef1, 0x8c772cc7, 0xab1cf7a5, 0x0fda365d, 0x61ed7794, 0xfb05da17,
- 0xf7e8ebc6, 0x7a59dd91, 0x59e58dc0, 0x43c03f0e, 0x91d2cc4a, 0x2f733e5e,
- 0xe2abe8b8, 0xf4fd015b, 0x72a2b0ae, 0x949ea47f, 0x451fdec7, 0x9ef453a7,
- 0xcb5faa80, 0x70fd3fd0, 0xe113a552, 0x8f3c70fc, 0xcfcdaad3, 0x3e03b826,
- 0xe29bc5b6, 0x5f6752a5, 0x1f1ef5d5, 0x2f70ff76, 0x12ec12ef, 0x0c0d82f2,
- 0xf92661b1, 0x7bde2b50, 0x1b10de64, 0xcb139269, 0xf432e787, 0x0f94f5eb,
- 0xcdcbc8bd, 0x90ae5e5c, 0x434bcb62, 0x65e4377f, 0xd2315cb4, 0xb74d1795,
- 0x5d54a7dc, 0x66f2463e, 0xc1ff6c64, 0xfcede3ef, 0xf3e66a1d, 0x2cf7a7e5,
- 0xdefd7807, 0x83d42f0c, 0xf7c57f0c, 0x5a27ac62, 0xcab89e3e, 0xf40357d8,
- 0xcd02d03e, 0xaff8f0fb, 0xfbad57dc, 0xd5b9e141, 0x9c140fa4, 0xa8b4a1cb,
- 0x11f13a76, 0x9318d3c3, 0xfd7c7c9d, 0xdf883d0f, 0x7ce2b5e3, 0xc61abd7c,
- 0x1b7da4b8, 0x0e607aef, 0xe3c175c0, 0xe38f9d32, 0x14d90d3d, 0xbcb2c2df,
- 0xef1ba7a4, 0xdf0f1e23, 0x31c731ee, 0xe9d4fc14, 0x37bffd47, 0x1f582c7a,
- 0x8d537fdb, 0x83bb44ff, 0x5da246f9, 0x675dfa01, 0x9fbff504, 0x18dde938,
- 0x18da1f23, 0x8fc733ef, 0xf15be918, 0xdc21ced3, 0x33f78adf, 0xab9dd217,
- 0xf4d79d0f, 0xdc7c17ce, 0xc733e863, 0x4547d273, 0x7dc0359c, 0xca7fc596,
- 0x098f49cf, 0xf473187f, 0xca271e52, 0x7b94bdbd, 0xd3133c78, 0xd3ff9763,
- 0x3d51a47e, 0xb821b4ec, 0xd3daf2fe, 0x2fa5deab, 0x6280f3d6, 0x60bdc711,
- 0x79787c63, 0x2059be0c, 0x102f07ee, 0x7d065de7, 0xd0df7f15, 0x465d39b3,
- 0xd4f4add3, 0x1fa74425, 0x5fc9541f, 0x87f4015b, 0xd4f4987a, 0x698f7a78,
- 0x3d9713d9, 0xf9c00b78, 0x95324393, 0x10739d97, 0x87ffb65d, 0x3bfce28f,
- 0xefd2ab7f, 0x70727c26, 0xb7ebc51a, 0xbb9ef78b, 0xedc5cef8, 0x5c5c1bda,
- 0xbb9c14ae, 0x8bbbe897, 0x35f3c2ae, 0x7382dbe4, 0x565e900f, 0x4ebdef80,
- 0x788f75c0, 0xe8229279, 0x1fb60277, 0xea1cbb92, 0x3e72b615, 0x15431361,
- 0x10de8fe4, 0x0637bbef, 0xf2e0df3f, 0x0b45e25a, 0xff50d75b, 0x24c3f40c,
- 0x02c85c53, 0x8507fbf1, 0xe584b878, 0x21a5887a, 0xd6f908df, 0x77d6ff4d,
- 0xd69ddbb0, 0xc2e91a75, 0xb04e75ae, 0xebdd61d8, 0x73e72efc, 0xb6146fa1,
- 0x7579f0e6, 0xe3e7e7ad, 0x7ba7ad63, 0x7da9131d, 0xf1ec627b, 0x1fe317ef,
- 0x9bc22aab, 0xbc44ac5b, 0xbe105bb7, 0xd5f7c35d, 0xf627d60a, 0x2aeb4c91,
- 0xc4b52dac, 0xe6d4152b, 0x857afbd3, 0xdbb5f3eb, 0x1753fb4c, 0x97fe425e,
- 0xc6eb0d27, 0x2e6bfdcb, 0xaea8bc23, 0x7e913bbc, 0x7c553d8f, 0xec5e7bc7,
- 0x84e9e397, 0x49531a16, 0x4f76eaf2, 0xf74dfbac, 0x56a9e347, 0x80ec09e0,
- 0x0c9e132c, 0x3fb744fc, 0x8efcb9b6, 0xe21cf0f7, 0x509afe11, 0x0a2bf2ef,
- 0xe1b1e97f, 0xd7a0a4f7, 0x040fa063, 0xdf7e082e, 0xf5cbc4b2, 0x6f813f0a,
- 0x77c63e03, 0x08c2e7d0, 0x379127b7, 0x4e3fb193, 0x5b83e70f, 0x1e82f8f7,
- 0xcf5ec526, 0x59eb5d6b, 0xc7a042ca, 0x3eb8d49c, 0xee7afbd1, 0x05c72162,
- 0x4f8ba7ac, 0xfa7c2df3, 0x385b9ada, 0x9ffc0a9f, 0xd10f7fdc, 0xbc70b1f5,
- 0x7a54e30f, 0x486bcf5b, 0xd062e307, 0x1b10b0c1, 0x8f7ffd95, 0xfe684e0e,
- 0x3ee08f11, 0xee15fb02, 0xde4fc5d3, 0xbf3cc63f, 0xfd27e2b7, 0x9aa5f69e,
- 0x0ea73b0b, 0xf41df64d, 0xfb277ed2, 0x434961aa, 0x633f815d, 0xa3cf12fb,
- 0x6e9fa19f, 0xc6cfe245, 0x578bd2c4, 0xc72e0556, 0xaaea8bf3, 0x8fd1cba2,
- 0x973d0aaa, 0xce9b9ea1, 0xd623177f, 0xcdcc7d7b, 0xaab2bbf1, 0x983fce92,
- 0x94f4c423, 0xd80077ee, 0x47f24c89, 0x7eab2e2b, 0x1d01a9a6, 0x789adffd,
- 0x025540a7, 0xd0b3d3ab, 0x1194945f, 0x1fefc132, 0xb2ee7e2e, 0x8ebf6d26,
- 0xe8761ae7, 0x8e60fd1f, 0x8b59ca81, 0x6545ecff, 0x93c05f41, 0x1c731cf1,
- 0x124bf06b, 0x46cf13f9, 0x5acf13f9, 0xf30491e6, 0x5b3b0afe, 0x1ce87871,
- 0x8fc26152, 0x5f01e02c, 0x5bbb1f68, 0x1e5cebe7, 0x607d21ef, 0xb23645d5,
- 0xff09d6eb, 0x2fd0cff4, 0xe851704d, 0xe0c301bc, 0xc096beb0, 0x73c4e1d7,
- 0xaded190c, 0xf8dde508, 0x4f4c9762, 0x4f984a1f, 0xf3095e64, 0x1564597d,
- 0x931d0fda, 0x3f20ef5a, 0xe69033a0, 0xd67ebc06, 0x84b0e5af, 0x817912e7,
- 0xb5ce118b, 0x0bc32872, 0x77217ff5, 0xc1bd6066, 0x1f4ef450, 0xf7845e9e,
- 0xf3a60212, 0x8eb421ce, 0x33dcbcee, 0x2552d17f, 0x6feffcea, 0x5fcb9b17,
- 0xc62ffa71, 0xf93b5479, 0x1f4960fb, 0x57be7448, 0x94ee75dd, 0x64f2fb47,
- 0xd123c737, 0x41d5d205, 0x559d37ae, 0xc87d09bc, 0xf3323d9f, 0x7c3ccb45,
- 0xec22bc96, 0x53a03ad1, 0xe832a73c, 0xb7e29863, 0xaf0d1d21, 0x3c66ef81,
- 0xfb77d0c6, 0xf079e8b8, 0x31b9fa98, 0xe897183f, 0xcb973e55, 0x7a28e3f7,
- 0xf9f12dd8, 0xdced8a87, 0x1921646e, 0x20c73af1, 0xcf05653c, 0x8fe33227,
- 0x8d77b5ec, 0x82b62773, 0x0b9e75e7, 0xb9cfc6de, 0xa733e7a3, 0x3c16eef9,
- 0xdcd399ef, 0x7b9e3e6f, 0xf8ba29ce, 0xab774c43, 0x51e3fb9d, 0x2250fc5e,
- 0xb7a6f67d, 0x21e3545e, 0x46e6f1dd, 0xae609f7a, 0x73bfef9b, 0xf88aa759,
- 0xe35d300f, 0x5a6156e7, 0x27cc6ddf, 0xfa2a0df2, 0x84896e1d, 0x721ab86f,
- 0xbe18beb7, 0xb9bdd51a, 0x425f3b07, 0xf41a05b4, 0x321b3a5c, 0x5ef935da,
- 0xaede79e6, 0xf14e0e0b, 0x838a47fb, 0x6ebdd5d6, 0x58c1c107, 0x7c24d427,
- 0xbc49c174, 0xa5c066cf, 0x37f1dd6b, 0xf8fe855f, 0x1cdce4de, 0x790fe8c7,
- 0x579f3c9c, 0xc13e9c34, 0x0b939022, 0xb91ffedd, 0xb77afca1, 0xcb4c2eff,
- 0x95839d1c, 0x5537c421, 0x0390af98, 0x1c00a517, 0xb8141a3e, 0xd1e11938,
- 0xf482f7d2, 0x2e4ec3fe, 0x1ba70e0f, 0x1bab6d7a, 0xc8bd9be9, 0xf7e35af5,
- 0x38ed5632, 0x008dff7e, 0xe55e8f9f, 0xcb95cdef, 0x22ee6bde, 0x62ccb2ff,
- 0x7a4621d9, 0x1e0df858, 0x7bc4db76, 0xf39d7cd1, 0x79ef0e14, 0xcf74f18d,
- 0xd952de6e, 0xbcfdbef2, 0x957e3ca5, 0xae632d29, 0x2b09d8b7, 0xecf75d04,
- 0xd11afd07, 0x3a5fccfd, 0xd92dde99, 0xc893e9a9, 0xa738f1cf, 0xfd53f9b3,
- 0x4ffdc632, 0x1f912d58, 0x6f51fc69, 0xe7e42b53, 0xc87d1387, 0x5ceff3ae,
- 0x97ef899c, 0x3f70b454, 0x28bcaa67, 0x7d203fe3, 0xefdf3f68, 0xe108bf31,
- 0x5d7bf2e4, 0x369af3a6, 0x474332b5, 0xe5d5be7a, 0x7f907947, 0xc45dffbd,
- 0x30e7e1a7, 0x40e7ddf6, 0xce38c00f, 0x39bc5bfc, 0x0df91f48, 0x0ea53f4e,
- 0x5c81c4a6, 0x039857cb, 0x298d54d3, 0x98e34c4e, 0xe5ecd303, 0x9daa7f42,
- 0x2783fa45, 0xf7c34f27, 0x9f9bf3c4, 0x17db14fc, 0x927d912a, 0x9bf29e89,
- 0xee82fd5f, 0x28f3f9c3, 0x5b5bf74e, 0x39dd8b34, 0xff9ac1ba, 0x9f359376,
- 0x33e6b111, 0x03f35a0f, 0x7d266d70, 0x1e1eff73, 0x9a7a529f, 0x1e7defdf,
- 0x3c22a060, 0x3e49d9b6, 0xce6d294e, 0xd38778c6, 0x586dbb4f, 0xdceffbbe,
- 0xeadceeee, 0xf72577a4, 0xe2c717bd, 0x6a1df092, 0x3f2c46e7, 0x8d90d71d,
- 0x4fa845fe, 0xbbb04b71, 0x71bb408e, 0xbd06a5e7, 0x69be2986, 0xfdf83fe7,
- 0xf6adce94, 0x9c51c630, 0xd3e4f5de, 0xb7a79f48, 0xec7d200e, 0xc3642979,
- 0x70f7437e, 0xf3884ffc, 0xe954e458, 0x7e3dab16, 0x1d01e842, 0xe879b527,
- 0xd6b8ba17, 0xc24beeba, 0xa8a77cd6, 0x7d331b7f, 0x10f8c74f, 0xdc34aaef,
- 0x7ec53767, 0xc173fdbf, 0xa53d4f17, 0x8b2b7419, 0x37991ef7, 0xe2befba5,
- 0xdb73eeee, 0x8e800325, 0x4316114a, 0x4697bfba, 0x0f85db8d, 0x38927fd1,
- 0xadfceb2f, 0x5539f04c, 0xef896455, 0xaafbd2e8, 0x4d53697c, 0xed4151fb,
- 0xd27c94be, 0xdca5f757, 0xca67da66, 0xb9481eb6, 0xdb6bfa19, 0xebefd0a2,
- 0xe279cd95, 0xf8490981, 0xf9c06e5d, 0xe7fa3962, 0xf25e1ada, 0x8bd03d60,
- 0xbde39ac7, 0xa5c76b0a, 0xe9f1354d, 0x834ba5d7, 0x0e74ca9f, 0x5a72e79f,
- 0x461ef172, 0x1dff2d69, 0x1b86d2be, 0xe11abbae, 0x4fdf9ebe, 0x9e5856cf,
- 0xb653fc0c, 0x8fef86fd, 0xc7c1ef86, 0x3e70f9c6, 0x2d24f8d9, 0x3fadbbde,
- 0xee76f743, 0x44ff71b5, 0x7b465c34, 0xfdef7e38, 0xe508ab81, 0xa2f7f412,
- 0x3fb52c6d, 0xe47d0368, 0x6bd0e4c4, 0xd3954337, 0x570fe1ac, 0x95965c53,
- 0x253e809e, 0x373ab7d4, 0xf48dbe4b, 0xb5f67975, 0x97fb5aa8, 0x943a3c51,
- 0x8a37b4c7, 0xa27ed6c3, 0x47a57cf1, 0x68f77e32, 0xa25e99a4, 0x119df5eb,
- 0x2ab7dfa2, 0xcd720a5b, 0x1d97efa4, 0xd878a1ad, 0x19c871e8, 0xc13b8a68,
- 0x7c4bd1fd, 0x027a14ec, 0x22d91c93, 0xcf287c5e, 0x48a7bbd3, 0xa5104097,
- 0x5ea9b297, 0x6cb5eb84, 0x4bcfa63a, 0x99640791, 0x33f203cb, 0x79278b6d,
- 0x3eb7a6d0, 0xa3a473f1, 0x1e74d1fa, 0xefdc5fd6, 0xe846f36e, 0x77e358bd,
- 0x9e74da71, 0x5276692f, 0x8fe9d53c, 0xcb979234, 0xeb138e30, 0xd9b4ed3f,
- 0xbd3b5f40, 0x8c64efbd, 0xe06b6e0b, 0x6a9f8aef, 0xfb593be8, 0x9a37fd8a,
- 0xf17d8def, 0xdf13fe08, 0x8bf8f54f, 0xacdfb83d, 0xa9d371e0, 0x2a332b7d,
- 0x68c9e063, 0x6655a497, 0x79d2bda0, 0x91b7cbab, 0x0ae953eb, 0xc8d3ddf9,
- 0xfc2f92af, 0x79e9f749, 0xbea07877, 0xe1faea1b, 0xe5073eff, 0xfc77e88d,
- 0xa1ddf640, 0x1f3eed0f, 0xa015905f, 0x03f4e3fb, 0x7cfe3036, 0xa0144585,
- 0xafb8f9b7, 0xc93ca18c, 0x25ebf9cf, 0xb05c238a, 0x7c1ebac6, 0x1fbcdae7,
- 0x292fe116, 0xb0b8c50e, 0xd68b4a06, 0x718bcb5b, 0xbc50f0ff, 0x94cbc517,
- 0x19cb59d4, 0xad1f908b, 0x7b4bfeac, 0xca7db82c, 0x6bf9f58c, 0xa3b9163c,
- 0x50f9dc92, 0x95f5a3ce, 0xd20037a2, 0x1cfec49b, 0x6d2733bc, 0x4b1da401,
- 0xc82da427, 0x7cee7bc4, 0x8ed3231f, 0x8fbf98f8, 0x45953a57, 0x7177f106,
- 0xa58fee18, 0x346452cd, 0xe42c1de6, 0xe3bfcb19, 0x6eb820fb, 0x63313df3,
- 0xf35eb8dd, 0xc726f677, 0x10cf71ab, 0x2f2e6bd7, 0xab287013, 0x3afc5bb7,
- 0x90a5ea13, 0x7f78dbfb, 0x55da95a9, 0xb7697e34, 0x5ff62bf4, 0x1399b7d8,
- 0x68a135f0, 0x798b8c83, 0x878e4ba8, 0x0f75892f, 0xdf80b0e5, 0xf4143743,
- 0x107d7e43, 0x02fecff5, 0x9f2439c0, 0x45809f84, 0x5c5e301c, 0xca9e5766,
- 0xfcf397b3, 0x8ae04f3e, 0xaf6081da, 0x873a01a9, 0xbde72f9a, 0x471bf78c,
- 0x425e0626, 0xf9b7ccbc, 0xb7c42b07, 0x17e411fe, 0xf0e1ca5d, 0x4bcad8f0,
- 0xc5d9632a, 0x933fbf02, 0x3e5ce81a, 0xa3ef8bb4, 0xd54eacee, 0x8bfef7ec,
- 0xfb094790, 0x4f5ee95b, 0xee890ee7, 0x1d223f13, 0x8fb6fba1, 0x6865e95c,
- 0x9e01a7c7, 0x223eee50, 0x5ef815b1, 0xace3565e, 0x9e212f45, 0x787ce2b3,
- 0x38de5fde, 0xd1772e49, 0x15beb9fa, 0xcf01b95f, 0x8de75283, 0x0e748b1c,
- 0x2d779eeb, 0xe3d0ff7c, 0xb9faf1a5, 0x96d3de38, 0x8f17d287, 0x16f3f1c2,
- 0x387c84bd, 0xa1ee8e3a, 0xdcac02a7, 0x8d5d287d, 0xcb1a547a, 0x60fa87d8,
- 0x58ef0cda, 0xe43fb9f4, 0xdb24e3e1, 0x50b379e4, 0xf3cb1bcf, 0xf92c7e7d,
- 0xae111237, 0xed5271a5, 0x17ce3a6c, 0xe85ea3bf, 0xcb823f40, 0x9529ef84,
- 0xea7e3819, 0x69269e50, 0x3c0f8a11, 0x99bde064, 0xd12de9c7, 0x25e9c919,
- 0x454a4c5f, 0x1b50ee3b, 0xbf20d418, 0xec340d0e, 0xf48b88cc, 0x792361f0,
- 0x2df7617d, 0x5ff7e0c9, 0xfa1b0692, 0xa1d7af0f, 0x513213fa, 0xf5c1beae,
- 0x7e5c4ff1, 0xa65f57f2, 0x4fbf8ec5, 0x0a78e048, 0x61638b9e, 0x3838ff93,
- 0x13d233fb, 0x2c3ce783, 0xf027da6c, 0x1c734dbd, 0x7ed15977, 0x72841dfa,
- 0x01f742d6, 0x71ac1bca, 0xc5c597e7, 0xf3a0d71e, 0x0b1b39e0, 0x1e3225f5,
- 0x21d7f688, 0xc2d573a9, 0x4b17ba24, 0x73c13be7, 0xc6990b1a, 0x63eb9e0f,
- 0x33cd77cd, 0xaee9fa85, 0x9af5acc7, 0x2c7aa73e, 0xe383d5a7, 0xb4adebb4,
- 0x29cf048f, 0x6fd8ced4, 0x90b6c23a, 0xeedcfc0a, 0xe21de5e5, 0x6fa8cf3c,
- 0x5b3ed7f4, 0xf8def713, 0x556de8bb, 0x2e007820, 0x219f368f, 0xf359747f,
- 0x418b823e, 0x89f0dd0f, 0x7c132167, 0x225baa52, 0x69ede036, 0x7bb86e0f,
- 0xc990d814, 0x871f05fb, 0x9feddd36, 0xbbf8e508, 0x8ebe260f, 0x73e2eacf,
- 0xd90f3312, 0x42172e64, 0x9d4f7775, 0xfa8bca68, 0x9b43ed5d, 0x340a98af,
- 0xb78a3595, 0x27c1e6bf, 0x4e4e595e, 0xdf111a8b, 0xcf3839df, 0xa23bca6d,
- 0x8fc82ef2, 0xa8f5e536, 0xf2a8a4f2, 0x40fca8b4, 0x1dcdbf5e, 0x40fb2c19,
- 0xd4f83fde, 0x9efbf815, 0x7322fd6d, 0x358f05f1, 0xf02bb6f2, 0xb3cb7cf7,
- 0x56d3eff8, 0xc93e4b34, 0xba2b3f24, 0xb55bf3ce, 0x0e10a3f9, 0x1ca32f2d,
- 0x74926b28, 0x0d5debd4, 0xc79423db, 0xbb535e76, 0x963f6e06, 0x76a11c35,
- 0xd23ff6bd, 0xef7c7c46, 0xdea9f7c8, 0xd89fcef9, 0x5befeb0c, 0x751e76f5,
- 0x4e2c0a44, 0x7f7eee48, 0xdbfb6dbd, 0x0a2fbfdd, 0xf9fbdbdf, 0x8d1c900f,
- 0xc41e07ba, 0xf9bab8f9, 0xbde380c4, 0x7bd2cf23, 0xdd1c7fb4, 0x03aa16fc,
- 0x2cce4bf1, 0x9fdda053, 0x438f8fcb, 0xb4df0b7d, 0x67e37dc5, 0xdc12f852,
- 0x81651e8f, 0x5bdc704b, 0xc3ef87cb, 0xac384c9f, 0xef863eb6, 0xf0786f95,
- 0x98142be5, 0xeb7761df, 0xb709fc20, 0xf06f094d, 0x7f2b727c, 0x1dff4551,
- 0xa0f0e7e1, 0xc83641d6, 0xa6c0993f, 0xeb787e53, 0x3d7f9863, 0x3faf04e1,
- 0xac9075ba, 0xf27209a3, 0xdf90a98a, 0xf7e6c7ac, 0x37ae04da, 0x369bf31b,
- 0x8453ffdc, 0xfbe32b0b, 0x76335e0d, 0x5b9d3c80, 0x66db6a72, 0x1fdcc780,
- 0xdb9c93c5, 0x55dd76dc, 0x50870479, 0xa611c61e, 0x7ed3780a, 0x215d7248,
- 0xee1fa27d, 0xf1ba7d81, 0xe2dc1ee9, 0xd2e2fda5, 0x37a8edca, 0x451dcea4,
- 0xc7a145fb, 0xddc9e92f, 0x52193869, 0x3ae92fa8, 0x8db2eb97, 0xef5223e2,
- 0xf51e9372, 0x033df8a0, 0x0fa23be0, 0x36cbc097, 0x096d9eb1, 0x80f6bfdc,
- 0xf3f51a67, 0xc47fe49e, 0x42ca6321, 0xc5a7f24e, 0xf372be91, 0x202b9006,
- 0x7989d7d7, 0x097b5baf, 0x466e29f9, 0xfc28f13f, 0x67d7efee, 0xbffeb754,
- 0xaef2032e, 0xdd6ebb6e, 0xf33f7f2c, 0x0dbaf6b9, 0x5b90dcbc, 0x7b79d2eb,
- 0xad4abf63, 0x3ea4e3e6, 0x5c46c978, 0x28c2bc47, 0xece17b7e, 0xd1971b11,
- 0xad2d7ffe, 0xfdfdf99f, 0x5a3f0ed0, 0x7a86c43c, 0xc29f81a9, 0x1257fee1,
- 0x89373d60, 0xf035efdf, 0xb74f8c64, 0x907f51e2, 0x3b407f41, 0xeb403135,
- 0x0c627d07, 0xfae06e0f, 0x3316d204, 0xad2997c1, 0xfffbf0e3, 0xfdb53820,
- 0x4ff4e02b, 0xc947779f, 0x0c379021, 0x7a5f2ffb, 0xedff72dc, 0x23d1013f,
- 0x8000702a, 0x00008000, 0x00088b1f, 0x00000000, 0x7dc5ff00, 0xd554780b,
- 0x733ef0b5, 0x9992bcce, 0x924c2664, 0x84e3c849, 0x71100840, 0xf0444312,
- 0x51888431, 0xd4503b69, 0x20717ad8, 0x9926023c, 0x4b62d5a8, 0x79120cff,
- 0x22341809, 0x0281c150, 0x06f55bc5, 0x701a8c45, 0xaf7a8a44, 0xb7ad8ef6,
- 0xff7f6c57, 0x4a8f8808, 0xd2f5a232, 0x5ad7fd97, 0xce64ef7b, 0xb6b4a924,
- 0xdc3ef9bd, 0xd9cfb3ee, 0xd7b5ed7b, 0xf6b5af6b, 0x4cf5a61e, 0xd8c05c0a,
- 0xce6a2566, 0x7c2c64ae, 0x61edf148, 0x67cf07f0, 0xf7fb193b, 0x95d5a0b4,
- 0xf19fd8c9, 0xe6c60aef, 0x2729bf7e, 0x8ded0658, 0x61cb1823, 0xcfbbf52c,
- 0xd500ded4, 0x7a3f4bb9, 0x3f7c0f7c, 0x8ca97bf7, 0x43ef03e9, 0xf7c18c8f,
- 0x5b6dbcef, 0xd2842ecf, 0x793519d2, 0xf986bca0, 0xef7bc056, 0x27435898,
- 0xbe0ef7f4, 0x5563097a, 0x35e5bbdf, 0xdbb19136, 0x93632a5d, 0xf8ab5b18,
- 0x258a9873, 0xbbe0db0b, 0x644b2cf0, 0x7d63114f, 0x0cd85311, 0x23b875fd,
- 0xb8c1175b, 0xf995d71d, 0x1f5fd0c2, 0xef867e63, 0xf7a54b2d, 0x4c3ddc3a,
- 0x744bf6c3, 0x0ec24017, 0x19faa17e, 0x5a37e3d4, 0x7814bb22, 0x76c2ce5e,
- 0x3e325f6c, 0xf3fa8612, 0x7f7d0e30, 0x0f644a63, 0x8f82cfb6, 0xa371dea0,
- 0xfe861237, 0x47622cec, 0xfa763a78, 0x8c1c3273, 0x05acaae5, 0x8228efe1,
- 0x2b59943a, 0x0701cdd9, 0x713fcfe2, 0x0f007396, 0x6899775f, 0x3d95a93e,
- 0xf437ff4f, 0x7ddbd6c7, 0xe1b0a063, 0xcf6f58ab, 0x3b997826, 0x66f88558,
- 0xb803fc1a, 0x89c81fea, 0xcce7c3ac, 0xb1eb8557, 0x479fe9da, 0x5520fff0,
- 0xb61ff847, 0x0ab635b3, 0x66d61528, 0x0bfc00cb, 0x43fb5878, 0x37630c00,
- 0x978000e3, 0xd670d7ff, 0x2bf3c3a9, 0x07ad0a5d, 0x556df9fc, 0xbc67cd8c,
- 0xd4f2fe7d, 0x58899577, 0x1a6b51aa, 0xa5735b3c, 0xef46c7bf, 0xe28f3fb1,
- 0x0bfa0da5, 0x25b7f132, 0x09ba44ee, 0xd86977e2, 0xba9defff, 0xfdf0eb03,
- 0xf8765c44, 0xfbe074be, 0xf9a3173a, 0xfc3955cf, 0x475535ac, 0xc8fc4afc,
- 0xd7c24eb2, 0x713f90fe, 0x724e393c, 0xfcbaf7bf, 0x00be2237, 0x0f74d1ef,
- 0x75a545e2, 0x63d7864d, 0x43b06f89, 0xd556dcfb, 0x33e0377d, 0xf349ccb8,
- 0x9cdef095, 0x158cbf1d, 0x74ffee0f, 0x8695736a, 0xe9c65ff3, 0x02b72d9d,
- 0x62f112e2, 0x5d03a819, 0x63f1642c, 0xe7886526, 0x8445f45a, 0xc247517f,
- 0x2fdff4f7, 0x49ef89ac, 0x92ba617e, 0x2ba0bf04, 0xdd70d15d, 0x375f0a82,
- 0x373e258b, 0x6e183650, 0x82d5cf89, 0x245d24ee, 0xe2357be3, 0x7c60d27b,
- 0xf93d2c7b, 0x99706fd8, 0xdc94f095, 0xfa11633f, 0xf03b21ee, 0x16ddd00f,
- 0xdd7a2145, 0x646a5772, 0x3da7f225, 0x19f117be, 0xad157c3a, 0x1492ef77,
- 0xdb2bc19d, 0x9441302c, 0x9c9d8733, 0x4a7a4b8f, 0x617a9f90, 0x9f587ece,
- 0x9dd5d7de, 0xc1024561, 0xeaebf358, 0xdeffa42e, 0xfde6af67, 0x19d548ac,
- 0x618843d4, 0xfe143718, 0xbc032b43, 0x2cc5349e, 0xe0175e34, 0xff09c257,
- 0x435fe17a, 0xe8bc80c5, 0xbf1c06c3, 0x9807cb8b, 0xe71a12e1, 0x1d6c29db,
- 0x526cdb8c, 0x6f6826fc, 0xb23e3a5e, 0x4361c392, 0x20146a3e, 0x9b589b35,
- 0xf7c03152, 0x2513a6cd, 0x36f195b7, 0x85bbde0d, 0xf78175f1, 0x5f002a8e,
- 0x4c7d6da3, 0xfa45ba45, 0xd8a5f687, 0xff80345e, 0xf9bff5e6, 0x7cdfc213,
- 0x8d1748c0, 0xb1e7198f, 0x8a9e9134, 0xb524e806, 0xd589e392, 0x8018c8b0,
- 0xa9ea29d7, 0x8a88b1b5, 0xcd565a78, 0x66e9024e, 0x8199e91e, 0xecace3f4,
- 0x0ca1f364, 0x11fcc07d, 0xf74a7b80, 0xc24697ce, 0x58daeefb, 0xb4374e3e,
- 0x4e8bb6ec, 0xbeb0345d, 0xba4bce12, 0x41cca937, 0x0077d1e3, 0x83bf7f8a,
- 0xfb371bde, 0x6ef2c482, 0xa4d32efa, 0xe0f6bd12, 0xcd1be423, 0x38c0a39f,
- 0x328c979b, 0x82a67ae1, 0xbcb9437c, 0xaeec7db0, 0x7f678415, 0x07b7ca09,
- 0x09ce80d3, 0x942abe9f, 0xeaeea52f, 0xbfa0bb5f, 0xffd5dca7, 0x138e258d,
- 0x47f4e270, 0xa648be90, 0x23bd64e7, 0x6e2ecbdf, 0x0c716f29, 0x17f01eff,
- 0x35be2de1, 0x4d0fcb9d, 0xffa2faa1, 0x475cef30, 0x374469f0, 0x222f6db7,
- 0xdac0dc79, 0x591ade89, 0xbbf482c4, 0x69c2c6c8, 0xe08b1740, 0x172874b5,
- 0x3d32b16f, 0x4496fd61, 0x2146f58c, 0x31616e0f, 0x7d96fefa, 0x2c35ed49,
- 0x26f684ea, 0x62a68b1b, 0x6f6c69d9, 0xef417166, 0x3e26b67f, 0xbe7c1d67,
- 0x77758b37, 0x20d444d7, 0x1dab7bcc, 0xbe065774, 0x33eb4ed0, 0x5a4ef965,
- 0x7f0af4cf, 0x4fa83dd1, 0x76fb355e, 0x27bedd01, 0xe7e24bd6, 0xbbf5575e,
- 0xd514f788, 0xdf8ff344, 0x9cfc2563, 0xeb8dbd02, 0xdd9b9f7f, 0xdeca1b3c,
- 0x7a3bdd56, 0x55c9a234, 0x1839db30, 0xb39eebcf, 0xb8dd2037, 0xb7c226dd,
- 0x65cc7e7c, 0xddd57aa6, 0x522bff02, 0x088abb23, 0x9e9113dd, 0x7d4946aa,
- 0x82ce26ca, 0x5666bbfa, 0xe6f509d7, 0xec411deb, 0x07ed07af, 0xb9b817a8,
- 0x5b7028de, 0x2eb27e68, 0x06e92be7, 0x52fea1c6, 0x84a5e22e, 0xc85b8c63,
- 0x7f89b641, 0xe6eff427, 0x493b2925, 0xafd3f6ff, 0x96fd1189, 0xd7882c05,
- 0x795c84e7, 0x3695ca4e, 0x9a2b972b, 0xa832ee6b, 0x9941f73f, 0x95e01d6f,
- 0x83de8295, 0x4a3f1bef, 0x5e9e91d1, 0xef5fe8f9, 0x9fb419fd, 0x5ba2c0fd,
- 0xd2017da1, 0x73dbac18, 0x6047970a, 0x8fd4307f, 0x38f6c08d, 0xb1c1e36e,
- 0xb41c7f64, 0xc846fb08, 0xe0b4c6cf, 0x4fd085d6, 0x3e9993e3, 0xbcf664a0,
- 0x5ee8f239, 0xf7643f6c, 0x1b7e81ed, 0x1b5e3853, 0xdf491b9f, 0x4e0f613f,
- 0x733cc377, 0x3c9f91ad, 0x05e37281, 0x677bd92b, 0xc2117459, 0xaed3b67f,
- 0x70277be0, 0x4250e95e, 0xeaf3829b, 0x043d9276, 0x10b39a7c, 0x36b93bbe,
- 0xe04bcf9b, 0x0986e4e9, 0xcd9b17c4, 0xb3f0bc7c, 0xc27fbd0a, 0x0391981c,
- 0x974f13f5, 0x534056fb, 0xb512c05f, 0xee873d00, 0xbd5e76e3, 0x7881df49,
- 0x09538762, 0xa11eb95e, 0x62678b8d, 0xf2e9687b, 0x1c7ca3af, 0xde51cf8e,
- 0xd9b904b3, 0xc805e2cb, 0x461adb4f, 0x9f514675, 0x91f38f74, 0x585e655a,
- 0x171ba07c, 0x9994f77f, 0xc87e35e3, 0xbe7cf44c, 0xb57ce3fd, 0x707fae2a,
- 0x65c8109c, 0xe48ff926, 0x1d5d4272, 0xfec8ceaa, 0x2d973d0c, 0xfb633aec,
- 0x1de0ceeb, 0xe6bfa06e, 0x9de7fffb, 0x38df8465, 0x9ed645c9, 0xca797c49,
- 0x748b9fec, 0x5a89aeeb, 0xf3e827e6, 0xeaaf820d, 0x63fec2ad, 0x1f224b51,
- 0x6aaaf6ca, 0x72cbdd23, 0x677fa0bd, 0xc1f7cb8c, 0x1fc126ed, 0x1ea2b4df,
- 0x6641c29b, 0x1c47a885, 0xfd4ebfd8, 0x6a20f94f, 0xe17a87a9, 0x9165a8f2,
- 0x004f9128, 0xcc1b51df, 0x2756d4fb, 0x03406fe7, 0x3268b3f6, 0x48b97d23,
- 0x02b5fb05, 0x3d5deb9f, 0x9fa72eb0, 0xfafa7376, 0xf0056023, 0xf7898f3d,
- 0x82ef60ac, 0x4da67b1c, 0x607ee289, 0x2eeb16de, 0xb5f2117b, 0x7ae2755f,
- 0x8e48576e, 0x569b6bcd, 0x4bea15b2, 0xeb405c0f, 0xd399369f, 0x9b88d2e5,
- 0x2114e2f4, 0x11adeb1f, 0x3fdfd90b, 0x01f21851, 0x74764ff4, 0x53947c23,
- 0x280f1831, 0x10f40dd7, 0x5d83a849, 0xcb93a534, 0x9cf20655, 0x524bd825,
- 0x671ca3de, 0x919ff649, 0x1f52c23e, 0xf4c7b971, 0x527b946c, 0x0aebdf2e,
- 0xae49b974, 0xf5c6ce8d, 0x72e4f585, 0x7842bf73, 0xa42d626d, 0xe81ea44f,
- 0x91e8571f, 0xeb986ad3, 0x2a26eb2b, 0xd117775f, 0x27594b78, 0x57a913e9,
- 0xd783a386, 0x7e0e84bf, 0xed007486, 0xe8b01f8d, 0xe35e3065, 0x9a6d1672,
- 0x44e74bc8, 0x4f5c8fd2, 0xc49eb8da, 0xf43ce532, 0x4c7eb265, 0x7ac987d6,
- 0xf5c2db30, 0x69675c9d, 0xe74f64cf, 0xe594c076, 0xfcc19511, 0x3ff9a636,
- 0x60349cce, 0xb2de84d7, 0xb10bf4d9, 0xe0a3601e, 0xd369c5bd, 0xf686ca6e,
- 0xc8fcc690, 0x9780a957, 0xbb7cf09d, 0xb36b7bb0, 0x2d7bdd39, 0x5acd7e9c,
- 0x703b9580, 0xcfb4625d, 0x1732678d, 0xe7c4a3d2, 0x577c2776, 0xfd71df81,
- 0x8dbdffd4, 0x7c24a5b5, 0x9d9cfd5f, 0xcfe7eae4, 0xb256233a, 0x6e858247,
- 0x57eb2fe8, 0x7b53b256, 0x3e92739f, 0xd0fa15ed, 0xd128f683, 0x5fae2acb,
- 0x21275d71, 0x648f5535, 0x35cafb48, 0x4a045123, 0xcdc9acfb, 0xf6c1aced,
- 0x8a2f6890, 0xcae9cf5d, 0xcfccfb4a, 0x62773ddd, 0x6861e01d, 0x588fff9f,
- 0xe981d0e7, 0xe787dfe5, 0xc7c380a1, 0x472c1fb1, 0xdfaab57a, 0xf406deb9,
- 0x1e5d4335, 0xd1e60bbf, 0xa170ef94, 0xfc29ab9e, 0x846f2ff5, 0xcc0787fa,
- 0xbceb8acc, 0x1b1d7a67, 0x5dfcbc35, 0xe89f3112, 0x5b97e049, 0x4deb19f6,
- 0xa87ac69d, 0xc82f58cb, 0x4f4e7a70, 0xfbe1d920, 0xd5b5d033, 0x4ec1f2da,
- 0xbcfad780, 0xa7d1f495, 0x067160ee, 0xfc535bca, 0x5ad9e218, 0xf444f1f8,
- 0x3fba846f, 0x02b4b051, 0x38cac4ed, 0x3faf91fe, 0x742bcfb7, 0x01b7810d,
- 0x899b31fc, 0x3ad60cf0, 0x85ce492f, 0x2c789f04, 0x845f0ffe, 0x9d9a2ff9,
- 0x9e9bbae2, 0xaa4e67f8, 0x60927b42, 0x572da164, 0x2dfb887f, 0xae096f78,
- 0xf059e9ff, 0xb0d5c01e, 0x46c3eb85, 0xbe434b16, 0xd3bb066d, 0x477c4b06,
- 0x5b875f06, 0x5155e2da, 0x8c8edff8, 0xa70871da, 0x802d27f6, 0xfb1ab1f4,
- 0xaf93b04d, 0xe07ae0cd, 0xd7767d96, 0xdd1e0329, 0x2ba87a86, 0x912a75c7,
- 0x61fc84ff, 0xb8968a79, 0x09577a1f, 0x6bf88b5e, 0xa658f5b2, 0xfc57f8c1,
- 0xf79233e9, 0xa7cd978b, 0x5d80c47d, 0xb4f9256d, 0x3d20aef8, 0xdf2b697f,
- 0x6ade9e17, 0xa7ef11d7, 0xe3fdf3b7, 0xc4473ce2, 0x857bff06, 0x8bdbdb9b,
- 0x19453be1, 0xbc64c78c, 0x55f0ffbd, 0xf7a3a45e, 0xdc2f1f19, 0xf78fedc9,
- 0x62af805d, 0xf7f60efe, 0xefd8177e, 0xaaf9e20a, 0x2e2e510f, 0xd0faaede,
- 0x9c87604e, 0xbc598fe4, 0x0b71cafd, 0xa7dfd81d, 0x5fa1a623, 0xe895c768,
- 0x02f7c289, 0x89d7ee11, 0xb5cf015d, 0x1d93171d, 0x95bb7477, 0xedb6e9c3,
- 0xf15c79c5, 0x4af89527, 0xda20b133, 0xff161dc7, 0xfd67e438, 0x70333de1,
- 0x959fde5d, 0x1ff7a26b, 0xf10b9857, 0x85965ee1, 0x5a2b17cf, 0x61b7f900,
- 0x899992cb, 0x866a4ef6, 0xad35eb4a, 0x8f567970, 0x7ae9f883, 0xdb4da3d4,
- 0xfc707f81, 0xf2ff6fd9, 0x3f224f46, 0x4cc55edd, 0xc3cbf609, 0xc27a235f,
- 0x6be028bf, 0x57d7c0b1, 0xaa6b2be5, 0x12968be4, 0xef8ba394, 0x0d71296e,
- 0xf3f45761, 0x0f9cc3c5, 0xb850cbef, 0xc32f20ff, 0x6e18cfb0, 0x3528e65f,
- 0xf9b15e91, 0x940f7f98, 0xc62db0d9, 0x0c81f7fd, 0x640fda8d, 0xfb5f7b70,
- 0x5efb6ddd, 0xcd4d7987, 0x80cf6e08, 0x97f3217a, 0x71ebbae3, 0xb1983557,
- 0xbbb26288, 0x6e56c3d8, 0x8edc6ac7, 0xf6c99cde, 0x8fd84bae, 0x997f6277,
- 0x62f61724, 0xffc7bd3f, 0xdaf10c78, 0x44f1f05c, 0xe7420fb4, 0x1fa0b33e,
- 0x90add1cd, 0x02f8773c, 0xd425e90c, 0x282d8b3d, 0x21c3901b, 0xc913d71f,
- 0x0653faf3, 0x3c84efdf, 0xfde7ea71, 0x3b7f9c11, 0xb73e9cdc, 0x3f214b2d,
- 0xc44f36e4, 0xb5ff408e, 0xa5ed2a7c, 0x67efc225, 0x5f94fddb, 0x288efa45,
- 0xd75831ae, 0x35f47f39, 0x30a88dcc, 0x8bbb87ce, 0x77d9dfc9, 0x854f9a60,
- 0x1feec736, 0x788519ad, 0xf0fb32ea, 0x27af877d, 0xe1f7e70d, 0x386993ee,
- 0x2add86bf, 0xf221bbcd, 0xb2c2d649, 0x33f0b901, 0xca3af825, 0x1c52e601,
- 0x0f94be38, 0x34feee1f, 0xfb83816b, 0x567f480b, 0xa7978d0e, 0x8e7ed3dc,
- 0x39715fdf, 0x1e8f975f, 0xee5046b7, 0xfd07647d, 0x3f6f2096, 0x777d7272,
- 0xefee432a, 0xdf500b3a, 0x2a6fd7f4, 0xf89ca135, 0xdfcf8b8e, 0x402ce963,
- 0x628dfc7e, 0x1ae967ec, 0x6c808b13, 0x5006b25f, 0xa3e8f203, 0x40299f47,
- 0x9ee1ff79, 0x27e60a67, 0x9dfc97c0, 0x78e57b2c, 0xfd266fc2, 0x344b1ea8,
- 0xef9bc70f, 0xe57f72b3, 0xf9547e30, 0xfdc2db3e, 0xab3e7da1, 0xbf28748e,
- 0xf1486beb, 0xc7db7da3, 0xe6ff246c, 0xacbf0b77, 0x83da3fdf, 0x7df918fb,
- 0x1e15ff52, 0x974a4f4e, 0xd483fe42, 0xe3c938b2, 0x7bde59bf, 0xe4133d60,
- 0xbff3ac3d, 0xd9345f21, 0x3246c7e2, 0xe20b0fa2, 0xd0ecd2cd, 0xad653f50,
- 0xbf15f4e4, 0x2afb44c3, 0x81d7ae4b, 0x928aecf2, 0x30133694, 0x6d2527a2,
- 0xf201c622, 0xfde94b73, 0xfba73570, 0x7f231670, 0x516b0e5b, 0xb8bb5e48,
- 0x326f3edf, 0xea83ad73, 0x9edc11ac, 0x16df32f1, 0x5dd698b5, 0xc490ff41,
- 0x480bd487, 0x3f1f283f, 0x3f446c52, 0x7642b74a, 0x9cea6aa7, 0x470efd8b,
- 0xc847134f, 0xa7a73ffd, 0x893ffafe, 0x188f269e, 0x3a829e8e, 0x36d793d1,
- 0x3f093d34, 0xcfbf79f1, 0xbfdc01c2, 0xdd7c0b66, 0xfc4ee427, 0x9bf49b0e,
- 0x99df382b, 0x3699bfa2, 0xfd455447, 0x9c7f33e1, 0x187dffe8, 0x27dc5fec,
- 0x0efda0e5, 0xf395c8e5, 0x16375a74, 0x417f41eb, 0xd236c5ea, 0x629af78f,
- 0x64af6845, 0x8fd96f8f, 0xb73d9174, 0xed2562ac, 0xa8dcf2ff, 0x92b7500f,
- 0x7559741f, 0x0488d4e0, 0xdf10e17b, 0xe5df34cf, 0xbbd3e7a7, 0x1a107db9,
- 0x387b216d, 0x7184a5d4, 0x96039b9d, 0x6b41da08, 0x095fee15, 0x3cebb06f,
- 0xa0afa3ee, 0x740fcfb8, 0x488a171e, 0x8ecf6fff, 0x35bd23ef, 0x91efc838,
- 0xf83a3f1c, 0x1fc7ca85, 0x8efc68c3, 0xeaaf1e72, 0xfee75ab8, 0x1d7eb115,
- 0x6e39fcb3, 0x18d607b4, 0x85c659f9, 0x18809cfa, 0x7afe6f18, 0xae43ad3b,
- 0xd2ccf1ca, 0x0cff5c6d, 0x67e40b96, 0x162c9ace, 0xfa6fc446, 0x05241cf9,
- 0xbb4573d6, 0xcb39378c, 0x79684502, 0xb7e9bbbf, 0xbd00a4af, 0x8e9fa166,
- 0x68c2ca6f, 0x987f93f7, 0xfc7dc9d7, 0xc90009a0, 0x5cffd6c5, 0x42697357,
- 0xf03fbc5d, 0x6b6bdcfd, 0xf6ef48f2, 0xa0d823b7, 0x6fdd658f, 0x351e31d7,
- 0xbd81aed0, 0xf852eb6b, 0xb5c761f7, 0x3c068e57, 0xfffc7228, 0x7f47eb5c,
- 0xc6199da1, 0x4b4f844b, 0xfd0cdfea, 0x7ef9743b, 0x784af6bc, 0x590ac1e1,
- 0x1fad66bf, 0x6ccfbbe0, 0x2a508fec, 0x1c8ac7be, 0x6dacd6ef, 0x0de7d6eb,
- 0x276005d8, 0x39911aec, 0x7eac1f60, 0x85fb667b, 0xebaa5630, 0x5dea0b53,
- 0x1e43e7a9, 0x648fec85, 0xe4203d7e, 0x572cdfc3, 0xf47641f5, 0x57241181,
- 0x4b20667b, 0xe483fec2, 0x80796876, 0xf6073da1, 0xdbc21748, 0xd3e3fc7b,
- 0xef7b422f, 0x1b1fdfec, 0xb77be3a9, 0x37bb45ce, 0xba234e74, 0x2353ed0d,
- 0x4dadd00a, 0x71e80bf0, 0x7a480b8a, 0x7412ea5a, 0x8c330eea, 0x521c7473,
- 0xbe898526, 0x83ae0a5a, 0xf8f7ccb5, 0xe438425f, 0xde7932be, 0xf7c11ebf,
- 0xead2a10f, 0xffd825ad, 0x9da1856e, 0x44f4aeb0, 0x37da02d6, 0x30b59bbd,
- 0x5d25bbe1, 0x973e120f, 0x890f33ec, 0xe08f5fc7, 0x67e6de71, 0xdca3f69f,
- 0x90a228f8, 0x22d0684c, 0xbd40a76b, 0x9684c1a1, 0xcc8cab20, 0x1ce291bb,
- 0x06361675, 0xed0477e6, 0xdf638426, 0x7053c337, 0x814ff0de, 0x8b02db47,
- 0xab6e9f48, 0x4e2839b3, 0x56ff3a54, 0xc52b83c2, 0x5758788f, 0xe3839d5a,
- 0xe19acf34, 0xd808f8a2, 0x7cded871, 0x2fc8b7d7, 0xd75ae124, 0x3b45ae65,
- 0xb9ec0aa7, 0xfcee00a7, 0x7d6a6b8c, 0xd523c7c0, 0x3bb7e5fd, 0xb43e5e30,
- 0x266eff1c, 0x25368ba7, 0x2546fe10, 0xa25941f9, 0x8bb0b35f, 0x8d9f8ddb,
- 0x2be218b0, 0xf6e08d9f, 0xd8e1a5ec, 0xc39f2474, 0xda2a4f5a, 0xffe621d3,
- 0x2ccff704, 0xd0f7d0e0, 0xe479713a, 0x3fc9d569, 0xdcf4f366, 0x5fb6217b,
- 0x85fed1aa, 0xe00f3d69, 0x3d6bbdb8, 0xf04c75be, 0x2aefd601, 0xbd4f7da3,
- 0x3278a827, 0x7d70bcf9, 0xaabd9f7b, 0xd288fd1c, 0xa8fb5aee, 0x5ae6f49d,
- 0x2d7f7ea7, 0x69dfd3ca, 0x16c01f3c, 0x7e874d8f, 0x833efe96, 0x8f6b5dc6,
- 0x0ff5c5ac, 0xbda954ef, 0x607411d8, 0xb9be4bbf, 0x2bd22265, 0x504a4473,
- 0xed3d9a8f, 0xb618e90c, 0xb12fe42b, 0xe30c0279, 0xf3c3d3c4, 0x45f50534,
- 0x1d333d92, 0x5fb455fd, 0xb6bf90f1, 0x18c7f05a, 0x36d382a0, 0x3fb68562,
- 0x6fb0188f, 0x1ce3f95e, 0xbb4a1f0d, 0xfee364c7, 0x14ba9af3, 0x5b2df686,
- 0x42663f15, 0xc627bd7f, 0xea6e0ed0, 0xa69c6854, 0xb82d27d2, 0x93a5b96f,
- 0xec4877f3, 0x057f0033, 0xf18c5768, 0xa07b0aa4, 0x5839fb8d, 0xc448d8ec,
- 0x3d7c63f3, 0x12f78319, 0xad8cabfc, 0xf440f2e0, 0x86711167, 0x0257e126,
- 0x3eed484d, 0xef5bb48f, 0xf3b7fd16, 0x59bb8c52, 0xc455f989, 0xf062b96b,
- 0x2af2cb87, 0x91fa7df1, 0xdfe40cf8, 0xfa17d038, 0xb32ab697, 0xcc29fd6e,
- 0xf1a4eb6f, 0xbcc1343e, 0x056a4e40, 0x0452073e, 0x7d7657bc, 0x86e90332,
- 0xd7e232d5, 0x6a69aee6, 0x6fc78393, 0x4ec85ed0, 0xed89d96d, 0x929737d9,
- 0xc8f8c67e, 0x35fe786c, 0x1cb3e70f, 0x79d7f707, 0x61170eef, 0x48fd33bc,
- 0xe29fd6e0, 0x90a417f8, 0xd61b35bf, 0xe54199c6, 0x796ff41a, 0xa88bf959,
- 0xf533bd7f, 0xc647840a, 0x382e30f5, 0x38e48cab, 0x8a7c33d5, 0x3794177f,
- 0x0e34dc78, 0x116aefec, 0x711e7c5e, 0xd119c40c, 0x62e3876f, 0xdecb0f1c,
- 0x7e46a89c, 0x7be7d07e, 0xacbb4e90, 0xccd7c42e, 0x42df97ae, 0xc6d33b7d,
- 0x9aee293a, 0xd3c4b764, 0x3a4419be, 0x7a733bed, 0xd7083dc7, 0x947d0775,
- 0x8f6492cf, 0xb739715c, 0x93da3fcb, 0xec3f23aa, 0xec1b7212, 0x797f1e47,
- 0x9323ef9c, 0xf6efc8ed, 0x23b72faf, 0x777febfb, 0x17c3923b, 0x28f3c3de,
- 0x890f7ca4, 0xc35f5f7d, 0x5fd434d9, 0xaed23d2b, 0xd8f7ca4d, 0xba3df22d,
- 0xd0f7ce87, 0x0ff8f276, 0xee494186, 0xae222dba, 0x43cef7e5, 0x84bb87ff,
- 0x7b2bc0e4, 0x3748c353, 0x64ed3b67, 0x4b6e6997, 0x7b6ae114, 0x3cc11ada,
- 0xe0453688, 0x578890eb, 0x2c1c4459, 0x834744a3, 0x4025a0e2, 0xa4fc3f72,
- 0xd2abc799, 0x85ee8f22, 0x1ce1e37a, 0xd462cf11, 0x54d9f87f, 0x8a6377c2,
- 0x37fd8e9e, 0x8608fbfe, 0x183eaa71, 0x09f9d70f, 0x87bb707b, 0x7fbc5ae2,
- 0xe75582f6, 0x8968b3f1, 0x33b0f01b, 0x93bfedc2, 0x05a8a6a5, 0x8993bde6,
- 0x32f59f3c, 0xd9e7c5ae, 0x8f2461b7, 0x8231a0cb, 0xdcb5b2fb, 0xe32f545f,
- 0x1fb98755, 0xa5c45eae, 0xf45ece4e, 0xb458a608, 0xb8b52d29, 0xdd7cfb4f,
- 0xdf9ff234, 0x2a2cff79, 0xfd18d7eb, 0x3fd08bfd, 0x3f103c5f, 0xf9f77e96,
- 0xf6e167cc, 0xd0ff80f3, 0xbe8cf604, 0xfd46ab46, 0x775cc459, 0xc3d03ea3,
- 0x43177ab0, 0x1a2506d9, 0x19600af1, 0x7ad6d3de, 0x57bd7052, 0x6f4899b7,
- 0x7e4cdb85, 0xcbd24f7c, 0x67ae1eab, 0xbd70f5df, 0xe08ea803, 0x336cb238,
- 0xe883788b, 0x4533056f, 0xbc2934b1, 0x6ad2ed5c, 0xb2dfd287, 0x8b7336bf,
- 0xcdda1a6d, 0x77f226f9, 0xd7f16e7f, 0xa338bf91, 0xcda9d684, 0x96a6b2d9,
- 0x7d2f13b7, 0xa8078f6e, 0x1b8d32fd, 0x40cf4c96, 0x8782fa79, 0xf19217c7,
- 0x58ddb0b6, 0x2cc38e4f, 0xf5eb1889, 0xa736382c, 0x120dc798, 0xf420bf9f,
- 0x8aebe7c4, 0x167dbe04, 0xfe72bb94, 0xde38f22b, 0x1cbcf94c, 0x875d5f95,
- 0xe30a3074, 0x725845ca, 0x84cc2abf, 0x99751fe0, 0x48fa2147, 0xcdcdb782,
- 0x96bc29e9, 0x5aff21fb, 0xfee193f8, 0xf82593d0, 0xb8c5efd8, 0x42cbbd65,
- 0xf5f3e871, 0x1a64a497, 0xf5fdb7f7, 0x96feffbf, 0xaad7e7ef, 0x45c6bf22,
- 0x8bbe6972, 0xe2a4e5cf, 0xe7c51bdb, 0x701fb00e, 0x0ad56b1e, 0xbfd32394,
- 0x3479a0e9, 0x8239061f, 0x3de5ac71, 0x9bd7a805, 0x304a7bab, 0x5f8c935e,
- 0xf2935684, 0xef9bde0c, 0xda08fd81, 0xf18c6b0d, 0x55f1c1b8, 0x2666617f,
- 0xee4e7bee, 0xd7f5197f, 0x2fe93b7e, 0xad17bff8, 0x16cfffc8, 0x388b5c91,
- 0x2e316383, 0xee894a14, 0xda1171f8, 0x6a8edc31, 0x44eeb6ea, 0x5b7e713b,
- 0xff0f7c42, 0xef18deb3, 0xc8326b63, 0x8c3aceef, 0x4e1e1bcf, 0xfc506efa,
- 0x65d69daf, 0x0e3825b3, 0x10f41df9, 0x599c1de5, 0xbeb86262, 0x116faaf5,
- 0x7633a92a, 0xc67e7da3, 0x466bd7c9, 0x3e3fd4a6, 0xebfabfb2, 0x57d9d683,
- 0x6f5ceb82, 0x7ec4c162, 0x619d709a, 0x3ac51b7d, 0xe2fa799f, 0x8fe75c12,
- 0x825c5ff7, 0xdcd9bceb, 0x29be47ee, 0x41af0775, 0x32ba9cfc, 0xe615f640,
- 0x9d1f20ef, 0x94de3d2f, 0xfd378f44, 0x2eb1e8e3, 0x59321f31, 0xe3f4363f,
- 0x3d1fa8cb, 0xe50f3d16, 0xf59b7cc1, 0xfc49ea2f, 0x679fd21b, 0xe3ff92b3,
- 0xdd3f1ff0, 0xdd18f948, 0xb227d92a, 0xb05ac3bf, 0xc3a3ed18, 0x617d796f,
- 0xd3fef865, 0xb5e5fd85, 0x59fa30b1, 0xda40bee4, 0x78f2c997, 0x03cf98b9,
- 0x8cdffe99, 0x3ce21bf8, 0x20dc7fd2, 0x3e45b1de, 0x6eef76e5, 0xc7fdc7c5,
- 0x6e4fe49d, 0x85cf343e, 0x220fe2fe, 0xfcdc7fdc, 0x8ff93974, 0x8a5e4497,
- 0xeb193e62, 0x1fb85c56, 0xddfbb259, 0x9003cc34, 0xe7d85efb, 0xf9499fde,
- 0xeffdc635, 0x69939107, 0x70003798, 0xa7708fbf, 0xa416e27a, 0xffd866fb,
- 0xb360de61, 0xfd863f16, 0xd9187b36, 0xc65d9505, 0xef8ca0fd, 0x48580b6e,
- 0x56eb6eee, 0xb3af2822, 0x3ca2c12c, 0xcf2c6bd4, 0x80753a75, 0xfe9922cf,
- 0x077e9017, 0x5dfeeae2, 0xa7fe9758, 0x44e9ad9e, 0xe6663dbf, 0xdb3ca177,
- 0x4cf214ea, 0xdbf6f923, 0x7591dd87, 0x6fc37609, 0x584edc23, 0x34c1f322,
- 0xbd60d516, 0x1ff1cd16, 0x7946f5c7, 0xf7924d1f, 0xaf197589, 0x494585bf,
- 0x9eb1352f, 0xc4b0bcfe, 0xf9e392f7, 0xf4370718, 0x75ca5ac3, 0xe4dd93f4,
- 0xab9c51f0, 0x6356cfeb, 0x9bef987b, 0x55961f81, 0x5cafd00c, 0xcdbf4907,
- 0x6a1d1fc2, 0xe90ab138, 0xb8a5d437, 0xe8dd7f70, 0x08dbf4e3, 0x9bcc2ffb,
- 0xd677e64d, 0x1d13cc69, 0xdd7fff8e, 0xff9c77cf, 0x9cac3d7f, 0x5bf8c7fa,
- 0x3f97efdf, 0xfce5ef9c, 0x7fbeffa5, 0xe70add9e, 0x2579a4cb, 0xfd935bef,
- 0x79df72ee, 0x8bf0f2be, 0xf17c7c24, 0x70c7c60f, 0x6b2530f2, 0x7242fde8,
- 0x96afe35c, 0xf8e0ff87, 0x1e8723c6, 0xa881334a, 0xf6145258, 0x6fcebb72,
- 0x50cf1788, 0x371e7e1d, 0x453e7955, 0x9f5ddc72, 0x9ceee221, 0x5a7a5f9f,
- 0x126af5a5, 0x43a6e1f1, 0xdabe1f4e, 0xf14c58e0, 0xe9f8e4d9, 0x067fb652,
- 0x1c72512e, 0xb8f911b5, 0xa9e3cbf8, 0x3d396517, 0x56749f24, 0xc90a7984,
- 0x392f5a79, 0x4c111d3e, 0x32eaef58, 0x410c08d8, 0xcc2d36d7, 0x4f9e1232,
- 0xf4f6e2cb, 0xc89f224b, 0x05e7e16b, 0xfaa673ee, 0x35e31f71, 0x7ca77cf1,
- 0xd67a604f, 0x02ef9424, 0xc0decf9f, 0x4797804c, 0x4f249dcc, 0x1f0e4dc2,
- 0xc7e93fca, 0x10effd91, 0xa5f38b71, 0x19676ff3, 0xfebfbce9, 0x85fbe24f,
- 0xdaffbe92, 0xc016ddb8, 0x181f818d, 0x186befd1, 0x4c1a2a67, 0x33f5c3b7,
- 0xcb2efd1c, 0x459edc0a, 0xa44ff178, 0x94f3e6fc, 0xf195a92f, 0x622fe893,
- 0xfa3aac07, 0xfce26d37, 0x239f5b0b, 0xaabeebf6, 0xcd979459, 0x73c88fcf,
- 0x8fd9c336, 0x9ff9fb1b, 0xf5fd8fdb, 0xc8fd93bf, 0x9c7681dc, 0x7e69a9e7,
- 0xed5ffbca, 0x5f71f804, 0xc875a8f8, 0xdcf22cf3, 0x5df997c5, 0xcdc3f6f6,
- 0xb0ef6ae9, 0xe563ff70, 0x34ff93e7, 0x34fbf9f9, 0xdf0ea3f4, 0x7be4584f,
- 0x9e22fcc6, 0xf82576c6, 0x9e3143b7, 0x8092f7af, 0x447f3e57, 0x6cf4c5e8,
- 0xa75c51ff, 0x6cdb8f8f, 0x9e4c1d2c, 0x9b172e4a, 0x2f8a0e03, 0xbcf27734,
- 0x8ce5e697, 0xfa3377e4, 0xafd0cb4f, 0xbda18b38, 0xf8233537, 0xf57efc33,
- 0x9ab08edb, 0xd9f77e8e, 0xdebbed0c, 0xa9febce3, 0x6c73f83b, 0xa1ef2d0f,
- 0xecc74678, 0xaaef288f, 0xae9fcfea, 0x7824adaa, 0xb1e08fc9, 0x7cadcf1a,
- 0x0fe3c591, 0xbf43fcb2, 0x5f93f13c, 0x9e06e3ff, 0xf8f21d9f, 0x908fe85d,
- 0x3d54f17e, 0xe6a67e46, 0xab68dc03, 0xd87cf952, 0x9e88f3f7, 0x2b4c0f9a,
- 0xeb29ff47, 0x9da397b4, 0x072bf55b, 0xbe3ef7ed, 0x24f2972b, 0x0fc13dea,
- 0x2b3a3e51, 0x5da35723, 0xa0e3085a, 0xfef1fbbd, 0x6e11cbab, 0xa336ff29,
- 0xdfc61cff, 0xc7fa34ec, 0xd9e78d99, 0x4f9bdd2f, 0x4762cbfb, 0x6fec53f0,
- 0x11c39db3, 0xa3ce23de, 0x3279bf08, 0xcfbe4bff, 0x4e344d56, 0x146db7f6,
- 0x6172972f, 0x6d0599b3, 0xe4f203c5, 0xf22e9678, 0x635e444c, 0xa79e2cf7,
- 0x8f0eea22, 0x81f3bf31, 0x238f2bcc, 0xb4b3c73c, 0xe61f96af, 0x402f9418,
- 0x187e62fd, 0x9c5805c5, 0xe7a92dfc, 0xca3d1db8, 0x727a2165, 0x9c51df02,
- 0xed09e806, 0xb1e34bf9, 0x6b9e78e9, 0x52f44774, 0x73e1f3c4, 0x3693c226,
- 0xd38a35eb, 0xbc7c2ba4, 0x6b3df5e2, 0xc61fa2c7, 0xb865e6f5, 0xabbb7aa4,
- 0x353a511a, 0x4d9f9023, 0x52968cfb, 0xbffaaf1c, 0xf29f3ccc, 0x17f92a50,
- 0x291a0a3a, 0x6df7b29f, 0x4e3ce1ab, 0x77661972, 0xa8e4fe53, 0xbc505fae,
- 0x194079c0, 0x72762f32, 0xd6f083b6, 0xa0cd8e1c, 0x3d4b9b1c, 0x43b56724,
- 0xb538a2bf, 0x094356b6, 0x7eccdac4, 0x0b439e13, 0xefe460af, 0x32e1d31c,
- 0x8a157ae1, 0xc3be98fc, 0xa418987f, 0x0f8c8afd, 0x937e7844, 0xee1567b9,
- 0x3d15b4c3, 0x3d718797, 0xcd4db80e, 0xbc5fd865, 0x872dfc99, 0x4fd21952,
- 0xddf15761, 0xb85ea153, 0xb0f145c6, 0x296ee7be, 0xcc2aff24, 0xf310cc73,
- 0xf336ca2c, 0x9aa50ffe, 0x9b699f50, 0xd5470f98, 0x04d559dc, 0x875083f7,
- 0x3c8a467e, 0x453f1955, 0xa9ea143f, 0xd7e0ecf4, 0xffb63f30, 0x14b2d21c,
- 0xe3490e7e, 0xb2e712fe, 0xf3c71fb7, 0xfc2c3b3d, 0xc391e79c, 0xdf936613,
- 0xe0a6ad6f, 0xe6ee7c3a, 0x663794f9, 0x42e70c9b, 0x847ff006, 0x1d4756f2,
- 0x6bd705fa, 0xaff61630, 0x68bd3999, 0xd13b3d6b, 0x2d38b8bf, 0x97ba7948,
- 0x8a5545b5, 0x3d4eb99f, 0xec27ab50, 0x3d70b673, 0xef8fbcd3, 0x35f793cb,
- 0x6e5fa65f, 0x2dda36cb, 0x927ff5fd, 0xfe83f2dd, 0xfdc6fff1, 0xf3ee330a,
- 0xe497ed92, 0x3b20dd7d, 0xe1bfa93c, 0x8f9918ec, 0x0e303d52, 0xd29da7b7,
- 0xf21b0a4e, 0xe21daa75, 0xd8cda17c, 0x5c23e5ff, 0xbf995f34, 0x5f52b593,
- 0xf1fa7981, 0xd7f2301f, 0x70a23cc9, 0x09f7cf35, 0xee746c9b, 0x29dacbd0,
- 0x8b24687f, 0xd3f90a2a, 0x6d7ce87a, 0xc111e636, 0x47b2eb77, 0x99dbbf51,
- 0xf24a8d6f, 0x6e105752, 0x509fe63b, 0xeb646abe, 0x3ae71c22, 0xc7638d07,
- 0x308b93fc, 0x15bfc085, 0x06f4ebe5, 0x05c85f1e, 0x9bf48c7d, 0xa1d39a3b,
- 0xa1e78ebd, 0x99133cc8, 0x50f12217, 0x3b9bf02d, 0xca115176, 0xf04ab5c1,
- 0x99ae7151, 0x4e0dffcb, 0xec195e71, 0x79c0cf6b, 0xfbc63ee4, 0xf898370f,
- 0xaf376479, 0xf9d18c77, 0xf82fa079, 0x728ebb39, 0x2832779e, 0xaf09253f,
- 0xc9e53f32, 0xe411e0b4, 0xcbf3e497, 0xd6124e92, 0x6f47ce8f, 0xfaedc43b,
- 0xcd0b06ea, 0x35c96fa3, 0x5bec97e4, 0xffa86262, 0x9cadbbab, 0xdbc692ee,
- 0x51616756, 0xd88b57ec, 0xf5ca7e51, 0x16bb32ff, 0xfd14b5d6, 0x6b5a47be,
- 0x38053a2f, 0xa01ada3e, 0x74aecfb2, 0xf9d217aa, 0xa928b9d2, 0xf9f2d89e,
- 0xe60e5ab5, 0x140bc4db, 0xb7e79920, 0xea93347e, 0xb077f199, 0xcf16eafe,
- 0xc39034d7, 0x3be2637d, 0xffff7814, 0xdbc47f79, 0x19731691, 0x87a1f77b,
- 0x5f1d8666, 0x91fddf41, 0x9c71e725, 0xc4d3bd41, 0xc8c5567a, 0x5df4245f,
- 0x5e879725, 0x25ec8587, 0x653fc8af, 0x151f2235, 0x5f503b23, 0x714e5399,
- 0x0fd3077b, 0x8f3db0c4, 0x7682cf9f, 0x6395ffa2, 0x26da7fb8, 0x49e582e8,
- 0x184f54bf, 0x22cadbe5, 0x2fdf7d37, 0x23580f8f, 0xc7c63fdc, 0x0be9e37f,
- 0xf325be28, 0xe573196a, 0xf280b9cf, 0xfbf50c6c, 0xa61ce2ec, 0x73c7cae6,
- 0xc2cd2bec, 0x36f515ee, 0x8bc53067, 0x043e44f3, 0x2b8dee7b, 0x7c865bbf,
- 0xf7e0e674, 0xbb5ca347, 0x82fb02ca, 0xeed8e421, 0xfac72e1c, 0x0a358ecc,
- 0x0ce3577c, 0xfac2f08e, 0x773a95bf, 0xa8291e06, 0x82cd311b, 0xf8581747,
- 0x9af11551, 0x3dc4e829, 0xaee7c387, 0x77982809, 0xc7ced2ba, 0x7e6a0ccd,
- 0x9c10f73a, 0x70075ca3, 0xbcb854af, 0xc9d28f86, 0xd3d52a8e, 0xa3611cf1,
- 0x0aaad738, 0xe74971b9, 0xf5ed1526, 0x35beb79f, 0xe006d355, 0x878885fb,
- 0x78c8a2ff, 0xcbdca23e, 0xce5962ed, 0x900bf556, 0xf0ad56fe, 0x12f336bc,
- 0xf8e9ce7c, 0x9565b4ca, 0x557da798, 0xfa254b6a, 0x4f3d0769, 0x0965e787,
- 0xaf7f2b75, 0xc02f16d1, 0xed0be673, 0x8f8849c1, 0x7bbde7cf, 0x3b87ca27,
- 0x0778df73, 0x30de24f3, 0xaf91390b, 0x98eef588, 0x79eb069e, 0xf22dd8ac,
- 0x0f446c3c, 0x3f72c6c7, 0xdb1e7f64, 0xfaf28538, 0xe7e1ce66, 0xb165af49,
- 0x9ef81eb6, 0x3ed0159c, 0xd9117263, 0xde453391, 0x02b78cc5, 0x9817e869,
- 0x435c4371, 0x5d9c3a39, 0xacd79574, 0xc3f024f7, 0x7eb1bad5, 0xfeb1a96d,
- 0xfeb19f35, 0x1a7fc98d, 0xd97f589b, 0xf48d9fee, 0xf3c2bcf4, 0x3097c33e,
- 0x47bdd117, 0x32fda309, 0x715c99e1, 0x27e7970e, 0x77d8abfe, 0x5199333d,
- 0xdb3ed67b, 0x20373c2e, 0x68aad7fd, 0xb665e09f, 0xef7e0cc2, 0xb8bbea03,
- 0x3d1cf222, 0x0761d314, 0x3f71756f, 0x816bbc2e, 0xd3ce0e7e, 0x46aa3f89,
- 0x4e9052da, 0x76261cb2, 0xa552f239, 0x239aec8d, 0xb9e4ee82, 0x058d2aea,
- 0x8602cf30, 0x1be5839c, 0xe88bd766, 0xc87f0ea7, 0x69dbe718, 0x8a5be51a,
- 0x415b1831, 0x5d0487f5, 0xfff2911f, 0x57589a07, 0xef1840e0, 0x1e5cfaec,
- 0x74652e87, 0x656cfe5e, 0xdd25d509, 0xae01fe4b, 0x41a18d1e, 0xe927f445,
- 0x0b4ea7f9, 0xbf7a83d1, 0x34bbf849, 0xea590213, 0xb8807092, 0xc93d42c9,
- 0x7195fec8, 0x6c9b7cba, 0x7ef8fcd7, 0x7e75930e, 0xd44b2bde, 0xaa6a29a1,
- 0xf2fcfd40, 0x3b7f48ef, 0x879c417c, 0xe746cd25, 0xa3e38693, 0x767f825d,
- 0x4b91f125, 0xe8f89abb, 0x3b92cea7, 0x9c6bee08, 0xa5afd42e, 0x0cba9730,
- 0x2a23fd2a, 0x4fce3bf0, 0x474f8a6a, 0xed66f9be, 0x825aa9f1, 0x9bef869c,
- 0xc6a9f7f8, 0x7df0bdef, 0x69f7c246, 0xe0d97df0, 0x6d3b77ef, 0xec44d351,
- 0x21ef4aa7, 0xc9a5187d, 0xade6235e, 0xaeeff166, 0xa3b17911, 0xd47de0d3,
- 0x3cc6a55b, 0x67d93613, 0xa4e4fca3, 0x94ab92bc, 0x57c839e5, 0xba9adb57,
- 0x97bfa07b, 0x655e3ac5, 0x82e67e0a, 0x2dcf2fe7, 0x57fc8a39, 0x98688b6b,
- 0x8b2d77d7, 0xedc5c2ae, 0xc47c169b, 0xe1f24c5d, 0x6693e459, 0x03363835,
- 0xedcc67ea, 0x222d6fa3, 0x9bce79fe, 0x495e1839, 0xa45e1227, 0x493fa417,
- 0xf770c92f, 0x3bd7e7af, 0x3b6f1129, 0x4a5851d8, 0x16b18abb, 0xe7ad779e,
- 0x880bcc0f, 0x65ad8668, 0x2f35da34, 0xdc93092f, 0x00fdcab8, 0x9cbd65e5,
- 0x944ffc1b, 0x7e177567, 0xcbe1a052, 0x716379de, 0xc6f000df, 0x95e137fe,
- 0xbca0e3f6, 0x862d0fe3, 0xf8e1e3bc, 0x421b8e4c, 0xfcc550bb, 0x47949de4,
- 0xf0e39a1c, 0x109179e1, 0x5256c1e6, 0xc2ec8afc, 0x6f6e14e7, 0xb09b1587,
- 0x3f37cee3, 0xaf7b7199, 0x33dedfa9, 0x9477d7e4, 0x6e3bb873, 0x35fde5d5,
- 0xc79c5edc, 0x4b393db8, 0x51742fb4, 0xefc3ccbb, 0x86fdc9d8, 0xd58f4f1d,
- 0x03b05fb1, 0xe9607ec9, 0x322ccec2, 0x7f839bde, 0xde40d64a, 0xb73366f8,
- 0x7c99b75f, 0x62e79455, 0x9ce2f7e1, 0x318cfe91, 0xff64fc7c, 0x628e6e62,
- 0xd7f74f88, 0xc5fe4eff, 0x3f307752, 0x585bfa07, 0x4c502fe6, 0x33f71708,
- 0x1c3e7d02, 0xd6fe9863, 0xfeed1a32, 0x9bcb59ab, 0xcfa262a6, 0xcfa41ce2,
- 0xc59f4009, 0x9d1cfa06, 0x24e5c993, 0xb3e925c2, 0x934b2e9f, 0x1782caf3,
- 0xee1d3f60, 0xa3355fce, 0xf56ddcbd, 0x9e5abcf1, 0x072c9827, 0xa059e012,
- 0xaa3c7871, 0xc24cf04a, 0x39e19371, 0xa4493e1f, 0xf9c66ccf, 0xc97e3861,
- 0x59d858d6, 0x2f2fc031, 0x083583db, 0xacdf3f7f, 0x41a3fbe2, 0xa20eab70,
- 0xe46febaf, 0x2a509471, 0x4f1847d7, 0x67f181c9, 0x5faff189, 0xfaf0e9cb,
- 0xdd10b17f, 0x8451f802, 0x9f68b67f, 0x7944ddd5, 0xcc6bb354, 0x00ed1227,
- 0x13a9b719, 0x94f1cdef, 0xe605919b, 0x4bc634cc, 0xf1e26eea, 0x8b58eb9a,
- 0x7ebde119, 0x3a9fb18e, 0xcc13feb6, 0xc9bbab0b, 0xd3983cf8, 0x8b19671f,
- 0xc2a39671, 0xfc07d08f, 0xd3f4fc82, 0xdf0fc5cc, 0xf63bf40a, 0xe8156587,
- 0x6b32ba77, 0x504deec9, 0xf1b6f1ff, 0xd669ff54, 0x06f3bfb7, 0xa128efb6,
- 0xb9260d7a, 0xf9083ee1, 0xd54df511, 0xc114d78d, 0xa2ed47b8, 0x39f95bdf,
- 0xb04a6f02, 0xe7bc1663, 0xf28a389d, 0xbc846b21, 0xdbc85be9, 0xc9d0bdaf,
- 0xd66f5e53, 0x9358dfc9, 0x79f5efc2, 0x2bbffcad, 0x66b73f30, 0x3c57a894,
- 0x47eb1e3f, 0x1ee84f95, 0x8726de80, 0xce6ff886, 0x09da7ee5, 0x1c744aa5,
- 0x4326a5e0, 0xe7c4dff4, 0xd1e2b335, 0x9a8fe45c, 0x04cfde6a, 0xc5b5b4df,
- 0x2ce99ef8, 0x6d737bd5, 0x250f2869, 0x70e7b59f, 0xa9ed2cfd, 0x67fbe080,
- 0x8db6effc, 0x36037e80, 0x0c5387c5, 0xdf977e4c, 0xe7e0e55f, 0x22fe02cb,
- 0xd3bcfd0d, 0xb37f3cfd, 0x0722b6da, 0x0f5fe7f7, 0x5e712a5a, 0x51f95b2e,
- 0x27d26fb4, 0xf9449b4f, 0x466636be, 0xdf74073d, 0xf1787c41, 0x48690527,
- 0xdd230e6c, 0x259aba4b, 0x48c6bde9, 0xdbafc0d7, 0x5cbf3272, 0xdae81b5e,
- 0xc3d7403e, 0xd700b9d9, 0xa9ae098f, 0x3fd5fd46, 0x265f124e, 0xbc9c3b8f,
- 0x7944bfc0, 0x275f003a, 0x661e5ff1, 0x7f2315c5, 0xecfe4bb6, 0xa62c3842,
- 0x29b39d18, 0xe9e37c54, 0x7630ea60, 0x1f2f8486, 0x8315ae7d, 0x4d3fc2e1,
- 0xcffc7fda, 0x3cf2fb83, 0xf9df0ed1, 0x5c00c659, 0x242bfe30, 0x7871570f,
- 0x5c2d2bb6, 0x5c7b08be, 0xe59be7ee, 0xf38cbb7c, 0xe7e14aad, 0x77e8bdde,
- 0xf97bdf21, 0xcfb87ef8, 0x7ce41d63, 0xcf6f4242, 0x169c05b1, 0xee75db98,
- 0x1b9fa27a, 0xb469f858, 0x8339968f, 0x74f117ff, 0x843e14c4, 0xcc859cfb,
- 0xa057f14f, 0x1272778f, 0x6f090dec, 0x879a9e32, 0xf3c9a791, 0xc0cfc649,
- 0xbec8c5ba, 0xfad8e793, 0xf39e7be7, 0xc7897694, 0x6577f462, 0x8654ff08,
- 0x452147f0, 0xc99e7ea1, 0x2fb87c52, 0xc853ee98, 0x6cc998be, 0xd6679724,
- 0xe19e7d72, 0xd487f6e0, 0xc7f1c3fb, 0x92339715, 0x991b3357, 0xe7c73738,
- 0xd9874c95, 0x2c0ee7ac, 0xadf4da67, 0xd1ef900b, 0xe007d14e, 0x7ee0e99f,
- 0x215cecec, 0x24cf583f, 0xf5fdf3d4, 0x67be7a41, 0xe49fca12, 0x9e66c9fb,
- 0x8cd2fee3, 0x99ca8c73, 0xa12777be, 0xeda8cf9e, 0xcc728499, 0x737bf2e9,
- 0x1fdc0d27, 0xd1c78c98, 0x871926b9, 0x4cfa2f3b, 0x3f191fe6, 0xc706736b,
- 0xcfd238e2, 0x55894671, 0x1e154be1, 0x583fe897, 0x76ec7484, 0xff434d15,
- 0xe81b1cc5, 0xcbba1823, 0x1730bc15, 0x008fede9, 0xf10e6e0f, 0x75e3c055,
- 0x347bc135, 0xe1e12c3e, 0x2b878136, 0xfb3d5e85, 0x89f14ab0, 0x43e97f1a,
- 0xbd084218, 0xe2116662, 0x45e93f57, 0x59d8bf79, 0xf8a2a030, 0xb24e63fe,
- 0x5abf1633, 0xb195f14f, 0x4f4c4c5b, 0x22e393d0, 0x327b8629, 0x30cbec26,
- 0xcce82fd4, 0x617fbc35, 0x7b4328d7, 0xa1bc7479, 0x2a57a2fd, 0xb149f50c,
- 0x2ff78629, 0x50daab7e, 0x1ae7a4bf, 0x3f53fbc3, 0x83a86d98, 0xde70d0c6,
- 0xd8559f7b, 0x65f79836, 0xbe196ff1, 0x19b6cdff, 0xf3bc60af, 0xb2f7d8a4,
- 0x0a563fb0, 0xe9205878, 0x637cdcf6, 0xaa25517f, 0xf3df2154, 0x79eb05bf,
- 0xc034f6be, 0x0bbf625c, 0xc4f68ddb, 0x7ac62de2, 0x55a6f743, 0xe7071b28,
- 0xe354b479, 0x79c93955, 0x79ae351e, 0x50cfa426, 0xe317d82e, 0x62ec1110,
- 0x8e1b33cc, 0xfd6cbfcf, 0x2fe8d84b, 0xfefe7f5b, 0xf5d90b16, 0xaa7d5f8b,
- 0xac8f0a2a, 0xdbfae35e, 0xa7fae375, 0xdfd71a96, 0x7fae33e9, 0xfae364fa,
- 0xf5c6fdbb, 0x5c6b511f, 0x7180ccff, 0x8cebb3fd, 0x34139feb, 0x06c8ffae,
- 0xb7e7fae3, 0x70bbd718, 0x8b3d7199, 0xed0d4bc2, 0xe52febc9, 0xdb9af165,
- 0x7a01ef8c, 0x2074094d, 0xa04168e9, 0xc677f281, 0x30cf7fb4, 0xc03d324e,
- 0xf744d1be, 0x6e3ec1bf, 0xf4fe729b, 0xfc8ad201, 0xf1f4c9bd, 0xeec2b96f,
- 0xfa017414, 0x0ae513a8, 0x614f17d8, 0xd8563759, 0xeda181fb, 0x12bf290b,
- 0xbee279f5, 0x36b93878, 0x7d894f48, 0x0a7ab0f2, 0x81f6c9f7, 0xf470f27d,
- 0x8fb31c7b, 0x4f5a8ec8, 0x5d1ba57e, 0xf14f8e1c, 0xcfe825d1, 0xf2f4827d,
- 0x32700071, 0xe71c7bc0, 0x4f1fe303, 0x8dfe4099, 0xd928b36f, 0x1982ffed,
- 0xcdd83096, 0xe2ada898, 0x953a4f3d, 0x2f6f42f5, 0x858ffe14, 0xb95be0f6,
- 0x9851efdc, 0xc5e6e385, 0x7b14bce8, 0xdd79c46d, 0xe3027123, 0x4f782008,
- 0xca011c61, 0x9ba73b5e, 0xf8ae52d3, 0xc049ee99, 0x4ae9fce7, 0x6ab5d929,
- 0xcd3de50a, 0xfd2141bf, 0x787fff34, 0x2cfa1719, 0x4cb95cb9, 0xd85db3e2,
- 0x482edc03, 0x149ac3c7, 0x07416277, 0xc2e7cde1, 0xb8fe8675, 0xfc47ff1f,
- 0x0ae3cd7c, 0xd06726d3, 0x675a3331, 0x0f3c6f5c, 0x9c38daa5, 0x0d999b8f,
- 0x058139f1, 0x57bc0ec9, 0xfbc6d103, 0x7bfbcf1b, 0xd3fa1463, 0x7cfff554,
- 0xcfe306ad, 0x9ffa2e38, 0xfe863e1d, 0x63ebd566, 0xf41abfe8, 0xba14c0fc,
- 0xcebfa324, 0x87f87bf8, 0xc27e9178, 0xbb2f413c, 0xbdfb8c9d, 0x2386fc92,
- 0x98c09055, 0xe7e663bf, 0x16dabdc3, 0xe63c9fbe, 0x984d635b, 0x37666337,
- 0x32fbe79e, 0x6df3087b, 0xc7e4274f, 0x790cbac3, 0x3cb4e98f, 0xb657efae,
- 0x71865c36, 0x07115ea2, 0x7835a7bb, 0xaab7ae19, 0x0e2f28f9, 0x277257ef,
- 0x40f16f7c, 0x6a9f027b, 0xdd43068e, 0x5e1008ec, 0x10b6b556, 0x3dc598dd,
- 0x6ef3ab50, 0xfc130573, 0x148e1712, 0xcc2d86f6, 0x984c595c, 0xc1f7f0c6,
- 0x55f38674, 0xc4e9da5d, 0x0bd5a87d, 0x2bca25fd, 0xfa2590ad, 0xb6b4d7ad,
- 0x94abdc10, 0xb33b1060, 0x3b51668e, 0xe1aadbe0, 0xbe785459, 0x67922af5,
- 0x3e6de716, 0x3867f7bc, 0xdabd59fc, 0xc87289e7, 0x8728d23f, 0x5db56fee,
- 0xd95af88e, 0x93c68cba, 0x756f6b78, 0x8df58e5d, 0xbed15ead, 0xb54dda82,
- 0x71f482ba, 0x8621681a, 0xc7ad1671, 0xb03d7189, 0x03c61933, 0x045b5ecd,
- 0xe1eac899, 0x05a3b2f0, 0x5d731f44, 0x8df4061c, 0xbc7d03e5, 0xfb4cccb3,
- 0x1df3dbd3, 0xafedfef4, 0x0fd1798f, 0x1e01607c, 0xf98aff51, 0xf0238ff4,
- 0x88721167, 0xf200c169, 0x23572595, 0x6b86747f, 0xdfe3ad36, 0xbbc49fda,
- 0x1f28cec5, 0x20ef92d4, 0xe17cebbb, 0xf7148d0c, 0x27bc0950, 0x44f00fe3,
- 0x8176f472, 0xe2efdba7, 0xefdbbe7e, 0xcec79460, 0xd55fc196, 0x148d5d00,
- 0x059b25f2, 0x056f6ca8, 0xeb8252c1, 0x0b416365, 0x49d675e8, 0xbfd1db2f,
- 0xcd7eed83, 0x4deaa18d, 0x58599e35, 0xaa7c9c6e, 0xbef1d91d, 0x618b3f4b,
- 0xc474be89, 0x4581ab97, 0xc51fccf0, 0x1d783d8e, 0x89a7af35, 0x5e3ab4f6,
- 0xe9ed174f, 0xf7cf5e01, 0x20d4a93f, 0x97f14960, 0xd5c6477c, 0x2dbe51a3,
- 0xb27cfc60, 0x3b60e7b8, 0x91c2f213, 0xdb06ab31, 0xbe74626f, 0x50ffb640,
- 0x4e38e7b4, 0x394629ac, 0xfdf8c73c, 0x6c878156, 0xe9f689c7, 0xb6319f14,
- 0xa64af8cb, 0xf42bece3, 0xfdb1997d, 0xd3bdf141, 0x1d363671, 0xc71b47db,
- 0x53da20df, 0x08ef3c1d, 0x473f21c4, 0x15efda2f, 0xc76c76ed, 0xed8d4bf1,
- 0x2bf8c56b, 0x43ad0095, 0xf8899f3f, 0x9d568ee4, 0xf67cc9ea, 0x7e0cc8ea,
- 0x99f0598e, 0xf21b196b, 0x23abfcdc, 0x9a4cbe79, 0x0ff7e3de, 0x7b650f21,
- 0xb8a34b86, 0x10b5eaaf, 0x421d591d, 0xec3e088e, 0x8b4a2397, 0xf717138f,
- 0x3d197f97, 0x8e7ee103, 0xfe00acf2, 0xbef39e90, 0x04c16263, 0x98db9679,
- 0xef0982c2, 0x1864177b, 0xe53759ea, 0xccf7de1a, 0x77686519, 0xb4378e54,
- 0xf13e58b3, 0xae826dc7, 0x0c2aca52, 0x02bef2ed, 0x923e73a6, 0xf479b576,
- 0x677bc314, 0xa474f54b, 0xcb57d3ed, 0x367cabfb, 0x39b70b94, 0x1f236547,
- 0x3275a4fe, 0xef20df1a, 0x8974a26c, 0xc9474bd2, 0xa2eab656, 0xc7f54a5e,
- 0x7aaf3cdc, 0xd78fab65, 0x6f9d188b, 0x4b5ad95e, 0x2f81c7f5, 0x56d7fcb1,
- 0xa07b953f, 0xfb0e160e, 0x43aff411, 0x7fa13b3f, 0xfd023fac, 0xfa1db963,
- 0xd087f2c7, 0x856fb63f, 0x10feb17e, 0x83e585c0, 0x7f3e0fd0, 0xfac7fa00,
- 0xd500d6a6, 0xa3ad6bef, 0x20d686fa, 0x36b6f795, 0xadb5f3d0, 0xdd5f542d,
- 0x7bca8cba, 0xae54c35a, 0xed435d6c, 0x1f37a116, 0x1f1fe713, 0x7dcfc69b,
- 0x467faf27, 0xeed5f29e, 0x4504a8bb, 0x93c8655e, 0x7dc3c8c8, 0x2f31a775,
- 0x7047f110, 0x931e39d8, 0xe02b18e1, 0x2b62cf18, 0xa0dcb952, 0x2e98eb38,
- 0xc0a9dddf, 0xf85b23a7, 0xc57517ba, 0x81a73da9, 0xcc56378f, 0x2cc27993,
- 0xef1f8aaf, 0x957af7c5, 0x8f2a7558, 0x831f9337, 0x553f0179, 0x9133dce2,
- 0x7084c479, 0x7f419369, 0x1fb3cc27, 0x270e6e5f, 0x78286de2, 0x7c78f22b,
- 0xe4ecad43, 0xb6d49bf7, 0x52cd9147, 0xbf742dfc, 0x102ead89, 0x04f4a0d5,
- 0xc24f7482, 0x603373f8, 0xed720593, 0x874ce5dc, 0xb8d1af32, 0x505dcaff,
- 0xa8e7d861, 0xfd3236e7, 0xccb7e822, 0x194a4fb8, 0x3be19b7d, 0x0cf7de5b,
- 0xddcf16ed, 0xb7f9f686, 0x22f2ad14, 0x8a32473e, 0xafd7593b, 0xd7003960,
- 0x044d8ec2, 0xbde05057, 0xfdf9d157, 0xefc5fbed, 0xfffb0844, 0x2f812ec7,
- 0xd7da7adb, 0x6af3758e, 0x84d87a49, 0xa7e3e7fa, 0xee8e49d2, 0xfe44c47d,
- 0x622c71ed, 0x01337942, 0xbf6c48cc, 0x56726f00, 0x151ccae9, 0x574ce5eb,
- 0x8b117eb1, 0xec08bed3, 0x17a43aff, 0xb11fffb0, 0x7e4cfd43, 0xbf3cc7f0,
- 0xba7a4a2b, 0x8967ac44, 0xd16d07dc, 0x73c3fd92, 0x635fc8f3, 0x26d6073c,
- 0xdc2b01f6, 0xef18d955, 0xff261ded, 0xd6fde9ce, 0x1eb005d4, 0x2a3a9cce,
- 0xba0df3e5, 0xd173c869, 0xbf2abecb, 0x623d016c, 0x086597e4, 0x9fca99ff,
- 0xaabba167, 0xf89c7479, 0xe52ccda6, 0x728e9e98, 0x4beea06c, 0x3ba2bb27,
- 0x89a3f087, 0x1adbd9f5, 0x3900fca4, 0xd377ed4f, 0x560f985c, 0xf74ff222,
- 0xb53adeb5, 0x661f2126, 0x52dfa0b7, 0x3d45ab16, 0xf2665a5a, 0xaf27a845,
- 0x1f617fc1, 0x73c7eedd, 0xf3055afa, 0xc71e18a1, 0xbabce9da, 0x794a85f6,
- 0x4b91da40, 0xb0760e98, 0xe16511c3, 0x997e81b2, 0x477c83f0, 0x5ccff5c8,
- 0xad0f3435, 0x3e47da40, 0x33ecddd4, 0x74863f87, 0x998759f7, 0x6309e5b3,
- 0x9183a97b, 0x6a545b9e, 0xa60ae889, 0x3dd3b423, 0x850eda8b, 0x1c2115e5,
- 0x50f3bdd3, 0x254c1f8f, 0x52dd4dba, 0x7bc35745, 0x79f5c14c, 0x1e99c700,
- 0x1a49a0fd, 0xd35ef057, 0xb42ecb04, 0x5e22c71b, 0xa5d19c70, 0x6285c784,
- 0x575afbbe, 0x159e9e10, 0xefcb68f3, 0x87873bc7, 0xcf78fcf9, 0xe90ea2e9,
- 0x73ce31bf, 0x37f56543, 0x95c6def0, 0x74d85531, 0x33ae7c46, 0x53ce26c7,
- 0x3802e006, 0x5538459f, 0xbffc9b84, 0x8f4d7e7c, 0xc819bf70, 0xbb8a5ab1,
- 0xc4b1324e, 0xa32cabb8, 0xc8cdfe42, 0x4ebc1173, 0x0ba9dcef, 0xdfac4a2e,
- 0xb8fd7444, 0x761fe7c2, 0xcd2f3c6a, 0xfd13d7ef, 0x7ee4ebc4, 0x487f9c59,
- 0xdff6f011, 0xe79e36e3, 0x6c583a61, 0x0d2de60b, 0x25fe1fb7, 0xc4a4ca2e,
- 0x18e830fd, 0x649d5718, 0x759f3ca3, 0x7f4b8f32, 0x337cc743, 0x8afcf12c,
- 0x6ae9d04d, 0xe4af31a7, 0x77b71e5c, 0xe8f589ce, 0xc6be71b3, 0x567964b8,
- 0xdd17bdc2, 0x91ffe4f5, 0x6ebecc71, 0xfd2e0f9e, 0x09044b6b, 0x78e51df4,
- 0xa5587be8, 0xee92e5f8, 0xa17df96b, 0x7ba01e87, 0x1d2fa156, 0xbc5ea1e9,
- 0xe8c6bf5f, 0x3bb059ef, 0x1f452ab0, 0xc45a57ec, 0x48d7e4c2, 0xfb2527f6,
- 0x279b7e91, 0x563e69f6, 0x93ca718e, 0xa58f8beb, 0x88a67ee0, 0x91dbb9d1,
- 0x8f7493ea, 0xedfb5831, 0x2b294f78, 0x24f4f7e3, 0x0525fbaf, 0x3ef3c216,
- 0x1c63aeb9, 0x37d867e4, 0xbefff389, 0x7d7ecf17, 0x96f3f40c, 0x81ce18ae,
- 0x099ba5bc, 0xae81e38f, 0xac64ecb1, 0xa0fba876, 0x5f4df3b2, 0xa5c0bced,
- 0x68d7dfc6, 0x9639eaea, 0xcbbc93aa, 0xfa7807ca, 0xad3efd8e, 0x4e27f88c,
- 0x575107bf, 0xb841e1c4, 0x7ecbfcf1, 0x137327d3, 0xbe7c60e9, 0x7c83edc6,
- 0xbf9357d3, 0xceb84635, 0x7599bd94, 0x1c6b870d, 0x3d1bd5c2, 0xb7689591,
- 0x0ff6b848, 0xa5fabf73, 0x934f155f, 0x0120fa8d, 0x12ff534f, 0x865bf69e,
- 0xc0966786, 0xf28e4fcf, 0xb70642fb, 0xd5fd457f, 0xccf78461, 0x51ebb163,
- 0xb3bc023c, 0x53de7f08, 0x15331459, 0x14acebf8, 0xe42959f4, 0xa8ce8f8e,
- 0x17dbd0b0, 0xa75e7e53, 0x7743dbc6, 0x79e08a2e, 0x0b8bdf02, 0xe0dfd10a,
- 0x7ba56e3c, 0x7949429e, 0x2f5cb222, 0x573fb1e6, 0xab0f1219, 0x78bcb9f3,
- 0xd4f9b5f1, 0x596fbddf, 0xed83ca19, 0x5ef5df22, 0xef0da757, 0xc47895ef,
- 0x2194057a, 0x2a117c4b, 0x3f2b7bba, 0x218ee9b3, 0xf1f133c6, 0x1be24bee,
- 0x572c9e39, 0xbb7297e4, 0xe2aa3954, 0x2efb8739, 0xd9ee937d, 0x2352afba,
- 0xe337fb99, 0xfe127d7f, 0x7d666fa3, 0x8acbd39d, 0x2aa3f47c, 0x037da5ef,
- 0xfe2521ea, 0x9fc432b3, 0x0ff34825, 0x3b656dbd, 0x6a78c195, 0xe72bf414,
- 0xe12fe727, 0x80b65e76, 0x7ae099ce, 0xc5abe020, 0xa44f52fb, 0xf387bd0b,
- 0xa9713d22, 0x4c89cfc6, 0xef5d68d2, 0xce853c9b, 0xf917ecf5, 0x2c4bf114,
- 0xc32efe43, 0xf76f0233, 0x0c45fb9e, 0x770da9ef, 0x055ee99b, 0xbf78f5a6,
- 0x7a147409, 0x9a7ba35d, 0xf16a9e81, 0x5f17a8de, 0xfb869b3b, 0x66f903e8,
- 0x3e40fb82, 0xe77d8797, 0x6f3a5ad4, 0x2e67daf3, 0x9ffe8135, 0x5d8557ce,
- 0x39e18b12, 0xfc158d9a, 0xd84380dc, 0x4ed78e01, 0x8efc2035, 0x2ab3dfc9,
- 0x4f767a09, 0xdbbe95be, 0xf9678968, 0x48740e30, 0xdfee5165, 0xfaeffba1,
- 0x38ba0bcf, 0x8f2b9a1e, 0xe8e09d92, 0x3de2f7e6, 0x5c13af9d, 0x7841f708,
- 0x33ee329e, 0x57b63d57, 0x06a378c2, 0xf8ba77be, 0xe24ca67a, 0x77dcd0f7,
- 0x785dcfe9, 0xc2ba5eef, 0x4be8fee8, 0x3906cc0a, 0xd7c45f5e, 0x1632b3a1,
- 0xe5fc851b, 0xb6af28d2, 0x0d9b7a33, 0x17c97aed, 0xf4a947a3, 0x97916add,
- 0x29727abe, 0xe3a499f1, 0x57c105b9, 0x02366e91, 0x76493c5f, 0x9d302c4e,
- 0xc72ae3f0, 0x95c7e3fc, 0x3fb71d58, 0x2fd42e2c, 0x819326a5, 0x380b8adf,
- 0xec12c8dd, 0xee77b252, 0xf52cb410, 0xc6c45b7d, 0xb7ffbf30, 0xa3a566e7,
- 0x2796da5d, 0x0dbf3ced, 0x095db5f1, 0x38e117a4, 0xbed2a5ff, 0x4ed7c5ef,
- 0x6db8e034, 0xdbe42f30, 0x58ea7e7b, 0x9b49f68f, 0x2a7c4fcb, 0x26dcd7c7,
- 0x9fbc1eb1, 0x2bff16fd, 0xbb8c6fe8, 0x47447df9, 0x43635ca6, 0x4cf787fa,
- 0xad7bcfd8, 0xd81a0bf8, 0x07f90d4f, 0xcf66ba16, 0xb116efc0, 0x6bb42ae0,
- 0x86a87517, 0x11ee177b, 0xb9e162f2, 0xd84d1614, 0xfc9c2c1f, 0xb6373a2d,
- 0x8b1a5cf0, 0x8f75bd82, 0x8f7d1738, 0x0ac45738, 0x443b3d38, 0xdfe515e9,
- 0x24bef7cc, 0xcbf995bd, 0xdf39f3bd, 0xb7e802b3, 0x14b1e949, 0xa71b10c1,
- 0xebce9efc, 0x62ead7bc, 0x780492d1, 0x0473cd07, 0xd38c268b, 0x1b39deff,
- 0x7d6067cd, 0xcc0efd39, 0x787841d7, 0x784bd5af, 0x91ffbe1c, 0xf40e3c06,
- 0xc780ca3f, 0xd097fdc1, 0x96b5eff8, 0x13ff497e, 0x375fe986, 0xefd03fc0,
- 0xf7b71a68, 0xa71ffcc8, 0x891ddf02, 0xf9edbdde, 0x331dfc4a, 0x017efd2b,
- 0xa6aceaeb, 0x338f8473, 0xe77a673a, 0x83bddfe1, 0xee779af9, 0x8c70f8b2,
- 0xae7c733e, 0x333d086f, 0x78c2b99a, 0xc72c979f, 0x7cd31417, 0xb4db9f92,
- 0x32f30b88, 0x0b9aa56d, 0xc6d11f7f, 0x71bb9162, 0x236952df, 0x42e32739,
- 0xe53fdfb2, 0x3b3cf2a9, 0x6f7907c9, 0x979112cb, 0x5e08ec57, 0xd4beeb81,
- 0x13fcded4, 0xd283f6f8, 0xcc373a36, 0x33f69b98, 0xe1a36e32, 0xa315bf2f,
- 0xf0c0305f, 0x7a13cdfc, 0xf77e0670, 0x18271043, 0xd82f51c7, 0xb5bcc41d,
- 0xb8df620d, 0xfaf31ec1, 0x0de6e412, 0xb357da05, 0xe893da17, 0xf72fd276,
- 0xdedd3946, 0x227e8050, 0xfcc4f635, 0xedb7cc22, 0xe976f711, 0x55778a16,
- 0xfefba31e, 0xff7dcbe6, 0x8ebce49a, 0xd1da377c, 0x8694ce32, 0x6b687779,
- 0xbef7e46c, 0x7af2a7d5, 0xa08c7ffd, 0xffb01073, 0xf9432d49, 0xfee55fb2,
- 0x3adf1120, 0x67d0e62b, 0xf94058db, 0xe41f22f7, 0x744bf76c, 0x35d9e4af,
- 0xebfd6863, 0xdd3ef85f, 0x973fb70b, 0x43beb1eb, 0xf563d24e, 0xde155f56,
- 0x973fb85b, 0x5a9dabdb, 0xc122ad34, 0x579d5d7e, 0xe3f9f24d, 0x894c6335,
- 0x0aef8ff1, 0xfa51b079, 0x1578b537, 0xb8f9679e, 0xd233fa32, 0xf4ec07a3,
- 0x83a6513b, 0xfba2abbf, 0xe95a372d, 0x0faa0177, 0x875cdb8e, 0x8d34c3fb,
- 0x074d91f2, 0x99cf04ed, 0x2d7efc75, 0x5de516fc, 0xf491c1d3, 0xa9f556fb,
- 0x6c27ca71, 0x6095f14a, 0xe0feafdc, 0xffd7ba54, 0x057186e4, 0x644eff28,
- 0xaf7405ea, 0xf43c06f1, 0x6343f509, 0x17b5f3f9, 0xe75579d3, 0x50e0d4c6,
- 0x8fa9107e, 0xdaefef92, 0xdbde5b9f, 0x6719f885, 0x7dfca1f3, 0xb8f1f14f,
- 0xd9f12bef, 0xf915c53a, 0xd77ad2f9, 0xbc7dfa69, 0x6f778efa, 0x43dcf462,
- 0x73f72b74, 0x0bd5e3c9, 0x12dfb57d, 0x4bbf8b9f, 0xe052bf56, 0x624efc5d,
- 0x7e9ca9bd, 0x7de24faf, 0xb73dd263, 0x24fd084f, 0x69af93cb, 0xd8205f74,
- 0x1fe80511, 0x4ad8793a, 0xe3727674, 0x2eaf3a04, 0x9c07abc7, 0x4f2f80b8,
- 0x7113e864, 0xf2169f5d, 0xdf257eaa, 0x30e7caa7, 0xe77f0c7e, 0xa5487e30,
- 0x573eaebc, 0x92e30d3c, 0xef593df2, 0x4ab74f9f, 0x3fb597bf, 0x6f5a45f7,
- 0xf48627a0, 0x49c17a64, 0x82f43a7a, 0xe7ae1775, 0x8c2c95c7, 0x5bf0cffe,
- 0x8ec7f7fc, 0xfd92b21c, 0xef9c77dc, 0x9fdd076f, 0xe01788e6, 0x17a1a1fd,
- 0xeb1c9246, 0xe0ef8fcb, 0xdf9db6f6, 0xf046f8ab, 0xcdff1162, 0xe611f711,
- 0xf9f79da0, 0xed147b21, 0x9e29283c, 0xbdbb6610, 0x2a70fcf4, 0x940fff43,
- 0xca63cf14, 0xeefd2f01, 0xdf176b0c, 0x3bfbe8c7, 0x5163820b, 0x0c59df2e,
- 0xfbf03bfd, 0xe7def453, 0x521782a3, 0x5cb18a0c, 0xf52e5e31, 0xa42c1f9b,
- 0x5e67cae7, 0xed2a7bfe, 0xed463da2, 0x62f06b21, 0x9cafc79a, 0xf310e76c,
- 0xeef7aafc, 0x41182d1d, 0x06e128eb, 0x98dd933c, 0x05b3978c, 0x3b7bf126,
- 0x74c91f1c, 0x5f9ebfd9, 0x5ffa1f02, 0x21f6bce8, 0xc6eb8ebe, 0x591cb859,
- 0x63ec813b, 0xc86296d6, 0x88715b9f, 0xbbd0c3df, 0xdceb49c1, 0x843ff667,
- 0x86fe28fa, 0xed7bf199, 0x3f4022c0, 0xf9a1e4c5, 0x4f9123e5, 0xcf2d64bf,
- 0xd1e8fbb3, 0x39e60bf7, 0xfbf25cf0, 0xd2c97386, 0xa49d085f, 0xe1c63fa1,
- 0x97e6d3d3, 0x255d7b71, 0x7aeff8f8, 0xf4eb346d, 0x0de16bbb, 0x711fc8e3,
- 0xa41fa2d2, 0x775b87df, 0x4ae90981, 0x77f2172d, 0xbc9f9f13, 0x7bde4b2f,
- 0x8a9f8c95, 0x7f9262c2, 0x33782c4d, 0x827ea1de, 0x61c259e9, 0x91fff746,
- 0x6984df7b, 0xe29f9a88, 0xf485acb6, 0xf67be0c2, 0xbbf25f2c, 0xf5bbff6c,
- 0xf42b5c2a, 0xd38795ef, 0xe07eaf50, 0x3a46fbe2, 0x5d7a8f7d, 0xc36cf3e5,
- 0x83af300f, 0x4e14a605, 0x879276a2, 0x5dbc281f, 0xf341b9ca, 0x7ec17a47,
- 0xebe83df0, 0x7fee429a, 0x710cae63, 0xc16c2bc8, 0x9fa94d3c, 0xc2668a42,
- 0xdca7f373, 0xe3d21a7a, 0x19c5b5a9, 0xc60f302b, 0xda2567ad, 0x8ca3a1d5,
- 0x78eb8bce, 0xf8c5f8df, 0x89fe32fb, 0x9fdbf7e8, 0x243bf461, 0xb4e4f3c3,
- 0xed89b99e, 0x9eb90a73, 0xf6285f9b, 0xe44c8599, 0x8de32657, 0xb162fbaf,
- 0xf0796aee, 0x2687da72, 0x4b78b7bd, 0xa487a0ba, 0x7fcfede7, 0x1ea0f297,
- 0x4913de36, 0xef185fb1, 0x612c5783, 0x532c42e5, 0x61bdaf28, 0x0d739713,
- 0xb92cceaf, 0x5ee9d78b, 0xef3b6985, 0x59e3dfa1, 0x12caebb0, 0xad16e5c6,
- 0x05c7a483, 0xb412fe05, 0x555be2e3, 0xc345f217, 0x51e09516, 0x56d73ecd,
- 0x8b7a7e78, 0x06bbec99, 0xbce9cf01, 0x9bad1a60, 0xe00b34c6, 0x4c16b4fd,
- 0xab75fb23, 0xa4a1ddf8, 0x6f7bc079, 0xe043156a, 0x99d7c6c7, 0x043c53f0,
- 0xa261bc1d, 0xbf805a75, 0xec70890b, 0x79bfc854, 0x33783f3a, 0xfec14fd6,
- 0xabe9cf1f, 0x7dd0969b, 0x3ef8c936, 0x7d120b6d, 0x91f3162e, 0x471e4cf8,
- 0xf10fb3e2, 0x2bd2f689, 0x85ef4853, 0x6291541e, 0x9fdd8bd9, 0xda7cbed2,
- 0x99df2ba1, 0x8137cf8a, 0x9ea3a2dd, 0x6fb3f51d, 0xa35b9ea3, 0xfe7a8c52,
- 0x962ce2a1, 0xff71afa4, 0x39f5ff39, 0x3d04a669, 0xf1c83ea9, 0xa4e73aa4,
- 0xcff7a42d, 0xebe91d7e, 0xaacbee84, 0xf1ef7848, 0x83b8fec2, 0x37eabd61,
- 0xc70d21fd, 0xa66f5869, 0xe975c979, 0x7ca079c3, 0x208d4f6b, 0xc5e5f7fd,
- 0x4eb95fa9, 0xeb8df4fd, 0xde09e920, 0x9742affb, 0xf24c2718, 0xb05154e8,
- 0x9d0437ca, 0xc6007a2c, 0x38b6fec5, 0xf3d2fee9, 0xa3e2571d, 0x5f05bd7f,
- 0x71d71d53, 0xd1f91147, 0x74686f4d, 0xfb44e0c8, 0xc7c80555, 0xd02fa0f5,
- 0xc4af516f, 0x647ba1df, 0x1ee9590f, 0xb74dfae6, 0xd5e38cdc, 0xb09ab71f,
- 0xabe1d4fd, 0x495c1226, 0x2a780aeb, 0xfbde8a18, 0xbe05e28a, 0x3d81fc04,
- 0xe72dfc41, 0xc1370093, 0xba29fb01, 0x08afa88f, 0x0e4133d6, 0xedc859bc,
- 0x65df782e, 0xf7e6fa21, 0xd7cff561, 0x575f3495, 0x64df7cd2, 0x17ccdf44,
- 0x782cf9a4, 0xe7c26adb, 0xb6bfee0b, 0xa73df704, 0x79a74dd6, 0x4ff0ca9d,
- 0x553afe44, 0x210ffd00, 0x0fdc172f, 0x0bfb2cf3, 0xd3b76cf3, 0xcf3b0d7a,
- 0xf60ef88c, 0x89f9e617, 0xcf3943a0, 0x0d3d34f7, 0xcf43f9f3, 0x2efd0caa,
- 0xc6c0fca1, 0xbf4ebca9, 0x73321713, 0x4a6d087a, 0xdedf7ca5, 0x04fbfe6e,
- 0x78c00e52, 0x260f49e7, 0xd55387a2, 0xd0c9e6fa, 0x3f07ffdf, 0x00b71737,
- 0x0000b717, 0x00088b1f, 0x00000000, 0x7dcdff00, 0xd554780b, 0x733effb5,
- 0x64932666, 0x08124c92, 0x3c984081, 0x49849009, 0x768a8802, 0x02d10478,
- 0x89794f0d, 0x42100793, 0x69b5a05e, 0x0240cd6b, 0x350d45a2, 0x01d45a2a,
- 0x0da2a281, 0xbc150a0a, 0x45622a03, 0xb68b57c5, 0x514026e5, 0x5ea0c679,
- 0xffd7b5ae, 0x4e7dadfa, 0x5490ce72, 0x7dfbdedb, 0xdf1f7cff, 0x5afd9f66,
- 0xd7b5ed7b, 0xe7bdaf5e, 0xcbaa3dc2, 0xe4e216ef, 0xff6f05dd, 0xf7a517bc,
- 0xfc812eaa, 0x02cddf58, 0x2cc38ff9, 0x934a14fe, 0xfe70a68b, 0xa56b9b65,
- 0xa689c422, 0xa141fdbf, 0x367d85fc, 0x0bf2a0b7, 0xcef74529, 0xea8f7e46,
- 0x2fed415a, 0x259f680c, 0xd8b97386, 0x5deae544, 0x2e509a23, 0xcae61e1e,
- 0x0df2f2a0, 0x09644261, 0x6856fbfe, 0x3be9237f, 0x6ba50b52, 0x34786f55,
- 0xfd2f4da5, 0x6fa5c944, 0x578f3756, 0xf724abf3, 0xb97e34dd, 0xf9ed5855,
- 0x399edca8, 0xf388472d, 0x03136d7b, 0x233f32d9, 0xb03fcb87, 0x5d8d7952,
- 0x7bf85af8, 0x0e6a7dad, 0xd2b6e28f, 0x0fa98b38, 0xfae94a91, 0xea60ef18,
- 0x938d317f, 0x8b7de342, 0x0e5c1fbf, 0xe7cb0edf, 0x9fa88a0b, 0xf6626d7b,
- 0xf55dd973, 0x4ddb34f4, 0x6d46f61d, 0x553b577b, 0x3cc62588, 0x2422a1e1,
- 0x477914bf, 0xa432be57, 0x7ca42abc, 0xa7cfbf47, 0x1f2f3914, 0x1fc6037f,
- 0x12c785d1, 0x2c3b8f0d, 0x72eb1df4, 0x44d8128f, 0xbab12dff, 0xfe09cbed,
- 0x9b88c6e7, 0x55a94fd1, 0x47cdae38, 0x5f9e0ebd, 0x86345589, 0x87bbe3e5,
- 0xa6f3e9eb, 0xe2c31afe, 0xced11f28, 0x89bd53e3, 0xda9e4376, 0xab9ae09b,
- 0x4ba7a3c1, 0x4ebb85b7, 0x7fa0f3ea, 0xa6b12d55, 0xbeeecd7c, 0x7c0693ae,
- 0xfa7fc52f, 0x3449bfd2, 0x8bc091fb, 0xdddaabfc, 0xe892307a, 0xcdf14da7,
- 0x17bf5375, 0x9d1d7e0e, 0x1f75e6ed, 0x9beb4459, 0x7f3ea6af, 0xbedbe698,
- 0x426cf547, 0xfdd86fbf, 0xe7fd0c4a, 0x6e0f8b9b, 0x2fd5efa7, 0xddbb89a7,
- 0xc50ff35d, 0x17dd85e3, 0xfbe953a3, 0x08f643f9, 0xb9e68c31, 0x9dac7e37,
- 0x5c4762e8, 0xaf78b77b, 0xef5dd6d5, 0x35b5bcef, 0xdea1aa7a, 0x3d1ad179,
- 0x252f40cd, 0x8bd62fbb, 0x5f9fc65c, 0xefc2efcd, 0xc7bd7d89, 0xf4bdf4aa,
- 0x5ac6fdf7, 0xc35fbd28, 0xf736bddb, 0x6e096b13, 0xcf309eff, 0xfcfb8216,
- 0x682db31b, 0x728dfe7f, 0xcbcdbd2d, 0x244f5fe9, 0x8b68fc63, 0xbc7d77a4,
- 0xf70b6e35, 0x7b696a53, 0x8fda1aec, 0x93ebbfa5, 0x55d290d2, 0xcfc96a5e,
- 0xb76f3ac4, 0xdc002fb5, 0x46b115e7, 0xe7eaeb89, 0xdb9bb77e, 0xc9f3df9f,
- 0x270fe063, 0x4f901dee, 0x41f94d64, 0x3f2a3eb9, 0xa64151ff, 0x7f3dfa8b,
- 0xf80f5f4f, 0xfb9b76c2, 0xbbb7a636, 0xf7d83ca2, 0xa7187f7a, 0xb9effd16,
- 0xe90fa462, 0xca5e1247, 0xb8e4fae7, 0xabbf257e, 0xfb8b68df, 0x17e0d1be,
- 0xb679b7bf, 0xeffcb250, 0x31627d69, 0x6ee7ec3f, 0x4d74a1d6, 0xf89b7098,
- 0xbb864ac9, 0x22ec7844, 0x030b964d, 0x228995bd, 0xc9b0befe, 0xf1117dfc,
- 0xbc5f7c09, 0x5cbdfcde, 0xa56ead34, 0x98092df9, 0x3fda0bbf, 0x6bec04fe,
- 0x5ec5affd, 0xff7a0514, 0x4f54cc36, 0x40fe35f8, 0x255f091f, 0xc7c11fb4,
- 0x8102519e, 0xbbdf5895, 0xe8679e54, 0xa775debc, 0x2287bb70, 0xab4167ff,
- 0x5b8f5d61, 0xf0913584, 0x1c2edc7a, 0x47e8f989, 0xf5fa8508, 0x6c0b0bef,
- 0x0f7726a1, 0x04b92afe, 0xc231af7c, 0x5bbe0822, 0x427ce05d, 0x49f7d8ac,
- 0x5d29fa32, 0x356de853, 0xe6c177c0, 0xd4e7e87d, 0xe25dfdbe, 0xf8ef54d7,
- 0x58d340d8, 0xddf8eb82, 0x1ba1a7aa, 0xb1af4eb8, 0xe1014088, 0x02212ee3,
- 0xf27f94f1, 0x5a62e493, 0x7cb6cf97, 0xa4625c92, 0x36cc457f, 0x129ea3d2,
- 0xef3ebc24, 0xfcd2ef61, 0x305cd38e, 0x5d7ad09f, 0x57866beb, 0x2ab867c7,
- 0x87a3bb6a, 0x54f740cf, 0x5577f59e, 0xf7efb178, 0xcfa002d9, 0x3c5f8dc8,
- 0xb9f40f38, 0xa14ae6d7, 0xa9f66bb1, 0x2de6955e, 0x0c81a8f6, 0x4f7b639c,
- 0x9ce05744, 0x52e053d9, 0xd9aef30d, 0x7ce116a3, 0x62fbbf39, 0xf7366942,
- 0x44edc533, 0xa03c07fb, 0xf8e09edf, 0xf7fd5b9b, 0xccd79ff8, 0x7f65ceff,
- 0xf8037090, 0x9953c6c0, 0x07c4efe0, 0x79a6e6ff, 0xc6fccf9e, 0xad10bc8e,
- 0x047f4123, 0xe09bb45f, 0x2af810bc, 0x8e5c105a, 0xd037aabd, 0xa5443acd,
- 0xff4f19d8, 0x09137c32, 0xf82e84be, 0x94a89e08, 0x56705d11, 0x38eddbbb,
- 0xa2382f67, 0x694fc173, 0x12f29342, 0x0dc9f3b4, 0x493a5afe, 0xbf1d7f10,
- 0x70cae167, 0x8a4d0bc8, 0x97be8c27, 0xdcf955ed, 0x191bdb2a, 0x3f1816c0,
- 0xd2f9c9c8, 0x1840d547, 0xa3a827e5, 0xea9b30ff, 0xf547be2f, 0xfb148ed0,
- 0x07f6de37, 0x8375d61b, 0x881ca04d, 0x344b5c03, 0xfdec96b8, 0x8d0a67e1,
- 0x2ddf78b3, 0xe2ce3007, 0x170f1407, 0xe8edf3a8, 0x8a43c977, 0x67405788,
- 0x3a46e3b6, 0xce64d85b, 0x0bad122f, 0xc1fc1554, 0x9ef09dfc, 0x96fd415c,
- 0xdd730eef, 0xa102f18d, 0x4abc42e5, 0xff68d4f0, 0x3b58cacf, 0xcfd500f7,
- 0x3c6768da, 0xe2170f9c, 0xb5abf608, 0x0d204135, 0x1d6326b6, 0x6bf9efcf,
- 0xe6b1d632, 0x2995ff77, 0xcebf59ba, 0xaa37b4fd, 0x2148a9d7, 0xc4514eae,
- 0xfba0a9b7, 0xba8a538b, 0x201b6fa9, 0x9b36c5f7, 0xca879fbf, 0x8afc6c0f,
- 0x3d85c1f9, 0x6eae81be, 0xbf6bb7e8, 0x892dc3fa, 0x02e18348, 0xd716f0e9,
- 0x2427d80d, 0x35be620f, 0xdb4f569b, 0x97f0f944, 0x44b9386c, 0xf793864d,
- 0x42c7f60b, 0x3efabf43, 0x80be06d9, 0x0fe48474, 0x1cf201b6, 0x7b9daa3d,
- 0x4c77f6db, 0x9e06e8c9, 0xd71b6ea3, 0x5c100db3, 0xd17759ef, 0x845bd05c,
- 0xbe0d1fc5, 0x775ebc2d, 0xa2b3c22f, 0x5d4357d1, 0x89ef82ad, 0xfed389a2,
- 0x47d385a2, 0x5139f085, 0xc05c785f, 0x620310b3, 0xf3de3f81, 0xccbecf8c,
- 0xadac7f37, 0xe8357821, 0x022b1fc4, 0xeaffe85b, 0x63508746, 0x46b5ed20,
- 0xce5451a3, 0x5206fbb4, 0xd503edb9, 0x1dde40a2, 0xc7a7afa0, 0xa5f7fd85,
- 0x718c4673, 0x2e1ff6fd, 0xaafe8899, 0x8c22a976, 0xd3b73bfa, 0xd44e8226,
- 0x7c02fda7, 0x9ec2fe1c, 0x57b4be02, 0x6b979011, 0x35ef8f28, 0x80deada3,
- 0xa4772f01, 0xd50f18d8, 0x9cf29929, 0x4d0f7ab6, 0xbbcf7ea2, 0xeb90ec4a,
- 0x26cb876d, 0x25b1bce2, 0xd701d896, 0x1d63c3fe, 0x58b75829, 0xd59bef2b,
- 0x8f71f57b, 0x547fd0b8, 0x6f0c07ec, 0x4445b663, 0xa3c6bb53, 0xa6460161,
- 0x30a1f243, 0xc18daf0d, 0x37770ef1, 0xe317e3eb, 0x2a28c493, 0x044ea9df,
- 0x255ce79c, 0x2da3ac2e, 0x0aeee896, 0x4ef36f6a, 0x0dfa9abc, 0x078b8d8b,
- 0xd2526b7c, 0x8abf3d78, 0xbf3865ad, 0xcfc2f122, 0x08b6b7fb, 0x65fec6f9,
- 0xe9bee32a, 0x35cfde21, 0xd47e390e, 0x51cf953e, 0xe343a571, 0x4abbefdb,
- 0xc9059c69, 0x0f4147be, 0xc46dfc9d, 0x39fc02ab, 0xf96162cb, 0xe735f1ac,
- 0xbd21f05a, 0xa48a6cfc, 0x563d7d37, 0xc0bab2f5, 0xe8d51e3f, 0xc8ab9573,
- 0xa7986f91, 0xc345b7ad, 0x78039157, 0x3a2f61da, 0x9da5f384, 0x3cdce3be,
- 0x01cd3890, 0x59ea853d, 0x7aa9cfd0, 0xf47631da, 0xfc01c33b, 0x3255ea2e,
- 0x8b16ed01, 0x6fd8d5da, 0x22abd78b, 0x8dabe068, 0xa2ee3936, 0x1822114b,
- 0x22ee35df, 0x7f6e3f5a, 0xe9045a29, 0x970c6ddc, 0xe4a31af5, 0x452379fe,
- 0xb50f9fee, 0xf969b4f9, 0x7baf997f, 0x5cfd7ccc, 0x96b61fec, 0x46fefe48,
- 0xa55bf50a, 0xa1484eb4, 0xec4eadf9, 0xa7bf03b0, 0x98225dea, 0xb2f78069,
- 0xa08bc679, 0x7acedc61, 0x9f3c1c97, 0x3370f5ae, 0x75f35dfc, 0xd54e1e32,
- 0x7b1e3227, 0x84c93fee, 0x53feaec7, 0xbcbc784d, 0xff1e4cff, 0x77d67d54,
- 0x87b43ff4, 0xf826ddfe, 0xe74dfabb, 0xdf6ec571, 0x3b97f040, 0x980fc45d,
- 0x505f886e, 0x3df15db9, 0xdbe4357e, 0xe404c28f, 0x7dc2afbe, 0xfe065c83,
- 0x65ce0df0, 0x4982e7d6, 0xd17eb7e0, 0xeecd69cc, 0xded0138b, 0xfb017c4d,
- 0x11af2f49, 0xf8270ced, 0x3583e885, 0x7cb9bab4, 0xf4106fb7, 0x4e8e1d22,
- 0xa775e679, 0x20fb42df, 0xa3dfdf6c, 0x582f8fb1, 0x2878a7db, 0x46abd96d,
- 0x7c75f71a, 0xb1a7a4aa, 0x6dc8be03, 0x68d5efa5, 0xb6ef7c47, 0x020e9797,
- 0xdac3aa7e, 0x81f70173, 0x8b96ff97, 0x7dabe473, 0xfbe2074b, 0xf2cfaa36,
- 0xdabdbd87, 0x5d2fe863, 0x5196fcb8, 0x5533a95d, 0xefd0ffee, 0xf435f6db,
- 0x89db1c03, 0x0b9209bd, 0x0a2aebab, 0x0d83c64e, 0xff07ef79, 0x58b7c412,
- 0x5d3dda1f, 0xeef9031d, 0x28799243, 0x948f7c3f, 0x100f861b, 0xe40a4b01,
- 0x83670fbe, 0xb08f544f, 0x470aa0bb, 0x79611de4, 0xc384623b, 0xbffd50a5,
- 0xdbe397f7, 0xa1a42f21, 0xe83c617d, 0xf164caf9, 0x1b6dc9ef, 0xf04ff642,
- 0x34edeabd, 0x3ada955e, 0xfbc29c65, 0x7c153f28, 0xde2fadfb, 0x04d7f4d6,
- 0x9c01cfac, 0xfbcf046b, 0xa9653f5a, 0xcf502bbe, 0xe7bd68e7, 0x7337aa0a,
- 0xe864df56, 0x7e9ac547, 0x52112626, 0x947e64ae, 0xe5c83b03, 0x83d4b6e7,
- 0x3e7c525e, 0xd7dfc1e0, 0x35f9c1e1, 0xfa384934, 0x62455e12, 0x8d1a7520,
- 0xa2d5213b, 0xc0140fdb, 0xe39b443d, 0x965afd33, 0x1939f2c7, 0xfd1d0388,
- 0x4b4ee3b3, 0xfc064ef5, 0x670ffd7a, 0x75f1cbcd, 0xf2e86e73, 0xb2deddbc,
- 0x57b6700c, 0xfc7f5939, 0xeed44500, 0x41615989, 0x8a7a1a35, 0xf9f40d73,
- 0x0e0b91a3, 0x8c7c26f6, 0x43cdf28f, 0xbc6fb3ff, 0xcaf2357e, 0x72f77881,
- 0xeb7173d0, 0xc2efd648, 0xbca3377d, 0x981be1d2, 0x373c5340, 0x062837c0,
- 0xbc517c87, 0x9451275c, 0xfc2dd453, 0x45629e12, 0xe518df8e, 0xc53f472b,
- 0x5d8f2396, 0x23d66f81, 0x8d106f6c, 0x739fb9bd, 0x9dde5176, 0xe1e3affc,
- 0xfd8f3698, 0x25ed7136, 0x75fedf9a, 0x82069e31, 0x1bceecb7, 0xba50d417,
- 0x109452d0, 0xdf704d54, 0x575d4a96, 0xf6078bfa, 0x9cee7925, 0x4ebb834d,
- 0xcaeadb83, 0x50e7ee34, 0x79741bb8, 0xeb0a17e5, 0xf947fc83, 0x81b1fd17,
- 0x661f29bb, 0x74c1f8b9, 0x16395b9c, 0x886c93b6, 0x7a45bda0, 0x9c1a3be4,
- 0x73bed28f, 0x35f7f1c4, 0x21189ef8, 0x683e27db, 0x507ec009, 0xaf0f7634,
- 0x4ed513d3, 0x15634a8f, 0x721db70b, 0xb2f0a950, 0x31d7fcfe, 0x4ad7db7f,
- 0xf54e6af3, 0xddbc07dd, 0xfe496f1c, 0x0df0e180, 0x6b790a9d, 0x3fc79cb4,
- 0x1e793790, 0xc6cb84d3, 0x6b589942, 0xcd31fc81, 0x50b2a725, 0xba63fb91,
- 0xde30daf0, 0x7ae3e14c, 0x7bb79def, 0x07bc4fa1, 0xbee0885d, 0xfbf9f851,
- 0x74e0111c, 0xfd72089e, 0xe72b449b, 0x7d137c75, 0xd24bdcdc, 0x547d27c7,
- 0xc056ffc6, 0xee646efd, 0xc79a3a80, 0x650687d4, 0xdcd57eb0, 0x5df3f19b,
- 0xe8d54f70, 0x6feff686, 0xbfd88eb1, 0x699fa833, 0xdfec8437, 0xf5f5bdf1,
- 0xfb47f8cc, 0xa74748e8, 0x4bece4fe, 0x5b4eb878, 0x4bbcebd2, 0xc2127f59,
- 0x8fd1f2c5, 0xa85b7db4, 0x5a2f453a, 0xd26e239f, 0x89960897, 0x62259663,
- 0x10afafbe, 0x3ad0156f, 0x15463ebe, 0xcbd35c0d, 0xfd68a6ed, 0xe13fe94d,
- 0x0f5bd833, 0xe1af608b, 0x92f0aed4, 0x8218d5ef, 0xbdba8a7b, 0x27ca9631,
- 0xc6bd27f6, 0xefaeefc0, 0xfd0ac3b5, 0xf37486ee, 0x66d949f7, 0x68b267fd,
- 0x94fe3152, 0xfb7ae6e1, 0xb3a22781, 0xfea553f7, 0x21888622, 0x0b7af2df,
- 0x1d3e718b, 0x2fda2e93, 0x69111c10, 0x2eb18fbe, 0x75ff27cb, 0x5615c601,
- 0xb7ea9f39, 0x1debb655, 0x288b7927, 0xa7ac9c50, 0xca532293, 0x4a7fc825,
- 0xd3d203f2, 0xcf4e6ef5, 0xf28f79d2, 0xce1ef5f3, 0x9d15a417, 0x6b25bf40,
- 0x7d62b73e, 0xf8970cee, 0x9a696f2e, 0x762ab000, 0x5a441cb7, 0x809a2c16,
- 0xa1d17663, 0xef4883da, 0x6adbd4ec, 0xe1d3be59, 0xd3a345be, 0xfda6a25b,
- 0xe1d68730, 0x87aa3d96, 0x4da603f3, 0x790bdc9f, 0xa27be71b, 0x444baaa3,
- 0x54572433, 0x012fdeab, 0xdb6f7797, 0xdf9a78c1, 0x18a3f527, 0xbdeacfee,
- 0xfa99f70c, 0x4a4e9c89, 0xe81bfa2b, 0x673e2bcc, 0xf6f26c79, 0xd5126b36,
- 0x5e2af42f, 0xbd6bdbec, 0xfda01022, 0xcf26deb7, 0x0e74f581, 0xc98f1f60,
- 0xade8f699, 0x67da7c02, 0x6671a34b, 0x10a4b0de, 0x55194ce3, 0x1bbd456c,
- 0x201921bf, 0xbf4e8ba5, 0xf9f5ee8b, 0x76eb6957, 0xf18565ee, 0x2d33b1d8,
- 0xf2c17206, 0x907d695d, 0xf5d4bf12, 0xade048dd, 0xe18592e3, 0xc11a38ec,
- 0x6ede86fa, 0xe648aef9, 0xd807cb3b, 0xb760c203, 0x2ceb433c, 0x99e6f20c,
- 0x36e27e67, 0xe2672b9e, 0x18fabe5a, 0x922fedfc, 0x736491bf, 0xbff011ea,
- 0xa03cfdfe, 0x9c9af393, 0x24467a4d, 0xcd6abfce, 0x84fe08ae, 0x690899fc,
- 0x6cf91dcf, 0x2fec58d2, 0x4e1c478c, 0xf32bfce8, 0x7f5287d9, 0x6f1aeeee,
- 0x8fc2cb5b, 0xb9fca11f, 0xa36fc580, 0x689ce9f3, 0xf03bff39, 0xb64ecddf,
- 0x10a9ddeb, 0xb77f383c, 0x967ce3f4, 0xc3a88d62, 0xbc022bf9, 0xb714b3bf,
- 0x55f88eb5, 0xf70f73e5, 0x44bdfd03, 0xe5451838, 0x648bad2f, 0xcd92f67e,
- 0xfd0eac73, 0xfbfb2a3d, 0x3d3fbdcd, 0x3de91bbe, 0xc53ff955, 0x31c5a4f2,
- 0xb57ecbfe, 0xd3da0864, 0x52fa2ef9, 0xa8bf4f7f, 0x3f69c304, 0x5fef34e7,
- 0x1be097d9, 0xd2cda1b6, 0xcdbcd28f, 0xa1d2034a, 0x04386e03, 0x690df3bb,
- 0xb05f6e6e, 0xc24d453d, 0xf817ec36, 0xee7c07f8, 0xec81e59b, 0xf6c7cfe6,
- 0xc1725d13, 0xf4e5a510, 0x2c358246, 0x8fbe68f9, 0xf3c4d7f1, 0xfa77b5d9,
- 0xe604f3fb, 0xe0071241, 0xf87bb62e, 0x37f80a1c, 0xf9cf3d62, 0xd7ac3cb2,
- 0x061ff915, 0x25f39d9d, 0xbd2e7078, 0x55fc7a40, 0xcacc7fa8, 0xf3717cf3,
- 0xebb0d1bb, 0x1c7e90c4, 0x5e487f0e, 0xafd404fb, 0x7e16e01a, 0xb1e03f6a,
- 0x3f0226eb, 0x6d773bd5, 0x1d2a7ee4, 0xe5b9e81e, 0x4c1e2ebb, 0xbd789c82,
- 0x0e8064f0, 0x2ffcca77, 0x2a3d7bc7, 0xe37cb54d, 0xa47f3297, 0xa445f388,
- 0xbf515a75, 0x0f47ca54, 0x689fe769, 0xc8fe65cd, 0x5aeeeda4, 0x31525faf,
- 0xf8a7d7ca, 0xadaec2fb, 0xde749b9f, 0xab61a555, 0x23fb65d8, 0x3325e763,
- 0x79e7be5e, 0x2dced767, 0xec87bfbd, 0xfd4e1fc2, 0x3b036cc0, 0x3cbb06fa,
- 0x7f10b7a7, 0xe7e8bd01, 0x0bfb8d34, 0xef6a5fec, 0x524d3f05, 0x849d9c95,
- 0xc287a48f, 0xbef8ce58, 0x598ecfe3, 0x2eb6e7cd, 0x4844d567, 0x0567c83e,
- 0xe5185fb5, 0x5bf30bbb, 0xc2f39da8, 0x1c86ceea, 0x7bca2332, 0x3a57be37,
- 0x073193da, 0x45ef3f3a, 0xb9255abe, 0x7720cd2b, 0xd7bee339, 0xe51759f9,
- 0xbe7cc66d, 0x91b1fd6f, 0x520c6704, 0xad22cf5d, 0x9c7e5ba3, 0xfc05bdba,
- 0xc93081f8, 0x980aa38f, 0x0bf3e91f, 0xda15ffed, 0x33e23ef7, 0xe279d1af,
- 0x738fdc23, 0x7af2b18e, 0x3ca96abe, 0xa170e748, 0x6c84011c, 0x79ce1d8d,
- 0x6fe1146f, 0xbe1553bc, 0x3d45f46e, 0x1e7af5a5, 0x2bd099f8, 0xb0af54d2,
- 0xfb1dac57, 0x5bcefbf7, 0x8d47d6d5, 0xbba9f9d0, 0x37767097, 0x5bcf396f,
- 0x01f447c2, 0xdf2ac65e, 0x5b0ebe6f, 0xc3ac41d1, 0x9f1e6738, 0x539ce38b,
- 0xc304f98f, 0x43df187f, 0x1f3a19e7, 0xf27ef8e1, 0xe1158fd2, 0x7dff60b7,
- 0xdafb676e, 0xd3eb5b5e, 0xee7c25bf, 0x81ed925d, 0xf005e89d, 0x68cff05e,
- 0x7bb3cb3b, 0x7c1f84a3, 0x84d4ef65, 0x2f45ec00, 0xdf044f41, 0x79642de8,
- 0x77bfacb8, 0x7f53950e, 0x5f68c2fd, 0x2f345ec0, 0x069feb42, 0x7d15fb46,
- 0x52837db8, 0xda0e66fb, 0xbe6488af, 0xf9203473, 0x706c7378, 0x9bdf4a9e,
- 0xa814cf3f, 0xd6045477, 0xeddea2a4, 0xe5435fd2, 0x6fd43549, 0x122192f3,
- 0xf951ffce, 0xf3ce68dc, 0x32738df6, 0x4cfb671f, 0x5f6f54f3, 0x697aaff8,
- 0x51bcd5eb, 0x3d83f796, 0x9429e514, 0x9b63f4a7, 0xab573fac, 0x974691f7,
- 0x0f99cfb4, 0x5a44a6f8, 0xd2fde741, 0x99d2c24b, 0xc2fb7929, 0x5948f3ef,
- 0xe728db06, 0xc29f5c56, 0xcbd9a3f4, 0x5b7c6b66, 0x1c0d0fef, 0xcb2f2123,
- 0xb70b39bf, 0x679e8384, 0x41b78796, 0xbe5a3bee, 0xfb7a0a32, 0x0c1a9f4c,
- 0xa3395c83, 0xaf29dbd0, 0xaf5c62a5, 0xd74cb71c, 0xc0a582ff, 0x0eedcbeb,
- 0xf7cb3771, 0x3ea302c1, 0x556fafa5, 0xa37898cb, 0x27615cde, 0x2cf042fe,
- 0x9a6df6d1, 0x7d3bd7d3, 0xebe9f404, 0xf4fa8de3, 0xe40f65a7, 0xc6d2fef2,
- 0x8def5b3b, 0xb90e993f, 0xfaa7226d, 0x0f7a9d78, 0x57e74dd6, 0x25db97a0,
- 0xfb6b08bd, 0xdf298b47, 0x07887b30, 0xd389eaf6, 0x1d6f4c1c, 0x1f2ce12d,
- 0xf08ecc37, 0xb0d76ec2, 0x06ed8c2b, 0x83fb6b37, 0x1ba628f4, 0xee28beff,
- 0xf32ed2a7, 0x3065cf95, 0x0f60bcdd, 0xe515b93c, 0x7fb3872f, 0x8e5a32b6,
- 0x24bbf95b, 0x29bd2e8d, 0x5fb17aab, 0x32a5e98e, 0xe5c31dc2, 0x7a678fbf,
- 0x57dc367a, 0x7d127c00, 0xd2bc5db2, 0x258ccc1e, 0xe8d31ffc, 0xfb237a0f,
- 0x98a36af5, 0xf796856e, 0xf59e3cfd, 0x797f9238, 0x437ddf3c, 0x7bb3ef39,
- 0x3ec42efb, 0xf0c91e5a, 0xf2c9731c, 0xbcb19563, 0xb7dfe60f, 0xc5fc30f4,
- 0xbcec8ac7, 0x55ed8e5f, 0x73fade59, 0x9f841a9d, 0x9acfa75b, 0x86dfc725,
- 0xe1baa8f9, 0xd4dde4a3, 0x5595fccf, 0x7e6ed093, 0x7053edc5, 0xf69af6de,
- 0x4369fb29, 0x4afcf3f7, 0x97d47fb3, 0xf98c9dee, 0x760764d5, 0x1e7ea41c,
- 0x116a739c, 0xee9fd3d6, 0x3ef5869b, 0xe17d6f6f, 0xeb77044f, 0x5eb23f8a,
- 0x6fb47d74, 0xd85fbe26, 0x5fae1bf3, 0x16bff2bd, 0xb6afce41, 0xcfd17a4a,
- 0x7e8d1ae3, 0x1e6f8645, 0x7cae57ea, 0xc881f59d, 0x7f9223ec, 0xf8fdfede,
- 0x5bbde9ce, 0xdda8505e, 0xd5bd88d2, 0x5c81aa9c, 0x94676b9c, 0x0692b460,
- 0xed3d4a7c, 0x8d182bac, 0xa459f175, 0x5b74b89c, 0x4b181f88, 0x7fd9a091,
- 0x16d2dda8, 0xf242bf19, 0x19f41d82, 0x7d297f5a, 0xf3df7ae7, 0x9168857b,
- 0xdf7763df, 0xf75cb57b, 0xfc387060, 0xb09b19ae, 0xfd76e7ee, 0x77e8d326,
- 0x872f4d0d, 0xacffce57, 0xeace5fb6, 0xbdb665fb, 0xb9005ed3, 0x7d33fceb,
- 0xfe76744c, 0x3f9cc1c9, 0x112bb4ad, 0x577f974a, 0x72465a78, 0x65b78d7c,
- 0x07e7e424, 0xe34befb5, 0xaf82465b, 0x384e7ce9, 0xff59725a, 0x85c96acf,
- 0x47f3abbe, 0xc992d451, 0x992d03df, 0x4582ff68, 0x8ff853da, 0x3a78a8e0,
- 0xd2dde369, 0x0cb7e10f, 0x26e87e47, 0x1a71f5e4, 0xe91f25c2, 0xa58fbe69,
- 0xf9e63b4b, 0xbd9bf639, 0x7ad07f54, 0x707ca9bb, 0x9adf9cc0, 0x03e7ed2e,
- 0xfa6fe243, 0xc3fbeda9, 0x213c8e70, 0x3fd7f5ba, 0xd4f38da3, 0x3c719d53,
- 0x0acfa6aa, 0x6e1f4eb7, 0x80dbdf29, 0xf13a8fef, 0xf1126b7d, 0x6398a5e5,
- 0x9e5fcf2a, 0xfb494f67, 0xbe790bcd, 0xe7179c24, 0xff821781, 0x67ca5885,
- 0x7892be43, 0x3e3af3d5, 0xf2bfe743, 0xb04945a3, 0xae947edf, 0x7d3cf9db,
- 0xde3a9740, 0xefa46c1a, 0x2e3f4364, 0x8569382f, 0x2c49ecde, 0xdaec1ab3,
- 0xd81cf3eb, 0xe4378b57, 0xd6748c39, 0x10e0adb0, 0xece21c49, 0x2007ab36,
- 0xf7035837, 0xd86f7e42, 0x05f8b6a6, 0x54bc3b97, 0xc0f3acff, 0x68b7a8db,
- 0xe43e6c43, 0xe2fdbd6d, 0xcb1223f5, 0xdd0e700c, 0x9c875e66, 0xd87e7316,
- 0x04fe736e, 0xffde80ce, 0xa0bcbb7c, 0xc8705f39, 0x83e4ff9c, 0x9c81675b,
- 0xbdff55cb, 0x3f89f42a, 0xf384384d, 0x5e17d3f1, 0x2cfac68c, 0x41d94bfd,
- 0x71a149e8, 0x0a6eb422, 0x56ff08f4, 0xb2e3e985, 0xf81e9178, 0x810f1e81,
- 0x93a4619d, 0x683fe10a, 0xfebcb94d, 0xcb32d119, 0x5955744b, 0x64e0bcb7,
- 0x57bf5741, 0x43b3acb6, 0xb71d0bce, 0x9c2ffda7, 0x6aec375e, 0xd964a3c5,
- 0xc5637555, 0xd62df809, 0xf4013bbe, 0x854bfc57, 0xe7e28ae5, 0xbe0abd07,
- 0xce63b6df, 0x9ace9c0d, 0xedd0f8c8, 0x2af78b7d, 0xbbca28c1, 0x5dba4946,
- 0x7d615eb8, 0x1cd1a4bd, 0x36b65747, 0xd9a6de24, 0xf778be5c, 0x9f86fffe,
- 0x18f1dcbe, 0x1e5c33c7, 0x05781827, 0xa7c55b7a, 0x153ded82, 0x330dbf9b,
- 0x2d79cb97, 0xbfe1e7d4, 0xaee1e396, 0xcf3a5592, 0xd0c893b7, 0x574bf0f9,
- 0xe1066a51, 0x8de6aafd, 0xbd9b94aa, 0x7597ecc5, 0xb0ce39da, 0x918221ca,
- 0x28a1cf04, 0xdf45d7bb, 0x628fae2f, 0x18516179, 0x9cf99fc9, 0x438e708a,
- 0xdda0c4f4, 0x965477a9, 0x25e2aa83, 0x571eaa1e, 0x56c5b002, 0xfc8a48c1,
- 0x04bf3213, 0xd25526de, 0x3f00d78f, 0x1798cdd6, 0xab6f524d, 0x03f706b4,
- 0xc0e79d2f, 0x4abd7336, 0x38d1e79a, 0xefe659c8, 0xeb9da2d5, 0x36feecd7,
- 0x60ddf8cc, 0x527d65df, 0xc8556bd7, 0x7aa70433, 0xb3cb0447, 0x402398c4,
- 0xef14ab57, 0x29150ec3, 0xefa0e39d, 0x2f964e25, 0xe7946ee6, 0x838c3347,
- 0x0dd78390, 0xae67b966, 0xbe04cde2, 0xd670bac4, 0x1fdca9a7, 0x64e58bde,
- 0x4e484396, 0x7daa3966, 0x12e39d8e, 0x825af39b, 0x1f9ac790, 0x0ad0f148,
- 0xf3e47f32, 0x96709ee8, 0x4aa79a7b, 0x5d79a7b9, 0x31ff6e1f, 0x390beb40,
- 0xf9b9e25a, 0xb71e1c9e, 0x89db2a9f, 0x200f523e, 0x7a133ab9, 0x41e5c102,
- 0x67472eb9, 0xb04afac5, 0x9bfcfaee, 0xe0a3db63, 0xf1e512c7, 0xd86e4bdf,
- 0xed879da2, 0xf003c2eb, 0x8a549c53, 0xf60c5a0e, 0xe4325ba9, 0xac7231f9,
- 0x8f56ab77, 0x966519fd, 0x80ff77a9, 0xd07b29e0, 0xe9486ee2, 0xf5e1075a,
- 0x27fe6266, 0x83e785d7, 0x958e46ee, 0x7963a7f6, 0x0e479f92, 0x73bf1c17,
- 0xedefd6bb, 0x9a531619, 0x48f44118, 0x942c9cfd, 0xe1a8edf6, 0xa4076c45,
- 0xbbb9ba35, 0x19359038, 0xb32a9cf2, 0x9afefd17, 0xa4e9e06e, 0xde52f18b,
- 0xd94cb93d, 0x72f2e124, 0x5fc8dfbc, 0xf0fdb385, 0xe8de76a4, 0x347441eb,
- 0x8d71cf82, 0xe8d3ad9f, 0x74cf5d66, 0xb98ba263, 0x3741b790, 0xd8b9e473,
- 0xfada5749, 0x7af0dd12, 0x485d13b7, 0x6be211ba, 0x4b742fb4, 0xdf443b79,
- 0x7bb7d4ea, 0x0e88b7d0, 0x6de8c89e, 0x074217a8, 0xf1181ac2, 0x252cfc8f,
- 0x2a4762a3, 0x564904b4, 0x2cdc47e1, 0xd7c646ce, 0x4ac0d65d, 0x55bfa782,
- 0xab00cbae, 0x653a3ba4, 0x5cf911fc, 0xd9f88bdf, 0x0b17fbe2, 0x4e2fd52f,
- 0x4ab76c12, 0x2626f927, 0xa409db8e, 0xb0aa0770, 0xf68a50e7, 0xffb231c5,
- 0xc46fa262, 0x5e7f51b3, 0xdcc69c4b, 0x2a7fc246, 0xfb407e58, 0xef6e7ce8,
- 0x5ef6c8b7, 0xd303a52b, 0x5f6a3ee4, 0x2bf8c615, 0x264073be, 0x58d264e8,
- 0x66249d33, 0x4f41394a, 0xbadd331b, 0x7e0890dc, 0x9838d250, 0xf08699cf,
- 0xd85daaa2, 0x7d48cfa7, 0x4df578a3, 0xbe004793, 0xd83de367, 0xeca7a7c2,
- 0x494aff60, 0x7f1f9ce3, 0x5b653d08, 0x98df7f38, 0x780f7be9, 0x17b8ad3f,
- 0x250fa2ec, 0x27b15f33, 0xcb5f7b52, 0xa3bf73d4, 0xc77f8a74, 0xa62390db,
- 0xfeb950cc, 0xb9ed2114, 0x338e51a2, 0x35b9ffd9, 0x3c9bfa91, 0x94f0e15a,
- 0xf25770b6, 0xb455f832, 0xd1a63df5, 0x98b84377, 0x70139cfd, 0xcd4cc80d,
- 0x24821f86, 0xe4e46ed4, 0xfd5a9901, 0xc806ca31, 0xc9c70343, 0x47d7a7fd,
- 0x2d37e83f, 0xcfb7ee53, 0xe7a77db4, 0xbf5caf09, 0x5b584d6c, 0x5b52345a,
- 0xf3a51070, 0x039ec6b2, 0x2a94999f, 0xde07ac26, 0x4d8aaa7f, 0x317b6f0c,
- 0x4ca885f3, 0x8f82f837, 0xfba65914, 0xee99836d, 0xb7b4c6db, 0xb6f949dd,
- 0x7ed2392d, 0x0bf3e9a7, 0x82e5825d, 0xef9231b6, 0x64896fb5, 0xd5cc73fe,
- 0xed27151a, 0x97dfac5d, 0xd7f1246a, 0xe17b86ba, 0xda752e37, 0x2c7e70db,
- 0xfb3a607c, 0x499b4bfb, 0xfd5c47bf, 0x4f7eb35a, 0x6658787a, 0xa87afa37,
- 0x019a0e5e, 0x55ad951d, 0x36070e98, 0x997dec78, 0xcc2e29cf, 0x4c19ccaf,
- 0xf32fff07, 0xf05c7384, 0x37fb7a65, 0xb091f784, 0xba0e0b1f, 0xd7c83a1a,
- 0x3716e30b, 0x1a7eb315, 0xfe63ed99, 0xbc255035, 0xd4cf1d10, 0xec126fe8,
- 0xd64be0a0, 0x97d8bed6, 0xdf6865af, 0x4e995ce3, 0xbe70eba6, 0x7366d06f,
- 0xb6be0265, 0x9c16e155, 0x4a5693b7, 0xe77da6fa, 0xbb80bdc0, 0xfc0222ac,
- 0x7ed6b8e0, 0xd16b0afe, 0x77f7ca46, 0x1c546b08, 0xe98f2be8, 0xfbe5903b,
- 0xe9f7eb0c, 0xc828c42f, 0xd76ba50d, 0xfa34b849, 0xe323d610, 0x4f9c69e3,
- 0xc3e4a4b7, 0x53d3a0ae, 0x766c6b20, 0x5d0308e6, 0x1e9850cc, 0x60873e68,
- 0x55979d9f, 0xfa728f92, 0x32f41fbe, 0x1d306c69, 0x6a85d871, 0x76abc725,
- 0xe20f0a24, 0x3b443a87, 0x241d23cb, 0xea3f808f, 0x27e7467c, 0x475e1744,
- 0xeb7ad742, 0x3d6b657c, 0xde784681, 0xf4e0ef56, 0xb0977aa9, 0x5ed84f12,
- 0x67f9c89f, 0xb69cddeb, 0xf7f167d4, 0x9c3deae7, 0x8a3f59df, 0x7bd42ff3,
- 0x7ebbbf39, 0xabbfa722, 0x84efe22f, 0x3a4be61f, 0x93f9d1df, 0x9f3a5f4e,
- 0x05aba50a, 0x33dc6684, 0x0fccf6a0, 0x79883e75, 0xf8bbf258, 0xa9cebe93,
- 0x113f914a, 0xceb450fc, 0x5428ff01, 0x22f33ecf, 0xdca3b9e1, 0x1da1f1c9,
- 0x0ec1f242, 0x8dcf83a7, 0x0dd8bb64, 0x32c340fb, 0x869ddb6f, 0xb95e7873,
- 0xba06ac22, 0x5c36a9bd, 0x7d740d58, 0x29ac5d73, 0xfdeebf3f, 0xff50fad7,
- 0x2df18b3f, 0xbb1cfac2, 0x7fa3d4e3, 0xdf8fefa4, 0xeb033a71, 0x796c704e,
- 0x1edee308, 0x2ad1c1a1, 0xceddbae1, 0x08c0d2f2, 0xcfe14fa9, 0x2d738861,
- 0xfb7d894e, 0x31e70437, 0xda061d6d, 0xc146b35d, 0x754ab32e, 0x1f2aa4ad,
- 0xfbe8bd63, 0x2af5b59f, 0x7c630ba9, 0xfb6a3496, 0x4cff18d4, 0x57de3cf8,
- 0x78a75cb0, 0xe91f8085, 0x41ec2ff8, 0x71c41192, 0x685011c5, 0xad94851c,
- 0xae17b0f9, 0xe428fd79, 0x10eea574, 0x873ed5cb, 0x8428e393, 0xd8d676df,
- 0x9077529f, 0xfed689eb, 0xc8c838a6, 0xf83b5ee1, 0xeb1b6805, 0x40759256,
- 0x268b9f60, 0x94f1ef85, 0xd6cbdf69, 0xe2f8a628, 0xe655337b, 0xac32878b,
- 0x14ca0e9c, 0x89a5139a, 0x5e9d29cf, 0x3c707f89, 0x9e535963, 0x2f81917d,
- 0x4bdf6897, 0x78a62cb3, 0x321943c7, 0x98106a2e, 0x6777a505, 0x3217daa5,
- 0xdc7373df, 0x24bf5ebd, 0xea757f2b, 0xe883f470, 0x8ff6aea0, 0xddb95a64,
- 0x84970ca1, 0x59e741c7, 0x74e9c714, 0x72e82e7b, 0xeff8a7cc, 0xeb3f0c95,
- 0x3ecf1559, 0x7bfc2cfd, 0xe30a7f15, 0x9862a9f3, 0x0ec8df66, 0xf2ce9c8c,
- 0x8ca9d78f, 0xd72dfc84, 0x7fd3fc7f, 0x547c4689, 0x57694ecd, 0x690db4a5,
- 0x6ce5edf5, 0xd0f6ab57, 0x9f0388fe, 0x5fcdfb35, 0xd14ff67d, 0xf897acad,
- 0x5bf8b493, 0xdeaaf78e, 0xc0e38279, 0xd0afb8f4, 0x37ca3576, 0x71eaa7ac,
- 0xb63fba01, 0xf78d9f70, 0x851ecd4d, 0x5d9a98f5, 0xe7c01317, 0x4aadf66a,
- 0x272e2ee8, 0x5e3d5fb4, 0xd5bfb740, 0xc39fb588, 0xc384487f, 0xffad0ff8,
- 0xaf546676, 0x62054353, 0x3b60aed5, 0x1c705588, 0x8e2d72c7, 0xc19023b3,
- 0xe49ee17e, 0xc4f59aed, 0xedbf49f0, 0x1063bab0, 0x88417caf, 0x53addd89,
- 0x7e7920fc, 0x047da39f, 0xed85f0bf, 0x1791cb2a, 0x7ef147b6, 0xff7edea8,
- 0x55dbc441, 0x8dd8566f, 0x308e2557, 0xaa77aade, 0x0fe061c2, 0xc50bb035,
- 0xd2e70cf7, 0x416aa3a7, 0x145a4b5f, 0xadf816ef, 0xde98ee1d, 0x35da7806,
- 0xd61a5afa, 0x45d79232, 0xf814ff83, 0x5cce419a, 0x8e7ef7b2, 0xe77aa413,
- 0x6df9ae59, 0x51b3c724, 0xce036f0f, 0xd80a1b33, 0x65a4bd4f, 0x05cb3547,
- 0x105d23db, 0xccdb4e69, 0xd1be29f7, 0x9346fbc6, 0x4fc0ced3, 0xaacff682,
- 0x4e030f2c, 0x5ad3cbec, 0xcedeab3c, 0xb3b64832, 0x0dfb7868, 0xae88e7f6,
- 0xda5a4bfa, 0xfea9d3a2, 0xe7dfbb27, 0xee4839d4, 0x23ce25e3, 0x3f4738b9,
- 0xf7c919d9, 0xf9d93eed, 0xd12f09eb, 0xc65ae778, 0xfb0c52f4, 0x1b20e06c,
- 0x41b73fd7, 0x25f301c6, 0x5a0fd611, 0xb6673e78, 0x27ac2927, 0x9f84df03,
- 0x8f9f3b33, 0xf63ef0b6, 0xab717bff, 0xc86b15b3, 0xb2eb847d, 0x5bfe8047,
- 0xed11fbb5, 0x7fe5fd9a, 0xed6affa7, 0xa4529b7b, 0x3bef238d, 0xc20e3d08,
- 0xd53beda5, 0x796efbc9, 0x2fef9d94, 0xbee6182c, 0xe8f81e71, 0x518e329b,
- 0x043f77f4, 0x3bc16ffd, 0x596f6cf1, 0x41f7736e, 0x36c38bfe, 0x282c13f6,
- 0xa1f51cf0, 0xed9d8c7e, 0x75b1224a, 0x6dadec04, 0xa8be5229, 0x933b435c,
- 0xe88fdc50, 0xacf84fcd, 0x8f84580c, 0xa50793f2, 0x523ebaf2, 0xd9daf16e,
- 0xfbe413ff, 0xc2ecc792, 0xfe2f7b8f, 0x5d7ea4e7, 0x0efd2a99, 0x517f608f,
- 0xcc17195a, 0x4edd878c, 0x69ca9ba3, 0x9fa06e54, 0x4cc14dca, 0xed674fc8,
- 0x72891ed2, 0xf9954de8, 0x46835eb2, 0xfd07e8a7, 0xceb8a5b6, 0x2bbbbcb3,
- 0xb0ef404a, 0xed2518bc, 0xdf09bf21, 0xaf386614, 0xe9241a6f, 0x07f341b8,
- 0xf848b7fa, 0xf8e41700, 0x4ca6f625, 0xb8fab9c8, 0x789ba24b, 0x78dab3bc,
- 0xa49a224b, 0xc78b44ff, 0xdf1e7d43, 0xd3bfd826, 0xcb1864fe, 0x1efba7cb,
- 0x9fe30179, 0xc730727e, 0x04a5b411, 0xf2e6ed16, 0xaee38e70, 0x082c2a78,
- 0x327b3f78, 0x9f58ed8a, 0xf61ca4d9, 0xcb025459, 0x1ea28761, 0x3afe805c,
- 0xe0298736, 0xc2299fa3, 0x2df2889e, 0xa80e59bd, 0x3f63afa8, 0x17b10549,
- 0x4e94afc8, 0xd9f7dc84, 0x276cc196, 0x950decfa, 0xf7d0292f, 0x13eef835,
- 0xc67e0b4d, 0x3ff4bff2, 0x6fea7e9e, 0xaff3bb83, 0xdb366c54, 0xd7f5f4c3,
- 0x2418efcb, 0x0c7703ed, 0xcac97a92, 0x7fe92e41, 0x30796c8b, 0xf929e795,
- 0xeb03ad03, 0x131fb47f, 0xd63f6f60, 0x714127b2, 0xccc1cf02, 0xdbef035f,
- 0x7a759ea4, 0x42fd8dbb, 0x79462f15, 0xe774fed9, 0xb0ef7c15, 0x78729542,
- 0xdbde4585, 0x99eed0ab, 0xb2674456, 0xcdf08b7d, 0x16fb6d7a, 0x8e471b55,
- 0x01d6d9fb, 0xd4109fd2, 0xf0e42ff2, 0x7149b83d, 0x2c69e6e2, 0x05c86d5f,
- 0x8e6e2f5e, 0x1a79f8e4, 0x87b88bc7, 0x5cfd9f8a, 0x116633e2, 0xae7407eb,
- 0xd4ae7f31, 0x9dd573f8, 0x5ee0c757, 0xe5477881, 0xad1712fb, 0xbfe03e9e,
- 0x4f7af8a1, 0x5f4b63e3, 0x41f99478, 0xc417ed25, 0xfcd52d59, 0x529f4bcb,
- 0xba5c9e58, 0x9887eafa, 0x136dbeef, 0xb6705fb8, 0xe368fee5, 0xf8d5ec7a,
- 0x0f7b5767, 0xf54a5fd7, 0xa337fb65, 0x36ad9e19, 0x5d09e00f, 0xfeddefc7,
- 0x6a5ff529, 0xf242d15f, 0xf3e5ee45, 0xdc8e28bf, 0x95f027f6, 0x676ce1ed,
- 0x7be7f5a3, 0x2d6c6746, 0x33ff308b, 0xbf3384cf, 0xf72b1339, 0x9e7427fd,
- 0xe780edfa, 0x5db1f787, 0x02e9bded, 0x80e2d0e7, 0xae1d5fb9, 0xafdf1afd,
- 0xc0c4f78a, 0xeb45534f, 0x7d68fe81, 0xdfedc47e, 0xd0fb71b1, 0x768e3cf9,
- 0xf4fb0c23, 0x9ba64899, 0xbae4fd33, 0x1076799c, 0xb16d679f, 0xde09de92,
- 0x674be864, 0x1b8a6562, 0x0a87a03e, 0x3387a497, 0x1ed85a63, 0xc1d94670,
- 0xb64d9b69, 0xfcd3a8ab, 0x897f44da, 0x26d01fa0, 0xb58ea9ec, 0x80c72047,
- 0xe7cc8fcf, 0xcefb8834, 0xd07376a1, 0xbebfce29, 0x84dcf259, 0xcf3e0578,
- 0xe3f61b7e, 0x733df0b4, 0x564f269f, 0x4fdcbf6e, 0xdcaa7588, 0xeb3fb0ae,
- 0x02fe7692, 0xddba5eea, 0xa972e89f, 0x6e22f15f, 0xb2e3696b, 0xa5fba025,
- 0x81e6ebb5, 0x2c79f5ee, 0xb75feed5, 0xd3c32a29, 0x27fb4e16, 0x74f1f2fb,
- 0x8a59aafc, 0x5c279f1e, 0x7b45f9fa, 0x2dcb2c38, 0x4db288e9, 0xa3655fd4,
- 0x49c796b2, 0x395bf5d1, 0xb84f1d3f, 0x5efb02cd, 0xb9df769b, 0x70ebf9a7,
- 0x524f04f6, 0x6d4fe496, 0x6f9ef229, 0xbef25bfb, 0x0a6fc5f6, 0x81fee262,
- 0xfa91c83c, 0x7f047f7a, 0x72106816, 0x96e7c68f, 0x704eaec2, 0xfb306e66,
- 0x9b36b273, 0x9bb643f3, 0xcd3bd9f3, 0xe6bddcf9, 0x7355e7bc, 0x7b7185de,
- 0xfa09e177, 0xa103e236, 0xbe85236f, 0xfa94ceed, 0xb7d0f236, 0xc6df4291,
- 0xc8dbe877, 0x1e46df43, 0xd0f236fa, 0xdf4291b7, 0x1a39f7c6, 0x7b352a9e,
- 0xe381d629, 0xeb84f6d4, 0x5fbc00f1, 0x6049cc2e, 0x52ac2a3e, 0x24b0bd1f,
- 0x4ec7e59b, 0x0754d33b, 0x38f499db, 0x7ca2b7a7, 0xc37ab2e3, 0x75647b7f,
- 0xc76e14df, 0xdf9ae7f6, 0x6573fb49, 0xf613b87e, 0x9f55d68e, 0x13d886ac,
- 0x444df288, 0xf6b60bfd, 0x556fc0ad, 0x6fec2bdd, 0x7ee15d6f, 0xfd7207e7,
- 0xc7a2eed8, 0xdce3152d, 0x7d26df03, 0x7b6fc649, 0x6a3b461c, 0xac485fa8,
- 0x3f21e435, 0xa1f39b35, 0x35f0207e, 0x355f69af, 0x6e3c1d31, 0xbe0bef6b,
- 0x0749e27f, 0xa13af3df, 0x6cc4edd9, 0xba63cb17, 0x8f29df3c, 0xc26ca3dd,
- 0x2b24bdf9, 0x1c77db8e, 0xd3dd30ca, 0x2f4b4d0b, 0xdabcb3e5, 0x58ab5f99,
- 0x8cd94e30, 0xaf59fb15, 0x73e68c4e, 0xb60d16e9, 0x0dff9041, 0x440e0f70,
- 0xe868e898, 0xbf10b8b6, 0xfd533f65, 0x4353bb61, 0x4c4396fc, 0x16d7d3e5,
- 0x17b5ef98, 0x1f2a6d5d, 0x878cef68, 0x96ff4873, 0xd64b9f06, 0xe7cce8b9,
- 0x4bd686f9, 0x847f3c56, 0x25bc56bf, 0x9a32d3e5, 0x7b40b787, 0xfe1f239f,
- 0xe014ef39, 0x16c5bcaf, 0x54bef38b, 0x9d44873b, 0xb72e5cf9, 0xae2bbf0a,
- 0x5dcaee8b, 0xed4b1bc2, 0x2536b4bf, 0x71dd1d33, 0x14255934, 0x2472192d,
- 0xe57d0837, 0x8246278d, 0x8dd4aaae, 0xbf2a2ec9, 0xc56c0955, 0x71d3ec45,
- 0xa4ae123b, 0xf8b4fff2, 0x75a2c91e, 0xef05b64a, 0xba3e0f9d, 0xbde04d23,
- 0x9f6b1391, 0x3cb8e68f, 0x6d92fe8d, 0xc1d008ae, 0xf59526c6, 0xd4cdd814,
- 0xd93a2eb8, 0x011f14d8, 0x8c7ca6bd, 0x717297e2, 0x0bdf49b4, 0x9aa147c5,
- 0xe69b8efd, 0x2a90f17b, 0xf36a40ef, 0xf592ee5c, 0xaf6cba45, 0xe7d7b3df,
- 0x47d3527b, 0x96be362b, 0x3f7d0b79, 0x2e7f783b, 0xd65784ae, 0x2f79e6ef,
- 0xdadf6cb5, 0x1d7bd297, 0xd7985dbe, 0x45c6b7f2, 0x7ce3495f, 0x87c65db9,
- 0x89f9b5ff, 0x4fc4fcc7, 0xc27a6cef, 0x8541fb0e, 0x1e876035, 0x46e4fe5c,
- 0xae18e23b, 0xbf91b6db, 0xcc56da2f, 0xbefd00f6, 0x7c7aa7da, 0xf28f86b3,
- 0x1706cab1, 0x60ffb3cd, 0x23ca4fc9, 0xa14b1c64, 0xdc35fa3a, 0x4db8b813,
- 0x66bcc3c9, 0xe3b0ed14, 0x1a3bff1e, 0x37dd09df, 0x17a7871d, 0xabbd86f6,
- 0xdf20f145, 0x89993ed3, 0x0f4472cb, 0x39b92fd3, 0x0869719d, 0x0a1fd5eb,
- 0x8e70bed2, 0xd7e88764, 0xcf695587, 0xad123c43, 0xd83db973, 0x85e43a6b,
- 0x0ffbe597, 0x8d0e7455, 0x2ede87ca, 0x169455c4, 0x744d568d, 0xd23e335e,
- 0x0b660fb4, 0xfea2bec3, 0xa67e8966, 0x69498cfc, 0xce37faa6, 0x67e21a18,
- 0x672aefce, 0xe99575fe, 0xdbaa975d, 0xe3856efd, 0xbf9ac67b, 0xd33b7a53,
- 0xf6a60dd9, 0xe99a6255, 0x9b25975d, 0x133c65df, 0x8fa1d995, 0x41f76b95,
- 0xb4dafb66, 0x9dfcadef, 0xafda6226, 0x7f3cd303, 0x8da5e794, 0x1dba08fd,
- 0x9ffe367d, 0x1979ddd6, 0x898f19d1, 0x3bd85bf8, 0xe479667c, 0x42a9eb08,
- 0x669543ae, 0x92caaa8f, 0xff2aa8f6, 0x9be23b11, 0x24d6ff09, 0x93754942,
- 0xaa46f6c2, 0x938a48ef, 0x7df1dbf9, 0x075ef9a7, 0xf284bbfa, 0xf6316a43,
- 0x35796857, 0x42e71bcd, 0xb047ec35, 0x6bfde983, 0x19f4eafd, 0xb43ecf7a,
- 0x3760df1f, 0x6d8ae7ef, 0x23f60e3b, 0x8a2f4cbc, 0x497c43cd, 0x5b54cb65,
- 0x74e5f671, 0x8bfdf3a6, 0x7fb616e5, 0x857e1c75, 0xdca3ace9, 0xddf191ea,
- 0xd51f18ff, 0x0d6f695e, 0x3445bfa5, 0x1799f81f, 0x013c54ed, 0x5e03d645,
- 0x432e81fa, 0x0dd492f0, 0x753c74be, 0x7ca42de2, 0x1c33fe31, 0x004a11f1,
- 0xbc32f27c, 0xfad478e8, 0x2c13e45f, 0x013c1267, 0x3fa42786, 0xff742a31,
- 0x20efc2dd, 0x84506c74, 0x3c6ef94b, 0xed24bb4c, 0xe4d30336, 0x2977dbbc,
- 0xb3ebc81e, 0x7bf9592e, 0xc914bd27, 0x9319f538, 0x93b3fbcc, 0x7ee48a7e,
- 0x81297999, 0xd36ffddb, 0x8fd177d1, 0x8d099fee, 0x5defd6ff, 0xddac1a2d,
- 0x46211a4b, 0xc44ffb7c, 0x4072ebaf, 0xe749e74f, 0xf0d2e379, 0xf6ed4cef,
- 0x951e5e1c, 0x3edaf1ca, 0xf3a88ecd, 0x4ed69f63, 0xca98b71f, 0xefa005dd,
- 0x17b009fe, 0x4b4c6eaf, 0xe317be36, 0x3b63655b, 0x788af26f, 0x5dc38b4e,
- 0x8a473809, 0x4d77c857, 0x27d5df8e, 0xe388fe01, 0x26bd6cab, 0x7fc7d751,
- 0xe4593c3a, 0xe9c85f20, 0xb3617589, 0x3d78768d, 0xed2c1a6d, 0x7e39fa35,
- 0x7a3872ce, 0xaadff636, 0x0508d15d, 0xfdeaba5a, 0xcf3a2e91, 0x8f7c5957,
- 0xef7f660f, 0x85cf3e46, 0xec2e636b, 0x513cba70, 0x0fb0aab1, 0xffcafdce,
- 0x9c31e579, 0xb615befb, 0x9fa3c804, 0x840aa07d, 0xc679d0ce, 0xe1a7c472,
- 0xdd3fae92, 0x10f7c912, 0x1784553f, 0xea25a6fe, 0xe9975cfe, 0x0b3bdd5c,
- 0x41deffe3, 0xb8c08ee3, 0x1889ad81, 0xc4cfe3d7, 0x1915beb8, 0x57d9dd31,
- 0xbd66b4f4, 0xeab6f394, 0xeecd64f6, 0x791ef90c, 0x6270f7c8, 0x1e47be41,
- 0xc8523df2, 0x4dbef8f7, 0x6c0c2ff3, 0x7e83cf68, 0xb22b1fea, 0x75bcf96a,
- 0xbf7e4166, 0x80f08945, 0x78a2dcff, 0xc1bc70fa, 0xc4def966, 0xd57590f2,
- 0x49da6bd3, 0xedd03306, 0x84392e0f, 0x8c6e6e31, 0xc7e53588, 0xea9afa39,
- 0x4c52ba17, 0x0e25d7e5, 0xef5f9536, 0x7fe533ce, 0xa9a57598, 0x18cf64fe,
- 0xa347fe53, 0x9fd537ae, 0xca6a9dea, 0xc7389f4f, 0x51667f54, 0xc6fca9b1,
- 0xe54c4bd9, 0x4ccb7c73, 0x3fe579f9, 0xa9bfd535, 0xdca98576, 0x9c565c2b,
- 0x77a17b77, 0x865fde11, 0x2de945de, 0x8d38656f, 0x9c7a3aeb, 0x7977dba5,
- 0x5072694e, 0x36dea1bf, 0xd7ee25d0, 0x68070e80, 0xc0be67f7, 0x7e1bd2b9,
- 0xf522a0c9, 0x417d23de, 0x42f5a137, 0x1e4747cb, 0x35a6e8b8, 0x7a2a7a2c,
- 0xc4f895a6, 0x140e2be8, 0xf57e51a4, 0xad338553, 0x5f465fc4, 0x54f9e07d,
- 0xb53d37ca, 0x3b0f964a, 0x51e51170, 0xf320df4f, 0x1a8b05d3, 0x7af90c8f,
- 0x31e69f86, 0x6ba907fa, 0xd26ed23d, 0xa769bc6d, 0x80f0883d, 0x01e04d78,
- 0x13e89069, 0x4fa201e9, 0x7d12afa4, 0x710ba596, 0xe913e890, 0xf13fd221,
- 0x7fa4f7fd, 0xfa4c3d22, 0x49b7d227, 0x847a44ff, 0xefa44ff4, 0xf4e6cfd5,
- 0xb71f7a83, 0x397d43fb, 0x6beb47a7, 0xf5c7fbf9, 0xb9fe9c75, 0x5ddfcfde,
- 0x433b7443, 0xba31ed90, 0x7e1aabff, 0x76edd847, 0xfd1acedb, 0x9e578ac2,
- 0xb2bfbaa7, 0x46b456a1, 0x5ab69f62, 0xba394f63, 0xf33d90fc, 0x6538ab5b,
- 0x0f5ebf90, 0xe10d26f7, 0x98bbfbf1, 0x8fdf6b6f, 0xf203e989, 0x520a9d69,
- 0x9f28297d, 0x2aba5f99, 0x0fc7f886, 0x81b5a9be, 0x74b43e5e, 0x0bfb7f7f,
- 0x87da4e8d, 0x8c873378, 0xebbbf2e8, 0xf8ceef7e, 0x1e5f831a, 0x8e3d6cfe,
- 0xf3c7f747, 0x473e219f, 0xf1eb93f7, 0xef6ad741, 0x707ee923, 0xef47fe3d,
- 0x6092f0b7, 0x1acd77be, 0x512dcb2b, 0x38c41156, 0x35cf9c7a, 0xc43c968e,
- 0xe9535c3b, 0x3eb738e4, 0x23ef1df4, 0xde2f3d52, 0x25fcdb99, 0xf2edcfd5,
- 0xe6d1f7bb, 0x8f3ce541, 0xb63e4bc2, 0xc5a35ed7, 0x43bda01d, 0x753bf396,
- 0xfc831188, 0xe1db2941, 0x7da8551e, 0x001c577e, 0xfaca47ea, 0xfe97f441,
- 0xdd178d15, 0xc4068fb5, 0x6e21e4b5, 0x93b5406c, 0x8c36c6e3, 0xb9bdf209,
- 0xded7b1e9, 0x4e22aad3, 0xd8c7e638, 0xfaa74f47, 0xefcf0266, 0xf00f73ee,
- 0x5c5a7e50, 0x53a46f5a, 0xebb5de43, 0x62e67d66, 0xe97c755d, 0x4bd7d778,
- 0x9e21b7c7, 0x5dfcf18a, 0x6eba17eb, 0xafa5eba1, 0x2ea5e153, 0x977f03fc,
- 0xfad74faf, 0xfffb3ec1, 0xb70cfacb, 0xcc7df0b6, 0x07874ab0, 0x7ad77d70,
- 0x262edcdd, 0xf1783ee0, 0xa441f725, 0x5f7cd24b, 0x8a967f80, 0xc05c1331,
- 0x81cd4b91, 0xdeb4279d, 0xef59eff2, 0x077a90e1, 0x7cd60ae2, 0xbd79769d,
- 0x1af521dd, 0x7ed60b62, 0x374ced2d, 0xe43d7ce2, 0xed1fb1b6, 0x1e3d70cd,
- 0xa3ccebc3, 0xf1a71c75, 0x96a243a3, 0xd7120fcf, 0xf1df58fc, 0xcb8f52da,
- 0xee72cc5e, 0x6e59a778, 0x514df09c, 0xd09dc623, 0xd68e442b, 0x6837e1fc,
- 0x9a275efd, 0x7bd0dfb8, 0xf26837f2, 0xf93de869, 0xf26886e7, 0x01488a65,
- 0x3c2f1a9f, 0xbded2e12, 0xd92ef183, 0x2f46926f, 0x8c556e69, 0x9f083d06,
- 0x55f1cc15, 0x8b9077bc, 0xbf9cfd71, 0xfd38045e, 0x3f7208a1, 0x22918993,
- 0x6c2123ff, 0x79039df2, 0xf55ab33f, 0x2ce427fd, 0xc2e65efd, 0xd8abdf70,
- 0x4e44af77, 0x28f78f99, 0x4b8c15c6, 0xe303bb47, 0x1c9f2cdd, 0xbcb1a470,
- 0x8b657d84, 0x6f7fdaeb, 0x6e92f9d0, 0x9106f795, 0x3a60dee2, 0xe9d7966d,
- 0x86fe41fc, 0xed0215ac, 0x71cdb826, 0x1ffb7a38, 0x6b0ac6ba, 0xfdfccf41,
- 0xfa7bb987, 0x66f3aec3, 0xb0f1a0ec, 0x7b19bf83, 0xf7cc78c5, 0x163ed8cd,
- 0x39d98699, 0xbd3179cd, 0xa74e793b, 0x26f1aee7, 0xcf7c6b08, 0x1af1d678,
- 0xcf1d4f8a, 0x2f5e02ff, 0x2fd78774, 0x37290b06, 0xa23e4a47, 0xac2ab7e3,
- 0x1f671ef3, 0xa5445c63, 0x33e9e243, 0xb87b8c80, 0x3cf15775, 0xfd17a93e,
- 0x7545ef81, 0xd43cb8a3, 0xc736250e, 0xc77f5e70, 0xef83ccec, 0x7c122746,
- 0xea7c39d7, 0xd9cbc250, 0x492660fc, 0x0d93e230, 0xfaef7c0d, 0x07aab3dc,
- 0xeaa57ff2, 0x4f01eb5e, 0x3f655379, 0x95e6f8a0, 0xc509f864, 0xa3e3eee6,
- 0xaf121d2b, 0x32b3feba, 0xa7f788ad, 0xca241570, 0x3de4d5f7, 0xe81e5d72,
- 0x8be3261f, 0x3dccfbf5, 0x232307c9, 0x1feb1f24, 0xbeaef926, 0xf38ed49e,
- 0x48cfd449, 0xf74953e2, 0xb03eb045, 0x1a4de5db, 0x78ca7f0a, 0x75a79261,
- 0x97a3bfbd, 0x5af03f7c, 0x68d0f991, 0x643f8fca, 0xef2a0113, 0xf14c2f18,
- 0x946f8564, 0xfa16bbf2, 0x44b098fd, 0xfc0cafd2, 0x611ddc20, 0x32346f7a,
- 0x8f94ce2b, 0xd533f4f2, 0x6a95198f, 0x0ef58f2a, 0x4fc79531, 0x7be537cc,
- 0xaa655d17, 0x58f667df, 0xefafbe53, 0xa4fd5306, 0xbca669f2, 0xe49297ce,
- 0x76a03127, 0xc0fda9ae, 0xfd5312ba, 0xf9857f14, 0xf7bf54fd, 0x9e025648,
- 0x697f9477, 0xbc87966b, 0x96116aaf, 0x90ef5d91, 0xde5a3afc, 0x5ce89907,
- 0x6491efc4, 0x0cccfd34, 0x8a8dfa8f, 0x46292673, 0xae24f7e1, 0x60f99b73,
- 0x3f39a261, 0x2af795de, 0x2b9c6e96, 0xa828fe34, 0x6a929e80, 0xf3efa6ad,
- 0x347c6a86, 0x9eb2e457, 0xefeb5dfe, 0xff5a621b, 0x4e5d7c50, 0x05e7cf0f,
- 0x6f9ed2dd, 0xf9ec179c, 0x9ec0bc46, 0x9ec3cc6f, 0x7b0fac6f, 0xf61cb1be,
- 0xc179637c, 0x8c1d3321, 0x83a66238, 0xe99a8e2b, 0xd0cfa740, 0xd5b2baf5,
- 0xa7c21f4c, 0xb07f94f8, 0x6a7f575e, 0xf5d09fa6, 0xd78b0921, 0x1153826f,
- 0xfbfca48f, 0x642eb5eb, 0x87d73abd, 0xf6f90df0, 0xbe50e0da, 0x48785b27,
- 0xe4b77815, 0xd79e6d51, 0x27e5ad0d, 0x7d5bb6c3, 0xae7de6bf, 0x5f4355d1,
- 0x871d5749, 0x1f070f9e, 0xffa4347d, 0x02f9fbd7, 0xfe3b3fa8, 0xf41db262,
- 0x45df2ed1, 0xee1f036b, 0x49b715dd, 0x77bcba7a, 0xe39533f2, 0x9a598e18,
- 0x82ebf014, 0xf036df18, 0x6bb39bcb, 0x1367f815, 0x458ed145, 0x8ff9cb88,
- 0x17e464b0, 0x77f7940c, 0xdf2b7645, 0xe2f9d07f, 0x17192482, 0xf35432d8,
- 0xdc647af3, 0xa543f3ce, 0xe3ca24dd, 0xe2e338e2, 0x83bf796c, 0x05e499d4,
- 0xe1c7c039, 0x47c041f0, 0x69df85b3, 0x39b9b56c, 0x86ffc46e, 0x83f7e02a,
- 0x72f90b1c, 0x35df2680, 0x0070e47c, 0x85eb41fe, 0x1c1d9ce9, 0x5be29870,
- 0x99736e87, 0x892d39f2, 0x76c3faa6, 0x79e54dbb, 0x79532cc1, 0x298f21c1,
- 0x28c8e23f, 0x8e2bfd53, 0x2bf94d7a, 0xea9a275b, 0x9169fd5f, 0xda249f29,
- 0x077e061f, 0x3e8f522a, 0xe2553433, 0x7e382dc9, 0xb19dc16f, 0xa6a7def2,
- 0xba72eb5f, 0xd3ecf71e, 0xde5439e8, 0x71f7681f, 0x5f43751c, 0x187be1e1,
- 0x129f4d0e, 0xa7c03d66, 0xde772dc5, 0xe39bf0a3, 0xe578f596, 0xd3417d4e,
- 0xdd39740f, 0x35ecaf10, 0x082f2bc6, 0xe03dfeeb, 0x3dd6d2ff, 0x7681fe14,
- 0x9f86df39, 0x88def9da, 0x3c28570e, 0xda38b533, 0xefee8e2d, 0x25b2d8f5,
- 0x1465259d, 0xfef41dfd, 0xcad3cd98, 0x365fdd6f, 0x4fd5a79e, 0x0bf0d5f4,
- 0xfba567bb, 0x305bc7bb, 0xbe67ce4c, 0xd4f372c5, 0x32cf8e6c, 0x3bdf83bd,
- 0x51fdea5b, 0xf3b74ab9, 0xe323105b, 0xdd8c44a7, 0x79edfa0d, 0x44cf893c,
- 0xfbe468bb, 0xff9c5a47, 0xee5b6b4d, 0xf3454419, 0x7bda4ded, 0xe81b0160,
- 0x9258d261, 0xd884f2c3, 0xb35765b6, 0xc7a2e493, 0x3f6cacea, 0x35ddbfe9,
- 0xceb8248b, 0x49031bfb, 0x407d01ef, 0xb4be81b6, 0x71e54721, 0x1b9ec1ae,
- 0x4df6fd81, 0xfb3d9c67, 0xced08405, 0x754fa90b, 0x874c6f43, 0xaffe3cfa,
- 0xf143ede3, 0x42adeba4, 0xd74c338b, 0xd7f1d2e0, 0xf0d07769, 0x707fdfa7,
- 0x6d15b32f, 0x8a3df272, 0xd2db8889, 0x4725afd7, 0x86ad65d2, 0x3f03d40f,
- 0xa15ea9ea, 0xfb031d9a, 0xc7708772, 0x43a1bab8, 0xc2bffd3d, 0x9eff8e8b,
- 0xc4f557ee, 0xc2f9421f, 0xeab7dd77, 0xd9ff4e89, 0x3e06577b, 0xb468e321,
- 0x5ba40975, 0x677d3fd8, 0x6f3f7994, 0x8d7696cc, 0xa2beda71, 0x6799ddf3,
- 0xf60217e6, 0xaa5586f1, 0x39e42fc6, 0xc4529c5e, 0x3a8b11ef, 0xe533cb17,
- 0xcfd62f1a, 0xc80f85d7, 0xf5aee0f7, 0x455c2516, 0x9b6692f9, 0x15a048d8,
- 0xf38fbbfb, 0x1b93bf66, 0x449efe71, 0x3726cdc0, 0x49b4b71a, 0xb94fec09,
- 0xc5ecbdfc, 0x5c7ef94e, 0x8bd9bbe8, 0x2f17fd35, 0x86df602a, 0xcfee65fa,
- 0x8f6bced6, 0xe12b7cf0, 0x0ba5bd67, 0x02de8d7e, 0xe8311df2, 0xf3b4aac3,
- 0x8e969c70, 0x24fc3737, 0xc2795df1, 0xce16446f, 0xb76b46f3, 0xf89d7471,
- 0x9d2afdd5, 0x1cc3c27e, 0x171a1faf, 0x4affd670, 0x1a7e7774, 0xd3d37fdd,
- 0xdff4e83e, 0xa85f877c, 0x1e8969c3, 0xff043e05, 0x57e8dbbf, 0x8248f3f9,
- 0x3127fd90, 0x6ab48ff0, 0xb98d89fd, 0xf44fdddd, 0xf1c5d8ad, 0xbe2cab10,
- 0xf25c40ff, 0xef1fea19, 0x3ce5deb0, 0xf8fb8090, 0xd3bb3493, 0xe4d6f3e5,
- 0x7ef2d1b0, 0xe55f8740, 0x2898eef5, 0x1f1373ef, 0xba77d815, 0x08aa7f1f,
- 0xfbaa42f6, 0x466b7c49, 0x3f75fe31, 0x14707149, 0x61b339c3, 0x484f0db1,
- 0x7b7c3eb6, 0xcbbb8461, 0x403ad27f, 0xe4f4e7c6, 0xc97e9947, 0xb8cdfdc3,
- 0x73f71574, 0xca453b2c, 0x2cf78d6b, 0xd90d9d03, 0x67986c26, 0xdffbadab,
- 0x23929819, 0xf852d1f7, 0xe21b7bd2, 0xac28567e, 0x84572c07, 0x7cc4071e,
- 0x6c5fcf5e, 0x3285f2d2, 0x992acb7f, 0xc5ded56f, 0x3bd9aada, 0x98a44f30,
- 0xedf0f40f, 0xf3043d9a, 0xe0798a40, 0xf21af83b, 0x83c86be0, 0xbe0f21af,
- 0x0d7c1486, 0x51444bdf, 0xfd2a9e72, 0xfb0de33d, 0xf19efe03, 0xfe09b906,
- 0xfe1e631e, 0xf87d631e, 0xf0e58c7b, 0xe1cb18f7, 0xe1e631ef, 0x87d631ef,
- 0x8798c7bf, 0x1f58c7bf, 0x1e631efe, 0x7d631efe, 0xe58c7bf8, 0xcb18f7f0,
- 0xe631efe1, 0xd631efe1, 0x58c7bf87, 0x629d737e, 0xacdd07f2, 0xba503bbd,
- 0xa3e98e3e, 0x2928b539, 0x3ff7d687, 0xc7e7ff23, 0xf3ac54b6, 0x6efc25de,
- 0x47845560, 0x44d373ae, 0x2116eeb9, 0x0e7db9d7, 0x76edf3af, 0xf1942f99,
- 0x03f4a1c2, 0x74f8cabf, 0x0a4157e9, 0xf8520abf, 0xafc29055, 0xfd2ade32,
- 0x57e1482a, 0x55f877c1, 0x82afc290, 0xa4157e14, 0x8520abf0, 0xfc29055f,
- 0xbf07682a, 0x55f8520a, 0x157e1df0, 0xe0abf0a4, 0x038231fb, 0x2e1d15fe,
- 0x26e9f9c8, 0xd0e8943d, 0x4cba87a4, 0xc6f9c879, 0x8df390fa, 0x8df390e5,
- 0x8df390e5, 0xc6f9c879, 0x8df390fa, 0x88f11bf9, 0xef296f71, 0xde41db1b,
- 0x9a73e637, 0x86c1affc, 0xf9c37935, 0x46b69157, 0x2e298f29, 0x9e72eb92,
- 0x58ff059a, 0x1c92b86b, 0x763921eb, 0x8d676fc5, 0x89f892bf, 0x2b976f16,
- 0x6f582dda, 0xbad37bf6, 0xe38282f9, 0x3bfe7383, 0x7f75cb91, 0xbad1ff2b,
- 0xac14ede7, 0x90cb6c37, 0x3dede970, 0xd522a5c2, 0xbbe577eb, 0xbe3a17af,
- 0xa5f98f5e, 0x28520e01, 0x910710f3, 0x1f33bb77, 0x2d5bedf1, 0x5d0b8c8a,
- 0x4372e329, 0xe349aae9, 0x3b2d5b4b, 0xbb50440e, 0x83c562f6, 0x5699077b,
- 0x0f96c871, 0x43e6d53c, 0x89cba89e, 0x6b83e2d5, 0x903c42af, 0x7f6eb70e,
- 0xf7c13e24, 0x0bb746dd, 0x738d197b, 0x8ec217cd, 0x64985bdf, 0xda04f297,
- 0xea1cdf41, 0x0c9bbc57, 0x4732bdf4, 0xff3e7b9e, 0xe8caabb2, 0xb5edd0fb,
- 0xdd1ee157, 0xeed908a4, 0x33478f37, 0x2a34a71e, 0xc9fef09b, 0x8bc2ede8,
- 0xd4bfb1fb, 0xddba1ee0, 0x71e32f65, 0x4eff7c5d, 0x4378b7ef, 0x2c17df32,
- 0x13e3ad16, 0xf0a127d9, 0xde3ae6fb, 0x62af7e68, 0x0fe2c47e, 0x2ffc8ec1,
- 0x7121c3df, 0xc3dcfbf1, 0x6c7866b9, 0xc4dbe221, 0xe40ef95e, 0xabc5e1e4,
- 0xbe5c137a, 0xf2077c80, 0x5f6a2f9a, 0xf966fce3, 0xcf93240e, 0xcf8f8648,
- 0x857e41c3, 0xe298ffdf, 0xe5e968df, 0x15e0bdc6, 0xdfd404b6, 0x0b503c2e,
- 0xaf790906, 0xb6579f55, 0x57096238, 0x95e22f40, 0x11fd0378, 0x7a0198e7,
- 0xf8d8f3c9, 0x56a9907d, 0x46fc0d97, 0x5d8a7397, 0x7542ec72, 0xf7df0c74,
- 0x2e13910b, 0xb8e6f636, 0x8e3d7f8d, 0x93ef83a4, 0xce15df2f, 0xf88f8572,
- 0xb9e6f807, 0x5977193c, 0x91c3ecb9, 0x38aed496, 0x8129d392, 0xf3df78ad,
- 0xe88eea74, 0x11cb0a51, 0xdb5fc087, 0x7be79f1a, 0x5eabc582, 0x1710fbe3,
- 0x96881f1b, 0x7fa4aaf7, 0x9bc34ca5, 0xa85a6f6e, 0x16994fad, 0x5ebc743f,
- 0xe74bcfbe, 0x71f7bf30, 0x72c6d1b1, 0x28bca846, 0x880feb84, 0xb46f2b73,
- 0xc5d3ddf1, 0x27578b6b, 0x777eee8a, 0xcfe32bc5, 0x349771b5, 0xa84e38da,
- 0x2b477b5c, 0x965877f4, 0xd2e8726a, 0x27efe66d, 0x4fe44272, 0xad44fdfd,
- 0xaf5bf14e, 0xa83964cc, 0xee71c6d6, 0xb94857f3, 0x0110ec48, 0xbf9867dc,
- 0xef059c62, 0xe5dfcc58, 0xd0dd28f5, 0x7c9a3bd1, 0x12830934, 0x8a5ea7de,
- 0xed32be60, 0xcfce3f52, 0xe9c894ba, 0xe4b2978d, 0xd11dac77, 0xbca16b4b,
- 0x26beff5f, 0x1c44cd17, 0xb2e40165, 0x1dd74c3e, 0x2218d744, 0x4357e357,
- 0x302bcabc, 0xf9b24fc3, 0x734e2156, 0xf7c146d2, 0x7e432691, 0x90d982a2,
- 0x2fb00aa7, 0x3ef90a52, 0xef8544c6, 0xbe1e4cb7, 0xb407db4c, 0x11f3042f,
- 0x37c3f77e, 0xf1006a7e, 0x3b7db337, 0x7d77582c, 0x6dfcf83f, 0x64e60efc,
- 0x7bc762bf, 0xcf4d3e81, 0x743de9d6, 0xd4882c5f, 0x694e63ec, 0x8fb4eaff,
- 0x9c7e5801, 0xc446f227, 0x2d802eb3, 0xb0b69fb3, 0x6ca8aa84, 0x1b9c9e59,
- 0x94236379, 0x6ed37fac, 0x9162df32, 0xfe489ff7, 0x717578e3, 0xe50fb0a4,
- 0xf92ad78b, 0xe1d79788, 0xd8d87afa, 0x777ac349, 0xe74941d1, 0x03eeccfe,
- 0x5df960bd, 0x4cff2619, 0xf84a5a68, 0x105a3ec6, 0xfc63fad3, 0x5c84d0d2,
- 0x889f1de1, 0xf9f5c877, 0x02e2208a, 0xdbf96ae7, 0x8ff2bd9e, 0x278c9c6b,
- 0xedcd8fce, 0x3fe22377, 0x38fe65fe, 0x7f1ab15f, 0xf14daa37, 0x3de57379,
- 0xdf5809c8, 0x7e76ecc8, 0xa66660c7, 0x212f9e4b, 0x72db9676, 0x845df2dd,
- 0x694b7b10, 0x846f3cb6, 0x8f3c9dd5, 0xb66e3afd, 0x3ef3ea57, 0x33df336e,
- 0x5cead3d5, 0xbff83769, 0xa0f127ba, 0x7ffbde45, 0xf1d812c4, 0xa06bd122,
- 0xe6016fb7, 0xbde208fb, 0xcf1f7e19, 0xa3477f4f, 0xef694f93, 0x74f4e865,
- 0xdf22eeac, 0xda712897, 0x9e81aadd, 0x7c28d6ca, 0x4ea4b11f, 0xadf627de,
- 0xfcbde451, 0x8f57ec1e, 0xdf9af9cf, 0x17fc7a51, 0xc350b211, 0x91fb7cef,
- 0x5d291cd7, 0xdd53fdf8, 0x7f926caf, 0x6f103306, 0x9c36b73f, 0x7afe41df,
- 0x018fd158, 0x87b6647f, 0xf11269d7, 0x1a9fd434, 0xbe29fbe3, 0x07238897,
- 0xf05c6f61, 0x7df8b7f3, 0x29bd9ae1, 0xf161eefc, 0x78d5bcee, 0x61ebe547,
- 0x89723bbe, 0x2e9d8b7e, 0xea90e43b, 0x973e58c6, 0xeed1f417, 0xf6768ba9,
- 0xf3ebe9e7, 0x0794ae60, 0x9c723c8a, 0x453e9a0b, 0x354db308, 0x7fe793d5,
- 0xedd43ee8, 0x95f6a1a2, 0xbe2af7d0, 0x7b029ecb, 0x5760dd89, 0xb631edd5,
- 0x7073e3ac, 0x77b7cf9e, 0xaf8dbbff, 0x4d4776eb, 0xa9d85d9f, 0xe84f66cf,
- 0x9d7fb903, 0xbd1d82e2, 0x11bee9cc, 0x8765f5f1, 0x14f0886c, 0xf2dce293,
- 0xe4bb92dd, 0xb72525bb, 0x9b3f31e6, 0xc7c9358f, 0xbc5187bd, 0x9402cb8f,
- 0xdfbcf7c6, 0x657bade7, 0x53d01ec0, 0xe0f7cbd0, 0x7b5e5ccb, 0x2a2e419c,
- 0xef4c526d, 0x17f9e818, 0x721da573, 0xc019a93e, 0xa6b74ddf, 0xd086f1d8,
- 0x108f127c, 0x46baf837, 0xaa3b7a27, 0x932571c7, 0xf941c552, 0x9dc114ae,
- 0xfe33c722, 0x9349514e, 0xaa063df9, 0xfedd72cf, 0xafee28dc, 0x4ef345d8,
- 0x3862ea41, 0xa78c0f09, 0x3fa87bf6, 0xebc38f37, 0xd80c1a51, 0x8f983760,
- 0xcfca1678, 0x186c0575, 0xbe51a4a7, 0x2b5be28f, 0x89adf1c7, 0x2e40e7b5,
- 0x03ecbab0, 0xa360f28c, 0xbe78cf7c, 0x0411fbf6, 0x65cbcb2f, 0xf3dc2784,
- 0x867defd2, 0x8358abe2, 0xd629acbf, 0xad365f2c, 0xe67d61b3, 0xc35ef0f4,
- 0x971d1a97, 0xfbe18e34, 0x2f5665f5, 0x69f097df, 0xb2ebfef8, 0x27e1bbf0,
- 0x90fcd399, 0x8d79052d, 0x3c097d2f, 0x829e06f7, 0xd23efc19, 0x678e70b2,
- 0xe26ae39e, 0xfbe276f9, 0xe40fc201, 0xe3115715, 0x8fc4e89b, 0x66b2c038,
- 0xc176faf3, 0x65df2513, 0xfde62e6f, 0xb3eac8b7, 0xac708cbb, 0xfb819fdf,
- 0xdf68735b, 0xe127fde3, 0xcc7df1f2, 0xc8dc0f53, 0x3806fbbf, 0x8f28e781,
- 0x3bde027b, 0xba61ba22, 0x4167e9d6, 0xfacfdc81, 0xacc35178, 0xec3f0ed2,
- 0xf7a9f6bb, 0x06f3e420, 0xffd86f5a, 0x76a7da7b, 0x71a4005c, 0xddf265ed,
- 0xab7dd0ba, 0x9f7d57ef, 0xdf56fbea, 0x8ad98fcf, 0x174a8982, 0xbdf3a1df,
- 0xf06eb9f6, 0x77834934, 0x84aeb6ae, 0xc18557d7, 0x986237ae, 0x53f3dfdc,
- 0xfd1ffbcd, 0xbd54dfa1, 0x03306c7c, 0xfaf53df7, 0xe3f3b8fa, 0x03ec3b64,
- 0x30ea5bd0, 0xe5fd674b, 0xe262df5c, 0xfc9da51f, 0x04aafb63, 0x0a1d8ff0,
- 0xdf96e1fb, 0xe5bee523, 0xe17bc8cf, 0xf8bf9667, 0x77aa2cf6, 0x0b8dc1fa,
- 0xca2ff78c, 0x2c5f9282, 0xfc0b7924, 0x0f269163, 0xe5f4cc6c, 0xe7ec330d,
- 0xc99ffbb2, 0xdb98fec4, 0x6f0a7792, 0xf9bcd1a8, 0x3f3fa3bd, 0x5787d2f3,
- 0x5dcebbb9, 0x6b251e7d, 0x3b15b5de, 0xf493788d, 0x0756777e, 0x38a55b9f,
- 0x6953e8b7, 0x61f33163, 0x8f7a4891, 0xa1eeb5d2, 0xa8dc50f4, 0x5a579cb0,
- 0xfea03237, 0xd2ebf22f, 0x8df953b5, 0xf4bd7d28, 0x73f45f77, 0xa67f8757,
- 0x35734eb6, 0x4c3d9e7a, 0xe5b9c3ee, 0xbc45f629, 0xf8ec53ff, 0x5a39cdbd,
- 0xf3329cf9, 0x72f5cef7, 0xd5fbf275, 0x9fb827d8, 0x58eaf584, 0xcbf6936b,
- 0x57ad97ed, 0x1d02e432, 0x9d9ac58e, 0x6f66a172, 0xcbc9a45c, 0x8d8b5eb4,
- 0x71f8b5eb, 0xcfa55eb9, 0xbc17f5be, 0xd3f34653, 0xef93a3de, 0xecb4940a,
- 0xb39b75e0, 0x852d9d66, 0x5864fdea, 0xa8fe298a, 0x05cf36b4, 0x35dcfd3b,
- 0x07e06d1b, 0xf126193f, 0xf3f74a16, 0x1d62f8b5, 0x148f38af, 0xaf473f83,
- 0x83b83e0f, 0x5975b9c6, 0x77f1b478, 0x3d1a02ed, 0xc6c6d697, 0xdad2bc61,
- 0x7fa17be2, 0xe840e7e9, 0x2e113bfe, 0xf50945f7, 0x6279fd87, 0x55ef878c,
- 0x377ed7cf, 0x43feb42f, 0xdafddd1a, 0x4cbfdf26, 0x92796c8a, 0x226a3be3,
- 0xe913e03c, 0x8c01ade9, 0xdc067a0b, 0x2f7c8b76, 0xf5b2bd33, 0xa241c073,
- 0x20f5c73c, 0x105b7bc5, 0xbf2813ed, 0x79ef22c9, 0xdd32aaa5, 0xa607e1a7,
- 0x5e8b9437, 0x5f1efcad, 0x2151bbe7, 0x9b176af4, 0x1fdde0d7, 0xefc12f7b,
- 0xa9f4e9a6, 0xa7d3a3f7, 0xcd3dbf4e, 0x9cf7d76f, 0xcd1489df, 0x49e592ce,
- 0x0bb8d076, 0xbfc41bee, 0xf35df16b, 0x35ef6bb4, 0x4c37ce76, 0x65c7defe,
- 0xfa974df3, 0x6df3cf52, 0x66e84c2e, 0xd4f3a1be, 0x431e89f7, 0x694fe9df,
- 0x1394fe92, 0xd4639d0a, 0x70b2c4ee, 0xe7d3ab8e, 0xbff5dba5, 0x8f87bdef,
- 0xf669c586, 0xc828d6aa, 0xdfb5f397, 0x99411151, 0x86a9f7c7, 0xaff9faef,
- 0xf3a75fbf, 0xdab593e9, 0xef5a28f9, 0x75167ec1, 0xf50f7c69, 0x2889d358,
- 0x627313bc, 0x6f4f848c, 0xde4dab77, 0x76511673, 0xbbcfde37, 0xfe3cd6e9,
- 0x8d8594bd, 0xbd9f587d, 0xf98d2ea9, 0x587e4dc2, 0x1ea74517, 0x83e348b0,
- 0xaf16b791, 0xd7f502be, 0xc2eff0a7, 0x4e7a742d, 0x43f6e7ad, 0x2313903d,
- 0x53daa79b, 0xfa961e59, 0xbb17ee82, 0x7c451155, 0x127c0d4f, 0x3fb2cbfb,
- 0xe2cfe71d, 0x983f52f5, 0xe06b1164, 0x50d81d3f, 0xf82fa134, 0xfc8ac3c4,
- 0xe60d9a3d, 0x0e86bcf7, 0x7c02fa2a, 0xbc5df426, 0x5e2d6d5b, 0xe482a7e8,
- 0x16d1d80e, 0x9e588b3a, 0x93e345bf, 0xf8db9ac7, 0xaf1d7ebd, 0x78bfe08f,
- 0x7ec42aa7, 0x1a276a14, 0xff07d9a8, 0x7b8faf1f, 0x0080003d, 0x00000000,
- 0x00088b1f, 0x00000000, 0x7cb5ff00, 0x65545c0b, 0xce7bf8da, 0xc0cc2b99,
- 0x1245c880, 0x85848b87, 0xd780c034, 0x508151da, 0xb9bba0bb, 0x658e21ba,
- 0x500665ca, 0xd7775ddb, 0xa6a18cfe, 0x45fa7d66, 0x80ed65a6, 0x76c36a97,
- 0xa8283448, 0x59990bc9, 0x6a37627f, 0x5b63b92f, 0xba402de6, 0x6dbfedfc,
- 0xbcf3cf7d, 0x511730e7, 0x6fbefddb, 0x797bf9fc, 0x9f5ef3df, 0xcfbcf3fb,
- 0x8c346339, 0x63181b75, 0x418e8b2a, 0x89486839, 0x8d8c9964, 0x615f6909,
- 0xf6c3894c, 0xc645db25, 0x7cfb4046, 0x1962c893, 0xfa31d72b, 0x1fbf8f7d,
- 0x3c1f7631, 0x42f3c337, 0x07d634a9, 0xcc37d7fd, 0xd6c972a0, 0xf1ae6dc2,
- 0x2509258c, 0x606393b1, 0xb66ae3c0, 0xce258a07, 0x2b307719, 0x8da4d3cc,
- 0x73c325d2, 0xc7292bb5, 0x496f9fe0, 0x0c4943e3, 0xd4699dc6, 0x7b4377cf,
- 0x414e6981, 0xba5f8c14, 0x325b2a33, 0x6f5dfbfb, 0xc91b1811, 0x4673a558,
- 0xcc614b1c, 0x67e1ddf1, 0x1fb0a94c, 0xf304d398, 0x7709e57f, 0xa38ba0bb,
- 0x82492dae, 0xb3aa3c23, 0x7fa058a7, 0x6f31d895, 0x4e73cc12, 0xa04def70,
- 0x5338e6fe, 0xe5a1fac0, 0xccc63ae9, 0xff398ce9, 0xcf3487cf, 0x3b89e2e7,
- 0x8778c016, 0xce047f73, 0x1ff8f553, 0x6c3201f2, 0xb2cf689d, 0x8dbce1e4,
- 0x1c124d7b, 0x56637b74, 0xbee39c09, 0xda46c7c7, 0xf79f2f33, 0xa8b668b6,
- 0xdbcbda04, 0x6957c118, 0xd48ee85f, 0x5eeddc20, 0x696131a6, 0x28689a62,
- 0x956c48cf, 0x52dbca07, 0x06b9a2d8, 0xe10dbb7f, 0x899eeb00, 0x025492dc,
- 0x9f7b15ed, 0x79433248, 0xa5ebc8d6, 0x9c7a7f7b, 0xddff4045, 0xd5e20d5a,
- 0x0b1a62ae, 0x25d7bb8c, 0xb250dcd8, 0x12c668f2, 0x7d6ea310, 0x59b19199,
- 0xaf9a7096, 0x630e7b62, 0xc17dfeb9, 0xab3f6a73, 0x8fb8c562, 0xd903f531,
- 0x8bfca1cb, 0xe21f7bca, 0x7ab52ff3, 0xf1192b8b, 0xfcbc2662, 0x84548b65,
- 0x05fbaeed, 0xfac05636, 0xac1a637e, 0x6ac9165f, 0xf4a17c71, 0xcf049b57,
- 0xb2101c57, 0x787b30b5, 0x1ee6b766, 0xd1169103, 0xd389b559, 0x75768ad9,
- 0x7fe02251, 0x2d408b45, 0x3357950e, 0x2f2abe1c, 0x80e6664d, 0xb6b656fd,
- 0x8eb0cc68, 0x09ce19a3, 0x539e1dfd, 0x5e78a59a, 0x7cb185b6, 0x89fe27c0,
- 0xa53e6bf8, 0x3f0037b9, 0x2e1cadd5, 0xbede56ce, 0x3b900338, 0x1362b699,
- 0x26dea0d2, 0x6b3ebd50, 0xaa35fcc2, 0xfcfe7ac0, 0x9a586935, 0x354c4e08,
- 0xf0025490, 0xa3d194dc, 0xd73bfc41, 0x5d42f3ca, 0x0d5eb01d, 0xde48e512,
- 0xf1c06a9e, 0x3caf1a66, 0xd146b677, 0x6c33af78, 0x3609bb03, 0x61506d51,
- 0x4434ef59, 0x56b3b960, 0x715950cc, 0x09166173, 0x1611dfe0, 0x6122c591,
- 0x3d5eaaca, 0x3b501240, 0xf6845870, 0x83fb48dc, 0x0c719f48, 0x33e802b8,
- 0x06057991, 0xf9dfdff4, 0x7fce2e59, 0x17df18cb, 0x5eaeb60c, 0x017e7d33,
- 0x8b26c3d0, 0x5f4c8e7c, 0xc8f1d22e, 0xb0af4043, 0x6cd5a7bf, 0xcf073e83,
- 0x42e6c257, 0x08c2cc3b, 0xb984dfcf, 0xafdfc0f7, 0xce226f31, 0x54de74cf,
- 0xcc9af71c, 0xc35a25a7, 0xf5f60106, 0x63fb149b, 0x053b8fb8, 0x116cf8f5,
- 0xc58d2071, 0xfe6afd7e, 0xc2796d9c, 0x4ffc03a6, 0xa367e8e7, 0x4062e645,
- 0xf1519aa2, 0xc163a406, 0x60ab6366, 0x0f3307fd, 0x2e80cbdd, 0x31d01e1e,
- 0x5eaf9c2d, 0x7d3dcfcf, 0x0094ec20, 0x2a8f46fd, 0xf4165916, 0x2958ab37,
- 0x29943ff4, 0x9fd8557a, 0x9fd8dce9, 0xbe6d0ae9, 0x8196590c, 0x7a88d0fc,
- 0x78eff51b, 0xca011bf3, 0xe1e2e944, 0xe2573848, 0x3d4b052f, 0x3c1b29f4,
- 0x85fff4fd, 0x5352f4b2, 0xfca1efcb, 0x19bda475, 0xb0727751, 0x501d94f8,
- 0xa3c9b0f6, 0xf9f264b3, 0xf1dff702, 0xa2226fab, 0xfabeff45, 0x7bef4e07,
- 0xcea58ad9, 0xe9b8c022, 0x9b57921d, 0xfa7ef975, 0xa9e361e3, 0x39e18fd4,
- 0x5ba20dfb, 0xe1ffb010, 0xd37f710f, 0x14af0675, 0x17d4e381, 0x38ff3a7c,
- 0x751d1e66, 0x284646fa, 0xb1913ef8, 0x8c3cdc58, 0x7068b81f, 0x6fb9c137,
- 0xa14ff991, 0x488b1eaf, 0xf191e9f8, 0xe991c0a4, 0x7e9122b2, 0x5e8ad5eb,
- 0x4cb385f0, 0xe8d67f3f, 0x5e0cff38, 0xff386d12, 0xcdd6b960, 0x8ec18a60,
- 0x5727d254, 0x007fa792, 0xd740ca79, 0xfb6a97bc, 0xf90fc233, 0x78fc074a,
- 0xc02f0c97, 0x25f9c33f, 0x64bbfe79, 0x1065ddb8, 0x127e9c39, 0x6e992702,
- 0xf650ba14, 0x5863982f, 0x9f1fb469, 0x47ddd7ec, 0x8f099323, 0xe383ffe3,
- 0xdfc213ef, 0x01d62737, 0xff51b11b, 0xfc784598, 0x579fc05f, 0xf80bfeb4,
- 0x9fc50eeb, 0xe23d7f57, 0xd2d171ef, 0x0880fc84, 0x26d2a1c8, 0x0658f9c2,
- 0x932ffe23, 0xe09b2cc2, 0xffe4767c, 0x8fef889b, 0xfc2bdf22, 0x37d8a63e,
- 0x49e4f51e, 0x7dc19ec6, 0xb50f44f9, 0x10a766a7, 0xbac75f9f, 0xf01db013,
- 0xf117379c, 0xe876d82e, 0xfb7d2c24, 0x5df5865e, 0x1ecb0615, 0x5bbf6f38,
- 0xfe61a974, 0x8ef72886, 0xc36eb0a5, 0x1716995d, 0xd59633b6, 0x3ca07286,
- 0xbe7a82cc, 0x85cb8a21, 0xa4e90586, 0x277e0f87, 0x73c2ad25, 0x34b3082c,
- 0x6c86ff41, 0xa01323df, 0x6cd630de, 0x57d74171, 0x1dbe9605, 0xd1d1cfc7,
- 0x38730d3a, 0x323c36dd, 0x057a8dda, 0x7af3cff4, 0x1e593fa8, 0x0d9cf0c6,
- 0x6884b68d, 0x2297cba0, 0x61b3a3ec, 0x4e24a3ff, 0xd0c90dd7, 0xa136e50e,
- 0x387dc164, 0x6fbe78df, 0x17b082df, 0xfa2cc2f7, 0xd0591034, 0xb195727e,
- 0x42a5e509, 0x73a57797, 0x75c63779, 0xc9c2076a, 0xd4659d35, 0x937ffcc2,
- 0xbb814be9, 0x556c6360, 0x0afe1fb4, 0x70c8c59d, 0x7a735617, 0xe5974d73,
- 0xd7733562, 0xe65f080b, 0x96f8070b, 0x42414169, 0xadd93469, 0xe5faefb8,
- 0xf7091780, 0x527fe1cf, 0x619ee564, 0x2847e7f8, 0x4c88f32c, 0x328fe404,
- 0x0ca3f9c6, 0x6fe908e9, 0x0051d015, 0x75df31fd, 0x65c3a751, 0x6bf1823a,
- 0x70d3258d, 0x3f85cfbd, 0x89e363e4, 0x87f34a7f, 0x3656675b, 0xf40b0397,
- 0x9fd899f6, 0x51148eed, 0xf130ae5f, 0x7f644ef5, 0xc5f51a36, 0x79bd5fc9,
- 0x23c7961d, 0x86cb6e4a, 0x7c16dbfe, 0xfce2845d, 0x353e096f, 0x0b6fe39e,
- 0xb468fffe, 0xbf56ca43, 0x43fef449, 0x192859f7, 0xaf4e5032, 0x15a67d04,
- 0xb074e4b0, 0x74463ef2, 0x896ac890, 0xfd65e36e, 0x47a30c05, 0x00f37539,
- 0xbcca8ed8, 0x9747fff0, 0xce896c74, 0xa2c69f5f, 0x7433ea82, 0x0bfd4109,
- 0xcf41c94d, 0x171f8d6f, 0x39a67cf4, 0x3b3ea83b, 0xff505263, 0x82d32ddb,
- 0x9c4e77ea, 0x8e7fd419, 0xdd504e6d, 0x1f244cc6, 0x738aea3a, 0xe1bb013f,
- 0xdc92bab5, 0xe397544f, 0xd0f6aa63, 0xe805b37e, 0x5f3bdb24, 0x91ea0935,
- 0x43265687, 0x11cb537d, 0xf43c4f5e, 0x66e03245, 0xf9d1cb73, 0x53dbd02a,
- 0x45f43c6f, 0x6d1fd40a, 0xa7cfe2e9, 0x40a362c0, 0x39bcb6ac, 0x9af805df,
- 0x8adf629b, 0xa9779af8, 0xf98a28f6, 0xbdccd7f7, 0xb942592f, 0x06746730,
- 0xc53727ec, 0xbf3e10fe, 0x759ef62b, 0x1ffb0091, 0x46ab5b7d, 0x5d98bf3c,
- 0xa1e915b2, 0xf3a722ff, 0x91978853, 0x96097eff, 0x8a61d903, 0x3c92bd9c,
- 0x03adf854, 0x1512c6f4, 0xa54749c2, 0xe544ceb7, 0x2a78baa1, 0xd999d48f,
- 0x57638012, 0xc795065d, 0x7ed42cea, 0x95226ebc, 0x546cea27, 0x4c575bbe,
- 0x095d7765, 0xb2ff0a95, 0x6a0d96bd, 0x2a974224, 0x4fceb4ea, 0x63d2578f,
- 0x69d92820, 0xf9d09f05, 0x39adbd4d, 0x9d75ce9b, 0x6959e909, 0x81f9da3f,
- 0x9dfa0459, 0x3d11d56a, 0x9b74354f, 0x475e5675, 0x22fbb8b9, 0xbc118af3,
- 0x5fb02a9f, 0xfd1b278c, 0x030ea998, 0x841b4bf5, 0xefd8597e, 0xf79404cd,
- 0x16356b53, 0x509e63b4, 0xf61e9733, 0x90df146f, 0x20e31d70, 0x05d86cca,
- 0x903ad518, 0x6ba07157, 0x63f439f1, 0x0f77283a, 0x4746f5f2, 0xf9472ed7,
- 0x60ccba34, 0x95f2e7a9, 0x08e24be4, 0x2fee026f, 0xda86a571, 0x198f628d,
- 0x9d5f60e5, 0x69d21677, 0x0ae72c81, 0x30ef5c34, 0x80bde411, 0x576dfb7c,
- 0xedf3da22, 0xd02f9edc, 0xfa44ec96, 0xfe7156ae, 0xf77a3165, 0xd5475c1e,
- 0xf42cf15d, 0xb44d89eb, 0xc568426c, 0x6069641f, 0x14d617b7, 0xeddca267,
- 0xaf885b61, 0x13fd5ec1, 0x338fdbd2, 0x9945df81, 0xf89e6048, 0x4da6f0e2,
- 0xd7adda02, 0xce5d21e7, 0x300f9ad5, 0xf65f07e0, 0xdcfbd100, 0x7a1e7348,
- 0xafecbe0a, 0x7cce3d79, 0x26e78040, 0x00bf3036, 0xe9cf55ea, 0xf0049f4d,
- 0x1513d3a9, 0x4b69af54, 0xc0127d30, 0x07f855a7, 0x09b747fa, 0x0ebb942a,
- 0x04a72b79, 0xb7c405fb, 0x0d73f8b3, 0x0680dfdf, 0xd98bd8ed, 0xb06fa266,
- 0x0fef4997, 0x9bba34cc, 0x2371bf60, 0xa057b36a, 0xce6994fd, 0xea497ec3,
- 0x63f40881, 0x1555bffa, 0x19efc9bb, 0x78c9f888, 0xd33d7d3f, 0x287b5121,
- 0x70e6b5dd, 0xcd26af7f, 0x50f119b0, 0x51d3af1d, 0x88b171d9, 0x92569d91,
- 0x4db97686, 0xd0cbfdc3, 0xb8737bf1, 0xaf5e491e, 0xa240b921, 0x0b6cb608,
- 0xc5dd4a63, 0xf8d63226, 0xbf21b08b, 0x34c9c007, 0xc83f6563, 0x41476235,
- 0x1b7f505a, 0x8e7a1ff6, 0x8ff31cf6, 0xbb49794f, 0x5e4aad63, 0x2965e90f,
- 0x183fa373, 0x72abc72a, 0xc0b965a3, 0x8c74fcf1, 0x9cf111be, 0xe77d0126,
- 0x504cc950, 0xb2338626, 0xd75f1337, 0x773e91bb, 0xa7fd39eb, 0x2ddcbc89,
- 0x309afef2, 0x577a42e6, 0xb94d87fc, 0x79b929f6, 0xe6978f34, 0x91b25a91,
- 0x879813ae, 0x24ec57d6, 0x43d81fa5, 0xaa02127a, 0xd7c47481, 0x161c4954,
- 0xa672279e, 0x448ce515, 0x4fb1b0fe, 0x5f77e403, 0x40aac478, 0x78e355fc,
- 0xe9b8e043, 0xef194e34, 0x4fb2255c, 0x245c9047, 0x89a6723a, 0x4b562fe4,
- 0xfe8088ec, 0xa0d6eb16, 0xf5c6539e, 0x14fc1c82, 0x9047f0f0, 0x087e588b,
- 0xffd710f2, 0x2c43c833, 0x10f20aff, 0x3c824fdb, 0xf207d2c4, 0x063fdb10,
- 0xbce58879, 0xe4568dbb, 0x69b69a9f, 0x7e20d3ec, 0x017ddb50, 0xc369def5,
- 0xa64391d3, 0xe1e4dea3, 0xe1cbaf9f, 0x2def457e, 0xa0fd9f1c, 0x00ffd1bf,
- 0x8a6b5cba, 0xef1eb2be, 0x1ef9b237, 0x7cb6d380, 0x27f4876e, 0x1cd2faf0,
- 0x226dd535, 0xb7e38edb, 0xfaf86be5, 0x3e396229, 0x79f345b7, 0xb245d37b,
- 0x9e4ea69f, 0x9e0724b6, 0x3da162db, 0xbdef5fc7, 0x8db73f81, 0x7a43ede2,
- 0x253e7e56, 0xeff8a4d7, 0x652fdce9, 0xbd012764, 0xff4afcd3, 0x3e7226f7,
- 0x4eefed0c, 0xc3dd8b13, 0x992de3c0, 0xd02f896f, 0x483e469e, 0x6a8be00e,
- 0x4285f133, 0x55fd0a87, 0xa73872e5, 0x073a6569, 0x43f042dd, 0x3a72831d,
- 0x25f64f4e, 0xe0c6c5c0, 0x9905bb3c, 0x01f9425f, 0x0a07d44a, 0xa07c283f,
- 0xf0227bd0, 0x3fed1099, 0xf421cdc7, 0xca8f94aa, 0x358ee8e7, 0xdaf09cfe,
- 0xdfa136a1, 0x87cc3377, 0xc1c513e3, 0xfe46ef77, 0xd19a358c, 0xc87c2cf5,
- 0x1c9c3b50, 0xc2effaeb, 0x570b9143, 0x7065c780, 0x5ff2f0d0, 0x39c90385,
- 0xbf48e394, 0xfdadc8c3, 0x5db2d139, 0x44f7e9ce, 0xd21f6d8e, 0x57a0bf51,
- 0xafd0dfa1, 0xd9dac367, 0x7f39f2db, 0x05547428, 0x89eb103a, 0xcbd4ce78,
- 0x9e729ee5, 0x632e73a1, 0xc2d2ff24, 0x9e287b78, 0xc8057395, 0x0139c3bf,
- 0xb8c61ff1, 0xd81d717d, 0x4d4fe817, 0x3ed335c9, 0x567e47fa, 0xcff995b6,
- 0x6f0e477f, 0x88944a7f, 0x32fd141e, 0x8b482ed4, 0xe90664e6, 0x3f42661d,
- 0xfc4b53af, 0xe67f05ee, 0x3e871825, 0x3fe49b21, 0x71e320bf, 0x1158fe70,
- 0xafbebbed, 0x63d42e0d, 0x4e06a37d, 0x6fbe300a, 0x6436183b, 0x136ed897,
- 0x07deef40, 0xd4f5063a, 0x2c7b9005, 0x7273b19d, 0x73cfa11c, 0x73fa24f1,
- 0xa6243b35, 0x3b4a5003, 0xf4879abe, 0x6d53b4b4, 0xf6d0b8a2, 0x3d218ec7,
- 0xcc156e9e, 0xb5f49768, 0xbfa1f1c2, 0xd6e8c1b3, 0xa822ff43, 0x0665ff63,
- 0xd7ccdb8d, 0x4383f8a3, 0x7d53ef5e, 0x85c60a75, 0x1350ec66, 0x2f3e97dc,
- 0x3b3ed1b9, 0x0aa57dbc, 0x02dda7eb, 0x4571838b, 0x04aeead2, 0x2d3e57a8,
- 0xce30b458, 0x8b3a2861, 0xe7ca82f1, 0xf30bc599, 0xc918b657, 0xa0da5dcf,
- 0x6017d8fe, 0xb7bb945f, 0x29eed06a, 0x5edc19df, 0x0eb83bb9, 0xeff922f8,
- 0x00f68668, 0x8e6dfcf9, 0xcdec8631, 0xed1b2c71, 0xe3c0d64d, 0xbf7c8ab9,
- 0x71756edc, 0xcb82ba39, 0x8cbec66d, 0xea5f7f45, 0x63e92afc, 0x91cfaf03,
- 0xfea0a7eb, 0x2f1c57f9, 0xe5aa5c0a, 0x604f3fb5, 0xb79c0f56, 0x426f53ba,
- 0xfdbabfff, 0xb71811ef, 0x51f309af, 0x22bd9f7c, 0xdbded099, 0x10b926d8,
- 0xfd0ecebe, 0x56e0112e, 0x8d3de07d, 0x5f7088d9, 0xadcaf64e, 0xe31eb5cc,
- 0x64515edc, 0xdd4744dd, 0xb666a714, 0x4f38a581, 0x84debb5f, 0x2bf54076,
- 0x8ddd741f, 0xd30203f5, 0xfb471e23, 0xee964e88, 0x2da58640, 0xfbe426dd,
- 0xbc4244e9, 0x913d9e22, 0x8865af84, 0xe033c477, 0x212cf11d, 0x51bc713e,
- 0x2274e6e3, 0x73f4fd51, 0xde0abf1c, 0x1acda48b, 0xe46caf6c, 0x63b19e78,
- 0xa230b6cf, 0xe9933503, 0x7a7ef080, 0xa6bbc727, 0x14669d73, 0x08636fd2,
- 0x876bb41d, 0x77f700e8, 0xe0841d19, 0x8df002bf, 0x0e942072, 0x93dff142,
- 0xd806e5c3, 0x429fa7df, 0x7e08dbfb, 0x23c7f301, 0x1ef55646, 0xcaf5818d,
- 0x973bcfa2, 0xf8d8fb43, 0x08da5897, 0xe4157f8a, 0xe66bfc62, 0x5d10eb3b,
- 0xc85eb33d, 0x57a97a46, 0x813cf6fb, 0x70a88b71, 0x27f4e38a, 0x32f9d9cf,
- 0xfa20bb9c, 0xd816a49b, 0x5a6bcd7f, 0xc928deba, 0x35ec8715, 0xf129978c,
- 0xc533c074, 0x5a1d9cc9, 0x2d6b171e, 0x73fa05b4, 0x5cfc09fd, 0xb2819a85,
- 0xc017e8e5, 0x608eb87c, 0x555e7ee3, 0x28178f07, 0x1295597e, 0x8e0e6837,
- 0x77a6081b, 0x2e455fa8, 0xc6a55f8f, 0x3b466cdd, 0xb3017ebc, 0x4d5ea587,
- 0xcc78f03f, 0x74dfb2d3, 0x0af1fb45, 0x1bb1427a, 0x6e382b99, 0x65a9c8a1,
- 0x8f1ef913, 0x6ab8e2fe, 0x76fdc604, 0x8a8f840b, 0x704f900e, 0xdab70ade,
- 0xf802166d, 0x19ffee49, 0xedc01bd2, 0xa0f6ab8c, 0x19dd2128, 0x990ebf68,
- 0x8e91ab3e, 0xd695bce0, 0x9cf02237, 0x38ae590e, 0x7f148dda, 0x8a5b64ab,
- 0x612aee90, 0xf430ef3d, 0x0b5cf954, 0xa2d729f9, 0xaccec527, 0xb7ee0d6e,
- 0xce487731, 0xe01eff8c, 0x396401bb, 0x992e7bd7, 0xf12332fe, 0x99906fde,
- 0x879f9123, 0xedc09ff4, 0x5cfe4537, 0x3c581dbf, 0x6e71de60, 0xac05531d,
- 0xa673e37f, 0x4f78faa0, 0x9bff507c, 0xcf41ccda, 0x4119bdb3, 0x598f73cf,
- 0xdd79ea82, 0x4ffa8313, 0x5416d0f8, 0x0e2be49f, 0x4ce53fea, 0x307d5049,
- 0x9573ce13, 0xe35bc1fb, 0x33fea085, 0xf9a0facd, 0x05446767, 0x320d07d5,
- 0x52bb647c, 0xce5f77b1, 0x686ef6e5, 0x76f7c0a9, 0x8a3af04b, 0xc4e77ebf,
- 0xd8e6f5e0, 0xa1fbd782, 0xfa0bd978, 0xc27e0554, 0xb15fa073, 0x13f81dfc,
- 0x9a13f02a, 0xfac09fc1, 0x604fe08b, 0x027f01e9, 0x7f025fdb, 0xe0adeb02,
- 0x20fd604f, 0x6f583ff8, 0xf2a62bab, 0x6a12ba95, 0xbafc16bf, 0xc98f75e4,
- 0xd7971eeb, 0x74e177fd, 0x5def9e42, 0x9c6ebe79, 0xdcffcd2f, 0xbc563c59,
- 0x2d3cfc04, 0x87c6acfa, 0x5f0ac37e, 0x062dc611, 0xc61892de, 0x7ddd99a5,
- 0xf5062eac, 0x338a08d9, 0xb78192b3, 0x7d52ae31, 0xc9b4d520, 0x0fecfa8c,
- 0xbef3e2ef, 0x7c8cc956, 0xefeda879, 0x85cf3811, 0x5f74614b, 0xef107a4a,
- 0x5461bf1b, 0x31cf04df, 0x05b33a0e, 0x37e90804, 0x0bb7e90f, 0x4ddd4a69,
- 0xcd25bdf7, 0x53c41a2d, 0x3c29f215, 0x0ea3cb7f, 0x635cfe7e, 0xf61373d0,
- 0xe54ab287, 0xb9c238a6, 0x2f3e6536, 0xf1a477f5, 0xcf73cf7b, 0x053f5e1d,
- 0xe2cb6ff5, 0x5e7f7811, 0xec5efcd5, 0xc7c157bd, 0xc85f07e7, 0x76cafba4,
- 0x9fe0cf98, 0x96aed9cf, 0x8eff7ceb, 0x68a296b4, 0x02cd1c54, 0x05c50b1b,
- 0x5fee85b6, 0x38f6daaa, 0x65556e50, 0x0066addc, 0x248f7e9f, 0xbdf837c7,
- 0xb8c4c391, 0x22f9e71d, 0x5f57ef02, 0xc3bd1cf7, 0x38edf886, 0xf6eb811c,
- 0xfe414ab7, 0xb72b68d3, 0x355b478f, 0xad0bbf84, 0x5ef02387, 0x30e7a377,
- 0x4bcabb87, 0xd7243fe7, 0x7824a1fb, 0xfe7449b7, 0xd0624b8a, 0x5586763d,
- 0xb66679a2, 0xb9e2358d, 0xbd7c3c7a, 0xb799ab1c, 0x825e2da7, 0xbf1e3ffb,
- 0x7b224f20, 0xca350410, 0xef661bf1, 0xcaa43b41, 0xf386d923, 0x79e40aef,
- 0x4e9cd4bb, 0xdfdb4adf, 0x78f8f285, 0xd26c88f1, 0x699f8a11, 0x916f76e5,
- 0x7a869ec6, 0x3660c7a4, 0x583f9d22, 0xfc446a9c, 0xdb12c21e, 0xec69778b,
- 0xe6c7bc06, 0xba98f5eb, 0x7aee9023, 0xb425735a, 0xf2f99477, 0xe88775e5,
- 0x2e6f087b, 0xbbb953c2, 0xf8f380d1, 0x73dbc7f1, 0x7fea26ac, 0x3cdefddc,
- 0x327aabb4, 0xe92ec9c2, 0xa7f230d2, 0x5db99aab, 0xd891d3dc, 0x924f7818,
- 0xf2fd9563, 0xdaf0910c, 0xfb96a6d7, 0x0587bddd, 0x39d353f5, 0xde0eec2f,
- 0xea7dc98f, 0x1dc7b451, 0xf50c4b4f, 0x1b5d43a2, 0x6cffe78b, 0xcafef067,
- 0xd43b3865, 0x00d8d8de, 0x0fb4757a, 0xe8818df1, 0x13e15dbc, 0xc153e133,
- 0xb7064f63, 0xf9e27ae7, 0x65a3a4bd, 0xe5f5d10f, 0x64eea4f1, 0x7f121ff4,
- 0xe778a3a9, 0xc567fcb5, 0xaff0086e, 0xea8bfa18, 0x313cd4e2, 0xbc1f6fc5,
- 0xb6ab6b96, 0xabbf448e, 0x1ecafc84, 0xac2cf606, 0x3a7b44e9, 0xb61ff292,
- 0xad83bae1, 0x76bfba6a, 0x7d66daea, 0xa0d97602, 0xf6051805, 0x2d53b83d,
- 0x0cd97bdf, 0x952ed768, 0xcccfdaed, 0xf4097cf6, 0x488d73af, 0x866473e7,
- 0x27d31f91, 0x5bcfbdcb, 0xbb24ef92, 0x426498e1, 0x8786687f, 0x668ec1db,
- 0x7b56d76e, 0x2a63ff92, 0x6acdedda, 0x8a60d4cc, 0xed94e21d, 0xddb2d390,
- 0x80cd7a7b, 0x4e9bfc86, 0x8c963d81, 0xbb5b2a79, 0x33b9e112, 0xb3d91673,
- 0xec99a94e, 0x83db6589, 0x6fb007ed, 0xcf55ea82, 0x7217da85, 0xdc13cb7c,
- 0xdb87f8ae, 0xc67643ac, 0x0a67f438, 0xc871a9a5, 0x78c82f0f, 0x959bfc55,
- 0xb7942de3, 0x9e6551b3, 0x1021c4a5, 0xfb9d355e, 0x6edf702b, 0xfc859847,
- 0x10af558d, 0xe4bffb5c, 0x3c7f4c7e, 0x33f47823, 0x36fedf0e, 0x6a35e74e,
- 0x48f98dc1, 0x34b64035, 0xaf704e9f, 0x6bb338c1, 0x13e48230, 0x17c8c563,
- 0x7f70162b, 0x5f3186d5, 0x7e156b28, 0xb7abd108, 0x54527ca8, 0xb3689c80,
- 0x02bf50a6, 0x3ea3b30d, 0x90b4695b, 0xe3a31b7e, 0x6ae17a76, 0xc3d2364f,
- 0xb5c7f018, 0x31f8f101, 0xfb010186, 0xc7807eed, 0xc27895ff, 0x1d49951c,
- 0x191fa015, 0x95fd435b, 0xf0a241f9, 0xdf9ad7f1, 0xfc1bf304, 0x23bc03f3,
- 0x585fde11, 0x93b7a42d, 0xfff728e6, 0xca97c4b5, 0xbd002e79, 0x63181c61,
- 0xc7378834, 0x9fc837ce, 0xf5eeb273, 0x8228ae38, 0xf708a3ef, 0x5e30f583,
- 0xe79651fe, 0xbcbc79b1, 0xf9152e4d, 0x7b6790d5, 0x95f50adf, 0x593ff679,
- 0x8899ae49, 0xb4ca573e, 0x9c4cf602, 0xbbf9186f, 0xf0891de2, 0x03f005fa,
- 0x5ac2fbf2, 0x64169cc1, 0xaf3a712f, 0x3cec4de1, 0x454ef4f3, 0xdd6cb838,
- 0xc6d79819, 0x5a2d7f38, 0x05a737a5, 0xbd2007de, 0x0251ffa3, 0x2fd1f2ff,
- 0x5372bfe3, 0x57946dc5, 0x8cd62ab5, 0xc83517f7, 0xa6d7290f, 0x87ba50ff,
- 0xb7a44edf, 0xa0b5a66a, 0x0b69a97e, 0xa1516e7d, 0x084dfe3d, 0x74c9245f,
- 0xe81768da, 0x5bf1bd7e, 0x95a38f15, 0xbb37140a, 0x4e911a0b, 0xcafd87e9,
- 0x7e71b9a7, 0xfba0b3cc, 0x391886ae, 0xee862bef, 0x9f227ee1, 0xf7952eff,
- 0xa3efe40d, 0xc6324f6a, 0xf93a8e71, 0xe602d53d, 0x52dd7ba1, 0x6f654dd6,
- 0x2f01f578, 0x8d1aee4d, 0x7607f87e, 0x1a91c52d, 0x511936d7, 0xb5b166ce,
- 0x031fbc26, 0xfbee7936, 0x1bdb2bdc, 0x9468f7a1, 0xc7e7959f, 0x92bccaf3,
- 0x83a03cf8, 0xf8a38033, 0x57c7cb9c, 0x02207fbd, 0xfefe7ee1, 0xca7ef3fd,
- 0xb9020fd0, 0xd654f305, 0xbdd064b6, 0x67758b8c, 0xabf1fbe4, 0x1fc153e0,
- 0xf08399b4, 0x0eb9670a, 0x0d9f33e0, 0xd36e63e4, 0xc0a9f0b5, 0xf03d4939,
- 0xe8250463, 0xa1439231, 0x5ee05678, 0x3cd56acd, 0xeefb56fe, 0xb3ffe802,
- 0xed19a2b5, 0x7ef0cbca, 0xf578fc0d, 0x28d791fc, 0x257b3f90, 0x5a78297c,
- 0xff54bcc8, 0xfb8f8a30, 0xf144a170, 0x7c69ffc3, 0x4bd9e435, 0xb7c2aef2,
- 0x257a7ca1, 0x2ab45cbe, 0xf8437f84, 0x2d2f8874, 0x7f002ff0, 0xc41155f6,
- 0x1d7e0a8f, 0x5193f066, 0x2d1875ff, 0x3e39766e, 0xfdc5dfd1, 0xec0ab654,
- 0xf087e149, 0xe3fc8fab, 0xad017c50, 0x541f50d8, 0xa9f305e7, 0xc92bc782,
- 0x7dee452d, 0x4d47bcc4, 0x7067dd02, 0x9685fe3e, 0xfb94e9f2, 0xe2dee50c,
- 0x6fae3cd1, 0xc08fcb42, 0xa27bc16e, 0x233d194d, 0xd5ebded1, 0x7bf0f328,
- 0x74d68fd7, 0xcd7cc68f, 0xb2f1a68f, 0x4cf3c357, 0x8c2dba94, 0x4a3f03c7,
- 0x6e10bad0, 0xa6e3091f, 0x91f01da3, 0x783bcbf0, 0xc6634e3d, 0xe9b882fa,
- 0xaaf7a826, 0x83e1f895, 0x5376fcb2, 0x0982d1f9, 0x604fd405, 0x661e1047,
- 0x3ad09581, 0x0c5d1082, 0xe7e8f9fb, 0x5ef07363, 0x03ff3940, 0xf48e3c79,
- 0x431cf91b, 0x095ff6f1, 0x045f6f14, 0xf784c3aa, 0x289fd302, 0x93f6814e,
- 0xa6cd4ebf, 0xc115cafb, 0x4dfea3eb, 0x56e538a6, 0x4b96e79a, 0x99c5ea03,
- 0xe90d7dfe, 0xbc8b82cd, 0xa0d8c97d, 0xf45b667c, 0xbb27ee38, 0x8f512353,
- 0xf06d7a29, 0x60437ed8, 0x1cacf51c, 0x8faa1e77, 0x5029247b, 0xf7b1be2f,
- 0xa79c74e1, 0xb2cae35c, 0xf98f3018, 0x1fb424a9, 0x943ef7ca, 0xdeed764e,
- 0x9fe8e98d, 0x9c3d3794, 0xb87aa36e, 0x1523fc9d, 0x7df9f73f, 0x0a6d7693,
- 0x9d6fa3b0, 0x52fbedc0, 0x68851bdd, 0xf1bacedf, 0xb71875f3, 0x816bfb1f,
- 0x590b70e2, 0xb7d43af7, 0xaf9c1965, 0xe48e8358, 0xf747cc3f, 0xddc67ba4,
- 0xfee51bbe, 0xabbf8cf1, 0xcdfea097, 0x657cd153, 0x0e39bdcc, 0x041b6fe3,
- 0xfbf9bf8a, 0xd77ba68f, 0x4d056bc5, 0x51ea0c7c, 0xc7fd779e, 0xe38228bc,
- 0xbbb21b3d, 0x356cbdb0, 0x75a59f6f, 0x3ce0f6b7, 0xcf28684f, 0x4a65140a,
- 0xf63dc049, 0x3df8f31f, 0x72cda2dd, 0xcebcb1be, 0x8db16dd8, 0xa3fce781,
- 0xfe567f8c, 0x3b83c901, 0xb6dcbc65, 0xf123bdfa, 0xdaa46f30, 0x2b9467fe,
- 0x3a7e3eef, 0x4159e50d, 0xa44cd9f4, 0xfb1ab1f3, 0xee781593, 0x2bc52d26,
- 0x528959ad, 0xb9cff41c, 0x5863da7f, 0xf8bd5a2e, 0xfb8c0ac9, 0x1f91d76e,
- 0x856feca6, 0x5fd11660, 0xd3f8dc3d, 0x676e107b, 0xa479e71e, 0x8faf1a2b,
- 0xe2fe5abb, 0x1f3c75b3, 0x1d3af9fc, 0x99d42f95, 0xb88e1998, 0xea9e2eaf,
- 0x5333afbf, 0xfa73e6c9, 0xaea6f252, 0xa5ee5f34, 0xb65bca30, 0x1e51d06e,
- 0xf6d6ae7d, 0x6bc01e55, 0xa6ce0dec, 0xc6b9f28d, 0x576cf8c2, 0x83840cf2,
- 0x2ef2e375, 0xe54f6134, 0xedeaff71, 0x64490d9e, 0xf53eaf87, 0xcf3c054c,
- 0x0ef92fcc, 0x5e76ebc7, 0xe1c178a4, 0x10ca87f6, 0x5a4de5de, 0xdcf93e7e,
- 0x8f4f1e67, 0xbce3127b, 0x7fc9a96f, 0xea79d9af, 0xde508d99, 0x26b979bb,
- 0xe87fde90, 0xf795bf79, 0xbabe2d73, 0x75fe1c12, 0x89387abe, 0xf809a7f8,
- 0xe7dff32a, 0x6bd59aab, 0xf3737e08, 0xc3e6c64b, 0x5da8cffe, 0x674fc849,
- 0x744cddc6, 0x0814eaee, 0x571c8afe, 0xf3e6a7c6, 0xd12ae8fb, 0x48ec99b3,
- 0x057f8e59, 0xf7c2239e, 0xd2cff68d, 0xaafe8ed1, 0xcf55c16d, 0x3d0eb07d,
- 0xe99b8c22, 0x9e7d0ca8, 0x62a7b1af, 0xc8be715e, 0xe7d0e7ed, 0x712be7b7,
- 0xc5b71e78, 0xa790109f, 0x458d84e2, 0x13fea346, 0x972061bc, 0x9eb76d9d,
- 0x06ffa155, 0xc1c7e17e, 0x38fb2876, 0x695faf40, 0xab2ad7bf, 0x5f951e71,
- 0x50f84eee, 0x3d00de64, 0xc617c93e, 0x0eeb01bc, 0xa6d02bf9, 0x049efba1,
- 0x37880b92, 0x6bea87cc, 0xf584d71f, 0xc78e1ab3, 0x97e083be, 0x930cb8f1,
- 0x3ce7fdf2, 0x0b3e7edb, 0x79e86ce5, 0x4f395fab, 0x7b68e1f4, 0xe740a2e8,
- 0x9556799f, 0xbff3ed75, 0x167cf7b1, 0xdaacefe2, 0x57fe8f97, 0x8597c69f,
- 0x957ea878, 0x157ff3cb, 0xc57b4a0e, 0x138f0d06, 0x23f2260a, 0x140ba50b,
- 0xc63be807, 0xedd500e3, 0x0e9e48bb, 0x4c78f076, 0x145dd88d, 0xda8bf187,
- 0xcf285d53, 0x5fb9e306, 0x28dbf306, 0xd65521cf, 0xa481aa83, 0x1ed72039,
- 0xee07a219, 0xfe419e0f, 0x1e3ce0d5, 0x6561e507, 0x2bb43385, 0x433f21ce,
- 0xe4aad97b, 0x67e748f5, 0x507323dc, 0xf59dbe3e, 0xdf8a6a8f, 0x926e1ebd,
- 0x30958ec8, 0x4e0878c7, 0x4b70e743, 0x2987d13c, 0xb3387176, 0xd1abf405,
- 0xbf24ef98, 0x9fbf38fa, 0xf381b9ab, 0xf3857b13, 0x1bed7393, 0xf980f89a,
- 0x93f3257e, 0x7ace4f62, 0x97c41ffd, 0x9edae70f, 0x470cbe40, 0xc5f38859,
- 0xb51e5247, 0x72871ef2, 0x90e8691f, 0x8962f8fd, 0x49b4d79e, 0x58e5ef0c,
- 0x0af291bc, 0xca16d98a, 0x3cc59cb7, 0x8f5e7953, 0xf029d1ef, 0x52ebf67c,
- 0x81a1e62e, 0xdbf74d3d, 0x34f66145, 0x15ead3cc, 0x1eae1905, 0x7d009ceb,
- 0xf73e7ef6, 0x024aa757, 0x8481b1e9, 0x6653b270, 0xe29677ce, 0x5a7e957e,
- 0x9833eb91, 0xe62cec87, 0x7bc2c81e, 0xc81de655, 0xa556fbc2, 0xc3d7bcdf,
- 0x322f496b, 0xc05e758f, 0x79f3a73a, 0xbc0bf3bc, 0x5279071f, 0x16c3df23,
- 0x436edf4a, 0x27456b7f, 0x15ec7fbf, 0x3cc03f93, 0x19c01733, 0xf01e7af1,
- 0x63fd436a, 0xf21b3667, 0x6e91f8cf, 0x7d9a9fe4, 0xbd7cc302, 0x136d76ea,
- 0xd5aa85c6, 0xe7a458be, 0x6bef6d8d, 0xf06b9e90, 0x8e3c765e, 0xdcbc7267,
- 0x35bf7944, 0xf5efc626, 0x00ffaeda, 0x63ce76e3, 0x553a8b5c, 0x003c51ef,
- 0x57ae36e5, 0xfe42dad5, 0xc97983bf, 0x073477ff, 0x3c60cdd3, 0xf287e78f,
- 0x737ce9c9, 0xdccc7f10, 0x1e63f9ce, 0x681b73e6, 0x675fc538, 0x5d91c7c6,
- 0xf1c71fe2, 0xafce9360, 0x3fa63b43, 0xfc7ca045, 0x5ad730fe, 0xe95c8fb4,
- 0x7fe9aedc, 0xbd2b05ed, 0x5b73a3f7, 0x3cf98c7f, 0x733bddb2, 0x149556c3,
- 0x1d999fb0, 0x1fd8de3c, 0x120fcac6, 0x21d7edde, 0x25b97c3e, 0xbe31f267,
- 0x777819a3, 0x4483c60a, 0x3d0d1f1e, 0x6b8e5d87, 0xfdfc671c, 0xb3df6528,
- 0x3cb91313, 0xa3a26e63, 0x5bbf392e, 0xc651d7c9, 0x504132df, 0x9fb8d1ee,
- 0xfaae5824, 0xd7de1a5e, 0xde2b9e60, 0x3bf960d7, 0xef161f39, 0xa2feb06b,
- 0xf78b0f9c, 0xf78ed835, 0x956f5835, 0xbef161f3, 0x5f78eb06, 0x722be583,
- 0xdc71ec3e, 0x6df1e52a, 0xa2e90a7c, 0x946d790b, 0x1d1bdebf, 0xdc151f52,
- 0x085a37bf, 0xa8128fae, 0xc6c269bf, 0x78ff30a7, 0xc52f9293, 0xc3b446cc,
- 0xfbf9c22a, 0x7b06a91a, 0xf3f404ec, 0x45ed778b, 0x9bf81e7f, 0x882b9fde,
- 0xef4a505e, 0x1968c497, 0x27dba3ca, 0x804f47d8, 0xcd8ec7f1, 0x724adb48,
- 0xecf74f52, 0x31bb3fbd, 0x6f7ae292, 0x25824c49, 0xaee465a7, 0x9a7d42b5,
- 0x85fa2041, 0x512a6ef9, 0x67984cfc, 0xab62c746, 0x1307cb8a, 0x9285cbda,
- 0xb3ae0963, 0x8b9f4122, 0xd588f872, 0x51fb819e, 0x6a345de0, 0x45da1a59,
- 0x07f36a5d, 0xbd759f18, 0x57e866a3, 0xa53c7129, 0x69d693df, 0x99bfb8f9,
- 0x736ba919, 0x36607e70, 0x0d367794, 0xd9fdc66b, 0x9ea170c4, 0x855997e4,
- 0x027f20f2, 0x66e99ba7, 0x357b1f6e, 0xfa345566, 0x62d361f5, 0x4bb75ef0,
- 0x1931f3c6, 0x3c65c7cf, 0x81573de3, 0x6173df8a, 0x585cf789, 0x2da3e686,
- 0x4db12fcf, 0x240f7820, 0xcdb3e605, 0x0097df92, 0xd4f7a10a, 0xf31c729c,
- 0x34ee594b, 0xcadc95e6, 0x9e6879c7, 0x778e392a, 0x6f7c1d5e, 0x8ff38ca8,
- 0xbdce5467, 0x166bcb89, 0xbf79e1a9, 0xe61731d7, 0x397dcf15, 0x7d50e281,
- 0x06a5d16e, 0x5e05cfbc, 0x5ec67947, 0x8b2efee6, 0x77337ce7, 0xabf51c7f,
- 0xcea9e397, 0x7c74eee8, 0xe64fa3af, 0xf07ea52f, 0xe4979e3b, 0x81ba81cc,
- 0xf3a123de, 0xa776e739, 0x4fbd4147, 0x5f488bd0, 0xbcfe26ce, 0x673fe647,
- 0x7c9f3c8a, 0x24f3a61e, 0x3bfa3e21, 0xf7c24e5f, 0xbc193710, 0xf7fcb94b,
- 0x66dc93a6, 0x6fcc74de, 0x4e782f3a, 0xadf1be62, 0x98a5296d, 0xed5e7f6f,
- 0xb3eb0679, 0x5d78d2db, 0x0a693968, 0x93d23e7c, 0xb7c8f984, 0x6296a5b6,
- 0x91f9f23e, 0x5944cf2d, 0x97eaea02, 0xcd73e24e, 0x98a56983, 0xeb5b3c9f,
- 0x7487563e, 0x5f4e7bf3, 0x4e077dfa, 0xdaaa7c23, 0x7d3efdb9, 0x2f0b81df,
- 0x603e7ea1, 0x7582bca4, 0xdf099213, 0x6ecfedf5, 0x6beb7a46, 0x6c3f1351,
- 0x99ff7e6a, 0x2d3f50df, 0x6b665985, 0xc90c563d, 0xba1db494, 0x3b35f71b,
- 0xd625f3dc, 0x89bc4f17, 0x047b31f6, 0x13a5ebe7, 0x4f914a73, 0xfbec0efb,
- 0xd9b3ea05, 0xe2d86091, 0x13d05e7e, 0x8ff72a7e, 0x40b8c02b, 0x0cbbb19f,
- 0x9dfeafe7, 0xec1fe796, 0x718e9b8f, 0xc09cff82, 0x6e2a31f3, 0xfa8492d8,
- 0xf9e57c56, 0xf8c1bfbd, 0x74f4efe6, 0xcd1353df, 0xa94abded, 0xe1397f31,
- 0xcc5ed76f, 0x5e7be95b, 0x15aff74f, 0xe2b39318, 0x2963ac7b, 0x3feaff3e,
- 0x78865eff, 0xee769428, 0x772ff6c5, 0x438445eb, 0x7916c68f, 0x8f61f233,
- 0x0acefc9a, 0x3bd15eb9, 0xdc27ef82, 0x8bf84457, 0xfa8492d9, 0xafc472b6,
- 0xcf7dc0ee, 0x833cb696, 0x567b0f7e, 0x670e774b, 0xc1b8079f, 0xd47bb3b8,
- 0xfb034998, 0x5e90aa30, 0xca5b0bce, 0xf7f9c49e, 0xf5e77ef0, 0xae9e085b,
- 0x5c33d73d, 0xd431fa0f, 0xad85e7c7, 0xf767ed41, 0x7e859b3c, 0xcddfb9e9,
- 0xa154ff26, 0x2a5f8573, 0xf4836b77, 0x58824922, 0x3fca5b8c, 0x02198b93,
- 0x0ee759e2, 0x927be8ee, 0x6b9fc7f9, 0x00357b56, 0x5b2d0aa3, 0x0acdf98b,
- 0xde26543f, 0xabe78c5a, 0xd1d31b14, 0xf5c8a97e, 0x9c5f2195, 0x3c5d33d5,
- 0xd65b7bf4, 0x6bad955b, 0x7c1da0e6, 0x45fcfda5, 0xc95f4796, 0x9b55f87c,
- 0xdf781dde, 0xb5fe5a18, 0xa84f998e, 0xb585f5fc, 0x95e5b25a, 0x78d6def9,
- 0x55afe81c, 0x71f97347, 0x8337fa12, 0xac93fb1c, 0x0aad16ef, 0x04eeffee,
- 0xad594f9e, 0xfea3a5f1, 0x7b7fe653, 0x87db8982, 0xca3a5f2a, 0xb371d0ab,
- 0xbcde5925, 0xa9bc9020, 0xd14e156c, 0xd20824fb, 0x2b3c3f58, 0xe6372e75,
- 0x87870d13, 0x0f197cf8, 0x70f1e612, 0xd66caabe, 0x4f30f4db, 0x022f9855,
- 0xd18725ed, 0x50768117, 0x6b122bdf, 0xa317d192, 0x5fe29fcc, 0x5653894f,
- 0xfd36d478, 0x71c1eb70, 0x865e4fd0, 0x5628037f, 0x537ce44f, 0xeb4e16de,
- 0x1f2f9331, 0x677cb6e9, 0xa73c38f0, 0xfb1f8029, 0x06c576da, 0xf70cebfa,
- 0xa751f74d, 0xfffa6f88, 0x07bd31f9, 0xb5b2295e, 0x4e794f78, 0x4083efe0,
- 0x3907de9d, 0x5677df27, 0x43086d7e, 0x95f739fa, 0x4fb8f883, 0x7b9c91f0,
- 0x7246cdb1, 0x23ed4fac, 0x626bb739, 0xf947af11, 0xbd6e50ca, 0x24a7f138,
- 0x7c12fa3f, 0xd29ef865, 0x2f8ea566, 0xd01d81cc, 0xe490b6d1, 0xe7896cc9,
- 0x6a5db051, 0x71138f13, 0xe1932f78, 0xde86d8c4, 0xd443f23a, 0x3a97b466,
- 0x42f72a27, 0x25f9ff1a, 0x31f53f3f, 0xe456bef3, 0xc50372cf, 0x6abec07d,
- 0xc0ed097e, 0x8c16b105, 0x4dc287a7, 0x898c5fb9, 0xe22966fe, 0x7da31de9,
- 0xbc3cc4ec, 0x9f91f4cf, 0xf64ed401, 0x5a6bf57c, 0xd5fb37f2, 0x7e517b03,
- 0x71f68db9, 0x0e9e0113, 0x547af74d, 0xbed41771, 0x67ed342e, 0x1c91bd21,
- 0x97d6f4e1, 0x07bf8bb9, 0x4e4fdf22, 0xfa00f192, 0x7d22358c, 0x87cf1c08,
- 0x409ff6db, 0x9dd7d379, 0x943a724a, 0x3db6ce9f, 0xe3728116, 0xaeefd043,
- 0x87c07880, 0x7ca59f8b, 0x0798f980, 0x6b3de502, 0xf837cf83, 0x2fc98fed,
- 0xda039b64, 0x821b1e91, 0x4170a1eb, 0xf106f4ba, 0x7df68b81, 0xc01bf23f,
- 0x777a6aa7, 0xa861c235, 0x52ea173e, 0x4850fd40, 0x2b3fa43d, 0xfdc3f6e1,
- 0xebcd1813, 0x25eded18, 0xcf1f7e3f, 0xbd07adef, 0xe103f546, 0xee2d3f74,
- 0xc315bd03, 0x8bea16f5, 0x8a6e88aa, 0xd01df55f, 0x83cabdd2, 0xe1259fed,
- 0x291e81f9, 0xfed5534e, 0xf7fa2c72, 0x699826eb, 0xb18fd07e, 0xa0731794,
- 0x11fd163d, 0x7a21dda5, 0x0cf7e5d2, 0x287e50b2, 0x9bc94eed, 0x42e5794e,
- 0x5f3e1677, 0x8719cb27, 0xeb097508, 0x10e1ce8c, 0x76b3df38, 0x287ce489,
- 0xf4c956de, 0x8b21f20a, 0xe15e39f2, 0x1e4503f1, 0xe572c854, 0x7267b610,
- 0xf72937fe, 0x84cf7852, 0x9c8c3f7c, 0x23815af8, 0xcef8a5ab, 0xbccd13fd,
- 0x79a78f2e, 0xe789fc79, 0x3e7abded, 0xc713252b, 0x45f79599, 0xd528f2fd,
- 0x0e505f2f, 0x781c93c4, 0xe70b1d50, 0xb0467caa, 0x8a90c3d4, 0xd04535d2,
- 0x2d532d9d, 0x1ab8a22f, 0x2e1ae7e6, 0x1d2857df, 0xf8e44e45, 0x1fb914ad,
- 0xa057b95e, 0x6a73a5fb, 0xf2076f7e, 0x580fde86, 0x08a6b056, 0x18beeff9,
- 0x5fd026a7, 0x4bfcd6be, 0xcbeb821b, 0xc514d76a, 0x95e7c30d, 0x8d76b6ab,
- 0x57cf9764, 0x8a2c6f61, 0xaede5f35, 0x5e9cfbec, 0xf574e7d9, 0xcc7840c8,
- 0x1234535f, 0x7fba65ca, 0xdcfc1e17, 0x5eb5dae7, 0x5d2d57ca, 0xb7c4f743,
- 0x8a0daa5c, 0xbe6b5eb3, 0x7ba6e60a, 0x3fed2b90, 0xde0874b4, 0x312b8c5e,
- 0xc43dafe0, 0x0137c067, 0xf4cbc5eb, 0x289f143a, 0xfd063c5f, 0x3c5f6653,
- 0x113e3026, 0x339be25a, 0xb88ae522, 0x2c3e04a8, 0x0f030cb3, 0x89d1ffa5,
- 0x3f1ace3c, 0xa8f1d391, 0x5e3b55d9, 0xe9d71462, 0xa57bf941, 0x22fe4cf7,
- 0xbf07efef, 0x9c233267, 0x9bd4ebf7, 0xdfd3fe30, 0x87c50df9, 0xe619d7fb,
- 0x03077bf3, 0x5de7804b, 0x029be3f1, 0x26abc0e3, 0xdc243b71, 0x9a9dedca,
- 0xe3d5f50c, 0xa1c6994b, 0x1bd912f8, 0xdf74e199, 0x05f6d7d2, 0x8efeb7e9,
- 0x8bde133c, 0x0dbb75f4, 0xff356fc8, 0xa8b17ffc, 0x3e3afb87, 0xbeb4bca5,
- 0x7ca33f6f, 0xde728db5, 0x3936a1e0, 0x6cdbabdf, 0xe2fef6c4, 0xbf6117bf,
- 0x8fe9724d, 0x98f8f02f, 0x83f12a52, 0x3bf9ff00, 0x4c7b53d4, 0x54c51f1b,
- 0x2db0ca99, 0x7fc0bf24, 0xe1bd468e, 0xe3982b8f, 0x04c38b86, 0x54d215c6,
- 0x2580ae3c, 0xd2d215c6, 0xeb015c78, 0x12c05718, 0x8ed80ae3, 0x63ac0571,
- 0x18eb015c, 0xc63ac057, 0xb8c4b015, 0x297fb602, 0x0fd1e7bf, 0x3dc78b82,
- 0x57f7240d, 0xc0337e62, 0xbf27656f, 0x47b95abf, 0x7c617ba2, 0xdff503cf,
- 0xad3b7965, 0x678ede72, 0xd607dd2b, 0x882c901c, 0xc41f7c22, 0x3bf98e95,
- 0x1e314703, 0x5822d354, 0x7db198d6, 0x6363ed3e, 0xa507de47, 0x6d47bed8,
- 0x4f44cd11, 0x828d9f1c, 0xd57c8f5b, 0x57e287b1, 0x949d7105, 0x2cd35fef,
- 0xcebb8c30, 0xd93f72d3, 0x0e6b4129, 0x1d92abdd, 0x9376d4ed, 0x9cf552ff,
- 0xef7c0e60, 0x45e266bb, 0x7dca1392, 0x88fe52f5, 0xf37a3d39, 0x6b3d2092,
- 0xf85779e3, 0x29c7ec27, 0x1d9377e7, 0x2d176012, 0x6c6c7bc5, 0xf7a5be97,
- 0xe0e09c4d, 0x9dae108e, 0xd1d95577, 0xb5f31eb2, 0x55fe687e, 0xdef924e1,
- 0x47bf9b3a, 0x92f8fc52, 0xbd60077d, 0xb25a2dc1, 0x609f6e53, 0x1e526dbf,
- 0x28d819e6, 0x53b472ee, 0x27d67e4f, 0x8a0faf5b, 0xd74a14bb, 0x8563dc51,
- 0x7dfd205a, 0x3b9f6ac4, 0x4672e809, 0x6f14bdf1, 0x246f1199, 0xf0e8563e,
- 0x4fc96b49, 0xe315de70, 0x0a9877f9, 0x34e7ecb5, 0xa5cf9c9f, 0x5eb0a9e0,
- 0x2cf7e370, 0xbd0b3316, 0xc008b03f, 0xe5517187, 0x188b1ffb, 0xe850afcf,
- 0x8156c56a, 0xbcbe8ae8, 0x84bdf010, 0x103df845, 0x6af77fd0, 0x289bfdb9,
- 0xc4f27bf2, 0xe28f3c4d, 0xfca7663e, 0x7d486591, 0xd7d7e912, 0x0f6ed07c,
- 0xdb892ebf, 0x9c38e6f7, 0x3571f17f, 0xc61707e5, 0x276e9edd, 0xf9405f3d,
- 0x6ef78213, 0xaf1bfbe9, 0xf3833f26, 0xb9aa8e27, 0x927801dc, 0xf485d59f,
- 0x3b1ef14a, 0xcaebc795, 0xbf229ca9, 0x5efa161f, 0xcbe77f43, 0xb0be382d,
- 0xf84160c6, 0xc03df15f, 0xffbfabb0, 0xebf394e6, 0x5c9ec512, 0x6be3c233,
- 0x51e10583, 0xef49d718, 0xf3caa589, 0xb25b9c3f, 0x8b69f109, 0x1f5c2e60,
- 0x00b669ef, 0x40f08b7c, 0x3dd1c602, 0x66cf7c36, 0x513053a0, 0x7265f53e,
- 0xcc3aeb74, 0x1349a953, 0x2daf184c, 0x1852db0a, 0xa517f30b, 0x7677d324,
- 0x1c78da6a, 0x4e4a0fb6, 0x92dc5307, 0x62aac7c0, 0xf1cf7e31, 0x3fb5cbe8,
- 0xdfcf293d, 0xb3e65b3e, 0x782f8efe, 0xe3b5f11e, 0xfbe9bbb4, 0xef4f4c1c,
- 0xf60fd3af, 0xd1c6fb35, 0xe855af14, 0xae39b068, 0x45a8e909, 0xa5a513d6,
- 0x8ed1a9ef, 0x37b3cc68, 0x96ca1c23, 0x4b175c5c, 0x4e3e1ce7, 0x87dfe4a6,
- 0xe502c9c6, 0xde46ffed, 0x5aba89fd, 0x5baddf2a, 0x9d776545, 0xe8079e8b,
- 0xbf08238b, 0x7d6f101f, 0xf130d27b, 0x4733a656, 0xbe05be92, 0x90edf1e7,
- 0xbbf02af8, 0x33efc018, 0xd9eea23a, 0x8348f680, 0xcdf782c6, 0xd2bcff98,
- 0xfde1f240, 0x59c6c349, 0x2819f815, 0xf4c83b2e, 0xe9878839, 0x112aa919,
- 0x926dff9e, 0x44e71410, 0x2273c1be, 0x7c8960df, 0xf9f952a3, 0xa30d69e6,
- 0x7da194ef, 0x40fb22e0, 0xbf5df84f, 0xd40ae406, 0x20a665ef, 0x442172b9,
- 0xf32380ae, 0xac5f7a33, 0x0936cb43, 0xe9cffcfe, 0x19ca5c50, 0xb878ce46,
- 0xe61d199c, 0xb3be9e79, 0xf9461d50, 0x44efc0c5, 0xf2374767, 0xac25bdbc,
- 0x461dd684, 0x3e7bd0de, 0x38188ef7, 0xbff414f9, 0xd90361f7, 0x9613eb39,
- 0xe477ffe6, 0x71279fcd, 0xdf813c78, 0xed5d5073, 0x059b0e7b, 0xb15d8fbc,
- 0xbe236590, 0xc439ef95, 0x7bf218c1, 0x39eff5ff, 0x123c988c, 0x0ae0e7bf,
- 0xdc439efa, 0x30e7be15, 0x6171b26a, 0x461cf7e0, 0x30b11e4d, 0xc60e7bf8,
- 0xb29df885, 0x39efc1ff, 0xbbce4fa4, 0x370e7bfc, 0xa0ff364e, 0x3d8039ef,
- 0x4fe3899b, 0x63c6d8e4, 0x3b9f2899, 0xe3e5fdf4, 0x97643df2, 0xb2c52f68,
- 0xa2a5c228, 0xc56dd176, 0x73d16df2, 0x5f03b63f, 0x1578444c, 0x037d963d,
- 0x5125977e, 0xf2bca1eb, 0x49b6ad27, 0xb96bff38, 0x3cf8c9b6, 0x2f5fde34,
- 0x73f60f9f, 0xcd0bf60b, 0xe2e8531f, 0x0e5cc9ae, 0xa9cb93cd, 0xc7bfc3f5,
- 0xbf326f3f, 0xbed6be4f, 0xe077bf61, 0xd9feca7a, 0xdc56c596, 0x4ef7ec0f,
- 0xb7ec27dc, 0x88664b04, 0xf80f7a0e, 0xc9757a72, 0x2e7462fb, 0x3fb38f90,
- 0x9528f6e1, 0x14772ae9, 0x1ea30dda, 0x7ee14770, 0xe80e3547, 0xdf907df1,
- 0x68f406ba, 0xf576fc3f, 0x7fdb1e80, 0xdaf9e36b, 0x9f6ff3a1, 0xf491fdcc,
- 0x7e3403a9, 0x4dddfc0c, 0x1440c1fe, 0xe5e96dda, 0x14ae3447, 0xf66d4f7a,
- 0x93764127, 0x8c7bf899, 0x01e636dc, 0x8c3d2191, 0x1e78c1d9, 0xe90c4163,
- 0xef1d4ab9, 0xfdc0f95a, 0x38d1d222, 0x803bec37, 0xaedfaefe, 0xaf7e0c1a,
- 0xaae34bd7, 0x5ec025e4, 0x64ee7a0b, 0x9474bf3c, 0x5ed08f2c, 0x39d9efc4,
- 0x77d08fcb, 0x0b8ec0a6, 0x79be8f99, 0x594f9430, 0xe6bfb3ad, 0x62be5333,
- 0x77a5bf50, 0xfa3d66ff, 0x5ba5e5b5, 0x2f17e435, 0xa58f5969, 0x269ef1c3,
- 0x197d918e, 0xcbec1fd4, 0xfb65faa0, 0xf547d90c, 0xc7d717fd, 0xd02eb30d,
- 0x13a456c1, 0xaa8e0e85, 0x4fd0e33d, 0xb30cea3d, 0x3c1df7f0, 0x269a5df4,
- 0x5df4bdf9, 0xcadd39ff, 0x5d3965f3, 0x3f1df8c0, 0xa9ea8e8c, 0xaf1df2bf,
- 0x1c8a956b, 0x8dcefa1c, 0x5e28b986, 0x7248cb39, 0xfff646ae, 0xc89897aa,
- 0xbaf8511e, 0xb539e55a, 0x18c5fb1e, 0x8a9bfe79, 0x7aabf7d1, 0xcf9451c4,
- 0xcfac3f4d, 0xacfba54a, 0x178f7ad8, 0x5db81de7, 0x15b9efa0, 0x5ab97384,
- 0x9e389628, 0x4447e785, 0xa7815dfe, 0x98487e51, 0x37bfc147, 0xbf972530,
- 0xf8cf103f, 0xca98db77, 0x369df21c, 0xed7a1e39, 0xeff1b4ef, 0xf7e7cd92,
- 0x25510d72, 0xf9f1cba5, 0xf9e81b82, 0x1f52efc1, 0x2afee2b1, 0x71b4ef94,
- 0x4e61bf7b, 0x557f3d06, 0x3d41af30, 0x5d807ae1, 0x7a6d3be9, 0xef80fbe4,
- 0xf887bdb3, 0xd9f7d6ba, 0x1c0fef94, 0x23c3705d, 0xbd1c397b, 0x3355ef78,
- 0xafe418cb, 0x3c3117ff, 0x56c0d29e, 0x000056c0
-};
-
-static const u32 tsem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x3370278a, 0x45e39c30,
- 0x8381e9f0, 0x5fd32918, 0x50c0cec6, 0x4055c401, 0x3f880bbc, 0x7c3032b1,
- 0xff5e2566, 0xdb042935, 0x21818248, 0x88d7881e, 0x49a83031, 0xa41dc422,
- 0x03261819, 0xb150a1f9, 0x5f3a4047, 0x0f77328a, 0x80a69c16, 0x872ae629,
- 0x9163a760, 0x6819c647, 0x50e54bf2, 0xf40499f9, 0xa2be340f, 0xa2ffca8e,
- 0xa013a10a, 0xe4d157e2, 0x3be542bf, 0xa6bafea0, 0x4edcdd8e, 0xc35dfd32,
- 0xfc01a102, 0x9847b099, 0x009847b0
-};
-
-static const u32 tsem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0x7993331e,
- 0x31e424e4, 0x1e4e1081, 0x03086820, 0xb78a8884, 0xf6301027, 0xd57876d2,
- 0xaf0e2d58, 0x6b86f210, 0x7fb6bd2d, 0x78490806, 0x111fc1a8, 0x29e1d5ad,
- 0x311d82f6, 0x0388b622, 0xbdabd228, 0x557c5837, 0x0bd11feb, 0x2a44908a,
- 0xe5b5ef6a, 0x3ef6b5ee, 0x09939cc9, 0xafdb7b04, 0x7cfdffff, 0xc7ecee9f,
- 0xf5ed7bd9, 0xfdad6bda, 0x8131c918, 0xe4230da4, 0x06fbfc22, 0x109d9221,
- 0x9d37a132, 0xd72120e3, 0x66924218, 0x92ddfd2f, 0xbadc4214, 0xa349bfe2,
- 0xe4febba9, 0x5f5f9a1a, 0xa4aff0ec, 0x4d1f5b4d, 0x2d096a78, 0x2fa1efbf,
- 0x7cd04fc3, 0xad79ecfa, 0xce7eb4c5, 0x5d0fc924, 0x10ab1a1d, 0xd8e7ed02,
- 0x520176c2, 0x9097e581, 0x927fa130, 0x45f8e8af, 0x9fe8b884, 0x37fe9724,
- 0xa5b21c89, 0xd1e43e60, 0x99029ea0, 0x31364846, 0x7e6055fe, 0xf509fc36,
- 0xd0677744, 0x779e75ef, 0x7fec13e5, 0xdb0a5f8e, 0xf27347e9, 0x4dc87203,
- 0x6d08c6d3, 0xfb1dc749, 0xf908395d, 0xe4990cc0, 0xd8b68763, 0x0fca6ffe,
- 0xd214754c, 0x080b67fe, 0x49d9f9ff, 0xcc82da36, 0x3be1eda6, 0x1a1f4e22,
- 0xd99f67cc, 0xe0dfb8e8, 0x40dfdddf, 0x5fc0a7ff, 0xe5a1094b, 0x9e0c1ccb,
- 0xc5d9d9e4, 0x1989ce30, 0xbf4316d7, 0x3213a673, 0x9d4d5688, 0x4490f63d,
- 0x891aebf3, 0xcddb4edf, 0xcf1c0d29, 0xcbf8d981, 0xe80293a7, 0x60ee8e97,
- 0xffc45f7d, 0x64ef38eb, 0xcc3fde3e, 0xfa102b1e, 0x8a97f641, 0xa0725da9,
- 0x4bd153f9, 0x2d056a48, 0xee53191f, 0xd09a769f, 0xe6e9e4f2, 0x721340f6,
- 0xc425211d, 0x1aea7293, 0xc91677fa, 0xad4228ba, 0xee8c0b6a, 0x4a6b0fe5,
- 0x22f9fdff, 0x12fa01d0, 0x6a1fd6fb, 0xa0e9e99c, 0x7b375af8, 0xf4d08796,
- 0x0f2cc0f5, 0xd9f5efe0, 0xd68f10b3, 0x676673f6, 0xfb5e0227, 0x06feef1b,
- 0xfa08d03a, 0xb5b3c73d, 0xea48907e, 0x39fbf423, 0x31c3d13a, 0x9301dffd,
- 0x0964254d, 0xb34d1b30, 0xd2a6d525, 0xe88d6cfa, 0x95e33891, 0x3b69b102,
- 0x28994992, 0x0ff352e3, 0x2637bb61, 0x71c34ad9, 0xef0773e6, 0xb81a55c7,
- 0x6fa50e67, 0x751274d6, 0x2912ba51, 0x75e2c6aa, 0x1a548a5d, 0xddc7038e,
- 0x68425e1c, 0xe1c0cf7b, 0x02d86571, 0x47329fd0, 0xf5c2c40c, 0x42678003,
- 0x4ca24a6f, 0x18f8e6ee, 0xfbbf72fd, 0x338f506c, 0x8e00bb8f, 0xecaa9009,
- 0x0c8f0e3b, 0xb201937c, 0x43fc8296, 0xe02463c2, 0xb91eccfb, 0xe5070124,
- 0x17f0a18f, 0xa42dae15, 0x1412d47b, 0x47ec56b2, 0x0324a4f4, 0xde1157bd,
- 0x4f51290f, 0x42157e51, 0xd78b84ab, 0x129e6a5c, 0x35f06539, 0x193ba9f0,
- 0x5e1cbfc7, 0xe518a048, 0x88d43152, 0xe307c078, 0xed4df92b, 0xbacba502,
- 0x947ee5d1, 0x90218a6f, 0xe17e4333, 0x3bf457df, 0xbdccff37, 0xca91d29c,
- 0xd3396b91, 0x2cdf8a8f, 0x8e92eb67, 0xc82008b5, 0x0f49b964, 0x40241210,
- 0xeb6f0377, 0xbc78a2be, 0xfb5bbf04, 0xe7c86fdd, 0xc9983260, 0x053f9327,
- 0x79bd07fa, 0xf0077ed3, 0x5edf3af5, 0x5d6bcc07, 0x7a825efe, 0xe8c7d38a,
- 0x5daf95d7, 0x81d6ce52, 0xee808d7c, 0x9ea748c3, 0xc6a7d1f2, 0xa6767e02,
- 0x748bf72a, 0x08933b7e, 0x6b75d9ea, 0xd02b7848, 0xb5e594b5, 0xb5e1696f,
- 0x9d3b8e74, 0xd698bebc, 0xed06bcd3, 0x3adbbea9, 0x68870b49, 0x8d8b6b7e,
- 0x85ab1fb5, 0x311f9a45, 0x8a148491, 0xc2c56d4f, 0xbe5a4e95, 0x17eaa375,
- 0x34fd5eb5, 0x2d6725a2, 0xdeb2dfb4, 0xbdf00aa6, 0x3b23ad8f, 0x443849f3,
- 0x39b1dfc7, 0x69239bf9, 0xf9b2143e, 0xf24fd387, 0xd945faf8, 0x022844a5,
- 0x9c3a31b4, 0xae5c7921, 0xa9e50204, 0x7ecb7cbc, 0xa48ebfff, 0x5d363df0,
- 0x45a0aff2, 0x4ccfd63b, 0x769e28d0, 0x3f048168, 0xc0f07f4d, 0xccefcc7c,
- 0xdd00260c, 0x9f9c6e76, 0xc0f14c00, 0x461b99e6, 0xd2617b41, 0x6ce91d61,
- 0x1f47ffd6, 0x00ec3a28, 0x9e994b38, 0x7e0d6a4f, 0xbcf9a253, 0x89b91249,
- 0xadcf214e, 0x1fdbdc21, 0x4f5811b2, 0x8b6de8fb, 0xcdd44ebe, 0xb4eb5779,
- 0x5d7f818f, 0x2009160f, 0x86353bda, 0x923741e7, 0xbeec8af0, 0xc85cefe3,
- 0x5d2913ea, 0xbf2e0e80, 0x96675962, 0x4756f85a, 0x3c717079, 0x1c755ab9,
- 0x897a488f, 0x578bd690, 0x62469ffa, 0xf07ae9f0, 0xe9f58128, 0x8163e78a,
- 0x7ca05d27, 0x9cab830f, 0x1c1eb9ef, 0x6357caf7, 0x21b1f1e3, 0x7fa01eef,
- 0x6177c522, 0x50eb0424, 0x0a24617a, 0x57c9e2fc, 0x9a0bb034, 0xc5c93109,
- 0x7cfbd1a1, 0x1337201d, 0xaf583e22, 0x837e8dd7, 0x81568fc9, 0x6fe630f8,
- 0xb7e4f7b4, 0xc1fb5893, 0xf87287a8, 0x697853ce, 0xcb87bb39, 0x847f4f59,
- 0x732447ad, 0x4f75c21c, 0x5e7561e1, 0xc84c7d1c, 0x97cb940a, 0x817ae049,
- 0xedcddea6, 0x6c06a751, 0x7900dfae, 0x910240b7, 0x134ddf38, 0x42d27ad8,
- 0xe9a05d74, 0x162f44a3, 0x664b9d70, 0x2eb2d7fa, 0xbc9fd1f5, 0x16e9165d,
- 0xd468df40, 0x8734803e, 0x23cd31f8, 0x92474c01, 0x26af4c56, 0x49f34c11,
- 0xa405a63b, 0xaf43531b, 0x422a89f8, 0xfac4c47e, 0xa4e720c9, 0xe58b63da,
- 0x3264d0bb, 0x3cce3eb2, 0x73782d9a, 0xf8ebf890, 0xe75f021d, 0xfc8aa648,
- 0xf17af843, 0xe818b06e, 0xfc2854c5, 0xefccdbbb, 0x0ebe24e2, 0x693dea38,
- 0xdd335780, 0xcd54548d, 0xf06d5a7c, 0x1c2444a9, 0xc41f32c7, 0xd6b8cc63,
- 0xfb7356fe, 0x9c9f98c6, 0x491f23a2, 0x50cf666e, 0x71bdf438, 0x0828d1f0,
- 0xab419e7c, 0x29b23adc, 0xb6494bbf, 0x6b9a5ac8, 0xe8764f74, 0x893f2f38,
- 0x7ceb6747, 0xbe2af0ac, 0xa9b3c181, 0xcb0a9e07, 0xc297fa3a, 0xfea64ff3,
- 0x1db24ca4, 0x86a20bd6, 0xbc56de70, 0x42def9f6, 0xd2e4fe8f, 0x57d66991,
- 0x02d78a4a, 0x069f8587, 0xe37c7f68, 0xe47fea4b, 0x211bfac3, 0xa9ec2a41,
- 0xe60101f9, 0x1a40ad7f, 0xc85e2913, 0xa0eda268, 0x6af5cd70, 0x698b8ecc,
- 0x91f41937, 0x74c90b66, 0xee92cfbe, 0xe43ed023, 0xf41d9127, 0x6df367b3,
- 0x7d695ba5, 0x63b69faa, 0x1e4005fd, 0x0b6d1dae, 0x9fd1b940, 0xf5329e4e,
- 0x112efd47, 0xe836e1f0, 0xe4c3f163, 0x1fb436b1, 0x6fa27c95, 0xc75f2389,
- 0x1d157cb9, 0x9eb0ea71, 0xb094cab8, 0x8ffa1b33, 0xb53e4314, 0x5d61f89a,
- 0xe6cdd49f, 0x30e1c651, 0x59fa9de6, 0x6a7e0040, 0xc03b31f7, 0x3fd04855,
- 0x74da3254, 0xb4dd1ff0, 0x7e42f50e, 0x50531754, 0xd83fa23f, 0x5f3d9e1f,
- 0xd00bed3d, 0xb9d47d7e, 0x92be076a, 0x9fa0e9fc, 0xc8568f57, 0xf8bdfa60,
- 0xfff63b3b, 0x1862a7b9, 0x47cf9989, 0x0bb1d10d, 0xa670c1a9, 0x67a618e1,
- 0xed31da1b, 0xd30b786c, 0x594ae9fe, 0xebceda8e, 0xc0d7e27e, 0x3f0f101e,
- 0xc00f3447, 0x5c75d51d, 0x12a21c17, 0x82802eb3, 0xd36fff06, 0xdaf0bcd8,
- 0x086bc46c, 0x67d54de6, 0xe0367878, 0x9e000a5b, 0xc2223887, 0x77867cd2,
- 0x01d03fc0, 0x3c8e8bca, 0x5cf102b7, 0x9e02c64d, 0x0ca4c937, 0x13e03cf4,
- 0x827d89d6, 0x03800eed, 0xfe69f3f2, 0xc1fa8ffa, 0xf78659fb, 0x9e29978c,
- 0x4b494e00, 0x8eadc664, 0x913b95f2, 0x27d7120b, 0xf9927abd, 0xbdf6bdd9,
- 0xcf00eff6, 0xac894696, 0x68a6bc85, 0xf7b7114a, 0x15824a41, 0xdcdfc1d3,
- 0x28fd3e56, 0xe2b90bd8, 0x5a648757, 0x3a5eb43e, 0x4f2311d9, 0xfd746559,
- 0xb0c276a4, 0xecf2e6e5, 0x074f3990, 0xb7347f40, 0xc43e5cc5, 0x87aef5c6,
- 0xad1e4078, 0xe8b65af3, 0xd3fd7157, 0xea240d55, 0x02f26396, 0x1791a7c3,
- 0x423b13bc, 0x46cb7e74, 0x4c038c11, 0xb3f5b1b7, 0x7ca3be15, 0xd74f2f71,
- 0x5231fa5b, 0x46dba269, 0x193d30c6, 0xddba7d6f, 0x46ce3c56, 0x4db06bfb,
- 0x72a3671e, 0x042292e4, 0x5b9777ec, 0x93f9e3d1, 0x8e126dd3, 0xebb5209f,
- 0xfbab8522, 0x4adfe23a, 0xee4cbef1, 0x2c7c828e, 0x21fcd62b, 0x30fe4750,
- 0xd51263ca, 0x15f66261, 0x700253c1, 0x6c4a7850, 0xfb044e38, 0x0738a6e9,
- 0xcc997dfb, 0x4a365dfa, 0xf6376823, 0x3655e703, 0xd80ce119, 0x34fd0904,
- 0x1555974e, 0xa34df739, 0x9f554ed9, 0x2667fd05, 0x78c16705, 0x7e6fb946,
- 0x1963fa29, 0x2bf4ccc3, 0x0167d477, 0x2206547f, 0x4e7f80d3, 0x926c5f7b,
- 0x36b7bce9, 0xf144bf10, 0x702b9eff, 0x7357f41b, 0xb008fd7b, 0x5e06df7f,
- 0x3b2a0098, 0xa5ac7a80, 0xa25fa564, 0x148972e5, 0xca3f2995, 0x25bf0f13,
- 0x2a1a4017, 0x938b3886, 0x477d33d4, 0x35224bf5, 0xf5231cbd, 0xa27e218f,
- 0x72d03c80, 0x60256f55, 0xdba8380f, 0xef863270, 0x1e734c94, 0x7cd8fa6c,
- 0x72e37a7f, 0x27e79829, 0x09fe0387, 0x49dde9da, 0x26927fcc, 0xde000bfa,
- 0xa6ffaf7b, 0xc4fcf006, 0x67f93366, 0x5a4d7f56, 0x79696ffe, 0xfee26810,
- 0xd5fcb4b6, 0x80f1bcb4, 0x979c5697, 0x9432ca63, 0x24f0050b, 0xbf07f932,
- 0xe41d67be, 0xcf5bf878, 0x572f58db, 0xf835bc37, 0xa720e1c3, 0xa43f831d,
- 0x052d59c4, 0x3e42ff91, 0x1c28b5f0, 0x098f9992, 0x62134f78, 0x18176e52,
- 0x5a9c9bf6, 0xdc947488, 0x988ea9d2, 0x8fc0ddf5, 0xc1ddfcb2, 0xf4878e1f,
- 0x78ad4c6d, 0x0120a455, 0xd768d03f, 0xe018b713, 0xe234effa, 0x1fc479a9,
- 0xa47338a5, 0x7a6a78b0, 0xf30a285e, 0x09fd5272, 0x233dd3eb, 0xf0c56b5f,
- 0x3b0fc581, 0x3f20ad94, 0x61b68cb4, 0x7865b35c, 0xf90290e4, 0xd1406a0c,
- 0x5dca677a, 0x4c6d8821, 0xe37c63cd, 0xd4f5b3f4, 0x7e8c3c35, 0xbdbfa198,
- 0xad5e1f1c, 0x67b3f51c, 0x31ded9a2, 0x2b2701d6, 0xdb36f4a2, 0xa694ce51,
- 0xbe82c54f, 0x9b539a7e, 0x69e51a76, 0x233fb9a4, 0xe36ed1de, 0xc96b8bf1,
- 0x593768b5, 0xe1fd12e2, 0x71f86bcd, 0xdcbcd913, 0xfc1849d3, 0x5189f4e6,
- 0xcfd79bc4, 0x9bd866f0, 0x9bbf3e1e, 0xfc04234a, 0xf3f89ebe, 0xeb6f0ccd,
- 0x7fa28baf, 0x29ec7eb7, 0x85bd67b4, 0xce3f261d, 0xa1ca1ef8, 0x76c4fcfe,
- 0x18f6a1a8, 0x23711bcb, 0x19e9a78a, 0x61ebbd69, 0xaddbb72b, 0x92275374,
- 0x4763d062, 0x8315a747, 0x84b7bede, 0x3cab4ec2, 0x6297587a, 0x7ef2adf0,
- 0xdf867cd4, 0x7cd8cb7b, 0xd3f47b69, 0x93989def, 0xf266e304, 0x7f11b0f8,
- 0xebcbf1ee, 0x284f78cd, 0x2d85c4b4, 0x67eab77e, 0xcc4b52f4, 0x5f39abe5,
- 0x57a7222b, 0xe8ce192a, 0x4f3e3035, 0x84bcf832, 0xdf3279f1, 0xd12f4837,
- 0x921d010e, 0x4dff994a, 0x4df37e2c, 0x5e8c1d29, 0x00c88f37, 0xa9fefc3f,
- 0x97663edd, 0x7126ba30, 0xc6efbc7e, 0x71c80211, 0x40268972, 0xc33e727d,
- 0x13c53253, 0xa5c977ac, 0x4ef6efcc, 0x525db0d4, 0x0b5ba309, 0x5fe14c7c,
- 0x898a7403, 0x5b4b3b1f, 0x6b7fa075, 0x741d4ef1, 0xe1c53259, 0xd4cf0a20,
- 0xd81b0a52, 0x805fb49d, 0xc51853d7, 0x49525ab8, 0xfca5d870, 0x82a2427a,
- 0x10f887cd, 0xe94b686c, 0x7e58253c, 0x20b26268, 0xa7ef7ed0, 0x80f1c07c,
- 0x8f173c71, 0x785fdfa3, 0xfddcf512, 0xc8364df0, 0x1cebf6a9, 0x36a5279a,
- 0xf707f83f, 0xf108e697, 0xbcc6e7e2, 0x2acb83fb, 0x35f812c7, 0x9572fc31,
- 0x16dee3c8, 0x22475dfe, 0x57c82e6a, 0xa5f76f48, 0x830feaf5, 0x65e47aff,
- 0xfecbe312, 0x87a189f4, 0xb21824dd, 0x1fd5f765, 0xdef8ce92, 0x7940179e,
- 0x24ef03eb, 0x8a52afc6, 0x9136fcb9, 0x5e867fdb, 0x140792d1, 0x00a12727,
- 0xd72277ae, 0x02da4f4f, 0xf054c50b, 0x4eb8c3bb, 0xae74c8b8, 0xca9f1937,
- 0xe6a6ff9c, 0x4ae2bd33, 0x9776b089, 0x903aa78d, 0xa834d6df, 0xc65a1fa8,
- 0x439ed5de, 0x7866b0f1, 0x73be1f93, 0xb9196b8c, 0x3cdbf68d, 0x2b70797c,
- 0x30fdc00c, 0xac22bfd4, 0x8d5f8c83, 0x0e03307d, 0x61d21992, 0x7e09cc9f,
- 0x2467e011, 0x24905fdb, 0xeb8fb512, 0x4795df1d, 0x6967cde1, 0x0dc19f28,
- 0xb6ebc9fe, 0x6f9c2ae0, 0xa2946b7e, 0xc99bce9b, 0x42216acb, 0xebcc225c,
- 0xb21e7c72, 0x9f8ebe31, 0x025df7f6, 0xe1c4d3ec, 0xdb22dddf, 0x472d59a7,
- 0x7e085088, 0xf289ed1b, 0x6a6ceac9, 0xa381c797, 0xd56bf391, 0xc3f8672e,
- 0x89ab7e18, 0x75f29924, 0x1fc233fb, 0x7711fac6, 0x514fb80a, 0x4358d1cd,
- 0xcf00b23a, 0xf61a29ef, 0x48eb6b57, 0xe9177c83, 0x78025b4e, 0x8b8f0310,
- 0x5277fd74, 0x90b8c4be, 0xd6eb607b, 0x81a7f0e5, 0x4085d10c, 0x0fa9e4cb,
- 0x178e9879, 0x69e307dc, 0xd2bf2b2a, 0xf5f0e371, 0x4d7cb10b, 0x6a5957c4,
- 0x147f6be5, 0x129ddaf9, 0x9fb77ac5, 0x8fc1b5f1, 0xad1f9c89, 0xbf8c687c,
- 0xd6afc79e, 0x335f3e72, 0x708549a1, 0x9b51dadf, 0x2ce69e30, 0x7c015cda,
- 0x25aa32de, 0x64de7c0c, 0x17df35f0, 0xdb2efea1, 0xa35ad31f, 0x72264eb0,
- 0xeed456be, 0xeb7b9006, 0x38935d7c, 0xbe0534bc, 0x5f39b806, 0x93f807bf,
- 0xae08ddfd, 0x076bd7c1, 0x45bad7cc, 0xfed39b6f, 0xc2d927fc, 0xf1891ed7,
- 0xd7c067e7, 0xb30a4f00, 0x963edc63, 0xdfea7eca, 0x06e7e9c7, 0x6b99f989,
- 0xe5ac1cb9, 0x1fb6b072, 0x223ff839, 0x9afe03f3, 0xc98b3072, 0xe5a24381,
- 0x8cae9389, 0xd3b0251f, 0x9e7bc8e3, 0xe1b5fc24, 0xbc4334de, 0x27fe3c72,
- 0xbe84cd30, 0xcfd234f4, 0xe4c0e744, 0x73c98f3b, 0x76be727f, 0xfe387c68,
- 0xa7f46453, 0x26922ef8, 0xffbe395c, 0x7215705a, 0x43f0367e, 0xb728c582,
- 0x3a667a31, 0x86a92bc0, 0xd304799e, 0x28ad79a9, 0x81be86a7, 0x2bfa0a58,
- 0x3bc62b6a, 0x68ad999c, 0x98f3399f, 0x24fc31be, 0xb88d7ceb, 0x33d71378,
- 0x02217949, 0x853d9feb, 0x9eaa3f70, 0xcc9951f9, 0xd5e2301f, 0x18a8fd86,
- 0xbbd0d47e, 0x79a79f70, 0x97da3d78, 0x3bd637cd, 0x36c3ede2, 0xf077eefb,
- 0x3ed35f4d, 0x0e5a1aeb, 0xbbc9aefd, 0xc3b3c49f, 0xfb18798c, 0x6e3e4e46,
- 0xa8b51e73, 0x32df5c60, 0xc76adefc, 0xfeb26734, 0x7ae7be7a, 0xbbd1ee57,
- 0x54768f2c, 0x6f9f8c6e, 0x03e0c7e9, 0xa343e885, 0xe4183710, 0x4ce7091e,
- 0x3f04849a, 0x924dc7d8, 0x90729d20, 0x5aa97b1e, 0xff401689, 0x9cbc6627,
- 0x3db2f685, 0xbce406b8, 0x0380abe9, 0x53aba9e2, 0x96c6f35e, 0xe6f19d9f,
- 0xa56cc1b7, 0x7ee2d5df, 0xb148838e, 0xdc2763fb, 0x4b7ed1db, 0xe9c737c8,
- 0x09ae149c, 0xcc13c402, 0xbf8f0ae5, 0x72e69928, 0xa45fc799, 0xe7394b14,
- 0xbe34b90f, 0xeb93795e, 0x7602df15, 0x1cc4e74e, 0x713bd716, 0x30674f2b,
- 0xdbc73efe, 0xc234f375, 0x535feef5, 0xf6e5251f, 0xe29befc2, 0x9922f8c7,
- 0x3ebb4765, 0x2b9d852b, 0x26e7b120, 0xa26b5fe0, 0xccfc6244, 0xff9781a1,
- 0x61d4f108, 0x06cabe0b, 0xea156b3c, 0xdb465861, 0xc79c6ca5, 0x28f74263,
- 0x3ae6cf18, 0x02f5fb8b, 0x6a72e345, 0xdbf40b12, 0xef8521db, 0x3a52c0bd,
- 0x91057b8f, 0x37c0ecbf, 0x8c29d022, 0xb1448ba9, 0x303a43de, 0xe61b089f,
- 0x5187e0b9, 0x33c44bbf, 0xc61b614c, 0xf6cc7e8d, 0x7888d643, 0x03a8836e,
- 0xedc9bfb4, 0x4297f82a, 0x1ae77e88, 0x40be77f8, 0xc4c8316b, 0xc608b2e0,
- 0x7cedad93, 0xa039d853, 0xaffb7a3e, 0x5237df4f, 0x548f8173, 0x1ce8372c,
- 0x694ef514, 0x5ff2df42, 0x12f38189, 0xdc58abc6, 0x2a5f5acd, 0xde4017e9,
- 0x0bc2e5ac, 0x7e053a7f, 0x6467aaf4, 0x3ca7a3f4, 0x41bf4723, 0x045b35f3,
- 0x076d53f4, 0x770fe89d, 0x51f2c23e, 0xfb43a28f, 0x8c05db73, 0xdbd9d507,
- 0xe201bdef, 0x0488cf8a, 0x19708dfd, 0xe29d8bee, 0x59fb2673, 0x80079cbe,
- 0x9a1cb66a, 0xec57df0b, 0x77d813b7, 0xf16e79a8, 0xf9a06fb7, 0xf464c7c5,
- 0xac766a51, 0x657f6050, 0x40885849, 0xc1326bbe, 0xc4fb43f1, 0xbeda0ef0,
- 0x369edbcb, 0x2bfb0dc7, 0x455da20e, 0xa7b4f6e1, 0xa9f4a6cd, 0x0d353f0c,
- 0x2ddcabbe, 0x98ffc1f8, 0xa38eccf2, 0x9abbf419, 0xa73c0427, 0x45cbb550,
- 0x9cba18b4, 0xdfa3136a, 0x9d33f880, 0x8bc5f827, 0xc034eb49, 0x0d8ecd7b,
- 0xb713168a, 0x9230d33c, 0x7cdef668, 0x1c7413cd, 0x93ed5dfa, 0x58a61f82,
- 0xe041236b, 0x9ce7ce8f, 0x30dcdb65, 0x08ca15bf, 0x59abcc0f, 0xc38b7681,
- 0x7ec1f6f3, 0x8b78657a, 0x57d68d32, 0x2945b23e, 0xaaa7e18f, 0x2d10d75d,
- 0x6d4e3f86, 0xd4bf4dce, 0xae867b7a, 0x54f0b15b, 0x88b7a612, 0xc4665614,
- 0xc8767bec, 0x453f9c49, 0xdf06ff53, 0x18275e87, 0xef3d0ac7, 0x741abc41,
- 0xbd32a65b, 0xbcedd060, 0x7528e9ca, 0xb388cd17, 0xd02f7aaf, 0x2af10ec1,
- 0x1bfbd315, 0x6c6e987c, 0x9b3e90d0, 0xe1577f00, 0x7b9606be, 0x88629127,
- 0xa275788b, 0x3c9f52c2, 0x21962f5d, 0xf960124e, 0x8283dbb4, 0x1bf98976,
- 0x383926e9, 0xb75c820f, 0x964c4fc9, 0x49bebae8, 0x7e252e09, 0x77b4be3a,
- 0x6075c972, 0xc8e705a7, 0x1d9fb0a9, 0xe8f160ac, 0xa2e40f88, 0x7ccbef89,
- 0xd6f2664b, 0x7c60a194, 0x8bf7d364, 0x41eda1b6, 0x7d365e18, 0xec277cbf,
- 0xe67ed1ab, 0x1aae54ca, 0xee4fda65, 0x9b49fbe5, 0x4fd4d13b, 0xa30adcda,
- 0x8fd8c59f, 0x6cfd6073, 0x19bd7b9a, 0x4695b99e, 0x8fd8f53f, 0x4af36067,
- 0x199263bb, 0xb1aa3b9e, 0xfddbf49f, 0x06881f68, 0xdc7690ff, 0x4eef7517,
- 0xc496b71a, 0x1fe4d1f2, 0x2a1e78c3, 0x947cb155, 0x24c13138, 0xb27a494f,
- 0x74a83f29, 0x6a7da9b0, 0x9f54c720, 0x85b5765e, 0xbfa8dd2f, 0x8a814f31,
- 0xab38b126, 0xbd415832, 0x81d83c53, 0xbb06bbf9, 0x75dcef51, 0xb02af07d,
- 0xd05600f7, 0xc12977f3, 0xbe1c6a31, 0x0812f3a1, 0x1b34cfc6, 0x32ec7da4,
- 0x7939efbe, 0xde2357c8, 0xd9d7dfa7, 0xd12447ba, 0xf14a43fc, 0xadef3023,
- 0x8de3b332, 0x9d824338, 0xce6bfea0, 0x8a16da2e, 0x50cb6bc1, 0x6f422fca,
- 0xd0722dbf, 0x73b8fc07, 0x4a576ff5, 0xa1a6be14, 0x7a6e1e0a, 0xe1edfe5c,
- 0x9b99b510, 0x00fb9687, 0xea8576ff, 0x15f1d88f, 0x8e3e7e3a, 0xdfc61bbf,
- 0xd93b332b, 0x673dbe3a, 0x477c69a2, 0x7c698556, 0xa7c74287, 0xf56fb1f2,
- 0x8a7c7c3b, 0x7909ebbf, 0xc7077e56, 0xe05567b7, 0xa90acdf8, 0xd09f8d30,
- 0x9001fe33, 0xcdfdc39f, 0xf37ae73f, 0xcd2ab3fc, 0xfcd857f3, 0x80feae8f,
- 0xf3809f8f, 0x80fe597f, 0x92ab3fcd, 0xfacedfcd, 0xdbdf19ed, 0x6157ff83,
- 0x37f5affe, 0xe649dcff, 0x36ab0ff9, 0xc6cedfcf, 0x27f5637f, 0x8e377c7c,
- 0x09fca6ff, 0x6ab0ff9b, 0x07b15f1c, 0xca47c0fd, 0xf07a8490, 0xa461a99f,
- 0xa35d4061, 0x923a40e3, 0xc837a9c5, 0x5dc70839, 0x3eef8c09, 0xe6fca04f,
- 0x24a7d5ee, 0xea90254c, 0xd3ce5acb, 0x158bbb55, 0xd0842fe6, 0x41c4585f,
- 0xc45fb85d, 0xb46c8cf5, 0x78538787, 0x218bf73b, 0x78dc2fc8, 0xac5b9e23,
- 0x77dc13b3, 0xfa3056a7, 0xc0f1ff1f, 0xf3b1ade8, 0x5a8ba6b2, 0x13fecb65,
- 0xef38c783, 0xa6ab2454, 0xa78829fc, 0x127c3d50, 0x9e9a1ffc, 0xb478e996,
- 0x83f043fc, 0x1b958aae, 0x768c2e76, 0xce9f2277, 0xfe1cbbeb, 0xf7c31253,
- 0xdc053ba9, 0xc37cf847, 0xd9f40552, 0xc99756a2, 0x74e3a86f, 0x8ece7eea,
- 0x79c68dfb, 0x14505bbe, 0xc1fdf909, 0xbb051d6f, 0x41e6f171, 0x276eefa6,
- 0x1470d5e1, 0x79fac173, 0xff3a5543, 0xe3eccadb, 0xeb6b8c44, 0x9c1c5843,
- 0x49b8810c, 0x7906db59, 0x52dccd08, 0xf9ec9b26, 0xfce6835b, 0x7ce6156d,
- 0x6d961ca7, 0x112ccf60, 0xefda16c8, 0xcb65ebf7, 0x8e3600b9, 0x76e64957,
- 0xbbef1b25, 0xb4198694, 0x8e90fbe8, 0xe9156283, 0xdf65573a, 0xddd4f01a,
- 0xae28932d, 0xb8a91dc7, 0x454a140f, 0xb2a82dbf, 0x9de15b79, 0x00f43b2b,
- 0x8fee6785, 0x15a7c444, 0x2e838efe, 0xf3ed46dd, 0x907fcd8e, 0x9d6c7e21,
- 0x3bfe158f, 0xa3e75b96, 0xcc3eb02a, 0x19cb590b, 0xa9f9589f, 0x36f17f6e,
- 0xf37b3db3, 0xb5fb58b6, 0x530cd76a, 0x56f8497e, 0x9bc5fb53, 0x17ea99e7,
- 0xd5312eb5, 0x6a59682f, 0xfd0bcfca, 0x8efed4c8, 0xf54c2be5, 0x635fafdf,
- 0x62adbfaa, 0x6b7f2983, 0xfb5321f0, 0x98b6ca5b, 0x47076dea, 0x68e4077d,
- 0x9e22ebd5, 0x3ee0bdfd, 0x9bd82f75, 0xee12dc17, 0xed447e73, 0x33839015,
- 0xb4815ed4, 0xf478ff73, 0x2c1ea9a7, 0xf9a24d87, 0x2d5598ca, 0x0997a099,
- 0x6572cfea, 0x24d0aac2, 0xd7b0178a, 0x9b887ca9, 0x041d1215, 0x0f724cce,
- 0x318b771f, 0xa9971df5, 0x7d054cdf, 0xb17adf7c, 0xdd797e23, 0xd4c379d6,
- 0xaf6a7e38, 0xb02192dc, 0xce5975ce, 0xb569189f, 0xb1a73ce5, 0xeb817dbf,
- 0xe9856ad9, 0x19bdea83, 0x86736193, 0xe223e5fa, 0xf9ec9b9d, 0x0db0223e,
- 0x53feb048, 0x98861f81, 0x76aa6bf6, 0xfbe49ae5, 0xe11121ec, 0x409d05aa,
- 0x5217eaf5, 0x72028d60, 0x35923d16, 0xa1c0346b, 0xef4055af, 0x75c54fec,
- 0xe9436cfd, 0x3fafd836, 0xf4c010d3, 0x4c3286a3, 0x3104354f, 0x02a1b0fd,
- 0xf50d93d3, 0x2c347698, 0x86bdf4c7, 0x36efa610, 0xbbfa60b4, 0xdf4c5686,
- 0xe98cd86a, 0x4c610d1b, 0x4c741b3b, 0xd1e8790d, 0x0f6e01bf, 0x84d71b1b,
- 0x2e7cc3db, 0xe73da98d, 0xf7ff70c2, 0x11f3fbbc, 0x7f9fef60, 0x6cfb8ecb,
- 0xcacbe1fd, 0x51d3fd6f, 0x3ca57b47, 0x639d083c, 0x8133bd6b, 0x2369c9d1,
- 0xec1c64a5, 0xcff4ecff, 0xc4bcc7cf, 0xfd84f52e, 0xfa713c33, 0xfa5d7885,
- 0xf444e9e5, 0x949982ee, 0xfe1ea71e, 0xf7e822af, 0x607fac02, 0x71111c07,
- 0x6dd1261d, 0x95d7a07e, 0xe1784de2, 0x2f1059f7, 0xbf83d73b, 0x8b882cf6,
- 0xd8a8ab5d, 0x3b36f9ff, 0xf9d2f881, 0xcfbc2e03, 0x36d8fe75, 0x32e3c82f,
- 0x3d8e189f, 0x6b4d6147, 0xb761d922, 0xe736efc9, 0xa50ab7cf, 0x689a1e78,
- 0x0347b389, 0x3861a95f, 0xe0d9d20f, 0x67e8d4c3, 0x71c14f99, 0x65caecce,
- 0x5e7e3371, 0x424eec83, 0x277ea57e, 0x869fffb6, 0x0c7ebfa7, 0x23690878,
- 0x5e08381f, 0xdb98bb71, 0xf97efb7f, 0x814cfa49, 0x20392af8, 0x82f60e7f,
- 0x1177fe9d, 0x6122651c, 0x2eb7e8de, 0x63ec8622, 0x69b77ca0, 0x669dfa3c,
- 0x7317f4f8, 0xe6b7c52e, 0x042234fb, 0x9c46bf68, 0x80fe0aa4, 0x02f530f3,
- 0x788cabc6, 0x6ee49749, 0xc6f4c611, 0xbc78ea4b, 0xa1d1c6b8, 0xb9d16904,
- 0xee4bdcb6, 0x38699e9f, 0xaf39c2a6, 0x02ab470a, 0x64454fce, 0xb9e80954,
- 0xd2ab6d73, 0x12ac1ec0, 0x2f15dfcf, 0x67679b7e, 0x6125bd71, 0x8ebcdbb9,
- 0xb420fe72, 0x1d9ca35f, 0x8a9f7472, 0x31b59fc9, 0xefdadb3b, 0xf6c0fb04,
- 0x1f776a2d, 0xd683769f, 0xfbb54f17, 0x3e30553f, 0x5c53112e, 0x7bdfc0c9,
- 0x9d82604a, 0xd772a9e2, 0x7e8f68fb, 0xdc468724, 0xd4fd097d, 0x9f6e7e77,
- 0x88727ce9, 0xf338c3b4, 0x8881f227, 0x743bcb76, 0x15f8fd3d, 0xe4db9d99,
- 0xf67b80e7, 0xfebef995, 0xdf9b9e02, 0x84e78556, 0x8ff7de3e, 0x242dff68,
- 0x81d22f01, 0x1d8116b4, 0x4ad88e79, 0xc8e74f01, 0x31f1de6b, 0x3a95b874,
- 0x05ef404a, 0x863b662d, 0xfca6bfda, 0x7ce6cde2, 0x06999939, 0xa37ca4fa,
- 0xce02c24c, 0xb37f54cf, 0x177ec55d, 0x5826fa93, 0x8fee2557, 0x348957cc,
- 0x9ad5ea84, 0x34567f67, 0xb411c28f, 0x88c83f33, 0x66492cbf, 0x4a656076,
- 0xc27d8158, 0x7fc6da0f, 0x832006f7, 0x7104dc3d, 0xfc489228, 0xfc5f483b,
- 0x56fc295e, 0xbaf58d78, 0xc3881c4f, 0xe212ee21, 0xdad603ee, 0x86cf6e05,
- 0xe7c03d30, 0xc705f86d, 0x7615f92c, 0x2452de7e, 0x9cfdd022, 0x12d908ea,
- 0x851fdeb1, 0xbb5edc78, 0x7106957f, 0x7b6ac0fc, 0xdfdc6f6a, 0x0f649768,
- 0xe159f962, 0xf73c72d5, 0xf00b4520, 0xef8f21de, 0xc41f9c2b, 0x9c016f04,
- 0xdc40f523, 0x3a75ce1e, 0xdf215bbd, 0xf3c0a9e4, 0xef20751f, 0xbc7bbfb4,
- 0x9c418ed3, 0xa35a41da, 0xbb5fe53a, 0xa01fb2cf, 0x902ef399, 0x5067d04b,
- 0x09a2e780, 0x235cb9c6, 0x7e3cedcd, 0x2e31fe73, 0x4381748f, 0xdf39ee3e,
- 0xe14770e6, 0x2899093c, 0xb7f1ed9d, 0x63dfc072, 0x56fdc3f0, 0xcaa77f68,
- 0x7df2d7da, 0x9edf3bdd, 0x097c9e9c, 0xa5f7547d, 0xeb31c240, 0xadd49d48,
- 0x7dd61f00, 0xd7f96129, 0x5d1a9bd6, 0xe6f46355, 0x59f04a2b, 0x27a604fb,
- 0x8e813e01, 0x64dfbb13, 0x027087bd, 0x2f4261f8, 0x386d7c3f, 0x7f498852,
- 0x8f04a7bf, 0x6be383c5, 0xd3ebeff7, 0xbbe009ff, 0xf3feb1ff, 0x11dff4fa,
- 0x679afe0f, 0xd10becf7, 0x17f2b5f5, 0x10e1780f, 0x6b52c7d3, 0xacef9c1a,
- 0x0bdab1de, 0x1491f972, 0x3f5d02f2, 0xef718b0e, 0x0c3ba6e7, 0x70ddd3be,
- 0xf396b08f, 0xaf9f99dd, 0x2ff836fb, 0x5590ef9f, 0xb2ec0f8c, 0x2994ed47,
- 0x3096db6b, 0x7f65d8f9, 0xf19be59f, 0x7edd53bc, 0x7ca8beb3, 0x0d3481fc,
- 0xb885550f, 0xff451cff, 0x7ffb76a0, 0xabbb034c, 0xdea3748e, 0xe3077eb3,
- 0xf68c997f, 0xb1253cc0, 0x0e71bd6f, 0xa5e38eab, 0xde1d6dae, 0xbb6baf13,
- 0x9a1334f9, 0xad3bf40e, 0xbb7055df, 0x9f30e1df, 0x42f034df, 0x5feeccc2,
- 0x0583c4f5, 0xceb853ef, 0x2bc57f6e, 0x29f2c7e4, 0x23e77fd3, 0xa5fb1e0b,
- 0x755cbfd6, 0x6b18fd52, 0xb4eb1b5f, 0x2bfb9fb6, 0x2d5a5807, 0x0fe0bd47,
- 0xf1916f56, 0x9ef57bbc, 0x861f3b6d, 0x76dbccf8, 0x7fda70ff, 0xde979ed5,
- 0xabe69eb8, 0xa653929e, 0xe1b869b3, 0x9f41a29e, 0xf2dffa3a, 0xa8f4bd71,
- 0x4525fa7c, 0x7fcacd1b, 0x974bdc9c, 0x290ea7aa, 0x7c5f7464, 0x521c894c,
- 0x85b67ed8, 0xa7f7913e, 0xeab15f81, 0xd0142f89, 0x141f1f5f, 0x1c767a48,
- 0x09796e7c, 0x13c063ed, 0xabd393d2, 0xf6967e87, 0xa82e9475, 0xb2f42d17,
- 0xaf98fbb6, 0xc42fd007, 0x3f7f29e3, 0xb7d84bf9, 0x0fdd9df9, 0xf278a878,
- 0x9f30bc9f, 0xe33d52d3, 0x4ead9ff3, 0x1520fb83, 0xc54d2872, 0x3c579594,
- 0xbfe403fa, 0x907fc7c5, 0xeac5cec6, 0x575cfc19, 0xd173cc06, 0x9e707323,
- 0x7c8824e5, 0x7633f158, 0x4482fccf, 0x238a9f4a, 0xd839f727, 0xab7a763a,
- 0x4f11371d, 0xfb0242c3, 0xe189af18, 0x640f181d, 0x607f0de7, 0x65913fec,
- 0x60e0bf98, 0x30e45af4, 0xa5d1f1ee, 0xb77f9624, 0x9d03b737, 0xd3d50cce,
- 0x475c8e21, 0x87c710a4, 0x2bf69170, 0xce9a9f1e, 0x52681dcf, 0xea8eff11,
- 0x0e5029ff, 0xdd65dbed, 0x8efa6059, 0x1deecc5c, 0x3e3e4eff, 0xec013b85,
- 0xd469d3d7, 0xbf338c1e, 0x9d630e03, 0x0c5676a6, 0x3bc8c59f, 0x6bedff93,
- 0xf21bbc98, 0x0a519e1f, 0x609d9ff5, 0x81df0472, 0x8ae142fd, 0xa1fd63a6,
- 0x07ea02d9, 0x93c6893b, 0x9732edf3, 0x95bd7373, 0x12fc285f, 0x7c3dc7ac,
- 0x2324e303, 0x2dbed01d, 0x8fbf48df, 0xae30abd5, 0x86bf6fb7, 0xfae62f1c,
- 0x1f45ad60, 0x07524790, 0x2d5b7fb4, 0x0c3e7787, 0x35e54bf2, 0xcafc81a4,
- 0x27c15ef8, 0xf1bc8fbb, 0x9fb72a3d, 0x35b90c44, 0xdcab55eb, 0x409dec56,
- 0x27edc9e2, 0x2b893f6e, 0xae3cb4b7, 0x903bbadc, 0x7ad6ff9f, 0xd3e3c0d5,
- 0x7a1a3c16, 0x5a7c3fb2, 0x1db7e4f5, 0x493d5c5a, 0x45209dff, 0xe0d1f97d,
- 0x2aff8343, 0xcf06a5ff, 0xa9f0f50b, 0x7c3d87c1, 0x9f61f06a, 0x8f09a478,
- 0xe1bbfad6, 0xc0853a6f, 0xcfc63273, 0xfdb00fab, 0xd1ddfa67, 0x2f888521,
- 0xd239971d, 0x4a48747a, 0xc96c3e6c, 0x75ed2c47, 0x69603e4b, 0xebe4b41f,
- 0xf7abed4d, 0xb9d8511f, 0x9da9a89e, 0xe4a7fcb8, 0x01f13883, 0x6baa1d63,
- 0x010954fb, 0xf1bbb87f, 0x0925797b, 0xfe5e2079, 0xf2f188bc, 0x26e38a2e,
- 0xeed74e3a, 0x608f7c6c, 0x57c593b5, 0x2f6ed4ba, 0x93ab93d8, 0x553bbe58,
- 0x683d0269, 0x593b7794, 0xd02bafdc, 0xb18a4ded, 0x203fdeef, 0x08ef1ea2,
- 0x7e78d293, 0xa140de28, 0xfd20edf8, 0x80fdb3d5, 0x61d7b02e, 0x30ac84bc,
- 0xd154e3f0, 0xe21cb59d, 0xde22ad35, 0xe2b85b6b, 0x239c2f16, 0xfb903ae9,
- 0xbe5a329d, 0xdb22d7e8, 0x52e90ca6, 0xf81f8c46, 0x9a6d0911, 0xf5fec024,
- 0x059fe47a, 0xb85f9807, 0x797c7d70, 0x95dfe4a8, 0x4054efbb, 0xee7f52ef,
- 0x87beec64, 0x23c54fd1, 0xff03f296, 0x15a6e5c8, 0xdb951fe3, 0x1e41f5cd,
- 0xe4ec183f, 0x92c7bee7, 0xb77fdcb1, 0x9e0fdec5, 0xa77fe62a, 0xeba7d28c,
- 0x3ce04898, 0x2203f9c1, 0x6efce7d2, 0xe3007e76, 0xbf01d7fc, 0xe7b12b77,
- 0x7c82cea9, 0x1ebfd55d, 0xefccfb3b, 0x3e06ee8b, 0xc14ef7da, 0x767a694f,
- 0x7e23dbdf, 0xdf67f905, 0xf4877acc, 0xa0e53f6d, 0xba55f713, 0xff907a0e,
- 0x4dff9ebb, 0x7f90ddd6, 0xecf18ece, 0x145f83ae, 0xad753f00, 0x1e8057b4,
- 0xefe7e2ec, 0x45ff3d56, 0xbfae0741, 0xa9c7488d, 0x9f4fe64e, 0xef5ff03f,
- 0xf381fdc1, 0xc0ace807, 0x42e838be, 0xa5fbaaf9, 0x5d6fe313, 0x14517fcf,
- 0xa5fc27eb, 0xfbe5a9f3, 0x521e5d9d, 0x4be017b6, 0x7544fb62, 0x1b6ebabf,
- 0xd3512fbc, 0x40594876, 0xf0bca7eb, 0xafd002a7, 0xdd997b5d, 0x3c7729d4,
- 0x8179fb0a, 0xca340f35, 0x209d5e94, 0xff698364, 0x0128de6b, 0x978bea39,
- 0x715c613f, 0xfc58f8a0, 0x043e0d7f, 0x4f3fe99d, 0x29854c18, 0xdef8ff07,
- 0x0e27a03b, 0x8d2f91da, 0x59127ef9, 0xe5ccf681, 0xfff4dde6, 0xe885bcdc,
- 0x03bde640, 0xefe13de6, 0xc0d7de77, 0xbed4a1a1, 0xcf97d072, 0xf30bbf9f,
- 0x847e3c7b, 0xfefc8077, 0xfcf9dfd2, 0x7bee98af, 0x97bddd29, 0x7f87f79f,
- 0x9feef3e7, 0xcb9ebfee, 0x79c2aee9, 0xfe17ba98, 0xa95df084, 0xfe12939e,
- 0xbfbde5be, 0xfef61bf9, 0x35bf9b5a, 0x93cf1b27, 0x70b0c03a, 0x40b6667b,
- 0xc8ed7178, 0x9dd82a99, 0xd5ef3f62, 0x7e60484c, 0xf7b02895, 0x1650c821,
- 0xcfdc240f, 0xf80d6382, 0xdd9b880e, 0x4ddc933b, 0xc9137768, 0xbc53aedf,
- 0xbe7abdac, 0x911acf1f, 0x21056f71, 0x8fc9399f, 0xbf8b6ef1, 0x5d1028d9,
- 0x74aef6a0, 0x818f37f5, 0xb48f23df, 0x9805ed45, 0x33690fbe, 0xaaca638f,
- 0xdc87f262, 0x53bce6f9, 0xbcede733, 0xf061073f, 0x0c247c3b, 0xd4716cf1,
- 0xd3ce1561, 0x02256389, 0x4938a54f, 0x0efc086b, 0x7dfccfbb, 0x7ee10252,
- 0xc7865fef, 0xa716048a, 0xed718512, 0x9471e03a, 0x78dce30d, 0xe2f11b48,
- 0x08baf7c7, 0xf17baff7, 0xf80ed4da, 0x663fc094, 0xd5fa17f6, 0x12d3fb84,
- 0x691a42ef, 0x76e69dd3, 0x2cbe8fdc, 0xb25d189d, 0x969d39aa, 0xd062e899,
- 0x4c7d0e21, 0x7cf03174, 0xd2b1f4a5, 0xebff8ac5, 0xf75f1813, 0x2e832f47,
- 0xef1d6e99, 0x7fdcc9d7, 0x133f0128, 0x820199f2, 0x7fdcabfb, 0xbc745290,
- 0x7eaa24a7, 0x7e0097bc, 0xe01a945c, 0x86deef2f, 0x3f73a4f1, 0x00dbff7f,
- 0x44afd54f, 0xebf8a0e2, 0x5121eddc, 0x2b0a5ef8, 0xb6569fe0, 0x404fb889,
- 0xacd168a4, 0xc3627d98, 0x85faa80f, 0xb953e707, 0x4e9e1ed7, 0xf7dcafbf,
- 0x61da0141, 0xcfd1bb2b, 0x605cfd09, 0x14750f74, 0xa5703ec0, 0x2b11fcc4,
- 0x6049acbf, 0xcfb396f1, 0xae20cab9, 0xe762ec23, 0xb7232b7f, 0x7398f6c8,
- 0x9904a14d, 0x739e9bc5, 0x3d085ea1, 0x28f9e021, 0xdcf62f80, 0x9c87e1a9,
- 0xf060427d, 0x9df197ed, 0x4f5dca98, 0xaa7c4275, 0x1fbb2df2, 0x5dbaf8cc,
- 0xc87ee29f, 0xf1ec5f94, 0x2e1fa076, 0x7d12e29a, 0x44bb01e2, 0xb6da8fe4,
- 0x6843f41a, 0x36a2f91e, 0x2beffdc2, 0x7eab57f4, 0xb83efcf1, 0xf4f55670,
- 0x7f885ee3, 0xe1df699d, 0xaec0b8c5, 0xfae7c74b, 0x3591fff8, 0xd6ffffdc,
- 0x3b4f7669, 0x067fffbe, 0xf176a0fe, 0xfb9609d3, 0xb106bbab, 0xb44914f7,
- 0x71ef52e8, 0xf0b9ed55, 0xcfafc428, 0x51e4fdee, 0xcffabb80, 0xfc14787f,
- 0xa9d0720a, 0xba827dc2, 0xf18ebf9f, 0xdfbbe33e, 0xf9d03d70, 0x2f18e3c4,
- 0xfa9b7ced, 0xe75ff41f, 0xc0b3a7f3, 0xea7ceccf, 0x4f10698f, 0xa9f9f3b9,
- 0x9dce6ef8, 0x27494ccf, 0x9189f471, 0x0786ff02, 0xd2b5af10, 0x11db48ed,
- 0x51ce7ff4, 0xd9ff83ba, 0xd489d713, 0xc69978b0, 0xe3bb39e3, 0xc4fbc7c7,
- 0x7d66da6f, 0x4842c6e7, 0x0646bf65, 0x4139c710, 0x006639e9, 0xe3cddc74,
- 0x5d6f9175, 0x0e738e32, 0x3af4a0fe, 0x85e3a16b, 0x3d8f45b6, 0x836d750c,
- 0x44e38dfa, 0x233f8007, 0x413fbefe, 0xe40122ff, 0x60bfef68, 0x37e80cfc,
- 0x73b84e9d, 0xd82c85cf, 0xee48f8bf, 0x85ef8b9e, 0x21576f3c, 0xfcf9511e,
- 0x9d4f289b, 0xf8c71ccf, 0xf071e136, 0x8ff3d24e, 0x99f92bc5, 0x1eedbacc,
- 0x74e1ff16, 0xe690f880, 0x071e72c5, 0xc46d7c62, 0x0b8bfa87, 0x73b1718d,
- 0x40bec627, 0x7877f6cd, 0x6e97a5bc, 0xd7a044c2, 0xcfdc97fb, 0x02a0f030,
- 0x8d8dae1e, 0xc38fc67b, 0x2d3dc4f5, 0x427a0374, 0xae27b3bc, 0x7b13d849,
- 0xcde16175, 0xcef47178, 0xda5e2c2d, 0x8f3fc729, 0xaf41c465, 0x9fe25976,
- 0x3fc581e1, 0x2b8f372f, 0x9760d3c5, 0xf15afd86, 0xf8abf675, 0xae5bfdfa,
- 0xe85f9d81, 0xdaad7f77, 0x3de61f7c, 0x05dd3825, 0xef6d6bfb, 0xa7cf042b,
- 0x2b73b374, 0xf967be7c, 0x3fb3d3f9, 0xd62e3117, 0xfa823914, 0x8c3faadd,
- 0xbc2b57fd, 0x6b787077, 0xe3f5b3f7, 0xd84f5eec, 0x7b39fb4d, 0xebe439f8,
- 0x63efddda, 0xaee8ee5c, 0x988e95a7, 0x8fd616f5, 0xce7ccc70, 0x80a8793e,
- 0xdfe379c5, 0x3171ab1b, 0x40eeb37b, 0x76ea71fc, 0xa71a6a7f, 0x9851142a,
- 0xf1e9701d, 0x2dfa48ce, 0x7699dfd0, 0x3a4ddf19, 0xbee31113, 0xc9701c17,
- 0x95a11f7c, 0x475d0fc9, 0x71c09ef1, 0xf0a77f76, 0x573c04b5, 0xd2f1e77f,
- 0xb7fde077, 0x8358a93b, 0x82b6dfdd, 0x4fdb69f1, 0xef4021f4, 0x13dfe3b6,
- 0x07dafd61, 0xffb18df8, 0x4fd44e8b, 0x50fd50f1, 0x10a06ef4, 0x77aad5d8,
- 0x66cb7dae, 0x938e9f82, 0x2342eb0e, 0x83ee07ed, 0xbc39b9c0, 0x569dee57,
- 0xaa88f00a, 0x7d0a754d, 0xf9bb21e7, 0xafde557d, 0x21ef9aac, 0x6bc6af90,
- 0x266f8fd0, 0xcc664b8b, 0x9f165232, 0x87f7190c, 0xabc213ca, 0xaf7f7ce8,
- 0x28bb3706, 0x8d9e7c5e, 0x78112fd9, 0x06a26a27, 0x2e63d3f6, 0x4bc1de7e,
- 0x83bcecbc, 0x7aa3643b, 0xf6ff61fd, 0x9e08930d, 0x7c06d867, 0x819e73d9,
- 0x2f800b44, 0xea7d768d, 0x321de72d, 0x5a2a13e1, 0x17338722, 0xfd5025ee,
- 0x77866ab2, 0xf11fe42b, 0xb2cdf7b0, 0x3821f748, 0xdb8db0df, 0x1560d9a3,
- 0xe77df6e7, 0x6fbeebec, 0x78a53296, 0x853f30e9, 0x535ff5d3, 0xca7c5ce1,
- 0x0d4fc52d, 0x2d856951, 0xa3dc1a63, 0x78bc7949, 0xcfcd066c, 0x34f4ff5f,
- 0xe2f7ffac, 0xff3459b1, 0xb20e7b93, 0xcf012afa, 0xaeb0bec1, 0xeff01a76,
- 0xd9fb96d7, 0xb9663314, 0x77f0057f, 0x77eef02e, 0xae706917, 0xefe15ba2,
- 0xdda00465, 0x7f0c89d0, 0x9f77ee99, 0x98657f02, 0xf00563ad, 0x7fcf63eb,
- 0x16f78491, 0x2aa1fbf9, 0xdce15469, 0x789a2d15, 0xf3e712f1, 0xccfbbcfa,
- 0x498dcbf5, 0x3f8177c1, 0xbc8de79a, 0xef1d1a6f, 0x0e718ae1, 0xf2d00e76,
- 0x829aa34e, 0xe9c85d74, 0xcb3df84a, 0x8b3e7c45, 0x02c290c5, 0x7f5caddf,
- 0x5751ef19, 0x1ef4578b, 0xdbab8735, 0x67fbefd5, 0x3378007f, 0x007f8293,
- 0x3fdf59fc, 0xb815c57b, 0xe519f500, 0x5c7de25f, 0xeb333de3, 0xea4468bb,
- 0xfb3efb8e, 0x5a2efe56, 0x9bfef07f, 0x69ba283b, 0x682f39ff, 0x39518f7b,
- 0xf150b31b, 0x31cfd1c3, 0xd2fd0bcb, 0x0426c220, 0x1fa71076, 0xf788cf3c,
- 0xb822ee1f, 0x1765db5f, 0xbbaff074, 0x7d4549fe, 0x3a70b99e, 0xae5d5ffa,
- 0x339c08ec, 0xc35bbaea, 0x018a3d7d, 0xe869e401, 0xf828c481, 0x3e1e5487,
- 0xe7c3c8b7, 0x8f37fe66, 0xdb5175db, 0xa9fd81df, 0xa06a3fbc, 0xed8bdcc5,
- 0xee9e9912, 0x8e10d06a, 0x087424a1, 0x8e81fdd6, 0xebe6e397, 0x46cfa737,
- 0x9eeb9e9b, 0xee1ff880, 0x28ffc18e, 0xcc74bf77, 0xe63a3377, 0xd1d0e3bb,
- 0x7bdd6efa, 0x6858e0ae, 0x28fcba77, 0x7d675fbe, 0xdf4aceaf, 0x21f5a93a,
- 0xed2b3b78, 0xfeb8a7c0, 0xb31bf418, 0x29d22c7c, 0x00939e86, 0x3e07318e,
- 0x06bc01b5, 0xe7ec1f1d, 0x9ba9793c, 0xf1d673ad, 0x063acad2, 0x9fb4e307,
- 0xf74cd6e5, 0x451c0a0e, 0x69ca897e, 0x87c58dba, 0xb7efb6fa, 0x9d4b9cff,
- 0x59502cf3, 0x73ff14bf, 0xfe064f00, 0xfbf3756f, 0x7ff17dea, 0xf8a3b43b,
- 0x3fe61dbf, 0xbbcffc00, 0xfb0dfe14, 0x87eb8abf, 0xa29fd82a, 0xda1ff47c,
- 0x3a1cb4cc, 0x8dd134ee, 0x8764b072, 0xd931f7c8, 0x3e865ffb, 0xfd5d7259,
- 0xb917b821, 0xf20267e4, 0xfefe42eb, 0xfdfc27e5, 0xc1b9eb4b, 0xea10b2f2,
- 0x1f9fcbcb, 0xaa3ea30c, 0xff2e65da, 0xbbcf7767, 0xde785997, 0xad352417,
- 0x2b4ebdf7, 0xb9bbcffe, 0xb4e858de, 0xd72f7bc5, 0xdbd68748, 0x33cce74c,
- 0x83f4f4a6, 0xa6cfa0fe, 0xb8f189bd, 0xc409957f, 0xa5297413, 0x2019de10,
- 0xf4094285, 0xd7e5cc5b, 0x72d86fe8, 0x1d9ffaf3, 0xcc43df32, 0x43df316d,
- 0xbe6ade1c, 0x66d57887, 0x51c43df3, 0xc43df361, 0x338d766b, 0xae4747e5,
- 0xb31fb537, 0x3f29b27f, 0x534dfa36, 0x66c7f1fb, 0xda13f29a, 0x7f6a67bf,
- 0x4df35bed, 0x5475d7f5, 0xf86fea9a, 0x7f299968, 0x9b3ff763, 0x311747da,
- 0x61b878fd, 0x5bdc1179, 0x7872f030, 0xa15362a9, 0x9b08e97c, 0x9e5b105a,
- 0x90056ba6, 0x7fe0e916, 0x532f27f5, 0x8a2a3f1c, 0x898ba75d, 0x536fd26c,
- 0xd47ce61c, 0x8f7dfe6d, 0x35722c97, 0xcb527ea4, 0xbc1d9a08, 0x63cf0f24,
- 0xc63af953, 0x01b1dbf5, 0xa0dfb7ea, 0x9b46d57c, 0x2f956f20, 0x9a01bde3,
- 0xad8fd886, 0x1f9f77b0, 0xd4f99a72, 0xf95e8fd7, 0x0738db9d, 0x53facad4,
- 0x264bc6cb, 0x3fca3139, 0x172d8c2a, 0x73c74f16, 0xabf5fd40, 0xb35c16f8,
- 0x3bbc107d, 0xa3530f3c, 0x16cca9bc, 0x67dfdcf7, 0x7fd0bfee, 0x8ec7dcda,
- 0x7cf00cfa, 0x26daf7ce, 0x7b56bf38, 0x51fa377b, 0x5e337619, 0x5decf37a,
- 0x479e0363, 0xac3e481a, 0xb6fdc6f7, 0xebe13445, 0xd177ce36, 0xe0d333db,
- 0x3f66419c, 0x87a155fe, 0x1b47ebe9, 0x042cd742, 0xe98711c2, 0xb456795e,
- 0x39f81a6e, 0xeb79f8c3, 0xe7f8b64d, 0x0c3c92a0, 0x48a0e92f, 0xdd505ec1,
- 0x2b9c2f68, 0x4f0bd77f, 0x0f68dcc7, 0x38e87926, 0x17b4c7f3, 0xbad4fbb1,
- 0x5ee8e67f, 0x947d0db8, 0x026c0ee5, 0x93e592fd, 0x17dd9688, 0x83dbf49e,
- 0x788ef02d, 0xefcdb263, 0x00b77cc6, 0x4c7fd9e3, 0x5e3a20c8, 0x84459fe3,
- 0x75f0f1af, 0xeec83e78, 0xabb8c7ae, 0xcfc24f31, 0xe6711809, 0x89d9be0b,
- 0xabc6cf80, 0xe107ee7b, 0xdc17907b, 0xf7e876c1, 0xc71946c2, 0x982c9c6d,
- 0x4b798dea, 0xf78dbf9b, 0x6cdcb2be, 0xde74e5de, 0x933db700, 0xa8f8d5c1,
- 0xae113240, 0x28f4bdff, 0x5cfb35f8, 0xc507def8, 0xc7c010c7, 0x73fb3d39,
- 0x3a79319b, 0xee419aaf, 0x9ed16bad, 0x4ea7ef89, 0x8fa1e637, 0xe33bd134,
- 0xe2fc332a, 0xc6fd1946, 0x3c6e4945, 0x886e10ef, 0xe79afa72, 0xf99be4df,
- 0x5c295b9d, 0xf8884eab, 0xd1d6b6de, 0xfd28f4ba, 0xe5cdbcae, 0xf17d6b0f,
- 0xf0634e7f, 0x7ba7f852, 0x4f36de40, 0x79e3f9c3, 0x31ff806a, 0x0d9c3c81,
- 0x452c17fc, 0x236c183e, 0xc7d36fb0, 0x7930f04e, 0xd951ed9e, 0x72be357b,
- 0x85be8726, 0xfda76cd7, 0x5dfa7995, 0xb0f36ff7, 0x4f36ff75, 0x72ff759c,
- 0x975707ef, 0x54851fb5, 0x37b445d4, 0x111fa908, 0x3d53476b, 0x1bfd0e56,
- 0xc7f13179, 0xff6fd005, 0x65bf9a76, 0xede5f644, 0x80cfb034, 0xecfb0d0f,
- 0xaed98f4e, 0x3fbbd18c, 0xfbbd30f4, 0xf4c0cf43, 0xfda18fee, 0xe345efe9,
- 0x4aa935da, 0xb4f7bd7c, 0xac1fdd87, 0xe7821553, 0x0fd9fb03, 0xdae5c9d8,
- 0xd6feef3a, 0x1ff9cba5, 0x4f832e39, 0xfcfefacd, 0xf4112d31, 0x4207ca54,
- 0x86b777dc, 0x3c6dbf2c, 0xad9b6bd0, 0xf7cc3378, 0x78fe1667, 0xf59f4d68,
- 0x18f1cc2b, 0x6ac78b8e, 0x099b478a, 0x973c3b8f, 0xb6bf0fb0, 0xdf30afbe,
- 0xf8e4e9f3, 0x09bf7aa6, 0xeb373bc6, 0x6b8822bd, 0x1cf9ced4, 0x1ed7fef5,
- 0xaebccca7, 0x1d397e18, 0xa1e00567, 0x799fd673, 0xe303ae7c, 0xb99eab4a,
- 0x58e2112a, 0x7a0d9335, 0xaa7df044, 0x4839f9f3, 0xecfb7397, 0x2e79c03a,
- 0x3d139d99, 0xa3daefb7, 0xa4f8f710, 0x2c7258e1, 0x793dcf7d, 0xfda648bc,
- 0xbc7bdb9d, 0x7703c248, 0xd43bd361, 0x5b7f1735, 0xdef77014, 0x37e1e84b,
- 0x368f5b07, 0xe57c593a, 0x37173841, 0x6abfda86, 0x7a65f212, 0x285eed9a,
- 0x1dbf1d17, 0x395c21fc, 0xa62fe63f, 0xd04ab259, 0x7ec11633, 0xee373cd3,
- 0xc972f967, 0x9dfa6cc8, 0xe387ad12, 0x6af9c4cc, 0x04efc098, 0xf1444eb8,
- 0xef3c02f7, 0x3ef86076, 0x02b243f1, 0xbdffc29e, 0x78093c1a, 0x09ab3a4f,
- 0x77c41a89, 0x471e6e8a, 0xd30a6953, 0x3ab7ddbf, 0x848cf7f0, 0x53aaaf05,
- 0x3cdafea8, 0xdd8efd93, 0x920b63f9, 0x55691fc0, 0x0df2de99, 0xb463e1eb,
- 0x6be7078b, 0xe6231737, 0x40577c75, 0x921d1955, 0x8a6b6c33, 0xf9c78c35,
- 0x25fe98f3, 0x3dff1a52, 0x1eb7ca29, 0x1c43a6cd, 0xc5cef8d8, 0xfc522bbf,
- 0x7803cebf, 0xf0fcdb46, 0xabfb8f4e, 0x92ca386f, 0x28ccfb69, 0x945e5fbe,
- 0xc39de1c0, 0xfbef07de, 0xd345e34e, 0xd4b5187d, 0x27b74efc, 0xe214b4d0,
- 0x6defd0fc, 0x8bcef8c9, 0x38a29eb9, 0x0bbb9691, 0x0aaee5cd, 0x47e18f9a,
- 0xf6d677eb, 0xae925f86, 0x37f63832, 0xbf0f1038, 0x79fd506c, 0x340e8f94,
- 0xb07f30f8, 0xda34c341, 0x0fcb1230, 0x2f31f837, 0x986cf4da, 0x7faffa4f,
- 0xeebb1490, 0x9d54efc2, 0x75c3e18c, 0xf9ade472, 0x88df8f80, 0xaf15af88,
- 0xdefe478e, 0x3a8e9a34, 0x7367bd86, 0xfefec632, 0xd257f2e9, 0x0d5f284a,
- 0xd3afd1f9, 0xefc3c64a, 0x17f3b096, 0xf63a4170, 0x257aee1e, 0xe093f9a0,
- 0x34c63477, 0xfbc2863b, 0xc95bc1a4, 0xfd239458, 0xbbf089c5, 0x6c337b0b,
- 0x949a7eb4, 0x07f8ecd7, 0x64deab80, 0xe7e7afe7, 0x6c9f1f33, 0xbce3afd6,
- 0x0a66ff4c, 0x71bce3c5, 0x537e09f8, 0x39acfd00, 0x3307b9c6, 0xbf54891e,
- 0xeb8a76e1, 0xdfb3efe6, 0xc754485f, 0xf7bde1fb, 0xcec35ecd, 0xbec5f7a9,
- 0xff99bee7, 0xe1e2440e, 0x29176825, 0x103bf63e, 0x0f7b0a29, 0x4d930489,
- 0xe5cdedef, 0x0606ccfd, 0x1f57d09a, 0x15fde6cf, 0xfb0e791d, 0x8897df83,
- 0xf087eff5, 0xccd8c3df, 0x3574d3f5, 0xed4dec50, 0x5bd4676d, 0x7759ebbf,
- 0x0bd1216d, 0x890143f6, 0xed04bd80, 0xd4bb698a, 0xdc02030f, 0xd7ce33ef,
- 0xcdf80b3e, 0x93ddfdef, 0xebc3027d, 0x8a7d3c93, 0xd4494eff, 0xe3079813,
- 0x123c16fb, 0xca7603da, 0x6206bb3e, 0x8fe47452, 0xf8947ef8, 0xe701c53b,
- 0xbc0f53fc, 0xd9e5eecf, 0xbf38143a, 0x7c5bd2b8, 0x4551c413, 0xf3033ea5,
- 0x816f4ef7, 0xfa9e83fc, 0xdda3d887, 0x1f0137c5, 0x06f7f3a4, 0x01000408,
- 0xe1aa080e, 0x43fd638f, 0x64654eb3, 0x2bf2cc9f, 0x873637bd, 0x3f5f2132,
- 0xf208f80f, 0x7dbfb48d, 0xc021c149, 0x86e16e47, 0x423763e6, 0x037f68de,
- 0x5789ffb6, 0x3b8ffe65, 0x4af60d98, 0x79a55e4f, 0x625e4c4f, 0xa960e279,
- 0x239abf31, 0xd073c47f, 0x3bd807b5, 0x6607a95d, 0xd4cf3008, 0xff1033fd,
- 0xbcb7d5e7, 0x878c342b, 0x04eb608f, 0xf41b978b, 0xa6e1ee30, 0x79f783d9,
- 0x9d61f863, 0xc4c76cd7, 0x0fbc27dc, 0x1fd3ddf0, 0x36cbaf8f, 0xf74a9ef6,
- 0xc6efd88f, 0x547b030d, 0x86b9b884, 0xa3dc2e69, 0x70c1fea7, 0x98395c12,
- 0xcde35fd6, 0xb55e3a41, 0xa9cdfb3b, 0xa75f2f5a, 0x80772964, 0xf8b54e3e,
- 0x3f5cd935, 0x7f8b508f, 0x372b4893, 0xf0b5c10a, 0x8f686c9e, 0x937de2ac,
- 0x4728195d, 0x228eb967, 0x5f3183f5, 0xcbbfefcd, 0x476b832b, 0xc4591e81,
- 0x76556ef4, 0xdfa658a0, 0x8d973d57, 0xf0670bbf, 0x2452555d, 0xf7bb9c6d,
- 0x3791b75c, 0x21e4477e, 0xef09d5b5, 0x5afb18f2, 0x6437fbb5, 0xc7fd3ec1,
- 0x3b46de87, 0x36624971, 0x76d359c2, 0x69df815c, 0x7ca36da9, 0xd8fbbf47,
- 0xa3c763d9, 0xc887f25f, 0xbe026fa0, 0xc368d0fe, 0xd9fdddcb, 0xfd522f55,
- 0xea85d3a6, 0xd3038368, 0xd5fd7a9d, 0xf09c0ae0, 0x49c9b82e, 0x1cf1e9f9,
- 0xeafe055d, 0xf51eb7bc, 0x3a8ae3d8, 0xd3aff80a, 0xe066c3fb, 0x9124aae7,
- 0x5f0febf3, 0x7ef8f3d6, 0xb9efcd3d, 0xbfa6edb7, 0xa160df68, 0x7ba9fed9,
- 0x41fc8dc4, 0x02df92ed, 0xb66ed51f, 0xb3fd6085, 0xbef1da39, 0x1be82773,
- 0xfbe65fd4, 0xa6051b99, 0x5873430f, 0xf772fa1c, 0x74be2b34, 0xfd8c7091,
- 0xe99124bd, 0x84290aab, 0x5f1576fb, 0x2ffeb17a, 0xba69c71f, 0x1c77da0f,
- 0xe31bd637, 0x838ef754, 0xf6fd527c, 0x5fcff461, 0xafb0dabc, 0x77ffd475,
- 0x61cfc53e, 0xe874f538, 0xd0d941e7, 0xa4cfd427, 0x1ee78678, 0xf9243e79,
- 0x47a97908, 0x2e6dacff, 0xf6fa04c9, 0x7eb313d6, 0xb74a25d2, 0x3e781297,
- 0xc9737f74, 0x13ed38a4, 0x8c73ed2c, 0x7fb14ffc, 0x3a0f3c2b, 0xda0ef37b,
- 0xbd93fa5e, 0x6df00f27, 0x4bfa59b0, 0x86dfc636, 0xb7fc19fd, 0x65fbbbc7,
- 0xa5e9ef78, 0x10f140a4, 0x2068df66, 0x15245b87, 0xc0d1877f, 0x3ebe1ef3,
- 0x8d797c55, 0x78bdff09, 0x9f95302f, 0xfb4cd06e, 0x2e178ba1, 0x7b3f7bc3,
- 0x41563af8, 0xdb3eec42, 0x7da6b923, 0xc70fffd0, 0xb8a385d7, 0xfe4a381f,
- 0x328c70c6, 0x385e81e9, 0x5fe54df2, 0x69310e17, 0xec366976, 0xa1b1ad53,
- 0x0b66909f, 0x6ec07239, 0xf7ec5ffb, 0x0734201a, 0x61a899e7, 0xce57da6c,
- 0x079f6039, 0x448e79c6, 0x40e3498e, 0x056d749e, 0x913f53ac, 0xe5a1afd0,
- 0x8619390e, 0xfde1d56e, 0xd8952a2b, 0xb0754e5f, 0xe6f51986, 0xab876277,
- 0xe5a258a4, 0xb879d5e3, 0xdd94e5ee, 0xfdf60755, 0xcfe17736, 0xbc931357,
- 0x5ab27da2, 0xc7f68a58, 0x9b17c49a, 0x3d38df61, 0x0233d981, 0x58f9b179,
- 0x267abc46, 0xbdf72daf, 0x31c41378, 0xaed4aeb6, 0xab6e7f06, 0x0c391c33,
- 0x6e3df9eb, 0xdcaa3dfc, 0xf816e175, 0x83710abd, 0x314bd70d, 0x2b6bbc29,
- 0x6078179c, 0x8bec1f84, 0x40d760ad, 0x5c6e35fb, 0x421a5bff, 0xe2af2f68,
- 0xf5f6c0eb, 0xe7385493, 0x9296e8dc, 0x916bbd61, 0xb8056feb, 0x64efba5e,
- 0xd03ae3b3, 0x4196fe63, 0x80cbef3c, 0x71cb4d75, 0x14f5e58c, 0x68575b19,
- 0x3485c183, 0x44ffc3f2, 0x33d412ad, 0x6b0ed127, 0x04ab2f74, 0xbfd68e3b,
- 0x7a78a0ec, 0x85e3993c, 0xe8f4e7d7, 0xa0cd93a5, 0xbd15c507, 0xef3a12f9,
- 0x7a633f1d, 0x3fda09ea, 0xe7452bbc, 0x18778213, 0xe84947bb, 0xc1242587,
- 0x74d0c76f, 0x9dfb0e74, 0xbd17aa5b, 0x3849c7e8, 0x491f635f, 0x0f7ec519,
- 0x7ac3da1d, 0x83919093, 0x0cca98fb, 0xe2835ef6, 0x66fde371, 0xdd5677e3,
- 0xb3a7f8c4, 0x67df2978, 0x43de5971, 0x895fae70, 0x784ee99b, 0x4f862137,
- 0x0b7bcb15, 0x07cc0912, 0xcd544b7b, 0xe449bfe5, 0xd8834afb, 0xb70eadef,
- 0xa32ed085, 0x35e98452, 0xd9f68a24, 0xf981d268, 0xe66de031, 0x0d2c35c2,
- 0x278d8e2f, 0xbbe2c8ba, 0xc7ec1101, 0x788d5bb4, 0x44f5f04c, 0x96bfdeba,
- 0xfc36e3c8, 0x66538c77, 0x7d7ee214, 0x5fab1266, 0x0fbbc815, 0x338dbcec,
- 0xc69c61a6, 0xf58cefb0, 0x16dfb0d2, 0xab579872, 0xc17b5c42, 0x3a16ebb0,
- 0xb6753e59, 0x8868e0fe, 0x0b53b66b, 0x2fee1b34, 0xf96af8b3, 0xb034e2e6,
- 0xba1e16cb, 0x4ce4ed15, 0x8b65d995, 0x8250ce36, 0xdadee1a3, 0x8a07f43c,
- 0x84484c37, 0x4ed5847d, 0x8575e27f, 0xfbe267e8, 0xc7b503b9, 0x355da6b6,
- 0xab71e419, 0xca90128d, 0xeeb24bfb, 0xb17c0b1e, 0xcced0f21, 0xc6c109ad,
- 0xd6efda24, 0xabfcd67f, 0x4ea7fe68, 0x8c38f0bd, 0xd5813ab3, 0xc051bbc3,
- 0x12e73d9b, 0xc9bbe1b6, 0x3d6f8dfd, 0x1252f097, 0xa8ca7f7b, 0x7e536fff,
- 0x80007d7c, 0x00008000, 0x00088b1f, 0x00000000, 0x7dbdff00, 0xd5947c0b,
- 0x66fdf895, 0x666579be, 0xf263c992, 0xc2130922, 0x9e4e5e4b, 0x124c2280,
- 0x4cb443c2, 0xe8202a10, 0xa79034f0, 0xbadc5d48, 0x30040cff, 0x5706b650,
- 0x84ea2b11, 0xbbaac562, 0x351ba341, 0xb88080ea, 0xda446dd6, 0x8ffd16d2,
- 0x4810154a, 0xfed2b58a, 0x39cf65dd, 0x7cccdef7, 0xb5f01993, 0x3efeb4ff,
- 0xe7ddf7ee, 0xce73df79, 0x12e973bd, 0x2c614dfc, 0x5630a494, 0x51c1d8ca,
- 0x618cf58c, 0x24dea98c, 0x064dcf06, 0x34e2d26f, 0xa37efac6, 0xf5e1bb67,
- 0x926f6617, 0x25d8c6c3, 0x79fa2ed1, 0xa0b199aa, 0xcdb3b189, 0xc11c166e,
- 0x336699d8, 0x1f966b95, 0x9fa0c698, 0xb9850e9a, 0xc55b19f2, 0x3f6336da,
- 0x69923baf, 0x3d0155dc, 0xf4648e0b, 0x5bfe0977, 0xd528fcbd, 0xebc9dd5f,
- 0xaa0eb2d7, 0x4f3192bf, 0xf76b3c07, 0x1cd0595a, 0x51df5fae, 0x4a1f69ac,
- 0xd7bf51d2, 0x3b06fb25, 0x5bdd8c9c, 0x2abefc3d, 0x5d569f78, 0xfae1f662,
- 0x13e38e58, 0x87afa8ab, 0xebe63af7, 0x77aeb188, 0x49de5c04, 0xac4e8a82,
- 0x32b1d0ed, 0xe03ad6c6, 0x1ec62e9f, 0x6c7cd850, 0x15f7f6b7, 0xc2632919,
- 0x9e2ad6ed, 0xf898c70c, 0xa8bc6a70, 0x88d48167, 0xc467dab2, 0x345e35f5,
- 0x0ef3fbd2, 0x63075fb3, 0x3ff4c91e, 0x7fac2d70, 0x1953eb26, 0x909f53cc,
- 0xcd5d8e38, 0x71258b58, 0xba673e37, 0x08a17d0c, 0x53333038, 0xf8337e71,
- 0xc4ebf62b, 0x71944769, 0xed403ed8, 0xa98ed967, 0xc473400c, 0x8303735e,
- 0x90b037f7, 0xce060aca, 0x28fdfa0f, 0x2359dfb2, 0xdd1be5b5, 0x09ecf2da,
- 0x7e6332da, 0x9a4fd782, 0x1a4eca9b, 0x04fefdc2, 0x0311d6a6, 0x5802b72e,
- 0x5eed7eb1, 0x0464e04b, 0x923beb1e, 0xaec6e535, 0x88c9c0ac, 0x1ff16a71,
- 0x135ff059, 0x589d775f, 0xdf4607f7, 0x5bc00ead, 0x71190b3d, 0x46c140dd,
- 0xacc658ef, 0x7c45e616, 0xf16fd81d, 0xcfe812b0, 0x00b76e66, 0xabbb1b7c,
- 0xdef02595, 0x30ef876a, 0xe196273f, 0xfaf03569, 0x0e88058c, 0x39da8fe0,
- 0x5bed99bd, 0xb713e415, 0xcdfedaab, 0xff00dde7, 0x4f0293dd, 0x24ac3d95,
- 0x0ea3ac46, 0x5e1e91d6, 0x07eb39c7, 0x582f8865, 0xa5ec6fcf, 0xa6461748,
- 0xf3d78524, 0x5cb5e1ad, 0x5dc6af0b, 0x1837a236, 0x1844bde7, 0xcea761a7,
- 0xceb2846f, 0x7e4463dc, 0x3ce917b9, 0x1c72de06, 0x6f3c4c4a, 0xe0c73c43,
- 0xfcaceda7, 0x1cc7e43e, 0xc7181fe4, 0x6527eeb6, 0x8f818b27, 0xfa1737aa,
- 0x054dbea0, 0x547186fe, 0x08a9bff8, 0x6d3bd9c8, 0xe9d03255, 0xc3e73b29,
- 0x7a2e890d, 0x0abc50ee, 0xe75d35e2, 0xd5fa47c9, 0xcc43b827, 0x66a3f1c1,
- 0xcb601942, 0xf962c1ae, 0xefe81ebd, 0xcb1b9821, 0xf0098416, 0xcbc2c878,
- 0xefca392f, 0x6ee308dd, 0x0de5e64a, 0xd5b9bd3f, 0x16ca093f, 0xe5439e59,
- 0x416d0c87, 0xffdde03d, 0x44f5c982, 0x28f7b53e, 0x32305e58, 0x4d4c04f0,
- 0x2365843f, 0x4226a65e, 0xf4b720e7, 0x9b769a2f, 0xeed05ea0, 0xa78427fb,
- 0xfb39ff5c, 0x26363cf1, 0x4d7e7f66, 0xacdf797f, 0x53bf183f, 0xfbf87577,
- 0x419dc4d4, 0xc2e76f3d, 0xe7a72c76, 0x9ff43f03, 0x6d89a2fe, 0x0623e285,
- 0xda179b76, 0x632c5dd5, 0xd43908c1, 0xb679f023, 0x5b7241d9, 0xf943afbe,
- 0xa9f9063d, 0x7d70e487, 0xfe46aa47, 0x7f5cb94a, 0x7f4d5af1, 0xc27c8e39,
- 0x43dabd57, 0xe2feadf2, 0x121efa64, 0x736cf4f2, 0xf889e926, 0xc8d20ce3,
- 0x1338f0f5, 0x72f8b059, 0xefa24ce3, 0xcbe61c72, 0x06bdb922, 0xa4240ce7,
- 0x87bc8237, 0x750c2e71, 0x465f2525, 0x0276d99f, 0x67ac4591, 0x63341a9b,
- 0x07dcdbff, 0xfc18be1c, 0xb844e520, 0x1edb51bd, 0x811b23f4, 0x4863edf4,
- 0x7aacffb7, 0xd4fa91cc, 0x5038f066, 0x8af6a86f, 0x34372e23, 0x86647e4d,
- 0x5169280a, 0xd97f3d39, 0xd1e881b6, 0x411f706e, 0x3aeddafc, 0xafbe1f97,
- 0x483ce9b7, 0x730e2d27, 0x51bdf100, 0x7281c1b9, 0x076bf643, 0xb8f38f31,
- 0x7a421b60, 0xd57ade3d, 0x0f54898b, 0xa9199266, 0xc6f7ff1f, 0x0f17c583,
- 0x31bd8f1c, 0xfa0b88f1, 0x6e744b57, 0x910be00b, 0x1d0471fa, 0xdf63f744,
- 0x779cc6a9, 0xff093d74, 0x8436f8b8, 0xe7fe1112, 0x8119ba6d, 0x4d2ef318,
- 0x9e9bbe56, 0xdf25145a, 0x3c3b7f93, 0xd095ed88, 0x49f20a0f, 0xa32696fe,
- 0x90bc2dfc, 0x3922e958, 0x73b5ee9f, 0xb6e385b1, 0x7d9a8ed8, 0xed988fa4,
- 0x3ebfd913, 0xb849fd3e, 0x64aade18, 0x04601f88, 0x4ae37a86, 0x412bb070,
- 0x1597e22f, 0xd3e50caa, 0xa76f3a40, 0x77d7f4f9, 0xeb11e743, 0x0edd516f,
- 0x75fd6ba4, 0x99ca331e, 0xe6398ef5, 0xaa379410, 0x20f9d9ae, 0x02defa87,
- 0xb7d6127b, 0x1cc8ad29, 0xc15a8f8b, 0x2df9c46e, 0xd669d64d, 0x1d669f23,
- 0xf7e8dfe7, 0x9eb9925b, 0xb13fdd68, 0x9f1253c7, 0x79d2407e, 0xcb9b8f51,
- 0x5856c754, 0xe7c0de9f, 0x0763896b, 0xc1e37eca, 0x0b7ecb6b, 0xa87569c9,
- 0x44f68039, 0x549b78f4, 0xbe078f77, 0xf8f9826f, 0xc7c39cb1, 0x3aa254df,
- 0x16d74376, 0x47330257, 0x4b3837d4, 0x6c17fe08, 0xdf0f4c69, 0xc63d2137,
- 0xd3849798, 0x68efe4bc, 0xe8a2f93f, 0xc3b7f732, 0x5d0d10d9, 0xcba2c6b6,
- 0x4b37a879, 0x3999fcf9, 0x9343fe72, 0x8c7c8ebe, 0x49b29ba6, 0x977c83cc,
- 0x5876cf01, 0x66caa76f, 0x807d43ec, 0x9844d6b6, 0xe636cddf, 0x393e9900,
- 0x32677cb5, 0xe7acb7ac, 0x3f219180, 0x1d693a74, 0xf47da275, 0x8e14a6b8,
- 0x838a533f, 0x3dc7499e, 0xf8014f4f, 0xb824f676, 0x99d4f814, 0x0630fa02,
- 0xbc088f7c, 0x9fc6d633, 0xf21c686a, 0xb65fac8f, 0xc3767988, 0x6b0250f3,
- 0xb2bd8335, 0xc607c84f, 0x154fe7ee, 0x99c61718, 0xdde8cafd, 0xf58a2f64,
- 0x80b5021f, 0x43d3d3f5, 0x77fd14e3, 0x585edbc0, 0xeade047d, 0xdbc221cd,
- 0x6bdf46db, 0xe3c69f08, 0x772c74a1, 0x87933d1e, 0x70b670f8, 0x25efb5fb,
- 0x6ee9006b, 0xd3d67e20, 0x0e2eeafc, 0x81e2fe62, 0x8353ab78, 0x2eeb5fa4,
- 0x5877d1e6, 0x129cdfb7, 0x6c1b3efe, 0x2eb00986, 0x4270e666, 0x47c2c4f8,
- 0x896be0bb, 0xa3eb500f, 0x081f02ed, 0x3ec48fa7, 0x4eef1fa7, 0x780666e3,
- 0xefe66b3f, 0xdf246799, 0xfe7d0987, 0x005e4251, 0x0d1f33f7, 0x7a46ce07,
- 0x91e95d50, 0xe2cea77a, 0xac3e6fb9, 0x67abbd9b, 0x5963c04f, 0xed15ada5,
- 0x4f2665ab, 0xcb5dda12, 0xeb2bd3de, 0xc48409f3, 0x3c042b07, 0x5df732cf,
- 0x36ff3f88, 0xc209e38b, 0x97ff769f, 0xf8bca3bf, 0xa2bf681d, 0x9346ef4b,
- 0xcda56971, 0xf596fd8f, 0x876d3c54, 0xad5b2bf7, 0x2efd062e, 0x04fee29b,
- 0xf765bded, 0xf21b5c59, 0xa438bf71, 0x5dfa0b3c, 0x03be60fb, 0x9d7581e5,
- 0x06ecd337, 0xeb7ee093, 0x6de02b4c, 0x8964b293, 0x7dac0852, 0x1516ca7f,
- 0x57feacf0, 0x281667e5, 0xc17f755f, 0x8c75f316, 0x1cb282bd, 0xd0ff59ed,
- 0xfedf6899, 0xf646a712, 0x7f6fb72e, 0xca274479, 0x82a65bc5, 0xece5180a,
- 0xce60d9d4, 0xb78a532b, 0xf4fc6198, 0x0ea14f14, 0x32935bc6, 0xb7f62661,
- 0x7fb1bef4, 0x77df09dd, 0xa99acca4, 0x44de13e6, 0xcaccef7b, 0x926ed0a1,
- 0x54b3cf2c, 0x56697f42, 0x27a7b616, 0x090fbf00, 0x77f68f8f, 0xbdfdbf67,
- 0x1cd4e660, 0x53454bc0, 0xbffd0aa5, 0x96db729e, 0x36315731, 0x877281fe,
- 0x983fc607, 0x15a664b2, 0x9469dff0, 0xf16d97f5, 0xcc9d58c0, 0xbe0186f7,
- 0xbafef1ff, 0x9fa86699, 0x742dea96, 0xcd53fac0, 0x91996ff7, 0x65f81dfb,
- 0x4fbd12a4, 0x1271482c, 0x90461cdf, 0x33ebade6, 0xf82afd72, 0x71d3873d,
- 0x9424797f, 0x4ce511ed, 0x10dcee5e, 0x4e9c7e5b, 0x33b972e5, 0x8f77f621,
- 0xef004b90, 0xb3e90ea0, 0x96181acb, 0xc027961f, 0xc409e64f, 0x3cb9db5f,
- 0x639abe01, 0xd98e3e27, 0x5fe537df, 0xd3f53b80, 0xe8ac7aa9, 0x0d7290bf,
- 0x71c56666, 0x69764cbe, 0xcf5975e4, 0xbfb79252, 0xeb7c154a, 0x5671f0e2,
- 0x330ae56a, 0xb8470cf7, 0xc58b76c8, 0x4b47f33a, 0x88d052ff, 0xe2d6b9fc,
- 0xacf9c0c9, 0xc19e57dd, 0xd787632e, 0xf8d72c5d, 0x98ebc24b, 0xf407ef4a,
- 0x44b9fd0b, 0x5f31eeff, 0x57c95e07, 0x7d1a5780, 0xc33ad2bf, 0x3bfd69fd,
- 0x7ee3fb03, 0xc57a019e, 0x1b9e7b18, 0x415eb853, 0xe422ebf8, 0x5f214ada,
- 0x3d916a41, 0xabc5fe7e, 0x8fcd6f76, 0xf503771c, 0x7a7df80f, 0x412fee0a,
- 0x2b1ca2be, 0xb0b33d53, 0x8a4f597e, 0xa079ed03, 0xde828db7, 0x8937a454,
- 0xa694cee7, 0x76ef5a72, 0x863bb1c5, 0x3913f81d, 0x83c536af, 0x22c649f6,
- 0xc4497e9f, 0x87fca4fc, 0xff453bfe, 0x1f9e9c25, 0xc5e7a7ed, 0x2fc23fc8,
- 0xdf40dcc4, 0x5fce0763, 0x08ce36c1, 0x2582f5fd, 0x7091f380, 0x2ff4b6fb,
- 0xb8ba87ed, 0xda912a7a, 0x260f1c65, 0x219ea0ba, 0xb9f9c5c5, 0x6bc4e3e3,
- 0xe9755f51, 0xebe2e299, 0x2651b946, 0xe7bfa4e5, 0x764a8548, 0xbb2e584c,
- 0x72919ec8, 0x87366833, 0xbdbfdfeb, 0x9446c667, 0x2fbe26ab, 0x1483d34f,
- 0xe3cf0a2f, 0x2fae14e5, 0x2798f827, 0x24781d96, 0x08e52ed9, 0x75e1e3ad,
- 0x5863ec95, 0xd7e85d9f, 0xf93f2109, 0x664c9eb3, 0xf0e13ec2, 0xb67bfa90,
- 0xdcaff429, 0x47a5a64f, 0xa53b0659, 0xee105741, 0x89cfbf1f, 0x8263fba0,
- 0xf3f1a20e, 0xc013e55d, 0x48708fc1, 0xc872e14d, 0xed056509, 0x17f4150b,
- 0xb55cffc0, 0x3f35bdcd, 0x2e36de62, 0x1d7a9d8f, 0xe0576397, 0xfe54b48b,
- 0x3b25efbd, 0x1e1873f1, 0x2ff98edc, 0x1d76f701, 0xc17dc1ab, 0x09f01d21,
- 0xaf8da2d2, 0x598bfcf3, 0x29e7efd4, 0xeffeb93a, 0x1bb72e45, 0xd7ce3c61,
- 0xbfd63f64, 0x3b5da83c, 0xdcdfde7f, 0x658f4e54, 0x68853dc7, 0xdaf30cc7,
- 0x285fb8dc, 0xc07399eb, 0xdde1e500, 0x4b6b038a, 0xc1de1f3a, 0x4ba814f9,
- 0x67ade5c0, 0xa5b5fb22, 0xbefa3a72, 0x38fc31d6, 0xcbc457a7, 0xcd3e08e2,
- 0x7871b54d, 0x084cfac1, 0x472b554f, 0x9bfbf3e5, 0x0180f787, 0xf0075bd6,
- 0xe12db140, 0x64b1d9d6, 0xf8f90583, 0x1f237338, 0xa258ef9f, 0xdd788b1b,
- 0xebbec8c9, 0xf00f0f97, 0x147b4875, 0xe903b2e8, 0x5cd4eaf2, 0x71d86f1a,
- 0x7c0c758f, 0x1376861f, 0xec3b95fa, 0x4c57dc01, 0x4dcdf54e, 0xedce7845,
- 0x4a2064ab, 0xeb4dac1a, 0xfbef112d, 0x7d4177eb, 0x7e9f63a2, 0x36f3ce2c,
- 0xc2bab6c6, 0xfaa981eb, 0x6f5a1fd1, 0xa02d3e04, 0xd6e11072, 0xfbf5e469,
- 0xcf8a3316, 0x8cfbe834, 0xf7f41df8, 0xa3cfa22c, 0x2fc414ba, 0x6ed09bee,
- 0x737bd3ae, 0x67d7dc14, 0x07a8dc98, 0xf4421f60, 0x54c2c87e, 0x26fff40b,
- 0x574e513c, 0x8fd8efe9, 0x502aaaf0, 0xae242ddc, 0x60dc85da, 0xcd37dc41,
- 0x7a25629e, 0x39dd5f64, 0xbff51ab4, 0xfa09e395, 0xcc7e8b31, 0xff30a2e6,
- 0x2aef3afd, 0xfd48ffda, 0xa8514876, 0x8dd7439f, 0xb112ddde, 0x50fec22f,
- 0xaa521ffe, 0xfa40ee73, 0xb23afb17, 0x7ac2d30f, 0x2295ed17, 0xfdde245b,
- 0x3ca17e62, 0x7b48a3a4, 0x7ed3ed14, 0xb1dfd67b, 0xd9c83a65, 0x823a33f1,
- 0xd152073a, 0x01ff33f3, 0xf60551d6, 0x70e005ac, 0x33972a5b, 0xfafdf287,
- 0x30df9c44, 0x3abc3f58, 0xd31be09c, 0x938f0b64, 0xe90ffc2e, 0x482fee46,
- 0xbfcfe04f, 0xe73b72a7, 0x1e5c6927, 0x978d21fe, 0xfb6313d3, 0xf510be2b,
- 0x1f971354, 0xfcb9cb5b, 0x41b7ae8f, 0xedadfbf4, 0x668a31de, 0xef760f7f,
- 0xf76e5486, 0x885fb91a, 0x0a9613c7, 0x873b06fa, 0xabb614f0, 0xda503c78,
- 0xccf45fa1, 0xf372f2a3, 0xbfe8d97b, 0xe69fedbf, 0xb6f487dd, 0xf27a37f2,
- 0xf1149c57, 0xbec99582, 0xbfdc64f4, 0xabf6c427, 0x75d6273c, 0x1f9199ba,
- 0x1b8c53f8, 0x893dec82, 0xaf284371, 0x34e0f9da, 0x2cd5bfe4, 0xe5e0fe40,
- 0x5c51373b, 0x61407970, 0x69f7052e, 0x1627ee5e, 0x47bd58f8, 0xdf4bf1af,
- 0x931936ae, 0x77e984c7, 0x6e369b45, 0x58abb358, 0xf6f6fe53, 0x440b2569,
- 0xfcb0a1c8, 0xa3ef4699, 0x1ef495fb, 0xd47ea76d, 0xc3f8d2ec, 0x461cee97,
- 0x97f597eb, 0x77ad3731, 0x66816b59, 0xf395acde, 0x49f9bc49, 0xd4bb45ba,
- 0x469e731f, 0x008ffbcd, 0xff08fefe, 0x4353d2ff, 0xa92d1e69, 0xba40ffbe,
- 0xcac3cf09, 0xdabf1afc, 0xb027c724, 0x7ee16656, 0xff23a049, 0x5081ece5,
- 0x6fffa72a, 0x71d1f70f, 0xfee305f6, 0xca0beebf, 0xcc397126, 0x0c3614da,
- 0x6aa7e31e, 0xa0bfb4ed, 0xa7c52bbe, 0x616beb95, 0xa45f2d47, 0xd45177ad,
- 0x5dea28bb, 0x6912bfc9, 0x2805299f, 0x0d7f78d7, 0xcff38f82, 0xa0ba351c,
- 0x6e34f8de, 0x3d3916c7, 0x6cef5097, 0x438e24b3, 0x4b36ca7f, 0x52f5005e,
- 0x38bafaff, 0x48336d1d, 0x033b8a3f, 0x5ffed6e1, 0x88a8b677, 0x0fb07dc7,
- 0xfe587900, 0x8a1641e8, 0xae375390, 0x01cb3c53, 0xef2176de, 0x7d7cdcea,
- 0x71a0ee75, 0x5d93f428, 0xd395e7c7, 0x23515fb1, 0x08d4e5da, 0x419a5f7f,
- 0xc1cccfb3, 0x8d254e32, 0x9a9ce3cb, 0xea1432a0, 0xa3daef65, 0x875fd8a8,
- 0xbb337a42, 0x41130009, 0xdc25d957, 0xa4b1b9be, 0x2636595d, 0x5d56870c,
- 0xe00718f5, 0xeadd35a7, 0x8f737d46, 0x0d2437d3, 0x182279e7, 0xf8fcedc4,
- 0xda2a3d13, 0x7a753fef, 0x619cd20a, 0x8ef4b838, 0xd6a7d46c, 0x6d9e7c13,
- 0xae63fbfd, 0x4da22867, 0xdcddabfe, 0x23b3d19e, 0xa487db8c, 0x8c37d2af,
- 0xe727bd24, 0xf4229e97, 0x3df33a45, 0xadfaa367, 0x68c9f08c, 0x861be93d,
- 0x2cf6e6ef, 0x815577c7, 0xafbe0f77, 0xa8aab8ca, 0x6c17de05, 0xa14baa0b,
- 0x62bbcbdd, 0x85cb83fb, 0x4c75813e, 0x75c9f5c2, 0xc82e495c, 0x7e38867a,
- 0xd60fc90a, 0x1ff7b119, 0x2f7d2230, 0x216d347f, 0xa36eb7ce, 0x30949991,
- 0xf4ea7ffc, 0x64f9c6ce, 0x082bb477, 0x93dfe91b, 0x1dff4ae3, 0xfcfe477e,
- 0x96f928c8, 0xfe5c5fd3, 0x2cf7a75f, 0x1b67948f, 0x6927848d, 0xc7e7873f,
- 0x69d5fded, 0xeabecf5c, 0xf9c12ef4, 0x276d7434, 0x3daacf7f, 0xf9631a1f,
- 0xe2f9a3ab, 0x6a54704a, 0x6ea0bef8, 0xeb8039be, 0x25547f2f, 0x68dda83a,
- 0xdd5938a4, 0x9fb8fb33, 0x46e61ee7, 0xb1d75139, 0xe30e594f, 0x4fb33ed6,
- 0xd7011159, 0x05017541, 0x2ec233e7, 0xafcb90f9, 0x3f47ba68, 0x872dda32,
- 0x9c4e5c2d, 0x15f9b72d, 0x8359eb80, 0x9deb0eaf, 0xfdbab2cd, 0xbc3c61f9,
- 0x11fa6fb9, 0x3fb037cc, 0xb3e20a67, 0xd33bb755, 0x475af50c, 0x5f48dd19,
- 0x36fa753f, 0x54525c23, 0x4fb6276f, 0xd7bbb34e, 0x89975b43, 0xfbbca115,
- 0x1f1870ba, 0xefe32745, 0x85d3fce1, 0x91db8872, 0x813fc845, 0xa7b4bb34,
- 0x361dae48, 0xc73c75f0, 0x9eff7cf8, 0xe89079ea, 0x8d0a48f8, 0x54175d9b,
- 0x7f9d9fd0, 0x6b9239e6, 0x9d30ffb2, 0xe4891e79, 0xb3cf2bdf, 0x56f488c3,
- 0xf950e42b, 0x8f947ba3, 0x4bfde623, 0x6e91f430, 0xba019fb2, 0xfdf7d1b4,
- 0x3ea8d333, 0xbdf0b933, 0xe16aed42, 0x79088afb, 0x4311d723, 0xf5c3ecee,
- 0x1cf44ed8, 0xc82772e4, 0xbe628dfd, 0x157cf8d1, 0x9a7c1fe5, 0xde99ea06,
- 0x3123fd1b, 0x48787a2e, 0xe527f502, 0xbedf3440, 0xe51ce82a, 0xfe46cea5,
- 0xe52bb25a, 0x22bd64fc, 0x34fec567, 0xc10f4382, 0x4a977ea1, 0x7a32a9eb,
- 0xc111de87, 0xfd16bf0f, 0x03f9b81d, 0x07fdca23, 0xa25dfdfe, 0x8536fac7,
- 0xedacf1e2, 0xd43ce35d, 0xf4a7fe47, 0xe2ce6768, 0xf1db0126, 0xa784bbc2,
- 0x2e5c9d59, 0x53ee77d7, 0x74c2d997, 0xc0e67f9a, 0xf56748ad, 0xfb86261d,
- 0xdfbfa022, 0xe9a27c20, 0xca47c254, 0xb4f878dd, 0x9472e0ce, 0x47e48df9,
- 0x3e54fd85, 0xdca429fa, 0x4eaa7bfe, 0xfbf809f8, 0x1cbc690b, 0xa7df1fa6,
- 0xdcb08f08, 0xe45f10b5, 0x603a299f, 0x5bb87dc6, 0x5a7f3f21, 0xe4678725,
- 0xc6c7aabc, 0x54ce9b97, 0x50d437a1, 0x587b1cde, 0x7fcbf7be, 0x810bfed1,
- 0xe41f786f, 0xd410d9ef, 0xd1fe72f3, 0x7277cbf8, 0xce831b7d, 0x11d71bfe,
- 0x3da4dfad, 0xc9e6e920, 0x8f46aa5d, 0xea469dd8, 0x731b0ecf, 0x728ec79c,
- 0x61d8cf1e, 0xc76cfae0, 0xe500737a, 0x780b9bc9, 0xa17d995e, 0x43cf8831,
- 0xf875a5ba, 0x1f3650fd, 0x5ba755bf, 0x0dd6e583, 0x7842d636, 0x4b3a24f5,
- 0x19127e91, 0x1e5c8f97, 0x973cf03e, 0x5b7e7567, 0xeb3fc180, 0x5397737c,
- 0xe2cd39dc, 0xf333b8c6, 0xb3ce341d, 0xd72ba40f, 0x2e8dfb73, 0x83ab3f78,
- 0x03c49ff3, 0x2fa253c8, 0xae120fc9, 0xb8727861, 0xf8927e4b, 0x67f4bbf8,
- 0xa77cbd03, 0xda3daabc, 0x46dbdc78, 0xbe4ed5df, 0x706c3acf, 0xc7869fa1,
- 0x6fd1e217, 0xb3b7baed, 0xb51d824f, 0x7a2df33a, 0xfd85be4a, 0x27bf86ac,
- 0x3817bc09, 0x74afbeb9, 0x2da9ba72, 0xacbe20e9, 0xfc44d93d, 0xe5c19b6c,
- 0x5684ed9a, 0xcff6331e, 0xa8dbbd62, 0x63b5955d, 0x5477e61a, 0x7038ae3d,
- 0x6e4f1fbf, 0xfcf0aede, 0xbd774fb8, 0x72f98891, 0xf2b02bec, 0xe1629e31,
- 0xe4eb9deb, 0x5eece272, 0x7bd13800, 0xf672f193, 0x63fa95fb, 0xc20a63c1,
- 0xfac056b3, 0x139533ec, 0xec7e84ff, 0x61ee49bd, 0x9ecfe4b0, 0x3feee9b9,
- 0xeecfbcc1, 0xf746e299, 0x978b5a65, 0x69cfa7e8, 0x037ee371, 0xf40cf7c4,
- 0x78efae17, 0x685af123, 0xabe9fa77, 0xd76e508b, 0x799e798a, 0xe10ebf5e,
- 0x7fc9e1b2, 0x6bdf8c9b, 0x09aa4a03, 0xf8fbd9c7, 0xbe63677f, 0xf2469eea,
- 0xfd3cb517, 0x17f311ba, 0xfe768174, 0x03926f7e, 0xf9fe9deb, 0xef08c9f6,
- 0xfa168e96, 0xede7e67e, 0xe4f03e54, 0x77f6bdbf, 0x1378e3f4, 0xccef58dd,
- 0x2f09fbf3, 0xf2953e75, 0xf5d1e2db, 0xb9fb7d8e, 0x8f3d44bc, 0xcb9f307c,
- 0x92d74931, 0x793f4f7e, 0xbd48c4db, 0x0ab7df21, 0x026b4e7f, 0x099f23d7,
- 0xe0adadfe, 0x9ecfcef1, 0xfda7ccb5, 0x1c343181, 0x6375c5f7, 0x2ddc5d38,
- 0x71d751e0, 0x46c1a187, 0xdf9fa9ed, 0x73e3df02, 0x27e7d02c, 0x64852923,
- 0xd7ca25cf, 0x0faa57f9, 0xbfa026f5, 0x1f45e6e7, 0xeb1f382a, 0x2d432698,
- 0xfe69f3cd, 0xf91d561d, 0x6c6d6cbd, 0x38bffb3f, 0xe02ec26d, 0x59dd907c,
- 0x3922e39d, 0x8b0f7260, 0x6bb387b0, 0x27182d7c, 0xcfad7ebe, 0xbe3c07ad,
- 0xb4e8ea7c, 0x727e5041, 0xf84c52a4, 0xcf5c2bd7, 0x4e346df9, 0x81c1fa3d,
- 0x3e0b768f, 0xf5307749, 0xdc03921a, 0x32a5501f, 0xaa7e46d5, 0xf513923e,
- 0xee0f42ad, 0x736e7e11, 0x764dde5f, 0x26bb676a, 0xed061f62, 0xf72a366c,
- 0xf310fde5, 0xe7f8674a, 0x1971de93, 0xa467be69, 0xf27e603c, 0x8b7e4a7b,
- 0xbca11bf6, 0x57d1fcc1, 0x285de59d, 0x3d33e51f, 0xefe4bf8e, 0x74b8fbe2,
- 0x15ca174f, 0xa35537b6, 0x95c9e20f, 0xe79f3703, 0x0f95fb7a, 0x901b0e89,
- 0xdf7c710e, 0x5ede8d49, 0xe815c24e, 0x890fa5f0, 0x7177970e, 0x55d0daf9,
- 0xd4fdc46e, 0x69d7e10e, 0x7484f410, 0xbfe8fb84, 0x9c69933a, 0xe1a1c986,
- 0x0bcea728, 0x12ff3bba, 0x3a43b7a7, 0x0e01f91d, 0xdedd1eed, 0x8fd40ca2,
- 0xf0978d4a, 0xe6f800dd, 0xa3daf376, 0xd7d56768, 0x6bf23730, 0x07e0a743,
- 0xbe117bb0, 0xcbd55d0d, 0x6941bfb1, 0x0ddfc933, 0x41b4c976, 0x63a86e50,
- 0xd96fc8a5, 0x425e2abb, 0x7c5d60ba, 0x035d9e3f, 0x4dd22cf6, 0x9f5bbd5a,
- 0xdb8f7a8f, 0x2c8fd7bd, 0x723bf6a3, 0xf2e7145d, 0xf38a3157, 0x19fb40ef,
- 0x68d65df5, 0x36fb3f6e, 0x5cc5dd92, 0x6537e409, 0xd60d753e, 0x622ff06f,
- 0xcd11d794, 0xb4292fc7, 0x5808680f, 0x56681f29, 0x1a7fb717, 0x9f1f38ba,
- 0x4f91f093, 0xe4adcf43, 0xc4c17f8f, 0xd0fe11fc, 0xce9a5f37, 0x268becf5,
- 0x359fb3d2, 0xb0c7d87b, 0xbc85b7a0, 0x6dac7097, 0xdd21d7cb, 0x09937632,
- 0xcc4cb1e7, 0xf5c0cda3, 0x03d0b246, 0x3cf8db05, 0x77e174d4, 0xa789d74c,
- 0xe2e79b51, 0xe17f93f0, 0xc88f189c, 0x39e85d22, 0x797eba18, 0xeea4f890,
- 0x9a5fde19, 0x677853c9, 0xfb4abd04, 0x0b1e9a28, 0xbbd9b8c4, 0x4c282a0e,
- 0xd1cd77b2, 0x35f5f9f0, 0xeb08d82c, 0x2e977ebc, 0xd91c6538, 0x9e490b4d,
- 0x58b237af, 0xd2232af9, 0x9556fdb9, 0xbf442dea, 0x36cdd576, 0xb93fa477,
- 0xb3a3c12a, 0x24571da0, 0x12ded8fd, 0x4a9d1b8c, 0x6f11bbb7, 0xd25dd2e3,
- 0x5bd8d30e, 0xdcdff703, 0xcda1bc0e, 0x1ff70e3f, 0xf309f581, 0xda09ae29,
- 0x0edcfc8d, 0xf7fb8f68, 0x9cfed7dd, 0xb85bdfef, 0x070402ff, 0x6f5499c9,
- 0x9d8ffa09, 0x5cb5de05, 0xb1ddd93f, 0x93aaf3d6, 0xcdc0e7af, 0x3ee216b7,
- 0x8dae61b1, 0x5781e1f8, 0xde9ca594, 0xbee21140, 0x83f9c7da, 0xe13c7f01,
- 0x3b247a22, 0x1bc9a1aa, 0x9c8f4d88, 0xaec01a5f, 0xe81b3b42, 0x93b70d71,
- 0x13f38c6d, 0xbfb94ba7, 0x6915b947, 0x8d3e4acf, 0xbf497be6, 0x35ff7cfd,
- 0x81bcfdf9, 0x8079e3f3, 0x3f7bd203, 0xe9ccbf9d, 0xe07aeb7c, 0x15bef847,
- 0x4225b1f8, 0x7fef47fe, 0x1fb89e70, 0x1ef6f290, 0x3a5177a7, 0x6fdda1ca,
- 0xab50c66d, 0x2f0d8f94, 0x397e196f, 0x958ccbbb, 0xf0335fa1, 0x60fd246b,
- 0x445ed68c, 0x09ea3f4f, 0xfed8baeb, 0x6dd2bb8f, 0x3f3fcddf, 0xaee52f30,
- 0x7981d2f4, 0x73a8e929, 0xadbb6f10, 0xa58fb401, 0x3e7a291f, 0x499f044b,
- 0x03fdca7c, 0xfeb021c6, 0x37ef82fd, 0x888f7a89, 0x84bec467, 0xf3a5c1f8,
- 0xf679487d, 0x6c91f471, 0xb5f97df7, 0x2f5238e4, 0x8c8dd346, 0xaa7ae0a3,
- 0xd7afc4c7, 0xcfec5fb6, 0x29f8e8a2, 0x800b5fc1, 0x6dde7037, 0xc417e086,
- 0x19d8778f, 0x99f813e5, 0x71e31527, 0x7ce08daf, 0x386fb234, 0xfa66b7b6,
- 0x92ba44be, 0x8f7c5d7e, 0x115aaa71, 0x6bddacbf, 0x7f9e4408, 0xd18337b9,
- 0xb376bd38, 0x91fc0f5f, 0x87dbe99b, 0xcc15fded, 0xf33d441d, 0x2b8a168f,
- 0x8a5b8181, 0x8591a6f2, 0xefce1112, 0x205efb25, 0x0cf7d5fa, 0x39e3bf47,
- 0xdf0e3425, 0xdafe109f, 0xfb5fc213, 0xcf7bd77e, 0x17ad02be, 0xf16e72bf,
- 0x5ece918f, 0x7d21e4b4, 0xe7f4b09c, 0xdda125bf, 0x92b9817d, 0x690e772e,
- 0x55ef5991, 0x2767fc23, 0x7ffdb1ec, 0x373c0b6f, 0x532b788a, 0xb7c3ed19,
- 0x19f97067, 0xe3c4bf3e, 0xb4ebefad, 0x1cf937fe, 0xdfe1c193, 0x501ce719,
- 0xd7df0661, 0xfce10e74, 0x50aed7d8, 0xdd66afbc, 0x41eb3ffa, 0xb5acd42e,
- 0x9f09e907, 0x71ab8ed1, 0x283a83f8, 0xb970309f, 0xcd737f04, 0x07fd6165,
- 0xc849d4f5, 0xc5077e33, 0xfd0a96bf, 0xcde9acb5, 0xa15fa1bf, 0x49e66546,
- 0xf2c71845, 0x9f041e1e, 0x4f2db53e, 0xf2bff144, 0xa3a67747, 0xd458ca7e,
- 0xa6c1f226, 0x55fed03a, 0x2fe8373c, 0x6f672f59, 0x132764a9, 0x1ede001d,
- 0x22f6f0cc, 0xe24a2f1f, 0x7745c17e, 0x08fe035a, 0xf057b879, 0x7cfd3461,
- 0xcdbce710, 0x01151997, 0xaa616fec, 0xefd46ff7, 0x7234e79d, 0xfa12bced,
- 0x5f4823c5, 0x4fddd877, 0x22f2eef0, 0x05d263f3, 0x0e316bfc, 0xb7b1a204,
- 0xbaf867b0, 0xbee3a47c, 0x5fa1dfbc, 0xf0e4dbab, 0x91bbf0bb, 0xf176cbbe,
- 0xe3f141e2, 0xd2232e40, 0x8545c347, 0xf76961e8, 0xae51c79b, 0xa221a837,
- 0x1b66a593, 0xa2e1b1e1, 0xd5a9e9ca, 0xdb243670, 0xa4d7ee03, 0x6032d27a,
- 0x277bfe9e, 0x093c5325, 0x17c389f8, 0xe39c452a, 0x37c332f8, 0xf7e00328,
- 0x36f13590, 0x305d7fdc, 0x8f3092bb, 0xf408d1ad, 0xe7753570, 0x43d84735,
- 0xa5aec72c, 0xfeb7ee83, 0x6e5af386, 0xaf5119f6, 0xd134f0af, 0x4945b179,
- 0x98c752c1, 0xd24fbc48, 0xf5fd1a5f, 0xc8497ef1, 0x3c8df797, 0x9d20646f,
- 0xcf6c3c73, 0x39b2f510, 0xc79fbcbf, 0xe7c39e6a, 0xbb427828, 0x728887f7,
- 0x170f2891, 0x7979d2f5, 0xf797e09a, 0xd17af1c7, 0xe3152ce3, 0x99e1997c,
- 0x7682708c, 0xc7d22341, 0x673a166b, 0xfe404ac4, 0x935bbca1, 0xc82c764b,
- 0x770869b9, 0x4c982718, 0x67a44cf5, 0x41c81358, 0xa96f67c0, 0xb5b3e08b,
- 0xe305e81c, 0x289aaf41, 0x2bf1241e, 0xcf8d1af1, 0x77ca1985, 0x181f4fcb,
- 0x51985ebf, 0xcd7e303a, 0x17c250d8, 0xf38c4bd1, 0xf5f0f11f, 0x03c73b6b,
- 0x0cf2ebf0, 0xb1c183d2, 0x49b37c91, 0xb5ca51c0, 0x78b413f7, 0xe39d3cfd,
- 0xbbd45ea1, 0xda1f7684, 0xe23eeed1, 0x7853f7bf, 0xae02b4fd, 0xfe5da497,
- 0x5f2e024f, 0x529f6ba6, 0xd1fb44cf, 0xe2f214bf, 0x47ee74cb, 0x8ddebc07,
- 0x09fa95f3, 0x19304ce4, 0xebd178f8, 0x6c339226, 0xd5e51f63, 0x83ffbd40,
- 0xea645af0, 0xf41535bb, 0xdec10fca, 0xbb511631, 0x0647284b, 0x48c7efec,
- 0xd433b0ba, 0x0e19addb, 0xf4941f6e, 0x48d7b8f1, 0x0ca5aebe, 0x657287e4,
- 0x210c63fc, 0x6bf0e40b, 0xc142bf22, 0x6214aebc, 0x07f61767, 0x8c97ff70,
- 0xa3dc30d2, 0xe8213bc7, 0x450cd1e0, 0xb215bc25, 0xaddbc442, 0x5f6e7eef,
- 0x139e5d0c, 0x4d9365e7, 0xe7ec76be, 0x916fddec, 0x18c27e9d, 0x8b66de1c,
- 0x7c18ddf1, 0xfc2521ec, 0xf4a7b6fd, 0x98d5e37e, 0xc1f67e7f, 0x4bdd619b,
- 0x1c6ef47b, 0x5f3de972, 0xed1e33bc, 0xc5031eec, 0x6fdf406b, 0x4dde7153,
- 0xa13caedc, 0x67c1d2d3, 0x3df76977, 0x907a0baf, 0xdca572e7, 0x157cfa91,
- 0x93797373, 0xcb1bb890, 0x3b71dd1f, 0xce5dcb9d, 0x003d87bc, 0x666bd3f7,
- 0x3b7c5d92, 0xcf5e51f3, 0x39ed56b2, 0xda6d15db, 0x073bedf2, 0x3925c39c,
- 0xfd102abc, 0x2ba5f85e, 0xf3fbeb63, 0x333f2e82, 0x7afdf88a, 0xfdf8cc53,
- 0x09fc85ef, 0xb4fbd9c7, 0x2f57fbf1, 0x8c6fbf1f, 0xed87df8a, 0x3df8e888,
- 0x6113f7ef, 0x91bf606f, 0x2acffc71, 0xa3e3af62, 0x58b7690c, 0x9f19f935,
- 0x125bb00c, 0x45e37be9, 0xd8f99c4b, 0x2b67fde8, 0xd7d38f63, 0x5f368e3f,
- 0xe79edc20, 0xb5fdc809, 0x8bc693a4, 0x6567a459, 0xe1c7da59, 0x3df43976,
- 0xf4babcfa, 0xf8be4b6f, 0x2ce66158, 0x176d47f2, 0xf29bbc76, 0xbb463f33,
- 0xba72f908, 0x4c10b5eb, 0x278fd971, 0x8487570e, 0x1d7a26f9, 0x42675f40,
- 0x98d8f211, 0xfd234f69, 0x3a6e66eb, 0xfee82797, 0xe8abbbd6, 0xbdffcf7c,
- 0x322332a7, 0x53f72a6e, 0x8f69460d, 0x96fa34d9, 0x65e3e945, 0x1d916f5d,
- 0x70d7f606, 0x7a7f3e14, 0xc3d26ef5, 0x1d37992b, 0xd5f7bde9, 0xe56e7411,
- 0x3961eadb, 0x4bfc9b9f, 0x35bf3c0c, 0x3987ec8d, 0x75373e62, 0x67503b73,
- 0x1c6818f6, 0xd239730f, 0xe7cd8b69, 0x8554420b, 0xf3fd75f2, 0x631de747,
- 0x15fcc493, 0xbdf00f6c, 0x52d93c4e, 0xdbce265f, 0x31eae384, 0x8990260d,
- 0x6e8996cf, 0x28a73e17, 0x83cf955e, 0x6b1a79e3, 0x3afac1ca, 0xd7cf4873,
- 0xc7483309, 0xa2f0fdf6, 0x37945db2, 0xeb70bdce, 0xb36f7c0a, 0x8a313c93,
- 0x04cf4c79, 0x6dfc88b9, 0xb75c6666, 0x4d3c16c9, 0xf4f133f1, 0x8f88b857,
- 0xf91843fd, 0x07581241, 0xd9b53f9d, 0xb171f9ce, 0xb050e60e, 0x085c716c,
- 0x9ce27ee2, 0xf3c7e6c3, 0x672f20c4, 0x5f3fa265, 0xc44ad5f9, 0xee67c80b,
- 0x5df78a17, 0x11f3f20d, 0x88a5de42, 0x7908b5f9, 0x8adcc597, 0xe480c7b8,
- 0x95f6fddd, 0x267ee037, 0xa3f7798d, 0x71387bbc, 0x32fdc506, 0x93e68f98,
- 0xc8d5433a, 0x5b57a72d, 0x46af98ce, 0xe7053bcb, 0xbed3e597, 0x9413b337,
- 0xbd04a497, 0x69529799, 0xfd12361f, 0x37210631, 0x3e78598e, 0xcf3166c2,
- 0x8853333b, 0x78598e6e, 0xb6b7c25e, 0x7ddadc5b, 0x3f0a437d, 0xdd3e7fbf,
- 0xc0f1c66c, 0xe113b98e, 0x07cc7607, 0xdfce167e, 0x41d29c2c, 0x6f9b0279,
- 0xe01bdc54, 0x6bbb66fd, 0xeba40abd, 0x7f70a99f, 0xc728ea8f, 0x3cf69c7c,
- 0x44f31b87, 0xf7be451b, 0xf6a38b66, 0x9a63f219, 0xb7d63d78, 0xed96e319,
- 0xac0e1d5b, 0x37d95697, 0xaafb88cd, 0x9bb1cc15, 0xaff7a0c5, 0xbe608f80,
- 0xe032c73f, 0x63f41149, 0x85bae23d, 0xefbe20d6, 0xf0177fc1, 0xdc3294f2,
- 0x82bff2bf, 0x773a42ee, 0xd27a3cc9, 0x85dd8d97, 0xbc60d86f, 0xe485b982,
- 0xf256f7af, 0x72132fb8, 0x571cbc60, 0x61b5d9f0, 0x85efa7ba, 0x5bb43ca2,
- 0x4cd37ff8, 0x80ebae3c, 0x91c4ca21, 0xc69fac43, 0xe4cdc1f9, 0x6bd3e71f,
- 0xfb0ff858, 0x4ff70cab, 0xf86a6972, 0x60ef9873, 0xbbb322a8, 0x8dea0ea5,
- 0x91fb8357, 0xcf15afaf, 0x543cf142, 0xe5e9237e, 0x65cd9d1e, 0x373e71d4,
- 0xc3aba017, 0x94b847ab, 0x60b4b639, 0x4129d73f, 0xd8cde67a, 0x9fd382de,
- 0xc94cfc23, 0x9e00c699, 0x00996b37, 0xc8bf2678, 0xffa30f9f, 0xac2fff5a,
- 0xcc74f118, 0x279ef520, 0xb9ffe789, 0x0ed53d68, 0xce97593e, 0xc22e7b33,
- 0xcf3f28f9, 0x8b74d0c6, 0xa997fef8, 0xd7974955, 0x300f3cbb, 0xe5cf4b25,
- 0x871e0ce3, 0xa66f9c6d, 0x7146e5bc, 0x7d53030f, 0xf08c3ff9, 0xc5b8c8af,
- 0x7f3606bb, 0x46fd8c5f, 0x07b7164a, 0xfdc0dce6, 0x1f228dc2, 0xcc4f7e47,
- 0xbfb27ee2, 0x377b4e64, 0x1e3dec93, 0x949dfd6f, 0x48d9235f, 0xf2115f94,
- 0x5f248fe5, 0x278edfca, 0x85dfb47f, 0x29e799fc, 0x40bed036, 0xef2921c8,
- 0x68ef22bd, 0x1018f301, 0x1ee23d4f, 0xabe5a395, 0xccdd0e48, 0xf7fef47c,
- 0x00ff3c15, 0xfd80d308, 0x6b4334dd, 0x6af3cd3f, 0x8fcf37cb, 0x3e38afb6,
- 0x7c0bb8e4, 0xa473efda, 0x6b433c9d, 0x87fa2f27, 0xcf4992af, 0xfea2fc67,
- 0x3e70e0d2, 0x3e546351, 0x27c88351, 0x3c2aec6a, 0x4f911694, 0xf3cdd8d4,
- 0xaeba1a89, 0xedc44f94, 0xb029af29, 0xde24e31f, 0xec94d25a, 0x727f910d,
- 0x8a4ff310, 0xaf6e74c2, 0x0c3cf3b0, 0xa2bca1e6, 0xce95871c, 0x8aeab45d,
- 0x9adb8fc8, 0xddf8d768, 0x5577aeb7, 0xbfe93d61, 0x4843f995, 0xc3f6b137,
- 0x5f7c59d9, 0x7ee143b3, 0x3302ff74, 0x059d3bed, 0xc15c4d5e, 0xd1c767a9,
- 0xa66ef8af, 0x3f27d64b, 0x2f830ec9, 0x019e18ab, 0x8979d185, 0xb67af6fe,
- 0x5190fc91, 0xea99ca72, 0x338038a6, 0xf5f92c69, 0x921775e7, 0x2cd9923f,
- 0xb84a61ee, 0xdb7379ff, 0x69ebcc55, 0x97576eec, 0x3774c2db, 0x43ec4b36,
- 0xf48accac, 0x7bd7efda, 0xbd7e44ce, 0x30b79364, 0x19d7da0b, 0x8bbfe483,
- 0x1f7a57a0, 0x2ede5f4f, 0xe150c5e8, 0xe602b05d, 0xd18efbd7, 0x0a6bfb8d,
- 0xcfff41cc, 0x7e4c94bf, 0x230e7549, 0x9cb1b53d, 0xf45e93cb, 0x3e3ac193,
- 0xfaf7e64d, 0xa466ac6c, 0x4ca7cf5f, 0xc55e3a23, 0xe83d8702, 0x7405db47,
- 0xd2cf7918, 0x8eb96d1e, 0xa9fe9075, 0x3d00667b, 0xf2947c93, 0xf4b99eb8,
- 0x741b8c06, 0xa1b3db6a, 0x285c395a, 0xbcf147f4, 0xff982da9, 0xf2e3ac50,
- 0x0f772d91, 0xf5fb439a, 0x2c4f8e45, 0xa17f7228, 0xebaece5c, 0x73d29fb5,
- 0xa17ae7fe, 0xad1ff454, 0x3d854abf, 0x17e41937, 0x7da56fee, 0x7ca9f506,
- 0xcfadd750, 0x59e785d4, 0xbb49da22, 0x890bea50, 0x8c09f2af, 0xbbb579e1,
- 0x1a7c84b2, 0xbe2086c2, 0x13e27fa1, 0x29583705, 0xf71fbfd4, 0xf18ad785,
- 0xa8fc1e80, 0x733afdbf, 0xb36be900, 0xd2fa44d2, 0x3c3ff68c, 0xd23e2ab7,
- 0xe35eff0b, 0x4c7d23d7, 0xdd374d64, 0x9926f500, 0xb728ac7b, 0x31fe4e80,
- 0x585a7e92, 0xa29f6f30, 0x7efa23a1, 0x98edf936, 0x5af52474, 0x9edcf7f0,
- 0x74bcc599, 0x0fe793cf, 0xa83aeedc, 0xd8267df0, 0xeed1079f, 0x93375b7a,
- 0x2c2664e8, 0x3955eb03, 0x9e9ff8b4, 0xdf472da9, 0x5ad0c50f, 0x48744328,
- 0x9c540678, 0x51bdf44f, 0x98f7291e, 0xb3e5ee56, 0xf8de78af, 0x423fc396,
- 0x1d7583ff, 0x0ef6891b, 0x8fc4aa58, 0x27b0f4d1, 0xb78f7beb, 0x118ac9ec,
- 0x7e15e96f, 0x68586be5, 0x40ca33e5, 0x687f3b7a, 0x82333e9d, 0xbc7f252e,
- 0x1379e06c, 0xae3cebca, 0xc6ccc135, 0x252e1104, 0xf928ffdc, 0xd3a41ae3,
- 0x95fd3094, 0xa487f789, 0x06cc197c, 0xd75dbd23, 0x01ea0965, 0xbfa2853f,
- 0x8afe906b, 0xdc89f6c2, 0x184cb477, 0x98f96740, 0x4cf60e17, 0xb495d201,
- 0x8e958a4f, 0xfde73c16, 0xb6f74bfc, 0xe8237ce0, 0xc3842dea, 0x8ae80559,
- 0xf4036afc, 0x147bf6ad, 0x4bfc49dd, 0x359cba7b, 0x6e677ed1, 0xc1b3d702,
- 0xcf49dbea, 0xba24b882, 0xa70e737b, 0x21e62abb, 0x5a672bba, 0x6b34a97a,
- 0x0974d1cb, 0x74b4ea23, 0x8bba23e7, 0x7478d7a6, 0x4ee91837, 0x2bd4dbea,
- 0x48e7ddd3, 0x8fc5df77, 0x3eee9039, 0xa7c672cf, 0x937a68bb, 0xc59f6cf2,
- 0x75768951, 0xfa428d63, 0xa19df8a1, 0x511e582d, 0xf6764f9f, 0xd93764be,
- 0xfc4d8ddd, 0x478f497b, 0x0533798f, 0x7cf7c56b, 0x1b96256f, 0xe877c1d7,
- 0xcf18f4ba, 0x0f7a19ab, 0xa1b85eff, 0xbfbc0de9, 0xdbcfd1a0, 0x337a7cbf,
- 0x6c0a879d, 0xdbcbed16, 0xd8dcb12a, 0x8a7fdbca, 0x31abae71, 0x82d02dbf,
- 0x96daafef, 0x6fdbe6ef, 0x114fd76e, 0x3ca7ddeb, 0x6bb506f7, 0x3f6eede3,
- 0xe4604e6c, 0xfaf6e027, 0x29ceb164, 0xd33af8bb, 0x867ebe3e, 0x4563e80b,
- 0xb9ec9f9f, 0x6575744f, 0xece2ef24, 0xb695cbb3, 0x474e7c1c, 0xbc47a639,
- 0x43f55bbb, 0x37741c78, 0x3675710c, 0xf8c8d3f7, 0x5429e621, 0x5717d847,
- 0x443b7367, 0x614f4bd6, 0xfd8d7e74, 0x72fe4ecc, 0x3e0cdf19, 0x07d414c4,
- 0x976146b8, 0x4e778cc4, 0xbb22682f, 0x1960fa62, 0x4ba90ce7, 0x4bc2dc61,
- 0xe58b4f9f, 0xe6cb2a47, 0x9129f3f6, 0xd7df2177, 0x4875f204, 0x4890fb17,
- 0x90f0fce8, 0xdb9ed077, 0xe734cc97, 0xf3e5f6dc, 0xbcecd4f2, 0x01cd6e7f,
- 0x549aeaf8, 0xe58bf7bc, 0xf2b79429, 0x4c161e83, 0xff381c4a, 0x1a0b2ae9,
- 0xcf8a0f29, 0x518b657f, 0xe5c257dc, 0x3f813cda, 0xd1186936, 0xa7815cef,
- 0x17a16cea, 0xca31598b, 0x6f0279a9, 0x1937343f, 0x336ebeb8, 0x798fc944,
- 0x1e3f28d9, 0x6bcf6b8e, 0x97c947bf, 0x4aee311a, 0x62afc761, 0xfd3fe47d,
- 0xa7f1d844, 0xfc76e61e, 0xfe41d66a, 0x719fded3, 0x961ebe3b, 0xed12f487,
- 0xabddad07, 0x6877d72d, 0xdea00dcb, 0xaec6ffb1, 0x8633b928, 0x1f7ba5fb,
- 0x3f432fae, 0x77cecd64, 0x235dffc8, 0x2b404ce5, 0xe740c067, 0x51a1e672,
- 0xd6fabfe4, 0xd819e3f2, 0xf26995d5, 0x76c9ef4b, 0x5e77f846, 0x0d2e79e4,
- 0x7a11fb8c, 0xc16f23ed, 0xd28b2c7d, 0xa572d14f, 0xe915c850, 0x5bf290ff,
- 0xc6429bca, 0x77ec14f5, 0x9b60f1df, 0xe1ef3b28, 0xc4afa16c, 0x4dfa4dfe,
- 0x88547da4, 0xd7d211f6, 0xba2226a8, 0xbf727eb0, 0xe847d26d, 0x662505a5,
- 0x19917bc4, 0xa6e11bf8, 0xd9f58db7, 0x68f1f434, 0x83f7e5f6, 0xf451efda,
- 0x0b63f723, 0x84dcfd05, 0xff181891, 0xb81f720f, 0x5ccfd38a, 0xf4843de6,
- 0x9cd5fbf3, 0xf0bee47e, 0x3d03ef9b, 0xa07dc8fa, 0xdd7e4fdc, 0xdd3f60fd,
- 0x863ec058, 0xe95cb1e7, 0xfdf1e017, 0x45d38546, 0x3ddf9cfd, 0xf2c2c556,
- 0x733368e2, 0xb97086ab, 0x8cc9a665, 0x0316977e, 0x99cd2fdf, 0xd2d97ef5,
- 0xb413f908, 0xb8401f97, 0xf9276eb1, 0xdaadeb77, 0x3d2b3671, 0xf711fd77,
- 0xc95a8f55, 0x08e174af, 0xc2e59323, 0x0f9411ae, 0xc78199fe, 0x6e7ce55b,
- 0xb5f7bc3f, 0xb95bd410, 0xcc6296ee, 0x0255a82f, 0xb7c1d62f, 0x77beac0f,
- 0x756bbf91, 0x672f7141, 0xe427c50f, 0xbafdf1b8, 0xc6c7927e, 0xf73f5c03,
- 0xdf940929, 0x4787ef0b, 0x38fee9c6, 0xdcefcb88, 0xb807df4c, 0x5b47a91e,
- 0xf827f3fa, 0x1b30b413, 0xa7ce1294, 0x704de708, 0x985fcb7f, 0x13798ae7,
- 0x04e2231b, 0xbe663ed0, 0xcf2179db, 0x01726147, 0xba6567cc, 0x7fd717a7,
- 0x4f85c44a, 0xa9e23889, 0xfc571e44, 0xfe7d7f7b, 0x7ae20db4, 0x3b8894e8,
- 0xc6d14a9e, 0x44bd649b, 0x6cd93cf1, 0x60346ef6, 0x37799ebc, 0x3d70fe82,
- 0x7ca26a64, 0x5f1c4595, 0x6b252fbd, 0x1ac811ee, 0x106a3e54, 0xd399fbb4,
- 0xe3041fab, 0x9ed36f2c, 0xf715ea83, 0xba0af6db, 0xa7f0b5e9, 0x506b371c,
- 0xd76c28f5, 0xb3df80bb, 0x289e5fda, 0xbfea5ecb, 0xc910baf7, 0x8ff2fea3,
- 0x3a9ce242, 0xf8c893f7, 0x61f8bc40, 0xfa30bc74, 0xbc74699c, 0x37e4b17f,
- 0x245fef11, 0x6ee2d4e4, 0xd5b86f1e, 0x820f36cc, 0x6775b7ef, 0x26b8fc50,
- 0x135c3fd1, 0xbf5bf7ef, 0xa4879e51, 0x9edcdecf, 0xcff8f8fe, 0xf5e3e222,
- 0x2f5a3e22, 0x5da9d7d7, 0xcf0164df, 0x3e3e31ef, 0x60739079, 0x9f3a3c7c,
- 0x33b445e2, 0xac3c610c, 0x55b87071, 0xd12aebe9, 0x39617c4f, 0x35f73ca3,
- 0x416b2d6f, 0x2d9af23f, 0x615596e2, 0x380bd777, 0xd3975bc7, 0x8d2e63ab,
- 0xb9813ebf, 0xe593d622, 0xc994d14b, 0x33c88f92, 0xad93541d, 0x34db9f69,
- 0xf07f5344, 0xef9a51ba, 0x4d22fef9, 0x1af5a0b9, 0x6d61fd4d, 0x88f29a15,
- 0xea6bd79d, 0x4921b217, 0xa23b6fe4, 0xbb125f47, 0xf347302a, 0x85def47d,
- 0xb29ff69a, 0xa0931da6, 0x7b45a75e, 0x7bf3332f, 0x8594c67a, 0x76c7a9f3,
- 0xc3f4d52c, 0x29504a82, 0xf633df0b, 0x79a7b899, 0x878f0f79, 0x5ab5dd5c,
- 0xbead4e33, 0x1d18f08e, 0x7d622def, 0x086e37e4, 0x1b20ee28, 0xd55dff18,
- 0xaeed4ed5, 0x78c8f764, 0x2241c6c8, 0xb2cd97de, 0xd3475d39, 0xc3ec8d85,
- 0xe4f4bb0b, 0xc3642c7f, 0xf0449a1f, 0x6b80b032, 0x302efe20, 0xf0bb17ee,
- 0x798ddd8c, 0xb5bfb745, 0xca63e68c, 0xde05d2d4, 0x5eb9181f, 0x5d2d48eb,
- 0x3a5addd8, 0xa5a09a48, 0x27786883, 0xc174b47b, 0xcbbff042, 0x86753bc0,
- 0xb7fe6e96, 0xf081dce0, 0x5be186b5, 0x62d3d07c, 0xbcf1b823, 0x999f6935,
- 0x1d143d84, 0x4e7690d7, 0xbbb09070, 0x2e323f45, 0x93f159b1, 0x771fd55d,
- 0x0bcc109c, 0xd53da3e6, 0xc95fb8c4, 0x6fe5107b, 0xbd24bf0c, 0x9497e78f,
- 0xc09b9d70, 0xf32d67f5, 0x663efc92, 0x93a4fee1, 0x9fc8abd5, 0x913592b4,
- 0x9cd9fddd, 0xe8efc2e9, 0xca577aa7, 0x9f901853, 0x8b29f600, 0x06aed7f0,
- 0x1fef1a8b, 0xd2a7868a, 0x78ed04ad, 0x4b75986e, 0xfca3e07d, 0xedde0f15,
- 0x68ff89a9, 0x51e65fed, 0xb497e522, 0x1278e587, 0xc9ae529e, 0x49ac4c71,
- 0x117c899f, 0xc8d8e725, 0xd693f8e8, 0x41fd239f, 0xe3238e32, 0x9bfed14c,
- 0x55b8bb08, 0xc1d2718f, 0xce782df9, 0x21e1d8b7, 0xeb29613f, 0x4fdf05b9,
- 0xa8b47730, 0xb8bfe12e, 0x2ffbf58a, 0x2babeae2, 0xf26fb5c4, 0xf247a12b,
- 0x65b3c607, 0xff961c7c, 0xf1a11ff1, 0x8b95c524, 0xf2f398f3, 0xd3d22708,
- 0xfba6bf40, 0x8fd02bf8, 0x8a97d75e, 0x3130aaf5, 0xfdde223d, 0xf5a212a6,
- 0x367990fc, 0x6fdb9e45, 0x6ed31d60, 0xe8327f21, 0xa727bc49, 0x58bbfb93,
- 0xac3db457, 0x0759bf92, 0xafba412b, 0xde711165, 0x2a77f0fc, 0x659607eb,
- 0xec95d21e, 0x82f1a789, 0xe0a3ca72, 0xc84c53f9, 0x8cffb941, 0xf993cfb7,
- 0x4f7ef218, 0x94547799, 0x1c75f823, 0x03fd871b, 0x94e595bf, 0xf8017fa2,
- 0xc7e48953, 0xfa253cfe, 0xa31f803e, 0x31f32fd6, 0xf212f6f4, 0x5c8b2d1b,
- 0x8780d7ef, 0x9c7e5bb4, 0xc8e9e8c3, 0x3eb3d171, 0x3d6fc4e1, 0x47a4b9f8,
- 0x68da3f93, 0xfa0d0d84, 0x79145e13, 0xbb5a1d81, 0x9d1c96fd, 0xf7df1b80,
- 0xf15e095c, 0xf8f221f1, 0xaebe3e04, 0xf8f3261d, 0x0c971c24, 0x0d0afb84,
- 0x8ff7fb5c, 0x115f70fd, 0x2e12ee0b, 0x7e7b4ae7, 0xdbd2f881, 0xbc23a58f,
- 0x577aa617, 0xe3dcfd63, 0x5d144fa1, 0xfa555e78, 0x7b8794b3, 0xe74f4ba1,
- 0xe3ae1aff, 0x25e1b072, 0xf386893d, 0xb38a26dd, 0x41bd74d6, 0x66d9e176,
- 0xfc06b410, 0x72180cbd, 0x08fc65d8, 0xb78ef051, 0xd9eb924f, 0xe5f62390,
- 0xef32fd62, 0x39b9d607, 0x475e6627, 0xdfb41c3f, 0xf4aa1c05, 0x1cf09263,
- 0x92be7f59, 0x791797da, 0x3af45f5f, 0xfe78722a, 0xf7b329db, 0xc3efec3e,
- 0xd81d9c9e, 0xfbbe955f, 0x67c23670, 0xbbe742ad, 0x79f898a6, 0x5e712cdc,
- 0xc9a8426f, 0x3399e78d, 0x667df873, 0xf7a47e23, 0xfdf91c62, 0xe0a677b5,
- 0xffd93439, 0xe7474508, 0xee7b1947, 0xc12c7f83, 0x3722e6f8, 0xd8bf6fde,
- 0xba2fee24, 0x002c1acb, 0x91baf239, 0x186547df, 0x66e744d2, 0xe4f592fa,
- 0xb3d34cd7, 0x727748a9, 0xadbcf2de, 0x01f78f7c, 0x7cb15e60, 0xafa5a53f,
- 0x7bfa0d78, 0x75c83d04, 0x2beca94f, 0xe185b26e, 0xa33cf32f, 0xf82553e1,
- 0x1b43ee43, 0xd05b5ef0, 0xbccde7bf, 0x6daf7d1c, 0x5874feff, 0xf6363dff,
- 0x837eb8c8, 0x1e3493c5, 0x6bdc51f9, 0x278717fb, 0xa477df89, 0xbcf6a7bd,
- 0xbf97b7c8, 0xdeef1253, 0x51ccff9b, 0x827b97be, 0xcb85e5e2, 0x7078ffbc,
- 0x99564869, 0x739d357a, 0xdeae5ef7, 0x8fadff2b, 0x28bedfb9, 0xd3dff7be,
- 0xbcec6af9, 0xceb15ec5, 0x88617e70, 0xe7f729ce, 0x7e54be2d, 0x1a477bd9,
- 0x08d23ef0, 0xf6bcc838, 0xb48fbc06, 0xd0bf4638, 0xe576cb9f, 0xc4aa877b,
- 0x8f301abc, 0x3df23530, 0x38f0b7a7, 0x302f2269, 0xfb7c8894, 0x9d3d2ecb,
- 0x11e5ffe3, 0x31dd8cdd, 0xcb9b9de6, 0xa9ca32e1, 0x0e8d1f12, 0xe3b5fbf2,
- 0x79e793d5, 0xe8d8b9e4, 0x845675f9, 0x63f9c56e, 0xf1ac729e, 0x3f7cb91c,
- 0x99dde72b, 0xf0d1f1c2, 0x9bdf899a, 0xf27cf2aa, 0x4ad094ce, 0x168713e2,
- 0x1e04c3cf, 0xe50faf3b, 0x99b2b9d1, 0x8f10efdc, 0xfaa7261e, 0xc8be51ca,
- 0xd4caee7b, 0xc111c526, 0x87a2578f, 0x1af5dc30, 0xbb840ebc, 0x7ecbbe91,
- 0x7c151f4f, 0xdc363ccb, 0xfa112dcf, 0x5a9ec96e, 0x7ee587b2, 0x3d4ef4e9,
- 0x669c6fe5, 0xba72ae3c, 0xd0fda14d, 0xeb631f52, 0x7cad2e40, 0xaa3378a2,
- 0xb09925ae, 0x1efe1496, 0xe9661f7f, 0xbaf8a8c6, 0xbd495fd8, 0xbe5fc72a,
- 0xd7176b4d, 0x467f6db0, 0x51f4e9fb, 0xb0563f2e, 0x2b3fd226, 0x57f6d01f,
- 0xa7d667b3, 0xbce8cf38, 0x8fc21180, 0xec572d37, 0x1958ca57, 0x4f358fea,
- 0x9fc46e7c, 0x17c78960, 0x434ffbf8, 0x7ddff187, 0x8efe27c2, 0xc96f3e08,
- 0x1720fcf5, 0xf2ef3efd, 0xf5ceaef9, 0x7f45c9cd, 0x7e7cbbc9, 0x702eea17,
- 0x8d2bb33d, 0xfd8b5bf4, 0xfaff922e, 0xdffe5cc1, 0x0035f78b, 0x71264c9c,
- 0x49aeba6f, 0x4df6489f, 0x43ece880, 0x7e731de7, 0x26776540, 0xd3da43f2,
- 0xbf6067d3, 0x1eada7ce, 0x72d6df5c, 0x2ffa214f, 0xf3f356b6, 0x8f1366a1,
- 0x397e07df, 0x538600f1, 0xaf6c7686, 0xa39d1740, 0xfd107f7b, 0x3fbaad42,
- 0x98bcc61f, 0x5f3cc9d6, 0xda175d32, 0x3c62283f, 0x899035a7, 0x68e77df1,
- 0x9a4e6f7e, 0xcb90bcbe, 0x36276e7f, 0xe85c5c08, 0x627f202a, 0x17fa41af,
- 0x2e742c3b, 0x2eff8eab, 0xf1c628c6, 0x70eaf32f, 0xf176910e, 0xf9a666d9,
- 0x1d51869d, 0x4890d04a, 0x3c50a8f7, 0x30436ea8, 0x67d416fd, 0x4f14a94f,
- 0x7b4bf393, 0xe302ab3d, 0xdd8f5266, 0xbfb838a2, 0x0bfdd84d, 0x71e3fc98,
- 0x9e82f9b7, 0xff7b0816, 0xf7872b16, 0xc3cee652, 0x2ccd0b76, 0x76ac0751,
- 0x2947654b, 0x90d6b3ad, 0x8c85768c, 0x47b7c51f, 0x1ac9fb62, 0xe7e7617e,
- 0xe1be959e, 0xf419c9d8, 0x3f865d41, 0x693c85db, 0xffcfce18, 0x83cca1b1,
- 0xd786caf1, 0x30efd046, 0x3c781299, 0x1996e41c, 0x843a11ef, 0xbdd61efa,
- 0xc88b15ea, 0x73880a5b, 0xd8defccd, 0x453939c6, 0x78f11e74, 0x71ffdd1f,
- 0x23ca10de, 0x847906fe, 0x92bea637, 0xe01fbbfb, 0xd90debbd, 0xf941d760,
- 0x789fee74, 0x25684879, 0x92991bde, 0x47978977, 0x72c13e85, 0x6cc25e4e,
- 0x5685172a, 0x3e3ca1ea, 0x7197932f, 0x36040a03, 0x6cf06f35, 0xc92dda3f,
- 0x87702ec2, 0xc377bce8, 0x917423cb, 0x1e7758fe, 0x84676797, 0x3e4cf93f,
- 0xc20e6dbb, 0xfaec647b, 0xded27969, 0xc9f5a36e, 0x2cf6caf5, 0xffbb7633,
- 0x957e7210, 0xc53da738, 0x3c2d5aca, 0x044fe7fe, 0x1eec1c3c, 0x7fcbf141,
- 0xfde14dcd, 0x4f74423b, 0xfa27ec8f, 0xb8e41c77, 0x7bfe15ab, 0xf2a3e759,
- 0xcb977ebc, 0xb38c2be5, 0xea19c691, 0xe79be7e1, 0xfe2214e4, 0xc0aa6f00,
- 0xc9f7ca9b, 0xd07e7ced, 0x13fefe2f, 0xf46287e8, 0x0afc1ffb, 0xe787e7ea,
- 0x27274d1d, 0x5aab38c5, 0x2fb6dc78, 0x69e880b9, 0xf7dc558a, 0xc75da252,
- 0x9f6e3cf8, 0xc592f3ba, 0xaf091d79, 0x69c6850c, 0x09cc7011, 0xf6339f0d,
- 0xaffbaf9b, 0x8eeb4bff, 0xef0797c0, 0xc5d8396d, 0x9f1e37ef, 0xf485f1c7,
- 0xe076429c, 0x677f4d76, 0x9fb547d6, 0xae5f28c0, 0xda80a521, 0x6fee2bdf,
- 0x61d9f795, 0xdc71fcbb, 0x57bb45be, 0xfcc1a7de, 0x1c645993, 0x8cdeffb2,
- 0x70bf710e, 0x286f3aff, 0x8874eb11, 0xef223a75, 0xcfe7ec33, 0x73797d63,
- 0xb8e903ed, 0xfdfdfe1f, 0xfd12298d, 0x563cf869, 0xf1d7c87f, 0x1e5572f0,
- 0x1bdf2797, 0xa33ce45e, 0xe70fd9e0, 0x7849f9a8, 0xbb537f22, 0x94ba5a31,
- 0xf411ccf3, 0xf3bf8039, 0xe278e5bf, 0xbbfad97e, 0x7338be79, 0xbebae969,
- 0xf9875f33, 0x07ddb209, 0x34a0c078, 0x21bc27ec, 0x7327ec4f, 0xbc9c4e58,
- 0x339e6f47, 0xde917fa6, 0x7b27ef47, 0xd9efe593, 0xbd1afd69, 0x397bfe4e,
- 0x7efc73fe, 0xfca36b83, 0x7a8f183c, 0x176e16ce, 0xf2da2fd6, 0x037e0263,
- 0x797d54fd, 0x5312bf38, 0x3bf8f3c5, 0x4af3ab5b, 0x7760ab67, 0xdc552494,
- 0xa6e50f99, 0xfc93c6c7, 0xf154192e, 0xf3c83e79, 0xe04d8f35, 0x7c5747df,
- 0x79cb043e, 0x8a797913, 0xf79479e7, 0x9eccb460, 0x2bb6159a, 0xd173ccee,
- 0x1d4afab8, 0x42676bdd, 0x63d60623, 0xf944dd7a, 0xf1ae1280, 0x5d26259e,
- 0xbff3ac53, 0x03d3f4f7, 0xc04cbf8f, 0x1fd0ba7f, 0x2105fc28, 0xe82fe355,
- 0xcfe7e44d, 0x92fd5f7b, 0x9bdcd7ce, 0x079f5be7, 0x67ad1bed, 0xf287cd6f,
- 0x1407eb06, 0x603c53ef, 0xc61fa087, 0x608b60e5, 0xadd9cabe, 0xd89fb45e,
- 0x2559b76a, 0x18ff0ab8, 0xf007a9de, 0xa7b5e57b, 0x0f883c7e, 0x4c79c5e3,
- 0xf1a07214, 0x15fdbfb5, 0x678dc4e3, 0x1b346e6c, 0x7c3f7627, 0x135fda27,
- 0x1bfedfbb, 0x3cfcc3d7, 0x44f79c90, 0xfbc27ff4, 0x9a265d09, 0xabeec4ff,
- 0x6bfd6056, 0x402eebdf, 0x44eeb93a, 0x42c505b0, 0x3effabef, 0x880e7348,
- 0x7cd97a7d, 0x39f1b8d1, 0x013f8f09, 0x1e0893a0, 0xf8f0e73f, 0xced9f28a,
- 0x0e6e8f3b, 0x7b549391, 0x78ec0ade, 0x605f3b8a, 0x7b8c6e09, 0xd1fd73c8,
- 0xd5e3d57e, 0x7f783eb0, 0x20cc1f5d, 0x729e9ec2, 0x24820cd1, 0xc9672e5c,
- 0x39a5729a, 0xcabf534b, 0x3ef9af91, 0xcd2af33d, 0x42ae99f7, 0xc8d6794d,
- 0x37fa9a89, 0xe535cbba, 0x6a6613d9, 0xaa7b57ea, 0x60c2e535, 0xf17ea687,
- 0xf7ed2e91, 0x788f4c63, 0x7eee3a28, 0x27a59f03, 0x2d9ee43d, 0x06f4d53b,
- 0x85fe273e, 0xafda2383, 0x8ec5cd7c, 0xf4bdf037, 0x9f9f472b, 0x9be67e92,
- 0x3180b6f5, 0x53393fb6, 0x83df082d, 0xf3f1d7a0, 0xfb25ef53, 0x937880fe,
- 0xa0a6a7e7, 0x5090195f, 0x9fb9db75, 0x5c32efe2, 0x6efdc458, 0x943111c7,
- 0x7f276e4f, 0xd34371e5, 0x79e47fb3, 0xf728b903, 0xaf9bebae, 0x8b94f759,
- 0xcbbacd3e, 0x3c28aad9, 0x5729a1dd, 0xd4d6ee39, 0x5eb99e9f, 0x6ba67df3,
- 0xb69e144b, 0xba37ca6b, 0x53c28e1f, 0x9e9e147b, 0xf4977cd2, 0x5ffc2ddd,
- 0x0adfa1af, 0x3d42939e, 0xc9878895, 0x1f08faa7, 0x2ada7a13, 0x1cd74f11,
- 0x957c20ef, 0x2895bd04, 0x348ecb2e, 0x20cf81bd, 0xddb0cbec, 0x7a4ce681,
- 0x91766c1e, 0xf370ebff, 0x691e7a48, 0xfffbd376, 0xcf409e68, 0xe87b355f,
- 0x33cd9ff9, 0xecd3d9e8, 0x734767a5, 0xae7fd507, 0xcffb8bb9, 0xddeffb52,
- 0xc1bf45c8, 0x01a85d79, 0xc18ec623, 0x9e9e495b, 0xc79d084f, 0xeb7f06f2,
- 0x3420a9ec, 0x901d67f0, 0x9e207f2f, 0xfb4f2e45, 0x1e0e7860, 0x19fdf8cc,
- 0x43a37f22, 0x3b4429e7, 0x0fe3f47c, 0x32e6a7de, 0x37bd69b6, 0x183a7f13,
- 0x132866cb, 0x90f7e9b2, 0x93cfbc1e, 0xa8b3d8c3, 0xf7bee84a, 0xb9636707,
- 0xe79efc57, 0x241fc7e0, 0xc75bfc3b, 0xe2033dd9, 0xc707a3ec, 0x7b3fb388,
- 0x7f4765ca, 0x46afd1cf, 0x471e11d8, 0xc3cbdf85, 0x3bf80d0a, 0xa16ae51c,
- 0xf1ecf501, 0x5421e738, 0xe0c97953, 0x7bb75c52, 0x5f91e51e, 0xe1dfa06f,
- 0xfdf0a39b, 0xec97acaf, 0xf7a0fae2, 0xa7ed1346, 0x2b3ce98e, 0x957a3f90,
- 0xce10c7be, 0x14fe3d37, 0x7b5ea9e9, 0xafc21e5f, 0xbcbdf1fa, 0x4c7becec,
- 0x0d944771, 0x8f953e1c, 0x6fdb393f, 0x33e15efb, 0x0d11d71b, 0x1d83b99f,
- 0xf4115f7c, 0x201da2e4, 0x3daac7cb, 0x2c5714f5, 0x75c30cf7, 0x389af51c,
- 0x81ed7aff, 0xf237e461, 0xf08bce94, 0x360cf4ff, 0xa2e7fad0, 0xe83f44de,
- 0xd6207d42, 0x1f9e15ef, 0xa23dedcc, 0x2e67dc13, 0xe0bed2b0, 0xa3df8e98,
- 0xeedf5d10, 0xcfa3fbe2, 0x9c87dce2, 0xdc57be28, 0x0becff54, 0x5aef5fd0,
- 0xebdd750b, 0x58f6411d, 0x1740136f, 0x54f7ba68, 0xddfe39d3, 0xa12016e4,
- 0xf82def38, 0x6cfef82f, 0xfc5f9df7, 0xb07fea06, 0x1d26ead6, 0xf04518e2,
- 0x2f2a285b, 0xfd93354e, 0x6e4e78b4, 0x5bc5ea05, 0x56f0bc44, 0x614e9abb,
- 0xe8d93543, 0xdb967e80, 0x0403370a, 0x6ab4cad9, 0x5364fe23, 0x9b1dce4d,
- 0xe87ab9f1, 0x58f22376, 0x9b7d98dd, 0x07ad8cd1, 0xf9252e16, 0x19a77a17,
- 0x3adb75e6, 0xe7ef8bbd, 0xdadaf9e4, 0x22f7946f, 0xc898f7e9, 0xd020024f,
- 0xa5c9357e, 0x4949f668, 0x181f4e82, 0x6331e22c, 0xda4bd8d9, 0xe44ed778,
- 0xdf8bb3a3, 0x1e271e19, 0xec2efda1, 0x7b8adfc7, 0x4fefa39e, 0x5c3ae391,
- 0xcc75ff7c, 0xf6899408, 0x07ae42e4, 0x7cffcdc6, 0x7fac2943, 0x4743b75c,
- 0xd5b70d79, 0xb87880bf, 0x68f025d0, 0x4fc85d60, 0x7c97f937, 0x4c421bf0,
- 0xf0dce69a, 0xbba5f495, 0xa91951c7, 0xde424b2f, 0x397d48ca, 0x12adafa1,
- 0x8fd4a2f5, 0x211ae6c1, 0x8e489b8f, 0x475e6c1e, 0x7ecdc3e5, 0x6e691e7a,
- 0x8db8f215, 0x79aaffbe, 0x01c790a7, 0xd2f78f21, 0xf9e6eefb, 0xd9ad7cf4,
- 0xa985cf47, 0x6e11d7be, 0xd73b8e32, 0xdcbca3ec, 0x189b0f43, 0x742ef1c6,
- 0x038f289b, 0x47b1e238, 0xc94f30d2, 0xa344e744, 0xe5a295f3, 0x743d3f7c,
- 0xe5b7b80e, 0xfef7e46d, 0x17b4233c, 0xa7a7c707, 0x4765cca3, 0xe0f1f4b9,
- 0x8e8724f3, 0xb4765cba, 0x2e3e4fa7, 0xdd971eca, 0x0d3fe500, 0x71fd25ee,
- 0x9bb2e7d4, 0xe3c9fca0, 0xdfbbfcbd, 0xf940b765, 0xfc7dc1d3, 0xd051807b,
- 0x2fe0ecff, 0x33958e48, 0x47f220e5, 0x2a7f39a5, 0xd7d00ba8, 0x2f9107e5,
- 0x992e67a6, 0x60b17c8a, 0x72e88bb0, 0x41fd6ba6, 0xd91acf2c, 0x1515e2ae,
- 0x46e15b1e, 0x5691576c, 0xa9bb62ad, 0xc46c7739, 0x6e86d376, 0xcddb2357,
- 0x236fb318, 0xb7706f96, 0x2e9f68ab, 0x1a563940, 0xe59647ee, 0x65a72977,
- 0xddd5dd3e, 0xe307d25e, 0x0fa4bcba, 0xe62a5c24, 0xff426f56, 0xe2976367,
- 0xa9a5dfc0, 0x27f4ab98, 0x62ee6033, 0x0a93de03, 0x3dfffaf2, 0x87ac77ae,
- 0xf9623675, 0xadb72a1a, 0xedfa06ff, 0xe2f6007f, 0x8000e831, 0x00008000,
- 0x00088b1f, 0x00000000, 0x3cd5ff00, 0xe5547809, 0x9dcee7b5, 0x4c92642d,
- 0xe2420836, 0x96249964, 0x26b6432c, 0x0c486410, 0xf90130ee, 0x10196544,
- 0x044816c2, 0x7eab17eb, 0xe0171a19, 0xd16b8d69, 0xb5c46faa, 0x61e4b6af,
- 0x1d0958d4, 0x87d252aa, 0xb410553a, 0x88a47479, 0x119099f0, 0xc7d278dc,
- 0xf7fce73b, 0x24cee666, 0xbefd1480, 0xff938607, 0xcfd9fbfe, 0x005ffff9,
- 0xb3f85380, 0x34607f02, 0x3d2538fe, 0x0468048c, 0xd1bf67f1, 0x0395b26d,
- 0x8c0734ac, 0x412fa3a0, 0x6010aba3, 0x76960eaf, 0x24a40014, 0x0b7afcc3,
- 0x74b08d96, 0x5de7960b, 0x05480368, 0x20bada68, 0xda85816e, 0x6066e3bb,
- 0xe21745fb, 0x52ce38af, 0xe0546e05, 0x9bd40a93, 0x4f34899c, 0x1fd24d9a,
- 0x856fc7ca, 0x064a7850, 0x3d9ab7e8, 0x448004ba, 0x0dac7b93, 0xfb9bedc7,
- 0x8758834e, 0x31d688af, 0xeb1ebd6c, 0x6c3200e3, 0xca1f1e56, 0x5e541982,
- 0xc846ed09, 0xcff5b846, 0xda22a4fb, 0x2327c597, 0x5f434e84, 0xf9ec5f20,
- 0x63fe1654, 0xe0543d06, 0x6e03e97a, 0x70d79969, 0xea566020, 0x743967f1,
- 0x226670ec, 0x7ed45ede, 0x18bf046f, 0x7dfb43bf, 0xbe8de215, 0xbf697537,
- 0x0f5b5403, 0x0230438d, 0xd9dfb8cb, 0x855efe12, 0x878f0dff, 0xc3c06749,
- 0x10f0a1a4, 0x1af01fb5, 0xd7de8e41, 0xa66ecb0a, 0xc0bee473, 0xd1fcca9d,
- 0xf7218108, 0xf445f2a7, 0xfe05dafe, 0x25ff02f5, 0x5a74e736, 0x38fcdd5f,
- 0x8e005390, 0x4d79356d, 0xa9ffdc99, 0x1744293d, 0x2d837593, 0x5b5b3e9a,
- 0x00de8367, 0xcdd5adb0, 0x14bad7d0, 0x3f8076f4, 0xf97336b5, 0x2e16d6ad,
- 0x30f568ef, 0x8ebad9dc, 0xdb5a5fe1, 0xeb577eb9, 0xdbbf2e46, 0x6fe865ea,
- 0x5fbf917d, 0x86657f3b, 0xff4d12db, 0x45cec9d5, 0x7b9e8fc4, 0x3e9913aa,
- 0xc853f7b8, 0xc81a9eab, 0xc344b66f, 0x9d658301, 0x8f65c094, 0xd9e1f711,
- 0xc36de316, 0x8c73fd7d, 0x19c689bb, 0xad7e09a8, 0x4a437c43, 0x30d0f180,
- 0xbe9abdd2, 0x3a1c464b, 0xe4f56689, 0xeb0efe12, 0x6407bf3c, 0xd39b56d9,
- 0x383e47a5, 0x17558f1a, 0x6582dc00, 0x78f3ce0f, 0xfa85abaa, 0x48c07e41,
- 0x3fa29ce3, 0x097c7193, 0x3af07766, 0x0e1ca210, 0xb1e808c4, 0xd18f2c49,
- 0x40ddc850, 0x60f99fba, 0x1913e9e0, 0xcb3382b6, 0xa8f870c5, 0x9e03ab93,
- 0x6567a432, 0xd584c3ac, 0xa4f8127d, 0x46538412, 0xd38e00d6, 0x13d46e97,
- 0x5644149c, 0x9fc3c750, 0x6322dfc9, 0x14cbf186, 0x6b94d448, 0xed35a3cd,
- 0x9a99aceb, 0x5cf4befa, 0xb4d2ff1e, 0xfaed348b, 0xc59a5746, 0x232f53bc,
- 0x6f7465d8, 0x0974805c, 0x9b1c9956, 0x98bdfeb0, 0x062822f8, 0xbf1b1698,
- 0x317be089, 0x376a5e19, 0x14c9c0ed, 0x934e7dc0, 0x108b237d, 0xc6db9755,
- 0x99edc76b, 0x76c36353, 0x6957e657, 0x25c121d7, 0x1dabdfb4, 0xa7df3453,
- 0xe9ae5e57, 0x93fb32ef, 0xcef5ad08, 0xc6f7cd7a, 0x9f41af96, 0xe5b1300c,
- 0x014be824, 0x343afbc6, 0xecee94e3, 0xbf1fb4d2, 0xeb12641b, 0x378e7d92,
- 0x741f9609, 0x152ac4ca, 0x24df9b87, 0x3fa5f558, 0x4e01f683, 0x9f5159b0,
- 0x83dc8a4b, 0x963d0247, 0xcae52927, 0x812db7a0, 0xf21270e8, 0x89bf48f5,
- 0x6321c230, 0xbff2a963, 0x4c1f104e, 0x32002052, 0x16abf607, 0x3a79804b,
- 0x4598d78b, 0x1be5056a, 0xc906c1f5, 0x3847a691, 0x50540e47, 0x8a0428f9,
- 0x973aca08, 0x2a6bf89e, 0xb2a58f34, 0x0469dc09, 0xbf74483f, 0x2fdc7c4f,
- 0xe2c4da05, 0xcfc4c982, 0x68ff3f75, 0x17ac6dde, 0x5c261c62, 0xfebaefdf,
- 0xfd6b4a91, 0x91f53fbb, 0x7e216c37, 0xcd7eb26f, 0x8dcb5278, 0x7f19c72d,
- 0x2d6fb96a, 0x92e177cc, 0x9f680ddb, 0xaffe3610, 0xed0a76cc, 0x53a23ada,
- 0xb8c9fc23, 0x1ed420ba, 0xc418be3a, 0xbfea3177, 0x04d35a7a, 0x5ddfd7c2,
- 0x6f576c4e, 0x9e087210, 0x1c4ef545, 0x29463ea7, 0xa7d44f83, 0xb2a1ed2a,
- 0x6ae9cb9e, 0x6f68957d, 0x587bc757, 0x96ad1fb4, 0x522ef195, 0x9ca2cdcb,
- 0xa0f7cea9, 0xe5aa1728, 0x397170ff, 0x613fb44e, 0x29ef559b, 0x53ffe908,
- 0x0f18ddaa, 0xa06ec9e3, 0xc933903d, 0x1abb481e, 0xeda21f98, 0xb15eb685,
- 0x237ff317, 0x44c58c7b, 0xdf63cb8f, 0x90eeb921, 0xf1bae480, 0x8bd38376,
- 0xd49e7ff3, 0x12c6b451, 0xb7e7dfc2, 0x6abb7c08, 0xb6329ce3, 0xde6af95f,
- 0x3923e226, 0x85c8f76e, 0x563addf8, 0x4ea77ac7, 0xe88138b6, 0xfbd0af7b,
- 0xd848ff6a, 0x8686f2d0, 0xb2f5519e, 0x6cc1f3c4, 0xfaf9c1fc, 0xf4f51bef,
- 0x8e59c206, 0x9370973f, 0xdcf42999, 0x95add448, 0xea36f3f8, 0x3dd23359,
- 0x3a9c1b25, 0x1af29f6c, 0xf1a267ea, 0xc7d0bf41, 0x24f8c5af, 0x8f959c14,
- 0x6ff6c9bd, 0x8e528ca1, 0xcf2d7bf8, 0x7c89979d, 0x9fce347a, 0xd0db7c4b,
- 0x75d78db2, 0xe3cadd8d, 0x10583583, 0xcce2cf8e, 0x9e97fc28, 0x3fa5ff01,
- 0x8271fe26, 0x75cfa403, 0xbeb47428, 0x78b796e5, 0xef95cbbf, 0x43325fac,
- 0x472cb8ed, 0x39c68f97, 0x0e1f0832, 0x74074e85, 0x5f050ab6, 0xfabe1357,
- 0x1373fb17, 0xf9f0ecb1, 0x3ed9ba47, 0x88972aec, 0x4071cdee, 0xf92a3f74,
- 0x410ef68b, 0x0ed68eff, 0x5a5bcbb6, 0x84be18bb, 0x55bad073, 0x8d10dd7c,
- 0xc067f9df, 0x131ffcef, 0x01f4a3bf, 0xadfb03a3, 0x4e3c07da, 0x1180ff85,
- 0x2b4cf4c2, 0x27e225f1, 0xfae24ba1, 0x2120b93a, 0x138fa9a0, 0x738e52fe,
- 0xcae9f13c, 0x37aabb19, 0x98792148, 0x311d0b1c, 0x0ed7cc49, 0xc41daf85,
- 0x22ff2ad7, 0x11ea963f, 0xc49d6fcf, 0x37e0437e, 0xf3c0bfc4, 0x3bba78a8,
- 0x881baf1a, 0xabc1a78e, 0xc607feb6, 0xc7fa276b, 0xaf8237a4, 0x653778c4,
- 0x77f9e346, 0x7c555e0a, 0x7fe4536f, 0x236f3c38, 0x7f9ea73c, 0xb4cb6f3c,
- 0xf891b8f1, 0x453ece1e, 0xf75d47d2, 0x7e5a7210, 0x2d3a722e, 0xdff8aadb,
- 0x461677e8, 0xa26dfdd3, 0xf74359bb, 0x53c8339e, 0x4f298fcf, 0x848b7891,
- 0x3ab8128d, 0x3fdfd12c, 0xdf561ccb, 0x4e3c179d, 0xf8d6ce0a, 0x75bf9367,
- 0x29b3fc6b, 0xfd696118, 0xe5349bd8, 0x9aadeb3a, 0xada697f6, 0x6e5fd4d5,
- 0xbfa9af5b, 0x4d01ff32, 0x63c76af9, 0xd3e67e11, 0xe77afa9a, 0x73f5346f,
- 0xea6bb79b, 0x68f4b7e7, 0xfe7817ea, 0x78ab29aa, 0x1c0adadc, 0x356b6d2f,
- 0x65d3f12b, 0xfe03ab0c, 0x8b83125a, 0xdfd9070f, 0xd7b7f4ac, 0xafb24bb2,
- 0x32d1fd83, 0xc296ab9f, 0xcd9d8aaa, 0xb5f4126f, 0x2d78955a, 0xad5be18d,
- 0x3befd636, 0xee19f35a, 0xf128756c, 0x5dc3255a, 0x4e254ead, 0xb48c3173,
- 0xbb66af0b, 0x3d2164a7, 0x44bcbda6, 0xe980b807, 0xc167f87f, 0x77bc5a5e,
- 0xdce28ebc, 0x8e5eca35, 0xffb37f57, 0xe3afe436, 0x950726cd, 0x311fb77b,
- 0xf9a30ad8, 0x32b7ee65, 0x6cf8c338, 0x0d5fcb6e, 0x45cd67e4, 0x0863ba0f,
- 0xa59a9d39, 0xf7207e63, 0xcc2f5003, 0x05218336, 0xd9ecc1f5, 0xf80da392,
- 0x189207bb, 0x3f58dcfa, 0x133e0f4d, 0x7a2deb96, 0x979e299f, 0x3fa332e6,
- 0x132c4b3d, 0x50f07a4c, 0x7324a43d, 0x7d0d7e9c, 0x383ca1b4, 0xbf18b865,
- 0x1c3f22cf, 0xe96f5dfb, 0xbddd9030, 0xfa2fe76e, 0xb87ac36f, 0xf1ce53d3,
- 0x25625c3d, 0x3e792dfd, 0x371a9dd6, 0x3520bcbc, 0x5f1850e1, 0x4e19254f,
- 0xe1d1f8a5, 0x7adc5277, 0x9cf1c193, 0x05dfba2d, 0xc9a77eca, 0xc16ffb12,
- 0x4dde4dd7, 0x713e4852, 0xb84d3b7f, 0x01e226cf, 0xc1b367da, 0x7e445797,
- 0xb3f676f6, 0x16d72a9b, 0x2e9a9d11, 0x15313e91, 0xa69de285, 0x8fd92f96,
- 0x91cfd48f, 0x90f14cf0, 0xfe656fc3, 0x93badfdb, 0x8b8d45f9, 0x5c7d5b7a,
- 0x6ab80b2e, 0x39a3e3c3, 0xa64dff93, 0x4beaa7b8, 0x3c4cff11, 0x53fbdce9,
- 0xd5a077dc, 0x17e52fff, 0x9a82bcd4, 0x5bcc8867, 0xde647aa8, 0x6e0975ad,
- 0x2c9aefdc, 0x94f30651, 0x5ea3a674, 0xdedf5540, 0x9765159a, 0xbd3ac8ef,
- 0xffd6d67e, 0x6cf9fac0, 0x4d31bff9, 0xbe48d5d8, 0x05e337df, 0xe553ad03,
- 0x9ffe48ef, 0xfe707d43, 0xd7924d39, 0xf67a7a83, 0x44c37692, 0x7df9dce9,
- 0x88a0e5b9, 0xc2ed238b, 0x3607b6f7, 0x2b5c9ba6, 0x92617c73, 0x1e50726f,
- 0x4743a544, 0xcf3add34, 0x1fceb740, 0x76d16e93, 0x73bce0f1, 0xf1a08bb3,
- 0x8acbdfcf, 0xc83e27f2, 0xa91fbd3a, 0xf781ffad, 0x636b1d6d, 0xef4472b8,
- 0xea27593c, 0x01627c45, 0x80eff21d, 0x74b8e657, 0x3c7b6669, 0x195033c5,
- 0xb77d278c, 0xf2065bac, 0xd4ef410f, 0x5cfe468f, 0x1f67f0a2, 0x7e243ef8,
- 0x7ef7055c, 0x25980941, 0x22ae4bd5, 0x09f4b73d, 0xfc4f0843, 0x27f393af,
- 0xcb7e94ab, 0xda469d2d, 0xb567f2ef, 0x1a71d4ed, 0x1fc88a5f, 0x19fa5f57,
- 0x73f0ddb0, 0xa7556fde, 0x5977dfb6, 0x62872971, 0x084b1659, 0xa7d267ef,
- 0x1baec947, 0x5b27cac2, 0x3f20bf39, 0x9e03e0f3, 0xc4fa21b1, 0x71f14764,
- 0xf9e9f65c, 0x23ff5b58, 0xf71cb1f3, 0xf9e891ac, 0xbf78f97d, 0xeb4599dd,
- 0xa0f3f556, 0xc4c379de, 0xdca0677a, 0x37a4f226, 0x9e2daefd, 0x3804e4f8,
- 0x2a161d88, 0x6a85d2f9, 0x369d74be, 0xcfb93a5f, 0x49b979c7, 0x716dbd07,
- 0xbd89f748, 0x55dbce1e, 0x59b776ed, 0x5dd3fcb0, 0xa3fc994e, 0x64b96ff1,
- 0xdfeab75a, 0x484efea8, 0xbeb0e58f, 0xf66bbce3, 0xd53bebd9, 0x30f6aa2e,
- 0x06560ed2, 0xfec96bdb, 0xe3b6f84d, 0x2be7824d, 0xf7691eaf, 0x7a138bde,
- 0x57c1a8e2, 0x8cfc97be, 0xcf1c63d7, 0xaffaf441, 0xc67e16cb, 0x0302cf4c,
- 0x1f091fcb, 0x450cdbca, 0x764fae6e, 0xf54d975f, 0x99d0bd8a, 0xa3b2069d,
- 0x23df7275, 0xf95f12d7, 0xde1bce65, 0xbf07c77c, 0xccedb5ff, 0xeb2685f9,
- 0x863ff671, 0x749a338b, 0xa2f8a6e0, 0x4a56d6a4, 0x6dc50c7e, 0xf3544794,
- 0x9fed918a, 0xc8acd7b0, 0xb5573ce6, 0xd9eb49df, 0x1c33d628, 0xbe5a9abd,
- 0x8731e4d0, 0xbba9bf9b, 0x4c30badc, 0x16ca5e3e, 0xdbd22ef1, 0xa21cc87a,
- 0xc5f2d9f7, 0x65f8b7ff, 0x091e0c9a, 0xe4a16ced, 0x082ffe15, 0xf80e783f,
- 0x2083ce19, 0xf9583743, 0x38216a7c, 0x17022e18, 0xdbbb7cc3, 0x60337c4b,
- 0xbe248e08, 0xbbf57fea, 0xfe9be202, 0x57b6278b, 0x5f3bf9c1, 0x06fff48a,
- 0xfe78dbc6, 0xdbbe5781, 0x7039fc43, 0xf4ace187, 0x6764eac6, 0xe451f127,
- 0x53bbcb79, 0x01d73e64, 0x8b967afd, 0x03e8ab7a, 0x1b72a497, 0xe64cd8eb,
- 0x1cde908b, 0x37aab4f5, 0xc2bf6017, 0xd7ac744f, 0xb5e49960, 0x80aed363,
- 0x70ac458e, 0xa657a671, 0x2fa8a772, 0x95e8995c, 0x15585cb0, 0x4a6fea23,
- 0xc52642f4, 0xcb960143, 0x0fac00f9, 0x8bd08017, 0xf7938237, 0x96419189,
- 0x6f17fd84, 0x3e709735, 0xa4390216, 0x8e288bff, 0xb74e221a, 0x2f7908e6,
- 0xbefa12ce, 0x179b46b8, 0xc95b30f9, 0x4a6bdb1b, 0xe7561072, 0x1d12f738,
- 0x1bfc938b, 0x7ca32a1e, 0xa1360e90, 0x75567d7c, 0xaa779f2b, 0x35ed1afd,
- 0xcdbf84bd, 0xe2bc7012, 0x9f7936e9, 0x238ce713, 0xf2cdcfc3, 0xa807b5ed,
- 0x7b5a11dd, 0xc578f0f9, 0x47f71c7e, 0xd78795cb, 0x1bb14c57, 0x43f1fbe7,
- 0xe5cbcf25, 0xebe679ff, 0xf80b3bfa, 0x7e43c14c, 0x7ddda372, 0x046fd79c,
- 0x9ffad0b0, 0x40147114, 0x47e50673, 0xd2653c97, 0x11f19f91, 0x03c8639a,
- 0xddc61bf8, 0xe31bff04, 0xc77f8267, 0x27e099f8, 0xfc133f18, 0x04cfc607,
- 0x1e3b7f17, 0x8d802283, 0x4e4b4e39, 0x301ce879, 0x1c86bd72, 0xf9c1cf81,
- 0x7f3c8dbb, 0xf8cddd9d, 0xebf7a41d, 0x9973a5e0, 0x0bc189cd, 0x6fc34e92,
- 0xf0dfdd03, 0x7870e9f9, 0x2325cf51, 0xe853bfeb, 0x67a9d45a, 0x15d45ffb,
- 0x6b086f88, 0x918e4177, 0x395f0beb, 0x1fe34f18, 0xd7e20eb5, 0xa796e129,
- 0x82f944e9, 0x08332d67, 0x677675bf, 0xe51bed09, 0x51f6833c, 0x83c1f5d4,
- 0x7c78cb13, 0x75a364ab, 0xb8e51f04, 0x911f6221, 0xb5f75078, 0x81bfd139,
- 0x257e6ffa, 0x7a82768b, 0x10dc8407, 0xed43491f, 0xcff32d77, 0xccb05374,
- 0x7e9deb8a, 0x0a1e6e4a, 0x29f675ff, 0x5477e78c, 0xc7cf537e, 0xe952fe15,
- 0x1df2ae76, 0x6b901e39, 0x6ae77e84, 0xb236a5d2, 0xc9e3274b, 0xee57ac2f,
- 0xe6757419, 0xf4fb47bc, 0x6ec194ec, 0xc8d63e63, 0x5f8562df, 0x6dd85854,
- 0x36bd1174, 0x59ca1f77, 0xe4fa6164, 0xb3f6c62c, 0xbc9aec72, 0x89d56167,
- 0xe14a1fc7, 0xea9a56f6, 0xceba783a, 0x60dfe38a, 0x6d36fede, 0x93f5ae69,
- 0xcf2c44ba, 0x1076934f, 0x9ccb605c, 0xe5a3649a, 0x37fd797a, 0x41d94fe6,
- 0xa3957522, 0x29b9fd9e, 0xecc264a4, 0x9639ad43, 0xcb071f0e, 0x4d64d675,
- 0x31b4d2f9, 0xdb97f69a, 0x57f535b2, 0xd4d38fe6, 0xe55ef3ab, 0x2bb4d528,
- 0x51660a4e, 0x60fb875c, 0x64e780b9, 0x7da25daf, 0x1c62beef, 0x3f3da796,
- 0xca6e41cb, 0xda7ea566, 0xd12f5a96, 0x69f10063, 0x70ea8744, 0x1f47fae5,
- 0xe222c1a2, 0x67eec686, 0xe76d3876, 0x130c3710, 0x7100ac2f, 0xdc5c3f8e,
- 0xa02f1910, 0xf4907cfe, 0xd7abf167, 0xdc70db58, 0x2e2755cd, 0xef3ee1b0,
- 0x8238c1cc, 0x47128dec, 0x833fc70c, 0x04d92272, 0xf0c8f4ff, 0x03fc10dc,
- 0x1f850bf0, 0x3ef69c05, 0xdf0533fa, 0x4a7dbf5f, 0x07f38dfa, 0x57efc51e,
- 0xafbe4460, 0x6f78e8d8, 0xdea7e50d, 0xf9ce8191, 0x03ae24e1, 0x77e81beb,
- 0xb0f7c439, 0x46bbe9e8, 0x0f77f0a7, 0x94aba6b9, 0x731fdffc, 0x71aabf14,
- 0xcba35dfb, 0xf370f542, 0x70f69a27, 0xa6b774bb, 0xb6a6677c, 0xbb94ef7c,
- 0xe70ffbc3, 0x5c6c3597, 0x9ca37460, 0x392c3c36, 0x8be843bd, 0x28a4f5c1,
- 0x097ba1fa, 0xdb43dbeb, 0x716d1997, 0xe157edd1, 0x6cb79478, 0xaadec618,
- 0x193aea7a, 0x7faa879a, 0x71cf9d47, 0x08fbe77e, 0xcdf64f71, 0xc3b09af3,
- 0x8db8251f, 0x2fb27ce1, 0xf47b9c47, 0x1dc0f63f, 0xee79d35f, 0xeabe22eb,
- 0xa3f6144f, 0x9d33f3a8, 0x08f1610e, 0xd6455fc1, 0xd2ec8e80, 0x0f58d2c0,
- 0x2d359ca0, 0x8ae8f38b, 0x7e088fc9, 0x5e4f1e68, 0x9a0f2dc7, 0xeb1fce91,
- 0x3cbb1a74, 0x9616c140, 0xd9fd9efb, 0xf7e93b8c, 0xe92f7102, 0x2fb3ed7c,
- 0xad7d8407, 0x1e637a11, 0xb7629ff1, 0xd3565500, 0xc768305d, 0x5e10cf48,
- 0xbf6b9ca8, 0xc987fdf5, 0x7a11efcf, 0x370af283, 0xb4e05fb0, 0x1d0df368,
- 0xbbf8e72c, 0xd73efc2d, 0xb78feb59, 0xf3968dda, 0xd84647a8, 0x218779b5,
- 0x57fbc5f4, 0x5e9b3d22, 0xd05ef997, 0x04f6adb1, 0x911fd308, 0x28da6c78,
- 0xe5ab9cb3, 0xcbe55ba3, 0x830f6cbc, 0xd185f519, 0x83a706f8, 0x55b57fe5,
- 0xd27ab7cc, 0x4ec83337, 0x8bd6eeaf, 0xcdc32f4b, 0x5b064eb3, 0xb79b3cd8,
- 0x5d929699, 0x603fd753, 0xf749f455, 0x0a534957, 0x843b5c04, 0xc0bf457d,
- 0x417e4290, 0xecf1c4bd, 0x3551ee9e, 0x123da784, 0x3c256cf8, 0x5c6635c4,
- 0x1c314cdf, 0x5e50b77d, 0xf9f2d214, 0xd71aa59e, 0xacecf1aa, 0xf27659ee,
- 0x5cec3f63, 0x072907b8, 0xccd9ec93, 0x8782d74f, 0x893deefd, 0x93ca74ae,
- 0x3fee534c, 0xf60c49ec, 0x67bdbf91, 0xf744ac52, 0x3bfc7019, 0x5f757c69,
- 0xf4ae0c7b, 0x9297de66, 0x44fe752f, 0xf67b153e, 0x67aaa271, 0xa7dbe4eb,
- 0xf7e7495c, 0xf14ac073, 0xf85974ec, 0x2147f0d5, 0x6d5eaacf, 0x6c49fc92,
- 0xa633edaa, 0xa34f11db, 0xe4a97e5a, 0xf735db7d, 0xafd6cf00, 0x5fa38c1e,
- 0x567f9894, 0xb1bc4439, 0x47f3faaa, 0x57f9c5ae, 0xfe4fbc61, 0xedaec2dd,
- 0x917f08fb, 0x7c60fdf1, 0x7be62ff5, 0xd733e3a3, 0xcddfda32, 0x73df1c77,
- 0x69c7442d, 0xea817183, 0xcb173e5f, 0x58a8d6e7, 0xfc287c85, 0xee5b647a,
- 0x7f5835de, 0x66062fe4, 0xfd2737d7, 0x58ade8ea, 0x58b9f9be, 0x2491f3c6,
- 0x391d90f0, 0xebcf29b2, 0x744b06c1, 0x6fb25ec1, 0xcf8e25b0, 0x327b3e69,
- 0x512fb7ef, 0x76b7f27e, 0x7e4843f6, 0x7cc2e86c, 0xe88ff746, 0xb9a3cbfb,
- 0xbcc5b81f, 0xca5c8a0d, 0x5fde142f, 0x242ff54d, 0xa5427e73, 0x6327e1df,
- 0x7dac149c, 0x2b22be05, 0x92e7deb2, 0x5bdd10e7, 0x697ba15c, 0xf97c84bf,
- 0x06f708d5, 0xc7f2f7da, 0x89c3f3ff, 0x17da9fb8, 0x1555feae, 0x07d96fae,
- 0x84e340a9, 0xdfb43ae8, 0xb66b6c70, 0x3f057f90, 0xf18c5e2b, 0x27d30c1e,
- 0x35123b2b, 0xd1aea6e5, 0x7a6183de, 0x729ef068, 0x04e7c4a3, 0xed5c8a8d,
- 0xeddbba37, 0xfba5d794, 0x713f4ca9, 0xce84b51f, 0xf7ff08ab, 0x91ff1899,
- 0x5da2f67c, 0xf3566739, 0x4e60c93c, 0x0b75b923, 0x97dc0dfc, 0x31e289b7,
- 0xf1493d9f, 0x33b9823b, 0xb3f9c30a, 0x9c1bd577, 0x7b8931e7, 0x9f43318f,
- 0x13da77eb, 0xf9837db9, 0x699e4d4b, 0x4d09cb55, 0x015567fe, 0xd2501fb0,
- 0x89bd2b66, 0xba1487ce, 0x7aee9fdc, 0xf1def18d, 0x18bbabc0, 0xf2dc4f9f,
- 0xd3bbcd31, 0x5d83f4c2, 0x11163c4a, 0xbf98356f, 0x69efe450, 0xe87e7f8d,
- 0x9445bdb1, 0xcaf438ff, 0xd3ca22b8, 0x87fd942e, 0xf7c99d7e, 0x86dff69c,
- 0xf7cecb70, 0xb91e2f39, 0x0c7ba8de, 0x8d43d092, 0xba648fb4, 0xc77ae3ff,
- 0xf42e72ce, 0x850d81c3, 0x1f353f8c, 0xe864703d, 0xa75d5078, 0x3ebabe3a,
- 0xddb57c75, 0x5f22ecdf, 0x17f46fd0, 0x415ffd91, 0xfb6130e7, 0x17f78fea,
- 0xbbe85a25, 0x4913f855, 0xb7e30e58, 0x2abcf57f, 0xf06a7cf2, 0x47c9565c,
- 0xfdadd3ed, 0xaff91199, 0x8321e3af, 0x7eef5c3b, 0x752a73cf, 0xdafdeabd,
- 0xfd85ab7e, 0x2576939b, 0xe90e9f1f, 0x1deb0ed4, 0xb7bff23e, 0xc7e41c98,
- 0x905c9a27, 0x3469f88b, 0x9afef8fa, 0xe4d12fda, 0x7991efe6, 0x234481f9,
- 0x81e5bdd0, 0xf7fce554, 0x42bd602b, 0x9c16e871, 0xd756acb7, 0xd212c5bc,
- 0x2cfeaa87, 0x0bdf871b, 0x3ea91ee8, 0xdf2027e4, 0xdb6b1594, 0x2da3f687,
- 0xa0ae7bff, 0x6eb25963, 0x24b938c8, 0x1b65c857, 0x9e42c874, 0xa89d1d85,
- 0xbf0d1de0, 0xacd7ee1c, 0x40fcf452, 0x0743d9bc, 0x8ab713bb, 0xf513ab7b,
- 0x5104edbe, 0x124b400b, 0x89f4995d, 0xfab4baf1, 0x1cc86c9c, 0xd8e3cbb6,
- 0xc8504f2e, 0xccd4b77d, 0xf7435bf7, 0xc132fd5c, 0xd0c8218b, 0x413d5609,
- 0x4bc30324, 0x2a70c5c0, 0x0cbc3334, 0x015e19da, 0x02af0c1d, 0x89f8433f,
- 0x1ed80daf, 0xff656edc, 0x3a25f2e9, 0xd765cbb2, 0xcf97ed0e, 0x3c35f052,
- 0x57cb503e, 0xa63e3b9c, 0x8772f72a, 0x7cd8cbc5, 0x2f157be6, 0xec4fe226,
- 0x34de0317, 0xc0209382, 0x46264ce3, 0xdd78a6ce, 0x6b7ef7c6, 0xbae5c9c1,
- 0x6547c4b3, 0x1777adc0, 0xda97810c, 0x9e64f9a1, 0xb90327c2, 0xe951f8c0,
- 0x8dae48f5, 0x30dd2acb, 0x7b234c50, 0xc84f4d10, 0xc59675a0, 0xa7a71cd6,
- 0x5f3fb722, 0x7a8f5336, 0x66b4acb4, 0x5f90a90d, 0xe5154ee6, 0xd32f3589,
- 0xf3fb7d51, 0x71728a97, 0x81c1a94d, 0xcbdae85e, 0xfa825e66, 0x27dcadd9,
- 0xa011a337, 0xb672637b, 0x2b761738, 0x724dcaf7, 0x2fba5ae6, 0x580dba66,
- 0x0063b8df, 0x22d7ecfc, 0xb8bc91b7, 0xb37b1c45, 0x3aafd055, 0x2e4b7dd6,
- 0x2fb333d9, 0xb87486de, 0x28dd6d79, 0x18f79bb2, 0xa49ff8c5, 0x81bdc6da,
- 0xc49932f8, 0xbf7556bd, 0xc189ef58, 0xadb24072, 0xad0cc969, 0x59c75d4b,
- 0xe9d77bcc, 0x774fcde6, 0x023d206f, 0x15c70736, 0xbefb1463, 0x34c4cb65,
- 0x1d7030f4, 0x20475e56, 0x0b4d772e, 0xee91dd56, 0x1bc6847a, 0xf87c1388,
- 0x7529d108, 0x75cbe878, 0xc43b943e, 0xdfb581f7, 0xbd23eabc, 0x042e29f4,
- 0xae4df9c7, 0x475a71fb, 0x51902e93, 0x45fbf48a, 0x05007a2c, 0x9096be21,
- 0x0f107398, 0x1af04e6d, 0x77945e59, 0x99f9ca36, 0x8b03172a, 0x4fc43c71,
- 0x8b55cb99, 0xcc5422ee, 0x60937e6e, 0x16bdbba5, 0x179e686b, 0x724d3d68,
- 0xe4f881b0, 0xc607e268, 0xc76e594f, 0xf454fe0a, 0x9eb6f759, 0xa288c6db,
- 0xb2e4c20b, 0xaf89db69, 0x6f7486ff, 0x5071663a, 0x3e3c90f3, 0xe79c46b6,
- 0x46fa345a, 0x5d09d395, 0x9c383e26, 0xc5a2f5b8, 0x07d26ed4, 0xb7a4d9bd,
- 0xda06f727, 0xe81e7dc8, 0xc8463bde, 0x7fd7ea89, 0x7d8b9d23, 0xfc8cccf9,
- 0xf9104091, 0x839c5e23, 0x8af4fc73, 0xad5f0738, 0xeca93de4, 0x788b7de1,
- 0x573b8d54, 0xde2dbcf6, 0x6ff07985, 0x122bbd05, 0x713e967f, 0x6fc455e3,
- 0xd48bef91, 0x6949b478, 0x7bd7a2b7, 0xf227ed37, 0xc51351bd, 0xbfc345a3,
- 0xa27a6a37, 0xc8d1e396, 0xb9bd46f7, 0xb14afe4a, 0xa1f8a08f, 0xb436944b,
- 0x87c70b3f, 0xf709af46, 0x35c9fab6, 0xd3952b0e, 0xc7d60e2d, 0xe10e3d57,
- 0x6489e1ed, 0x9e5519e6, 0xd893ad97, 0x5af156bf, 0x49c9bcfc, 0x7e7e28eb,
- 0xe8cdfb14, 0xe97b8bef, 0xde913e4a, 0x837bd012, 0x2cc189cd, 0xb9ba67ba,
- 0xfe41df3b, 0x9d5a1ff8, 0x68430ff0, 0x503c6a7d, 0x4b54bf27, 0x2d8e87ef,
- 0x3f0b38c2, 0xa679eead, 0xd5e58ccd, 0x1055e9eb, 0x13f384a5, 0xdf2aafc8,
- 0xc6978329, 0xd543ef01, 0x39153b08, 0xc0e9a537, 0x188f8616, 0x0db008db,
- 0x29300f91, 0x4fcd8bf4, 0x39c7d4d2, 0x4ff4d02e, 0xd4d2cca8, 0xf788c5b7,
- 0xfa71e032, 0xef422a0b, 0x3f9d1248, 0x0083f4d1, 0xbd08adfe, 0x7e27b917,
- 0x4f7e4eea, 0x3ce06fe2, 0x2565f245, 0x7926f69a, 0x5dfc4cab, 0x435ea5fd,
- 0xa6529fcf, 0xb956f11b, 0x9c1cfd1b, 0xb69f4267, 0x01e0263e, 0x5bb317ea,
- 0x984bc9af, 0x85f2da6c, 0x629e4a79, 0xe4d58c2c, 0x2ef10629, 0x61d8fef8,
- 0x0545f31d, 0xbaaafce4, 0x006cf08c, 0x6f1a2daf, 0x5df840c7, 0x1c5ac6c7,
- 0x426a96f4, 0xc932cbcf, 0x8b4baa41, 0xb5b351ff, 0xd6ed1ff8, 0x52cc7be2,
- 0x9bd3be2d, 0xb0bef8b5, 0x4cd78b45, 0xd96f168f, 0xda6826eb, 0x346bdbdb,
- 0x578dbce5, 0xe45fda68, 0x8f29a19d, 0x4d7af17b, 0x858ec2fb, 0xaee2fa9a,
- 0x957a9ae5, 0x83e386cf, 0x11d5bef1, 0xdd03a6fc, 0x74a0f869, 0xf335cfe7,
- 0x9ff450fd, 0x05e8a79f, 0x2bd7fe85, 0xf8dde576, 0xb892f7c3, 0x7a158b4e,
- 0x50df3070, 0xee78e06d, 0x6d725b3d, 0xc505e91c, 0x7b14b9de, 0x894f3907,
- 0x1d9455b2, 0xa2bf717e, 0x36ab9f64, 0x2cf746de, 0x8a8afdc4, 0x09b5edc3,
- 0x1de23ed4, 0x494af4d6, 0xf91dde73, 0x67a66b2e, 0xd1209cad, 0x3f7144bd,
- 0x841ef231, 0xdeab3efa, 0x2739a319, 0x96bdee1f, 0x78c25f9a, 0x2f148c01,
- 0x3efccce8, 0x721fda31, 0x5fd9946c, 0xf6ffb373, 0x79cdc967, 0xfecc6ba7,
- 0xecefe20c, 0x79f5eeb1, 0x3aa3b788, 0x3dfd8d87, 0x00d6fde5, 0x2fdf8c6d,
- 0x3ca4ccf5, 0xbb8600e9, 0xdfd4d794, 0xbd2663b3, 0x5be5c45b, 0xac221503,
- 0xe68f3fa6, 0x71a41fb9, 0xbbd6480e, 0xbbefb14b, 0x20cf3e13, 0x73a2667b,
- 0xff3e12fe, 0xfc2f387e, 0xee147bfc, 0x406df50f, 0x79f0f367, 0x8e25cfee,
- 0xc1a73e53, 0x77e4c2aa, 0x4f79419d, 0xb9b6e22a, 0xb8d4be0a, 0xff328e6d,
- 0x29621c01, 0x5db9f3ea, 0xacbc667f, 0xe253eb48, 0x158766bd, 0xac71bfc7,
- 0x7bef84a5, 0x221d4b39, 0xb8e357de, 0xb1f7f231, 0x87ba67b3, 0x88ed22b5,
- 0x97869e26, 0x57cc8792, 0x42c5e646, 0x1fe316fb, 0x76cb1f58, 0x74fac0e8,
- 0xc6863fce, 0x85f9ca3f, 0xfbdacdb9, 0x3e5bf3dd, 0x02dff0d2, 0xfa9a27cf,
- 0x30d04a40, 0x781ff706, 0x1bd4f475, 0xaffd7f10, 0x9e282a98, 0xe4f5ba45,
- 0x0fc68795, 0x897797dc, 0xb4ce1bf0, 0x1d79cfcf, 0x5afdcabd, 0x5bfb9f75,
- 0xd03971f7, 0xefb8881a, 0xbfc4d1e4, 0x09fe342a, 0x0e8fc9f2, 0x431c234a,
- 0xe76673e5, 0x57a9388b, 0xabda7779, 0x55ed3bbc, 0x2af689de, 0x957b42ef,
- 0xbbeaa177, 0x9c095edd, 0x8e64bf74, 0x816a7ae4, 0x0f76efc4, 0x969b3ed1,
- 0x5de88b07, 0x60715363, 0xbbf3249e, 0x7df423dd, 0x45bb7788, 0x69f49592,
- 0x6ef435ea, 0xcf08f0f7, 0xd9d8b251, 0x50d789f9, 0x28d870bc, 0xc5f4a3e4,
- 0x7bd2666f, 0xdd53c7bd, 0x3fbf89c7, 0xf31f6495, 0x9f12ebf3, 0x6033832b,
- 0xef16719c, 0x13cbbf7a, 0xf32734e7, 0x0a89b9c4, 0xbd0be647, 0x9cb04a56,
- 0x2e6f72e8, 0x68dabbbf, 0x385777e2, 0x7617539f, 0x7df2221f, 0x4d1fc95c,
- 0x6a1fd23e, 0x5f2127de, 0xbbd3379c, 0xca675a39, 0x6ef126fd, 0xa0cfe02e,
- 0x0f747677, 0xbdf245ca, 0x1de29c1b, 0xf0a6de5e, 0xf90930f7, 0x45bd3dca,
- 0xb7a779a0, 0x7ec0e7b2, 0xe5af27d2, 0x53f393b9, 0x56c7ef43, 0x7f676fc6,
- 0xc6df20af, 0x797ae2f3, 0xee17a8ff, 0xc79cfa24, 0x7e56617c, 0xd7fff479,
- 0xf5bc3860, 0x5a3ff62f, 0xf77a1990, 0xaddef616, 0xaf2c3f20, 0x343faea7,
- 0x42e5e9ce, 0xe5a97bcd, 0x93dd8f43, 0x7486724b, 0x5948f911, 0x88633f9a,
- 0x05f3d3fe, 0x774feffd, 0x97f9a04d, 0x60bc8b37, 0x6fda6f88, 0xdce898f9,
- 0x3ef21963, 0x723fdabf, 0xf5b72b9f, 0x9f703e30, 0x617f68f3, 0xf08cbcfb,
- 0xbfb3eea5, 0x05a3ef7b, 0xdfdf73b6, 0x6e777df7, 0x6d71811a, 0x767950d2,
- 0x7e613eb4, 0x3fed4999, 0x8fedaf56, 0xb1e5390e, 0xd1de48bb, 0xe254e96f,
- 0xc4cbb21e, 0xee5daa17, 0x2920e254, 0x02ed83b0, 0x71724bcd, 0xfb61e4b7,
- 0xda3be6a8, 0x947fb424, 0x61af7057, 0x685f217b, 0x775f1071, 0x49f9ef22,
- 0x58cef41e, 0xc44773ce, 0x758b3fd7, 0xbc7844df, 0xa335aff9, 0xf2defe28,
- 0x38942b97, 0x72abd84e, 0x69cb3f85, 0x4147da7e, 0x996df302, 0x730abeb2,
- 0x55c9fb33, 0x5e4591e0, 0xac93c943, 0xdff1c1df, 0x141a01ff, 0x43d0aaaf,
- 0x000043d0
-};
-
-static const u32 usem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x1894738a, 0x18357a18,
- 0x326b3618, 0x31686830, 0x20318830, 0xaf8568e4, 0x9fa65371, 0x8181959b,
- 0x81f98817, 0xd7881058, 0x6c303133, 0xff5e2260, 0xfb045111, 0xc303209e,
- 0x197f2051, 0x6614ee90, 0x64055860, 0x2fe2031f, 0x1080be40, 0x100c8303,
- 0x606115ff, 0xc1d20530, 0xc4036c40, 0x9bf145c7, 0x7c80827f, 0xbf2a08bc,
- 0x279f8d1b, 0x25ff5f8c, 0x0ff2fc11, 0xc363c808, 0xc7e41632, 0x7a052247,
- 0x29370207, 0xca8ff2a2, 0x543c3033, 0x51d06060, 0x919bf082, 0x6280ede4,
- 0xec21e4c7, 0xb8c09229, 0x28b5ca07, 0x2a773762, 0x5004fe50, 0x34894bce,
- 0x41d3dcf7, 0x8434afe5, 0x3ebc00d0, 0x03a8e414, 0x000003a8
-};
-
-static const u32 usem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0xc5547c0b, 0x3d9cf8b9, 0x926eece7,
- 0x2126cddd, 0x26c2bc21, 0xb80d4401, 0x41a00c40, 0x94520f37, 0xa2a1e1a8,
- 0x24786c22, 0xf622ef21, 0xddbf1f62, 0x52c488f0, 0xd4c51f1b, 0xb051768b,
- 0x40368bd1, 0x5c1758d0, 0x6d8b459e, 0xd5a045e8, 0x5e40137a, 0xa540b206,
- 0xcffd45b6, 0xdd9ccdf7, 0x26364e73, 0xf6ffef6a, 0x9fdbfffe, 0xcccce61d,
- 0x7cdf3337, 0x9be6bdf3, 0x91be6489, 0xf21387d8, 0x256efc25, 0x108951e4,
- 0x9b4e1892, 0x9fc6933c, 0xedb10994, 0x3bea247e, 0x9e0c8499, 0xd146706b,
- 0x64085fa2, 0x21064b4e, 0x758d65c9, 0x793dfa46, 0xe8bc7d91, 0x9819c308,
- 0xbdbae47c, 0x720c8409, 0x8266f6d3, 0x7fe92fbf, 0xc637b73f, 0x79c87491,
- 0xe131a285, 0xbc9a4afa, 0x877bfa48, 0x149bbeaa, 0x48dda675, 0xfd51fbfb,
- 0x9085b720, 0x4678c31f, 0x40cba942, 0x78b8e8b2, 0xfd2e6f5d, 0xaf0e3a3f,
- 0x295be8cd, 0x1c1a2210, 0x242444b1, 0xa0482326, 0x679fbe9d, 0x49d7ed3c,
- 0xaa36a708, 0x49e74ac8, 0x0896b4c8, 0x808972f5, 0x76cd8878, 0x78e97b25,
- 0xe22e7d57, 0x220d57bc, 0x27d69da4, 0x684ed392, 0x61c4953a, 0x232dc7bd,
- 0xd57e4206, 0x07123fae, 0x199b1b85, 0xdc155e24, 0x0e210f06, 0xc7afc513,
- 0x8f2ae98c, 0xc4c9a79d, 0xab210d71, 0x574c0e3d, 0xfa634679, 0xdb27d0d8,
- 0xf9d00673, 0xe9d8320c, 0x63834848, 0x1191dda6, 0x2dc72786, 0x0938e730,
- 0xae2926c9, 0x2f5a54c4, 0x4dc840d1, 0xf342dc84, 0x19082375, 0x5084ec49,
- 0xbc933dfc, 0x019dca2c, 0x45e60779, 0x7cc37103, 0x2e033263, 0xc62de291,
- 0x1c95cf69, 0x1bf8efe1, 0x785fdf80, 0xc1d6152c, 0xefcc1b7d, 0xf0ece219,
- 0x46dd9e02, 0x7f5a26e7, 0x5e4ceca5, 0x468ae14a, 0xad832eda, 0x1e1094bb,
- 0x1fc04cdf, 0xc9cc8fed, 0x30d7acd5, 0xb4224718, 0xeb05dc73, 0x75b27164,
- 0x1574095a, 0xf2e61d61, 0x77655875, 0x38fd19d9, 0x11fa2449, 0xb1fa5aed,
- 0x8fe96864, 0xba9fb17e, 0xbf69e79e, 0x3bed424d, 0xbd3ce953, 0x4dce0c4b,
- 0xa160dbf4, 0x0af80051, 0x80c425bc, 0x41f92afd, 0x63a05265, 0x179e1ab4,
- 0xf6f7e9cb, 0xefcf730e, 0x52e2062d, 0x2a5372e8, 0xcec4777c, 0x6626e3a0,
- 0x6b4cec47, 0xe987f1cf, 0xc925d924, 0x4c0eef40, 0xac47041b, 0x477ce300,
- 0x9c049b24, 0xf6a4727f, 0x08edd3ff, 0x377ae1f1, 0xda5475f0, 0x3d203c51,
- 0x468b1f79, 0x3450883c, 0x17e70c39, 0xad17cf1c, 0x4a434f45, 0x5868e348,
- 0x875f9a5f, 0x79a663f4, 0xb09be62b, 0x3fca1edc, 0xacc9e58b, 0xba5e5d3e,
- 0x55e3bd18, 0x6eda1759, 0x4291c203, 0x38445e70, 0x9bbf5096, 0x94203f30,
- 0x1fd625ff, 0xb7f7eaca, 0xceed251f, 0xf9c29e0d, 0x003b2ebf, 0xd6dbc29f,
- 0x2e94adc0, 0x7c106e0e, 0xec0f9a26, 0x75fe418c, 0x9f0cfd7e, 0xd767e289,
- 0xea0b9338, 0x8398df9f, 0xefedbcf9, 0x5e5a24db, 0x20945db5, 0xd679d86f,
- 0x5bf141d6, 0xfc7f6a63, 0xb83dfa66, 0x602f245d, 0x9f71d377, 0x48b4e29d,
- 0x92f9633e, 0xdaad9628, 0xc01e6bb0, 0x91336b2d, 0xeaa70a28, 0x6f3bd2cd,
- 0x03d2f9a6, 0x552a8132, 0x838cea9b, 0x4f897e69, 0x8afc8168, 0x3f601f9d,
- 0x0ca4b9dd, 0xe039f7f6, 0x752f945b, 0xee93dadb, 0x7dcbdfa6, 0x7ea00a5b,
- 0x09c166f9, 0x7ebe5c4b, 0xbf0087d7, 0x211e55bc, 0xcd15f852, 0xdaa1c431,
- 0x17db792f, 0xade309df, 0x9426477a, 0xabb291ed, 0x1891190f, 0xe02346a4,
- 0x13d36ab5, 0xe79be046, 0x1fb0073c, 0x2f559f05, 0xbb687ed3, 0x2704d7ea,
- 0xc0daad4c, 0x3785cdf8, 0x68bce6a3, 0x19d57981, 0x37fb4147, 0xbd42351f,
- 0xebf15f52, 0xdf180e51, 0x8c016306, 0x6306fd73, 0x566f8a89, 0x3356ff34,
- 0xe94d53ae, 0xbd19dd03, 0xce39e7af, 0x397c95b7, 0xdf484015, 0x4338cf92,
- 0x339e87c5, 0x57fd21c4, 0x11c48b34, 0xdf781f81, 0x8760fbe7, 0xbe03f195,
- 0xc0ed4b5e, 0x75ebc21a, 0x4fd7cec9, 0x88cd660a, 0xe71ee7c0, 0xcb91a3f2,
- 0x7e41278f, 0x2e69f4d0, 0xf971d63f, 0xe271e4d1, 0x933d67f7, 0x71ef5d30,
- 0x67bcfa61, 0x4f3ea61a, 0xc17bd611, 0x8dd30733, 0x7f7e371e, 0x698653c9,
- 0xbf16a7b3, 0x8e59e2bf, 0x178f66e9, 0x59e6bfbf, 0xa78b6983, 0x9eadd311,
- 0x3d5b4c26, 0xbaf7ac3e, 0x36d319a7, 0xff7e0b4f, 0x530da7b5, 0xe98027bf,
- 0x9a5f584e, 0x98ed3c06, 0xc31cf6ee, 0x03a7af74, 0x9cf7eddb, 0xc72d74c1,
- 0xe49b2dbb, 0x366f1448, 0x18394117, 0x91cae85f, 0x88be3e69, 0x7ae693e5,
- 0x9f348c73, 0x8a79a6e4, 0x8195c1c7, 0x0fcd131c, 0x29e565ae, 0x66b9243f,
- 0xb2f14f9a, 0xaeb5b4f2, 0x4f9a28dc, 0xa3e5646b, 0xa3737bd6, 0x8f947e69,
- 0x39b75f95, 0xf3431b90, 0xf2b0b5d7, 0x67927eb1, 0x01b1f9a1, 0xd07f1f96,
- 0xf9a56795, 0x9f2cedf1, 0xcf37a1f5, 0x1d59f346, 0x5d4dfdac, 0x9a58bc81,
- 0xcac829bf, 0xf24ab96f, 0x2e4003ed, 0xb5cf980b, 0xd1c7e4e4, 0xe59dae7c,
- 0x4b16860b, 0xb7f4088e, 0x0858ee53, 0xb0867c22, 0x7e5125d1, 0xf1d8d3b3,
- 0x647d1510, 0x4baaf0a1, 0x2033fca2, 0xfe504593, 0x963af0b0, 0x19648c07,
- 0xbc2a3f94, 0x65bbe58d, 0x5cff9607, 0x46f2c038, 0x87ff9607, 0x7bf30870,
- 0xef961765, 0xf2c4fe10, 0xff961746, 0xf981385e, 0xcb1bb2fd, 0x962e853b,
- 0xfcb1ba37, 0x5753e949, 0xdf2fed3e, 0xdc2e9ee0, 0x5ddb7208, 0x6a597286,
- 0x597e0649, 0x04fff9cf, 0xaf2d0640, 0x3944641f, 0xacf3f3b8, 0xd3814517,
- 0x97c800f6, 0x05fa04bc, 0x485b3385, 0xc2827d04, 0x7386fb11, 0x349317cb,
- 0xa2f96e70, 0x20f3814c, 0x1fea89c2, 0xdc5f9d9c, 0x17cf1da4, 0x129c0ae5,
- 0x7fb5979c, 0xcbe5baf3, 0xbe78ed6c, 0xd4e054ac, 0xfeb89c20, 0x4f20278d,
- 0xc809c0d4, 0xe59c0aa5, 0x7fb12708, 0x271971e3, 0x8cb8e06b, 0x7538144b,
- 0xff506708, 0x378c04e0, 0xac63c76b, 0x863ce050, 0xbfd61e78, 0x534cb979,
- 0x5531e3b4, 0xc29e7029, 0x0ff6a4f1, 0x16ab6ece, 0x21adbb3f, 0x3847acfc,
- 0xaf37fb23, 0x3f169b5c, 0x7e10b6b9, 0x6b9c2136, 0xb76707fb, 0xdd9f8b4d,
- 0x5e7e10b6, 0xe98cfc43, 0x6372bcdf, 0x8dc9f8b5, 0x0de7e10d, 0xfeb8cf1c,
- 0xa26f678d, 0x137b3f16, 0x2009f843, 0x37fb1b9c, 0x2d24fc9e, 0x4293f27e,
- 0xe10779f8, 0x9c1fee4c, 0xfc5a49bd, 0xe10a4dec, 0x67080fe7, 0x95e6ff4a,
- 0x9f8b503f, 0xfc2181fc, 0x7270807c, 0xa94ccddc, 0xbdac70a4, 0x4c3fd9c3,
- 0xc3fd9f8b, 0x8939f842, 0x3852a670, 0x29c37de9, 0xa7e2d148, 0x9f842520,
- 0xb6e708f3, 0x9fd9c1fe, 0xfecfc5a2, 0xae7e1094, 0xfa3b9c20, 0xe182af37,
- 0x0c14fc5a, 0x55b9f867, 0x8672871a, 0xd8274eca, 0x9a19dfe7, 0xc13212e3,
- 0xd179624e, 0xf7a024ee, 0x433e8a88, 0xad225dda, 0x371cd96f, 0xd6a231fe,
- 0x068d726b, 0xaa56cf4a, 0x9af5a9e5, 0x1ad149d8, 0x15ce2a3d, 0x4c27c9af,
- 0x9fa9ac1b, 0x29a69458, 0x3ae7381f, 0xf720f94d, 0x487e4d78, 0xfa9a4dd9,
- 0x35736ac3, 0x6fcbe1f9, 0xf54fd4d7, 0xd3e4d4ce, 0xa9afdcd7, 0x8171b23f,
- 0xa69afca6, 0xb5f94d72, 0xfc9aa5be, 0xd7dfcdf5, 0xb2d31fd4, 0x437e5342,
- 0xf29a63db, 0x35278171, 0x9e0709f9, 0xb1bfd4d5, 0xf94d05fd, 0x68af63c4,
- 0x6c7727ca, 0x3e6fe4d5, 0xfd4d6bf3, 0x9addc129, 0xbd9fadfc, 0x439fa9ab,
- 0x6fab53fe, 0xd4d03f9b, 0xa13f6a9f, 0xf24eff29, 0x553d3a27, 0xccaf1f6b,
- 0x32afcc21, 0x01afd988, 0xc6f311ab, 0xa76616c1, 0x271c4b58, 0x7718fd29,
- 0xa00c742f, 0x033403f4, 0xe0ce5176, 0xe83a6bb2, 0xe4ddeff7, 0xbf4ec6be,
- 0xbee8cf7f, 0xbf411ec1, 0x9026f4a1, 0x061d4864, 0x8fe5f548, 0x73de8cca,
- 0xd51d5c87, 0x18d7db49, 0x68e2a382, 0xe73123fe, 0xf9c7a03e, 0x83ee0306,
- 0x42d49168, 0x411368bd, 0xd4d1e9bb, 0xaabd17ac, 0x1866b0fd, 0x308433d5,
- 0x3bb235dc, 0xc328f519, 0x9bd03af8, 0x79d187ea, 0xd164260d, 0xbcbb718a,
- 0x61fb6823, 0x8fe0c925, 0x3f991930, 0x91bfd424, 0xfd819ff6, 0x6bfe812f,
- 0x94dfe97a, 0xbfd34936, 0xd34ca539, 0xfb48d9bf, 0x90f213b7, 0xbfde26e1,
- 0xcb36fd19, 0xfec64c56, 0xd865294d, 0x6a46a3ff, 0x8ffba977, 0x88fff50e,
- 0x31ebf681, 0xc7b9bb30, 0xd26ed3fc, 0x5ca53fce, 0x9b237f3b, 0x2e434aff,
- 0xe71a3fef, 0x0e456abf, 0x394a7f9b, 0xc189bf9b, 0x0b6ff50d, 0xfa01bfe1,
- 0xfd2f69ff, 0xb5b3d29b, 0xa95e1ff3, 0xf589bf9d, 0x76e194ff, 0xfb05bfde,
- 0x6dc57a7f, 0x2bc3fe6c, 0xc9a37fb1, 0x31fa04ed, 0xf5ae890e, 0x50c9fed1,
- 0x040d256a, 0x40fda172, 0xfd1e3a3a, 0xd21a7708, 0x8bdf1c70, 0x2576f466,
- 0xf21bd29a, 0xc3b32f33, 0x5273947d, 0xd39aaabb, 0x1ce6c57a, 0x2c3df023,
- 0x3164224f, 0x36a2ea1f, 0x3c9be911, 0xa48df26d, 0x26d0bde3, 0xe8bf217a,
- 0xe03e29e9, 0x322635af, 0x49da08bf, 0x3fdf0024, 0x1798d9fe, 0xa7d2f3d4,
- 0x53e51b8b, 0xde45fc91, 0x96ba325c, 0x1002ef8e, 0x9c7f2a81, 0x186071da,
- 0x1eed487f, 0x139fed42, 0x23efeb32, 0xbe41ef6a, 0x687bda83, 0xe63a9338,
- 0xdebaf357, 0x5fc7411f, 0x0b9f9444, 0x6e2f79e7, 0x624f0a29, 0x5af8f7fb,
- 0x31eb07c1, 0x450c797f, 0xc53c787e, 0xbe4d04de, 0x07eac4c6, 0x2f7c136f,
- 0x0dc30808, 0xe1c199f8, 0xcd2f1811, 0x36b3b1cf, 0xb1de7747, 0x7dd1b05f,
- 0x5d0866b4, 0x599c308b, 0xa40f25c4, 0x565eefed, 0xa76b832c, 0x8186105d,
- 0xa166b09f, 0x3768024c, 0x0649137b, 0xde3a0e27, 0xfe0cedfb, 0x527c970c,
- 0x239b47ed, 0x74455d9b, 0x458a733c, 0x69acff1c, 0xed3ff2da, 0xc619718c,
- 0x53cd74d2, 0x45ddcfd8, 0xe77bf2da, 0xb9f7f368, 0x572a79b5, 0x0fab9065,
- 0x53bfe994, 0xdf8124b4, 0x001bf431, 0xe3907ce3, 0xd95ac1e1, 0x6a5759ab,
- 0x72951b76, 0x09b88470, 0x8bdb0bce, 0x5fcfeb3d, 0x7b17cdae, 0x6b85f9b5,
- 0xdd39f074, 0x7febe29c, 0xa683e81c, 0x283e81a7, 0xfa724f3e, 0x2d55f308,
- 0x9a13dc7d, 0x650fa306, 0xb624a71e, 0x33d6a704, 0x18dc58fa, 0x8a1e9913,
- 0x52e0f443, 0x0f4297d3, 0xfc3d38f3, 0x6943d399, 0xeeae9693, 0xc9d5be23,
- 0x6b03fdb4, 0x1d3ae177, 0x3d198a11, 0x87a140fc, 0xb83d0d0e, 0xd7e83d39,
- 0x87a71e6f, 0x7a308f79, 0x0767afd0, 0xa68e87a7, 0xeb4932cb, 0x1d74aeb9,
- 0x0eba7934, 0xa3b775ba, 0x47ae8a1f, 0x10587a44, 0x389d379a, 0x65e42fcd,
- 0xd38bd63d, 0x01a79603, 0x09e209da, 0xacf7a7db, 0x2684f94f, 0x7914da5f,
- 0x36da6bfd, 0xfaa93dac, 0xf2f2d55e, 0xbb7fb55a, 0x268b79a2, 0xa6f7c4bf,
- 0xd3697ea6, 0x717e4d2e, 0xfa9a3be3, 0xd21cd70b, 0x7fbd8be4, 0xbf9fd4d4,
- 0xfe5353bc, 0x4d59ed60, 0x176503f9, 0xdcfbf935, 0xbfd4d37f, 0x13f08e77,
- 0xa2eefe75, 0xeba89fa8, 0xa7169acf, 0x0d70cfc9, 0xec37d4d2, 0xa02ef6bc,
- 0x8bef83c7, 0x4f8ff404, 0xffd1a79d, 0x7653a9f9, 0x1e939d42, 0x5383ee07,
- 0x9e98d19e, 0x9f7138f1, 0xc24cf39c, 0x1edb42f4, 0x2a15c80b, 0xc8e04b47,
- 0x96e574a6, 0x20d935ba, 0xdfca09d7, 0xd46f958a, 0xb2128779, 0x8a639414,
- 0x2326c2ef, 0x44204c09, 0xc7c4e100, 0xe5551415, 0x37947d1d, 0xd0914151,
- 0x23b0bcb3, 0x279af7f2, 0x23db878b, 0xf7847f9c, 0x7a021935, 0xe72f7752,
- 0x29029524, 0x64277f52, 0xad81f205, 0x34a94f5c, 0xb9517e32, 0xb12e5075,
- 0xaa303e41, 0x6bfaabf6, 0x206c9ba1, 0x66ba49d0, 0x5d36973f, 0x04f7e1af,
- 0x4089cfbc, 0xdf34136f, 0xd66f9a2b, 0x25daebb4, 0x81abb8e2, 0xfdb95097,
- 0x527a292a, 0xd8153e04, 0x0c6b3293, 0x14f5d38c, 0x5112dbe6, 0x34f2ec8f,
- 0xc7f385af, 0x4c169e73, 0x30da78cf, 0xac09e53d, 0x93c07385, 0x1e98039e,
- 0xda63b4f7, 0xe98639e1, 0x4c0e9e47, 0xc19cf43f, 0x209e4ff4, 0x9f3cc7a6,
- 0x43c47a61, 0x0e70027e, 0xfe98cc7b, 0xb4c763c1, 0xe98c93dd, 0xfb0f8f05,
- 0x5f5df651, 0xcb867774, 0x7f4073ed, 0xbb6ce811, 0xcd6eac78, 0xbd9d30d0,
- 0xa423f2b9, 0x85cf0533, 0x0f4e264d, 0x087a1a49, 0x2377ed80, 0xe51f4bd0,
- 0xc3a7324d, 0x2e47dade, 0xbfe179af, 0x7caede87, 0xd30b7a4b, 0x3d1d10d3,
- 0x4f45f7a5, 0xe9e9aa1f, 0xe4cec18a, 0x1fa7a720, 0x7d6b73f3, 0x3b1251bf,
- 0x77e90ca7, 0x800cdbae, 0xdcfca5aa, 0x98699084, 0x5efbc4bf, 0xa3b5c149,
- 0x0d1be81e, 0xe8d2eb72, 0x73828fbf, 0xe8c74b87, 0x3ef6a7e2, 0xf49d3d3f,
- 0xda17778e, 0xba3e2543, 0xc61109e8, 0x1af0cd1b, 0xc8d32065, 0x461a4278,
- 0x905ce4be, 0xc4897981, 0x739f7b43, 0x3af38446, 0xc06b7542, 0x5d785f6f,
- 0x1632bd69, 0xf67a9de0, 0x5e90591f, 0xf475fae1, 0x7cf5111e, 0x09d17812,
- 0x25c90df8, 0xfc193393, 0x4691c1f3, 0x6409ea3b, 0xde7f16ba, 0x6bf835db,
- 0xcfce5548, 0x7f11931b, 0x1a8cae23, 0xf5fc0fd4, 0xc2fbdfc5, 0xf79802e7,
- 0xfb3e037f, 0xf17d8fe2, 0xbc72e245, 0xdfe746d6, 0xf8cc73bd, 0x07c01cc7,
- 0xcadf1abf, 0x3c7e9c79, 0xb5f492f9, 0x493bb8e8, 0x14f6e3a1, 0x24d85b88,
- 0xa5fe11da, 0x61626bd6, 0xfa70425d, 0xede14f58, 0xbd80a73f, 0x0b553e7f,
- 0xef074b2f, 0x6d1781d2, 0x4d2d7760, 0x3270d85e, 0x69283ac2, 0x835d4b55,
- 0xb687ad45, 0x1a97f369, 0x382d6985, 0xecec472e, 0x6a272031, 0x5edf181b,
- 0x6702a98e, 0xf6097269, 0x3d39ae73, 0x3e7bd996, 0xc7360fc6, 0xe738bf21,
- 0xfffac329, 0x06f4f1ec, 0x210f1947, 0x1984e4ad, 0x4b2d31f8, 0xaf7ebdef,
- 0xc5fd2cf4, 0x7edde788, 0x89e80af9, 0x97dffa66, 0x09107760, 0x9adc0af3,
- 0xba6bd116, 0xd66fbe01, 0x39db47f4, 0x2fe23394, 0xdf6abed3, 0x4294e448,
- 0xd45e54b7, 0xe780bd83, 0xd41a4b9b, 0xcb55597a, 0x9af93577, 0xd41a47b6,
- 0xfc055c7a, 0x525ff283, 0x3740482b, 0xba8c9c95, 0x811acb25, 0x8218af8e,
- 0x088f804f, 0xb9955eac, 0x9fa6e8c3, 0x75b2b7ce, 0xe77c6deb, 0x8854e63c,
- 0x3733283b, 0x597239e2, 0x20f9b5cb, 0xaeb7ce67, 0x5bf9024c, 0x5efa5e21,
- 0xbff68451, 0x5f2e0494, 0xcf56a0e4, 0x2841f4e7, 0xe9bcd55c, 0x17c212cf,
- 0x981977cd, 0xb70f465f, 0xbe91cb8d, 0xf9bd53f0, 0x8ecdc150, 0x6eaa789e,
- 0x237468bb, 0xcbffa45f, 0xc149e30a, 0xd454b15f, 0x9771d126, 0xffa27737,
- 0x1dec8ce2, 0xe0af83f5, 0x67e73d97, 0xa3153e49, 0xb497979a, 0x260b3f43,
- 0xe3888ef1, 0x1f280fde, 0x995bfb3f, 0x57221f00, 0x742cad69, 0xc7bb70cd,
- 0x61590c40, 0x6b4167bb, 0xfbe02145, 0xd1d3ebec, 0x8a445bee, 0xa40eb86c,
- 0x9cec0b31, 0x7180c4f3, 0x1fc9e755, 0xeb54136c, 0xe464b1f0, 0x305ca678,
- 0x1034bb89, 0xd8107bbe, 0xf539a65f, 0xf858e2ed, 0x9076292e, 0x15ca25f0,
- 0x17f180b7, 0x2f77d873, 0xfd01d731, 0x634a7b52, 0x4a7b51af, 0x94f6a793,
- 0x66425f26, 0x453c4126, 0xf132d3c9, 0x4d278809, 0x8ec941f9, 0xb5252be3,
- 0xfd1fa0f5, 0x16e1fb9c, 0x843489d8, 0x37aa87ca, 0xa62acb9e, 0x9892e9f3,
- 0x0f894bff, 0xc5654258, 0x5e5e5a20, 0x2cba33e6, 0xa277e73d, 0x943dc275,
- 0x163c03f3, 0xd1bf7007, 0x886be2c7, 0xaae2ca43, 0xf3ef5a4f, 0xba2ad81f,
- 0x8f506ca2, 0x9bc6577e, 0xafe7f5fa, 0x4f212f9f, 0x9bca3ce2, 0x561c6067,
- 0x3e07788f, 0x7059b91f, 0x27ec22f9, 0xf1341651, 0xc332092e, 0x1ad7e29f,
- 0x0f5fcbae, 0x6bdf9579, 0x1bfcaea2, 0x440197f3, 0x258a5fc3, 0x913970f7,
- 0xbfc013f1, 0x7f710520, 0xc9f8637d, 0x2f5fe03d, 0x844ff8df, 0xefbb543f,
- 0xff89fc29, 0xe88ff1d4, 0x48bcfe31, 0x78deabf0, 0x778875f5, 0xcfd5ff2c,
- 0xb7ee846c, 0x926352b3, 0xe57bae93, 0x1736d5a6, 0x6bc91df0, 0xd6717d83,
- 0x448b4e27, 0x7997df0f, 0x59711fdc, 0xc2bbf004, 0x73fc293f, 0x4ef8fcaf,
- 0x6caea3b0, 0x4fe8ed92, 0x4c05366d, 0x5bab9e94, 0xb1921497, 0xf964ef98,
- 0xfd022f47, 0xc7c9b4d7, 0xfe5a74d5, 0x41259fcb, 0x94a5107c, 0x48648621,
- 0x549f6803, 0x00b8fc6f, 0x121a8df4, 0x6faafdc4, 0x167ffd07, 0xd8b0f28f,
- 0x1cb3db18, 0xd049341d, 0x5a6afd9e, 0xb4517c7f, 0x69db7a41, 0xb2d46fe0,
- 0xbe90bf44, 0x3bb7195d, 0x00eb642a, 0xc913abe4, 0x0aabe044, 0xd98f885e,
- 0x7e5f2b1d, 0x1d276c66, 0xdfc6d757, 0xbe1504da, 0x52e97b14, 0xfc5fc2cb,
- 0x1f3bd1da, 0xa3f740bf, 0xe455bf5a, 0xdb8da394, 0x56967e4b, 0xc41b01ca,
- 0x906e5573, 0xb9fa5e9d, 0x5f17d5f2, 0xd9fc167a, 0x4739347f, 0xaf15f852,
- 0x13723bee, 0x916c57cd, 0x69b21407, 0xf0a48458, 0xffd0d4fa, 0xaf0f8f96,
- 0x7db6f947, 0xf618c746, 0xe1f187fd, 0xb2d8a975, 0xf4c648cb, 0xcb5e47c4,
- 0x2587632e, 0x74b4fac2, 0xb7fe8016, 0x1abfe5f2, 0xdd9def81, 0xa9819029,
- 0x61b9f011, 0x8087ea1f, 0xbe4f5c27, 0xd3f5a15e, 0xeba1afd5, 0xbf467202,
- 0x857afa5e, 0x5c00bf9c, 0xf4a1b388, 0x21afdafd, 0x264fee0e, 0xeca1e027,
- 0x306c87b5, 0x2d52d39f, 0x56e7f3a3, 0x2bbf0127, 0x7649bd93, 0xb2f7d94c,
- 0xfa461fe7, 0x70f43d2b, 0xba57f312, 0x76501906, 0x3cc1077a, 0x1bbfaf17,
- 0xdc4259e7, 0xcf658748, 0x9a3e4589, 0x69912a7e, 0x93ec225b, 0x9c9f7c4b,
- 0x2e2e817e, 0x4569e79d, 0xe441fc2e, 0xe8bbe172, 0xcf987d0f, 0x98906a85,
- 0xd6ccd4ff, 0xd06c80eb, 0xfd10d1c8, 0xe5147c6e, 0xae61b9c7, 0x56ee7081,
- 0x28179613, 0x5343c447, 0x6275b207, 0x51db0772, 0xdf0793b9, 0xecbb7ea1,
- 0x69ab1a8a, 0xe9467287, 0x9fef197f, 0xf41a3b8e, 0x9149d3b7, 0x46e191ed,
- 0x3d500f85, 0xaa674543, 0xfff6cefd, 0xdfb606c6, 0x9beffd95, 0xffca0d31,
- 0x23ed9872, 0x97720768, 0x10302b8e, 0x16cd77cb, 0x48983f90, 0xdf3ed220,
- 0xae7df328, 0x0bd3d72d, 0xc424bf1d, 0xfa06e8aa, 0x4075c789, 0x34f25f79,
- 0xa3e2af6d, 0xadafd035, 0x1f655c27, 0x707e7297, 0xf5c1f81e, 0xd6407e61,
- 0x5e2bf627, 0xbdf652b4, 0x5fec2cf4, 0x0ebd5fba, 0x1172bfd8, 0xcd93ffcc,
- 0x4fdc8e7b, 0x2d27edf7, 0xf2d5beca, 0x2dbefd55, 0xc630fadb, 0xedf7eb9f,
- 0x496b4327, 0xbf4b7dc4, 0x43b7dc47, 0xf847fe3b, 0x24c782aa, 0x2aaf96a3,
- 0x7c37b27c, 0x16e4f9ea, 0xd57881d9, 0x3bfa49f3, 0xd27ab24c, 0x0a8742a3,
- 0x47ff95fd, 0x47e070d5, 0xe8553a21, 0x0aa74430, 0xade7ea1d, 0xfcbea3c5,
- 0x522df023, 0x537a297a, 0x4a95f3c6, 0xa6038b3f, 0xc90ff6ed, 0x50b97c44,
- 0xfdc691cc, 0xf3a80643, 0x45be5d3e, 0xcba5df57, 0xbbeae917, 0x4d5af975,
- 0x3db6cafd, 0x10748246, 0x9713d4d0, 0x31393bff, 0xfadd1221, 0xf5a1bf98,
- 0x39ee11a2, 0xd88258d4, 0xbc415e5e, 0xdc191f10, 0x51b9e221, 0x3d71c537,
- 0xa73637f8, 0x8f94bcfa, 0x7e628eac, 0xd07b6e85, 0xd5d34f16, 0x4c1f2c71,
- 0x1f03d634, 0xa307be54, 0xbbb1df98, 0x538b6828, 0x7e9d5bd9, 0x8778f911,
- 0x0dbdf22f, 0xdd70692a, 0xd7b97a3b, 0x758f9ca1, 0x62c6db47, 0x3e29d17f,
- 0xa2a9c7a0, 0xf8396525, 0x27451aa1, 0xea8bece8, 0x79c1b5ee, 0xfd3fb755,
- 0xfbf439ae, 0x164477e2, 0x4975e38e, 0xd0765483, 0x975de219, 0xf05c402d,
- 0x859fa45a, 0x2d17667e, 0x3f791b5a, 0x2576f394, 0xe0466596, 0x390ed4bb,
- 0x51ef3eae, 0xd7ad94e0, 0xe74ff77d, 0xed11a6fb, 0xda8df2ff, 0x9fb73772,
- 0xfce4647f, 0xc7191c67, 0xbfe657ed, 0xaa7b7ce1, 0x1cd77198, 0x07dd3eba,
- 0xf9a26244, 0xd7117e4b, 0xc166d2e7, 0xe237fe07, 0x57fdc44d, 0xf546824d,
- 0xd82e887d, 0xcef4d75f, 0xffb6bac7, 0x4007eb39, 0x307faf47, 0xda69dff6,
- 0x471ffaf5, 0x37f905bd, 0x407ca68e, 0xdbcfd67a, 0x02f18519, 0x48ad3bdd,
- 0xde3bddff, 0xe401f94b, 0x613934df, 0xff3bdd9c, 0xa9e8163a, 0x0ca9857b,
- 0x30f760f8, 0xb95dbfe6, 0x3b63afe3, 0xc2aefe50, 0x1a366c75, 0xffc99f99,
- 0xdee08f8f, 0x9d3f25c2, 0x3c17e815, 0xd7e6beae, 0xf0823e51, 0xbea59aff,
- 0xe76df40f, 0x43e3cd53, 0xce64adba, 0x1c5f1856, 0x79a87f8b, 0x758bf26b,
- 0xd6aaffb4, 0xb485c65d, 0xcfedef3c, 0xfd1c62c7, 0x5d37a656, 0x879e3b90,
- 0xc66d87f8, 0x2994acef, 0x26c02f9e, 0x5df646a3, 0xb07935a6, 0xe5e27a8f,
- 0xf5a7f473, 0x1aef1f17, 0xaffd7d99, 0xc5c10f8f, 0x67d59ff8, 0x7fde6016,
- 0xf403e8fb, 0x2e909a83, 0xd27ef995, 0x4cfa8752, 0xfb3ef35f, 0xfa0e86bf,
- 0xd0216f3b, 0x4d9b799f, 0xfdebdaff, 0xeb81d1b8, 0x3d07dfa2, 0xf7c77ce9,
- 0xd5aaff30, 0x27ede389, 0xfd368fbd, 0x5beeb63f, 0xfadbbae9, 0xfe77f79e,
- 0xfbdde7c5, 0x8f33bfba, 0xce1dbbaf, 0xfede6b53, 0x75f7c71c, 0xffe95cf9,
- 0xf457ba52, 0xad4376fd, 0x6f8e933d, 0x82b4690e, 0xe25f7162, 0x03a64b25,
- 0x0f2f70a2, 0x383bf8c0, 0x57608d5f, 0xbf989935, 0x581824cd, 0x82dddabc,
- 0x3b4447e2, 0x5fae4eeb, 0x0cb439dc, 0x5d3b90f5, 0x827d413f, 0x39edb548,
- 0xee7b7eb4, 0x6ac62742, 0xdcc7f192, 0x853d9f90, 0xe6f6b5e7, 0x12e204ef,
- 0x677f7ea8, 0xa003f4ee, 0x12e5dee7, 0x29a60f51, 0xa7efbfea, 0x93efb014,
- 0x7dd0f6b4, 0xdefe6d6e, 0xddfcda39, 0x843dde1c, 0x229eff8d, 0x587e07c1,
- 0x8953ce53, 0x2d3597e0, 0x0a908996, 0xabb54671, 0xbbb8eec1, 0x197edb48,
- 0x7f2a6728, 0xe3c537e3, 0x5c78436f, 0x3921788a, 0xed03de22, 0xdc7c8f13,
- 0xf9c7b3ed, 0x489ace20, 0x7bc7864e, 0x37e89caa, 0xccb8f6e7, 0x3596cbdb,
- 0x659fb0ed, 0xd8ae1d9d, 0x9be1bdd3, 0xe11cfb70, 0x2ff185a4, 0xcfb444bb,
- 0xae7d9d65, 0x5dd7cbac, 0xbf1d650f, 0x073cbaed, 0x786372eb, 0x5c5a865d,
- 0xccabf604, 0x8b7c87ed, 0x1687e593, 0xe8ae7611, 0x00d2fac3, 0x8466f117,
- 0x9897d1e3, 0x9ce02b8b, 0x405a3ccc, 0x6b5dc87f, 0xe60f9445, 0x55c7010c,
- 0xf8c64934, 0x450d8fe3, 0x85deb059, 0x7f562613, 0x09c30d9f, 0xf1c25cf8,
- 0x516a425e, 0xbf57257f, 0x0b3b32fc, 0xea0825ce, 0x845c4bbf, 0xb8ed41dc,
- 0x10216c92, 0x126af10d, 0x078ec6f1, 0x8e40b93f, 0xdae4fc6b, 0x496efc3c,
- 0xabe9c30a, 0xe5fc6f7e, 0x17fe9d9f, 0x29c767e5, 0x3a427491, 0xd497bb12,
- 0x3f7cf776, 0xa54d63c3, 0xba434be0, 0xfbeac80b, 0xb66605d3, 0x87ebfe0f,
- 0xe64f9013, 0x2c4c74fc, 0xe26407f3, 0x6e1ac47d, 0x3af25c37, 0x760fc162,
- 0xcfce9fc9, 0x6a6cf373, 0x87a4aabe, 0x9ffe1db8, 0xd3489710, 0x51a17cee,
- 0x048b3b04, 0xcdebffd1, 0xc57bc28f, 0xcca376fa, 0x6bafbe06, 0x3f002fd1,
- 0xf2afee11, 0xa6d29479, 0x75aaf1b1, 0x59c77b5b, 0x75cf6c69, 0xd571df80,
- 0xc5b7ddf9, 0x80fdd82f, 0x1d5143d7, 0xe6114505, 0xafe3893b, 0xf0dff770,
- 0x7f4ceafe, 0x99780caa, 0xce6a2f99, 0xee669df9, 0x264098cf, 0x770ab8c0,
- 0x0c9b66df, 0x744072eb, 0x1ad57dc2, 0x3ba345ff, 0x1eb1f9c2, 0xfc1f009f,
- 0x676427f0, 0xc4f3e009, 0xd808a24f, 0x73f1efd5, 0xcfb80cc9, 0x1eae8191,
- 0x731df817, 0xb84fcccc, 0x74c76cce, 0x9c8e6156, 0x68cdfb48, 0x50838fb5,
- 0xfebcc1b5, 0xcb03b33a, 0x4a76f087, 0xac95c1bd, 0x5ed1a75e, 0xbffe691d,
- 0x79f8128b, 0x937bf399, 0x75bd7f84, 0x35a9f9cb, 0x41fa0b90, 0xd167e2be,
- 0xfdc135d3, 0xe09a6971, 0xf60df903, 0x050be630, 0x53de1fd4, 0x64cfafee,
- 0x7ba15672, 0xcdab9e3d, 0x1e02f7da, 0x887f78e7, 0x678287d3, 0xf1fabf05,
- 0xbf29f52a, 0x9fed55ba, 0xdc6dabba, 0x54dfa06b, 0x81bb05fb, 0x3a96aa82,
- 0x6b0fb08c, 0xe1909eda, 0x073ee67c, 0xa2a44b83, 0x83f8eab1, 0x0f166675,
- 0xcdfc67b2, 0x2e4e80f3, 0x2c8135af, 0x1745ae24, 0xdf87c06d, 0x0f7f3833,
- 0xdfde6c71, 0x57d36489, 0x3c0fabf0, 0x597cf2f6, 0xe715370d, 0x4732ab33,
- 0x03da7706, 0x81e4bb95, 0x675a7a2a, 0xe572c78e, 0x074ae0fb, 0xfb420fbe,
- 0x1f7871c3, 0x4fb81137, 0x8ed2d192, 0xa81f6cf7, 0x5874638d, 0x88cbb2d6,
- 0x7bcd54f9, 0xfa3f4a22, 0x50bb34fd, 0x30bcaf1b, 0xe02863af, 0x5814d0a5,
- 0xa7408ce6, 0x7394a393, 0x2729afca, 0xc76e945c, 0x27247ffe, 0xa2722996,
- 0x95e3e303, 0xe7df02f6, 0x3031392a, 0x5a589c92, 0xeb0818e7, 0xfa4774b0,
- 0x4b24d840, 0x149a99df, 0xefbc4e49, 0x47cce761, 0xeef67df9, 0xdc4e54d9,
- 0xb31392a0, 0xf44e90a3, 0xf6513eed, 0x42725f49, 0xcbffb759, 0x907de6fc,
- 0xf7f61113, 0x71393a17, 0xe518bf8f, 0x45b33dc4, 0x4facbdcd, 0x391394fb,
- 0x5e61f749, 0xa044c676, 0x7db9f79f, 0x0bdf9473, 0x5e407e80, 0x11d94664,
- 0xd1b97a6f, 0x53ff5f1b, 0xfffaf97f, 0xbe159e10, 0x3fda94be, 0x7448d4a6,
- 0x979e9048, 0xbaf947de, 0xf8c8f400, 0xb907d2fa, 0x67c7539f, 0x66cf808b,
- 0x6b2cf9aa, 0x7266ed5f, 0xf52da6a1, 0xfcb4b999, 0x09d946fe, 0x30fef2a2,
- 0xf352cddf, 0x5ea8ccdd, 0xe3196ef8, 0x13fd97bb, 0x6dea7f50, 0xfce67f7e,
- 0x11b3f296, 0x31f408ce, 0xe68c6e67, 0x7189dede, 0x06d8c9bf, 0x113de5fb,
- 0xe63f79cf, 0x71c1c07a, 0x7d04c9bf, 0x9e3e49fa, 0x2f3d7c79, 0x3e794878,
- 0x22de5fc5, 0x6d574fa6, 0xd57f1116, 0x57ff6cad, 0x073e0b37, 0xff8c17cd,
- 0x56d79e1b, 0xb5e760ec, 0x39850674, 0x78aff5aa, 0xce1ea3af, 0x08362a09,
- 0xf70cde78, 0xa59f001e, 0xce259f1c, 0x29573c0a, 0xc1fad26d, 0x2f6da21b,
- 0x1e101b90, 0x78abc3fa, 0x105342fd, 0x7f0a1dcf, 0x20373829, 0xabb6d49f,
- 0x59fb711a, 0x9a2a4fb0, 0x0d9ddf75, 0x3704ae78, 0xadaf41d4, 0x7b96d16a,
- 0x8b17bcf8, 0x146d8c81, 0xb33df93e, 0xf778f4f3, 0xf653f1e8, 0x8873f12d,
- 0x9ff327e2, 0xfe259f87, 0xf05e785d, 0xc7a2f175, 0x3f145d47, 0x324f181f,
- 0x6c7e3f61, 0xf17f2170, 0xbbe22bbe, 0x189e8b4e, 0xe50f79a9, 0xef2f1ca7,
- 0x83f5dc19, 0x80b55ea0, 0x6fd74af5, 0xf34497d9, 0x38c85b73, 0x6d286638,
- 0x90e3cad2, 0xa0756ffc, 0xbb5b9f7c, 0xdab88045, 0x60befcc5, 0x7c09ef99,
- 0xe5c1e63f, 0xfad3de54, 0xdc9bc70b, 0x287e5e70, 0x53fc882a, 0x409ddfa1,
- 0xfa6f94bf, 0x0c4e38f9, 0x9ca3e60e, 0xb8ec136a, 0x4c51032f, 0x8275d16e,
- 0x4cf66d77, 0x5f016bfe, 0x6a5fe617, 0x4358eb63, 0x75f60dd7, 0x5be79f81,
- 0x80f83e98, 0xe73b22ff, 0xd992eff4, 0x490238fb, 0x44e77e40, 0x8f915cfb,
- 0x939aee70, 0x1ddf5aa4, 0x37fe8c9d, 0xe0fc4e09, 0x36fbffa3, 0xbacbdbeb,
- 0x7f4cfa2a, 0xd3c157d7, 0x1f3add4e, 0x9c2f6a8a, 0x8272e780, 0xf20bdf13,
- 0xd179e1c7, 0xfef646c9, 0x1fae41cd, 0xd805f7e9, 0x78f7ea1f, 0x21c0c066,
- 0x145a7a2e, 0xbf6295c6, 0x533f4c69, 0x3bfd29f3, 0x6e375f48, 0xa3b486a9,
- 0x7f8e165e, 0x066edf74, 0xd04d3fb9, 0x19d149c4, 0x27ffbee1, 0xbea397c0,
- 0x36493e02, 0xc8797ca3, 0x19eebece, 0x1ef02466, 0x3235e5da, 0x06bdd1d2,
- 0xe06c91c7, 0x04c98f2f, 0x83e5c7f6, 0x3b9d1e37, 0xa445ca00, 0x26f7e28f,
- 0xa56b8354, 0x91aac598, 0x5c9847e2, 0xfffbc13a, 0xaed79513, 0xa097786b,
- 0x7ce27b07, 0xb674bf70, 0x0754d773, 0x0f325bf8, 0xcf7386ad, 0x23f67959,
- 0x1b1d6047, 0xc74fbbd8, 0x9da1e4d7, 0x0577d0f6, 0xe8c767dc, 0xbb9c017a,
- 0x391ea767, 0xe0f7c742, 0xb73c449a, 0xbc4aeb9c, 0xe731ce07, 0x0e9d141e,
- 0x5de16f5a, 0x7f9c0b56, 0x122d1f4e, 0x0f2f0ab7, 0xeff47692, 0xeefdadcc,
- 0xca4fb0dd, 0xf7843ca8, 0x87fcca9c, 0xfc840ea6, 0xd7db017a, 0xb846dd78,
- 0x74ded9e7, 0xfb4998d1, 0x00f5a12f, 0x59eb35dd, 0x028d9abd, 0xe25817be,
- 0x64f9027f, 0x1f0146c9, 0xfaa769c4, 0xf5c199af, 0xbed12981, 0xf9a7b69e,
- 0x700f6852, 0x03ddc637, 0x743593e7, 0x527ed89c, 0x97539e1d, 0x98b476d0,
- 0x2efc6fb4, 0x5eb25bc2, 0xb0af7020, 0xe3ea526c, 0x41de0093, 0x47e509d9,
- 0x08dcfd77, 0xfb479ee3, 0x2fe1441b, 0x42a63b14, 0xc103f27d, 0x152eef8e,
- 0xbafb8b5e, 0x623bef9b, 0x14e2cd1f, 0xefdca204, 0x2af1d493, 0xb869d125,
- 0xd7964a9f, 0x3abcc3d5, 0x06a989bc, 0x468ba7a4, 0x2927e390, 0x7f54ddbe,
- 0x7164613d, 0x27bc7b30, 0xfe2a1d8c, 0x1d3a32b9, 0xcb6a2fdb, 0x98b33e41,
- 0x853c6114, 0x23e98ebb, 0x7ca3ab9d, 0x94eb57e0, 0x7df029ed, 0x7e136acf,
- 0x932af0bf, 0x7586173b, 0xf4fb7fa0, 0xbdc0997a, 0xd3eb95c7, 0x9e3ac1d7,
- 0xe13b2cde, 0x8e7c40dc, 0xbe9411c5, 0x7b64fcca, 0xa7b833d6, 0xcb7f199b,
- 0x02eeee7b, 0x94a5dbe0, 0x7e70994f, 0xe2563e5a, 0xf53e4728, 0x4be3145c,
- 0xe7a57e7a, 0x1b8d6553, 0x65a1cb22, 0xd0e59105, 0x37ee7ad0, 0x6b9f2c8d,
- 0xbbe98588, 0xf078c9e3, 0x0d571663, 0xf404d79b, 0x70bb20fc, 0xf3781ed0,
- 0xdc819fd3, 0x3be2b4ad, 0x7d92d565, 0x83e8c09d, 0xeb9fff00, 0xec29f2df,
- 0x51b9b287, 0x29d90ef8, 0x47d80f58, 0x1cf0136b, 0x8c57c4bb, 0x79e25778,
- 0xf4b49b4b, 0xef21f8ae, 0xa5c48b73, 0x31655f96, 0x77aaa5c4, 0x6e9447f4,
- 0xdbf33f69, 0xcab01f04, 0xdcea3fa3, 0xe62670ff, 0xe5ae38ed, 0x6b583f5c,
- 0xfa3eba45, 0x40d5c5c8, 0x287ef3b7, 0x89dbd010, 0xf20f5dd7, 0x7049bab0,
- 0xf4b89f80, 0x297dac87, 0x3ee30f6d, 0x5f4673fa, 0xb01dce94, 0x3fd7aa0f,
- 0x6feb1fb1, 0xff001c14, 0xd46286e8, 0x22bcca27, 0x9d8df2c1, 0x79504768,
- 0x7b68f185, 0xec1262bc, 0x2655ea83, 0x1562b83b, 0xb3e8527a, 0x40a7bf93,
- 0xb3b1cecc, 0xb4673b68, 0x9eb2f903, 0x4239c52e, 0xfd029e48, 0xbd1978d4,
- 0x3b2abe75, 0x4df48b61, 0xbd1eec9f, 0xd0227f42, 0xfe98665f, 0x33cfacf6,
- 0xf69e3d02, 0x91671809, 0xf40bf407, 0x9fe2b2f9, 0x1eb51621, 0xea7d17d5,
- 0xfd07b0e9, 0xe958cbc1, 0xe854fa61, 0xc7874f51, 0x8c0f7225, 0x51d5a1fb,
- 0xfabc8f38, 0xce59ef37, 0xcf9e19f6, 0x923fd5e5, 0x44bafb04, 0x0a407162,
- 0x1624ab5e, 0x5c63d637, 0x0719d74f, 0xba7c67f5, 0x0e8acc71, 0x20f1edc9,
- 0x4a3ea9b7, 0xdf9fb402, 0xe3117e6c, 0xd2bfcf2b, 0x37ea2779, 0x003a516f,
- 0x92b66ffc, 0x3e21da00, 0xade547e4, 0x1369c622, 0x4b359029, 0x712bbf65,
- 0xb2bf1531, 0xb7cbbe22, 0xb4857c9a, 0x27ebf97d, 0xc25c62c6, 0x7b7fa60a,
- 0x39d8115f, 0x2c63b788, 0x972a3bdc, 0x5e8e7c58, 0x345df82f, 0xdebbc3b3,
- 0x7a03998c, 0xdeccd09b, 0xb96f2c17, 0xfca93657, 0x65a2fbbb, 0x939e1ea5,
- 0xc33ae979, 0x3e300afb, 0x4a76fbf5, 0xcbd74e5c, 0xdbcafe8c, 0xcae7d464,
- 0x805cb79b, 0x63f2cd78, 0x6b77b426, 0xc11a2f9a, 0xd5fbcd9e, 0xc41decab,
- 0xa7135136, 0xae3e23d7, 0x20980c59, 0x0ab5abae, 0xbe6871cf, 0x3c2df313,
- 0xc66bed1e, 0x6afc556f, 0x8a5eebc7, 0xbf6d8ac2, 0x857be1b4, 0x786c9bed,
- 0xabf9aa5f, 0xc47b55e3, 0xf034b5c3, 0x4e3bb878, 0x918fe413, 0xc1cee1e3,
- 0x7d21283f, 0x878dad16, 0xbf8ccd23, 0x456671d1, 0xa4350f7a, 0xe9fabd77,
- 0xddcf10f3, 0xe793f5b5, 0x5f95dc61, 0xe21e7e5c, 0x6882a86c, 0xe6a53d07,
- 0xfe31f795, 0x1f176955, 0x97a0edc3, 0xc3f1897f, 0x7268fe17, 0x3b0bb402,
- 0xfe80a74e, 0xdfcb6171, 0x782e2092, 0xe8a98ed9, 0x3db659df, 0xedbddf0f,
- 0xfa059ecd, 0x7e23f5f5, 0x7b6ebf59, 0x3c60f75a, 0xeeba79d0, 0x714227c0,
- 0x2c552d8e, 0xe3c1d47e, 0x8e47371b, 0xcf11ef17, 0xaeeb3ad8, 0x5b1fc029,
- 0x67d09e99, 0xba61e35c, 0x63f4379e, 0xf8f3371d, 0xbe3b96d5, 0x3cf1ae32,
- 0xd7ae83fc, 0x7c6d18b8, 0x8bada7e8, 0x942cf17f, 0x1af426b5, 0x07e818d7,
- 0xf47894fe, 0xd95da3cf, 0xdeb08931, 0xa4f181ff, 0x0e857eb0, 0xa69fd7e0,
- 0x8cf8bf80, 0x44bf441c, 0xef098770, 0x38ef966b, 0xc2e9fb8a, 0xef1843f6,
- 0xf85c784d, 0xb1fa1205, 0x03ee5df8, 0x6568d9aa, 0x1d7c90f1, 0x61d25e20,
- 0x2e3cefc3, 0x12b5d192, 0x9c5bd92f, 0x3498b2e4, 0x8b0b3efe, 0xf8daace7,
- 0x0c3f8f01, 0x09309baf, 0x2bf3abd6, 0x3c1550e3, 0x130f01d8, 0x91c071d5,
- 0x714352e3, 0x8375bac0, 0x1e3e04f5, 0xf9a5f38a, 0xe9ef10a1, 0x8a468e13,
- 0x81b0bf2b, 0x905f0fc5, 0x568fdf23, 0x626b82e2, 0xd7d6fb74, 0xbee078bf,
- 0xf175f1e6, 0xa1c63f34, 0x5f051ba1, 0xf323575d, 0x846327f7, 0x85b7646f,
- 0x0a549bee, 0x4f2cfbfa, 0x997dc0c4, 0xbe234ed6, 0x55d8a293, 0xdc5dbe7c,
- 0x8af5d6df, 0xf5a27188, 0xbf907b2d, 0x3547f9eb, 0x8fd1473f, 0x6f1f2377,
- 0x1f931b75, 0x3ead5b5d, 0xb5d3850b, 0xeba44dfb, 0x189dcdea, 0x79bfbaa7,
- 0x7543b19b, 0xc3f20cfe, 0xd77f1aa7, 0x22c6bb6b, 0xa2efe73f, 0xcad9fbe9,
- 0x3f8d63f9, 0x9b353f72, 0xa9fa6a2f, 0xed18b6f0, 0x3bfbbe96, 0x05eeb927,
- 0x99dae778, 0x45ae751e, 0xd08be69c, 0x6462cfff, 0x3237576e, 0xa395383f,
- 0x959c3ef8, 0xda2707bd, 0x5b2f51a2, 0x0c749d66, 0x665d21de, 0xcc5c6235,
- 0x471e3aca, 0x326723f3, 0xeb4af7ac, 0xbbc604ed, 0xb2abf01a, 0x9bbb65ef,
- 0x27273e80, 0xcfaa6517, 0x1bf19461, 0x4f881807, 0xd3ad8fbd, 0x4a7d8206,
- 0x1850ef24, 0x7f699dc7, 0xb62e4095, 0x9f7f987b, 0x02313d5c, 0xf64bb7be,
- 0x6e14097d, 0x04e0be7b, 0xba4f6cd7, 0x7e43f067, 0x1df69706, 0x4753bc5d,
- 0x69c977e7, 0x6ad13d40, 0x1569d808, 0x4f6a8d62, 0x41d70346, 0x5e12521c,
- 0x8978c0a5, 0x11e63cc7, 0x46d43f70, 0xf50adaa8, 0x5de6929c, 0x9249d895,
- 0x72159dee, 0x57a50478, 0xc557a70b, 0xff65675f, 0xf03b70a6, 0x0cb896fd,
- 0xbbe40752, 0x7d46ead6, 0x0b9b29e2, 0xdfd23fef, 0x88938868, 0xf54ed127,
- 0x5fb450bb, 0xda3b7dcd, 0xe71f26af, 0xa613e6d2, 0xc9232749, 0x8e3e049b,
- 0x7882d102, 0xe06a9b88, 0x70abb2fa, 0xdc785264, 0x19c48971, 0x2c3bf280,
- 0x6e808f78, 0x1e7aaf2f, 0xdc768b16, 0x3e1a7c74, 0xe1d19b11, 0x6a71b035,
- 0x0389dbbe, 0xe3a747df, 0xaf1bae3d, 0x70b56f26, 0x0911277e, 0xdcc59df8,
- 0x2ffe384e, 0x4abdf069, 0x224f8a2a, 0x38c2644c, 0xde2130e9, 0x83cf9625,
- 0x6fa9aff6, 0xeb01ef07, 0x0c870b5f, 0xb5efabb5, 0xe0e5c0de, 0x8a514b11,
- 0xac93ee85, 0xb818b5e1, 0xb82c9d9d, 0x65a04e4e, 0x9fc801fe, 0x61e796d2,
- 0xc8d08a5c, 0x5ac46ae8, 0x4466fb82, 0xad55c790, 0xd53d468a, 0xa8de2664,
- 0x8e3f70f1, 0xd0f1e578, 0x3f9f8f8b, 0x28185639, 0xa50d6928, 0x1fceda35,
- 0xa62c35cc, 0x4502d08b, 0x8b10fe14, 0x5ff40c6b, 0x6c9dc33f, 0x1bd30718,
- 0x2877bf56, 0xc16bdaee, 0x1ba86863, 0x14c0ffba, 0x2ef82164, 0xdd0ef108,
- 0x51b8720f, 0x0ec653c9, 0x463406ef, 0x332ef287, 0x698df7e5, 0xdaf37f2c,
- 0x7ef0f5a1, 0xe8bda74d, 0xc78c0b66, 0xcf0ebf6c, 0x9af102c3, 0x937bd5f7,
- 0x4738ca2f, 0xc1e40c6f, 0x07b7c7fb, 0x23c5fbd9, 0xfc7ba1ad, 0x59378f28,
- 0xed007c94, 0x43d6a28b, 0x5aaad7c8, 0x01b9610e, 0x9e1d34f2, 0x421bc810,
- 0x65bf79e7, 0xb5f2414c, 0x716b5e14, 0xb1c13c32, 0xbf6632d0, 0xb8c3c1a4,
- 0x61d9bdfa, 0x6e2b483c, 0x86e1e1d0, 0x858785af, 0x87a86f6b, 0x3bfa55f7,
- 0x0b174a6f, 0x73d35f00, 0xdb8ef80c, 0xf41663c4, 0x145fd0bf, 0x670e23ca,
- 0xbcf72f43, 0xc2853b15, 0x97d35729, 0xaba14ed2, 0x9d26e8de, 0xef63afd8,
- 0xe7e96a83, 0x87ae2ddf, 0x8b32de00, 0x8896dd2b, 0x0577c7f3, 0x8b8bbba6,
- 0x74c213f2, 0x09ee2c4d, 0x11feaef0, 0x5a1f82cb, 0xe9dafe54, 0x34c54b39,
- 0x011fde3a, 0x3c31b823, 0xdee5c49f, 0x9e7451a8, 0xc6032e89, 0xb8b11fd5,
- 0xdb3b4057, 0x6200609c, 0xf71226cb, 0xf70c4104, 0xfa8feca3, 0xaf8ecc1d,
- 0x56f8362f, 0xfc60f3b0, 0xfa611dbb, 0x47d1d0e8, 0x5b47d190, 0xb547d227,
- 0x47d193bf, 0x346e5d5b, 0x3b03573f, 0xc70491ba, 0x5937bac1, 0x61a40b0a,
- 0x82626e94, 0xb23740f5, 0xc282b6f7, 0x3aebc428, 0xf58f5f18, 0xe652e3e1,
- 0x36fadbd5, 0x71fb481e, 0x0799d806, 0xa61e780d, 0xb7a94de0, 0x46e2c2c3,
- 0x7ee6cdff, 0x99a9fa11, 0x961fb1d4, 0x3f81eb6f, 0xed875c60, 0xd05dcce0,
- 0xae9b36de, 0x6fdc2390, 0xf815c1e3, 0x7f23784e, 0x04963bd7, 0x7bd720bd,
- 0x3fdb07c7, 0xde807c21, 0xe8f80193, 0x0af2fdc4, 0xdd9667bf, 0xce40b826,
- 0xef618f0f, 0x616ebc90, 0x16bbf576, 0xaf4ca791, 0x5bb83c49, 0x7b2bfb04,
- 0x27eb0195, 0x9ea19a42, 0x5f5e2aff, 0x95ddf8d2, 0x89e85575, 0x7818d272,
- 0x78f9e4cf, 0xfd2d1ef7, 0xa9a4c7c4, 0x1eed29e0, 0x45a290f7, 0xee265094,
- 0xc810f05d, 0x3e3f4a55, 0x7231bb4d, 0x442de014, 0x233e943f, 0x776d0fad,
- 0x7c6bad88, 0x5b0be80c, 0xf1152ef6, 0xae7e8e5d, 0x47bc166b, 0xc567eb49,
- 0xb4adda90, 0x4d2c567d, 0xf3c09f21, 0x087e7903, 0x743fd34b, 0x7dfa041a,
- 0x9ecbf703, 0x922578e5, 0x6399bafd, 0xb8f4cf20, 0x9418e4ec, 0x85beca0b,
- 0x5ce05467, 0xdbe7e25b, 0x0334c169, 0x8fb29bac, 0x6021a0a5, 0x4d2b42a5,
- 0xce201872, 0xbb8f5de1, 0x7b0bce08, 0x5fb73be3, 0xea81eecb, 0xc7ce7fbf,
- 0xebf58df3, 0x2fb8f4bf, 0xb7e039fe, 0xf8f1dcca, 0xbeaf9a4c, 0x69fa32f6,
- 0xdf54c457, 0x68ef55fc, 0xeeffc7e8, 0x00c4dfd5, 0x333ffa1d, 0x353fbc45,
- 0xf1e8cace, 0xb60e6780, 0x04efe2cb, 0x1c4a8192, 0x15ce2ab2, 0x865eb8ca,
- 0xdf86994b, 0x05bacf51, 0xa7ac2059, 0xf6878a57, 0xae78a931, 0xae2eab78,
- 0xbb2f3955, 0x80fcc025, 0x42beb159, 0x74faefec, 0x3e49f7f6, 0x9992fa63,
- 0xa1ce0ffe, 0x3373f2a6, 0x5efb31d7, 0x09598710, 0x3f08f98d, 0x5afd1536,
- 0xfefb4439, 0xaf40d641, 0xf4f28064, 0x67978454, 0x13a795d6, 0x6b915bf4,
- 0x4df9c3ae, 0x0cfd2a25, 0x13a346e5, 0xd1f4f1f8, 0xf7f9fe94, 0xe1bff4cb,
- 0x867f3226, 0xcdb8ceca, 0xbe515f71, 0xc4696f46, 0xfb7e8577, 0x523f38b9,
- 0x2163c5fc, 0x4115173c, 0x8f1e803c, 0x95610eb9, 0xdf13d1d5, 0xf1e9fc7a,
- 0x8f51e0ad, 0x9d0f9cb7, 0x9e8ef1f9, 0x23e3d1f8, 0x5be97e7c, 0x7530eb0b,
- 0x4bf288b4, 0xfc4f7bc1, 0xedfaf5b0, 0x009eb4b5, 0x0df142f4, 0x30174cf8,
- 0x862b27be, 0x3a6c4fd3, 0x140b37e2, 0x0f4801c0, 0x55e3d798, 0x04acc78f,
- 0xd5813ede, 0x1af80fdf, 0xed00fc89, 0xb2dd6521, 0xc6f76bd2, 0xe8c4de41,
- 0xa7abd14c, 0xbd50bc72, 0xbce6f51a, 0x9bfa2b44, 0x9a9eaf40, 0x5e5bc614,
- 0xde571b15, 0x600bcb48, 0xfc0afe9f, 0x0608b1d1, 0x95bcc5df, 0x56e05ff0,
- 0xe2ca5f3c, 0xb7df0559, 0x93d5a67e, 0xce0bfaa7, 0xdc3dfe82, 0x05655ee4,
- 0x87108c7f, 0xff1479e7, 0xd7f875c7, 0xf36bb3b6, 0x0afc7c7a, 0x27b931fe,
- 0xab7a14de, 0x7cfd72b3, 0xfa0a1930, 0x3337d8f2, 0x137f8163, 0xbf447c7f,
- 0x4563c4c4, 0x6e9c3821, 0xe2059e91, 0xa7b77d0e, 0x763e0b7f, 0x15494a90,
- 0x7253bb1f, 0xd8deb3af, 0xeb298f93, 0xc7af8535, 0x05dde214, 0x4429a67e,
- 0x1ec84bfa, 0xffcf0d48, 0xb3f72b79, 0x6043210d, 0x1c585f9e, 0x79f3ff8c,
- 0xd54de686, 0x9b3fe84b, 0xb66d9ff7, 0x121bfde0, 0x7842ba94, 0x93f7c34e,
- 0xf0f8c6bc, 0xbd656438, 0xd3096a53, 0xfbe2e6e7, 0xe42f14d9, 0x38f098cb,
- 0x090559b6, 0xe3e20fdf, 0xf66cdf38, 0xd3db9c42, 0x2b0dfb92, 0x83843df8,
- 0x527e7163, 0x3fc81460, 0xb6e5f97d, 0x4e50d5bd, 0x3d6095eb, 0x910afe3e,
- 0x3b821ff9, 0x5217be4c, 0xe953d77b, 0xa13946f6, 0xdc3671d0, 0xe801bd7b,
- 0xb8c2283e, 0x655cfcfd, 0xcf7645e7, 0xabec45c1, 0xf6f0a7ae, 0x02f7625d,
- 0x81db28f2, 0xedfa7a7a, 0x49f34e8b, 0xd3b41e70, 0xcf22abd3, 0x5bfdf81b,
- 0x68bb3f45, 0xeb0fbf75, 0xe3efc0de, 0xba8e2ffa, 0x1be7d60e, 0x2d61d5d3,
- 0x44f4295d, 0xf438ebe9, 0xf1f99dd3, 0xdfcb503a, 0x049cbccb, 0xe3d151f2,
- 0xeb8afac3, 0x9bd7a863, 0xe6dc3f3e, 0x857eb2ee, 0x35e8af3e, 0x6423d97d,
- 0xd34644af, 0xebe3ce71, 0x2edcd733, 0x41c68bb3, 0x886fd38c, 0x73cbde56,
- 0x393e8344, 0x95ed21af, 0xac573866, 0x07f97e63, 0x3d8d656b, 0xbedb86ec,
- 0x67bd9ed8, 0xb6b97f3b, 0xef8a23fc, 0xcef8f141, 0x868ed6ad, 0x7e1491fd,
- 0xbf67b7cf, 0xc9c82f06, 0x31a32379, 0xafdf4e7e, 0x7efa7e7e, 0x7035fdf5,
- 0xd8c1aafb, 0xd2a9da38, 0x1636ec4f, 0xcd697d47, 0x14f0cd93, 0x73f86f5e,
- 0xd4b8879b, 0xa3ae6f7f, 0xa44e7a21, 0x781468f7, 0xc2e7be0a, 0x0fe098cb,
- 0x1eff95a8, 0x6cdd9de9, 0xf413f337, 0x6088efd6, 0x8683ea3e, 0xe82203a7,
- 0x048223f5, 0xa0ecf0f5, 0x6350b0cb, 0xb97b300f, 0xef003d87, 0x657cd0a4,
- 0x0f662eeb, 0x5da1d4b4, 0x0aed4951, 0xe01b3b90, 0x7cc1901d, 0x27681940,
- 0x885eec84, 0x7786caaf, 0x0c5db932, 0x37a5a74f, 0x1f33fab2, 0x8c35374f,
- 0x9dd5bb00, 0xce932f0c, 0xa8fb5db4, 0xf557da99, 0x508a24a9, 0x76c8aafb,
- 0x4ed677ed, 0xde3bdca2, 0xa4bbc025, 0x65a8ff34, 0xecedff72, 0x8fd1b699,
- 0xda81bf82, 0x54d9b767, 0xfb6f6f76, 0x039b66e3, 0xfedbd9f1, 0xcd17b4e8,
- 0xdf8a3804, 0xe421f282, 0xbe28fe07, 0xf442a3ff, 0x53780b17, 0xe5f6e5e8,
- 0x88ced10b, 0x0a6ae6ba, 0x736593c4, 0xb8db703a, 0xc186365f, 0x706189a9,
- 0x376e4a26, 0xfbbdd3f4, 0x3bf028ea, 0x04fa3bbf, 0x2b7e79da, 0xf41fdbf3,
- 0xe3a91594, 0x026d6bdb, 0x10c097a7, 0xdc777fd8, 0xec0127b8, 0xc0596c95,
- 0xb2fd4ef7, 0x99f1e9ef, 0xdb669fc0, 0x6629d257, 0xfde2364f, 0x60547f32,
- 0x3d2ac3c8, 0x4ddfcfce, 0x3fdc5ff5, 0xdcff1d44, 0xb5abcd6e, 0xc022f831,
- 0x7bdccecf, 0xde80f40c, 0xae584ee4, 0x2b9004b8, 0x24a1eae4, 0xdd6a5f3c,
- 0x689f0367, 0xe0e77f17, 0xa49eeb7c, 0xdaad3405, 0xb0369ff2, 0x3e38eae3,
- 0xf8ed4bce, 0x76e5535e, 0xa113df11, 0x003d26fd, 0x85d6eb7e, 0x1fdeec59,
- 0xc8a6afbb, 0xef9ff1d5, 0x9cc45219, 0x4cff7889, 0x98a737d1, 0x9f183ebd,
- 0x1dfd8ebf, 0xf7ba29cc, 0xefe56ec9, 0xcff5e993, 0xe2b26c67, 0xa9f8c32f,
- 0x4fd67665, 0xfb2bfb6f, 0x53e204b3, 0x296cbfed, 0xb3f8c220, 0xefc24b3f,
- 0x3da40fe7, 0x3df60855, 0x01239d91, 0xa2f644ac, 0xa7cfcb7e, 0xbc2f6fe8,
- 0x6793be7b, 0x3cbd6ede, 0x6e2466eb, 0xd004d72a, 0x9803dcc7, 0x07c991d3,
- 0xf5bbff45, 0x55dfad33, 0x722b07af, 0x6e3fd732, 0x780210d5, 0xfbc2cc77,
- 0x8c240713, 0xc9ebd2f7, 0xbd058353, 0x204fc3e8, 0x4d6d6d7d, 0xfe7b018f,
- 0x009f60df, 0xc65eb6dd, 0x49aa83f7, 0xc7781ee0, 0xb455baa9, 0x24fc6007,
- 0x67d87af3, 0xe0a13e8a, 0x1eeaeda5, 0x7fda58f3, 0x7d8345f6, 0x76f10505,
- 0x57682ff0, 0xc1fdf84f, 0xfe679004, 0x07e784a0, 0xc6f717d9, 0x45f1542c,
- 0x7e0355ff, 0x6eeafb7f, 0xfc60f7ed, 0x8b6ed0f5, 0x7bcbd981, 0x063dfff7,
- 0x57dbd4f8, 0x90bc212f, 0x6f53d13e, 0xcf3bfd46, 0xd1fc862a, 0x8899bd6a,
- 0xde2187d9, 0x152c6a6b, 0xfaef426b, 0x6487ce70, 0xd4f49595, 0x2778422b,
- 0xd0f0092e, 0xf0561f43, 0x3e33d3ac, 0x773d71b2, 0xef0f1918, 0x4d5db65e,
- 0xc77bc0a8, 0x0afb18fe, 0x8f4ccf94, 0xee7bdeea, 0xfdf0e9c9, 0x9ddec8a0,
- 0x7ee22ab8, 0x62b3bdda, 0xdf6a8778, 0xeb8a4e52, 0xc5d06576, 0xfad16f0b,
- 0x3345f657, 0xbce4baff, 0x224f7d5e, 0xf1c7df5c, 0xcecc1815, 0xe183bce9,
- 0xac6fa8bd, 0xb0f574cf, 0x4361fff7, 0x0058393d, 0xfad462e2, 0xffac234e,
- 0x3e8ad9bf, 0x25a5fc67, 0x978bf806, 0xb4210ee4, 0x9268b2df, 0xac15740b,
- 0x33b07623, 0x18301fb6, 0x37325d60, 0xcf5c62a5, 0x731cfc2b, 0x31a34b49,
- 0x4b174555, 0x19d839f8, 0xaf129bd9, 0x9632befa, 0xfb3397f1, 0x71817fca,
- 0x91347f1d, 0xd0f41191, 0xfe4cb185, 0xa77a336e, 0xc77a866f, 0x68df780d,
- 0xef5ffeef, 0x97937787, 0x038c731c, 0x5894e0bf, 0x0eda0fb6, 0x710f52be,
- 0x821f6dc1, 0x6672a2d4, 0xa068b163, 0x1c45befd, 0x9877afcc, 0x90d6bdfd,
- 0x12b8943f, 0xc5379e60, 0xd6fdbe32, 0xdce68301, 0xbefe2dec, 0x8cb1f5ef,
- 0x32c6a50f, 0x03d6dabf, 0x700b09b9, 0xc447b9ff, 0x64f01f82, 0x456c3d47,
- 0xe8a80fc5, 0x6f0f936f, 0xfe863e9d, 0xc1977273, 0x38edcb0e, 0xf30882fc,
- 0x24219c75, 0xf43d204e, 0xac6f0a39, 0x5d5bde1a, 0xc71d1e0c, 0x0aafd86e,
- 0xfe04a9fe, 0xbfcd0671, 0x43c52ed5, 0x7f82983c, 0xff4a1e65, 0xdae2168e,
- 0xe4adc160, 0xfe15fada, 0x31efe568, 0xe513b04c, 0x5d2033ef, 0x6eb9b76e,
- 0x6f72c589, 0xeccfe40a, 0x36d27a63, 0x72494f2e, 0x9fc070f1, 0x79f34eb2,
- 0xb7a78caa, 0xe3e7effe, 0x4bafd254, 0x0ec8afd7, 0x76cdd22f, 0xf0ee4f16,
- 0x10e9cc06, 0x8e96d677, 0x154a9f7f, 0x8e3f7b97, 0xfdf68cff, 0x830eb6c2,
- 0x558fee01, 0x50e210ef, 0xbea7eddd, 0xa933a21d, 0xedafe905, 0x5c7dc118,
- 0xe65dfcde, 0x9f72a48f, 0xe786ebbf, 0xf87fb0eb, 0x8120fb39, 0x1bfd93a6,
- 0xfc410e56, 0xafb06c06, 0xfba278c2, 0x46dad206, 0x92ebd023, 0xe52d2c65,
- 0x9a4bd5e7, 0x4b3fb8dc, 0xc478b3d6, 0x4ca9b165, 0x257a733e, 0xf8c1e886,
- 0x7b4dbade, 0x5c1ff08f, 0x7d6d9e7e, 0x4bf40f6a, 0x80fbebe9, 0x9eda9b8f,
- 0x55c30758, 0x46ecf5e8, 0x4594e119, 0x3df3cf6b, 0xb8cfccb1, 0xf7a330fd,
- 0x5ce51bc9, 0xb26c4f78, 0xbfc1d897, 0x4dc6d6fd, 0xb7eff022, 0xd9539e80,
- 0x7b79073e, 0x3163df66, 0xd6f907df, 0x47e02069, 0x652466df, 0x62fb545b,
- 0x343786ef, 0xb9bcb7fb, 0xebfa3a6e, 0xe005e23b, 0x55becaf3, 0xe8cdbef0,
- 0xfff70dbc, 0x9ffdba9d, 0xc2b7dacf, 0x4f7ad0ba, 0xd4fffdf1, 0xe9ffba34,
- 0x718db8a7, 0x66d9c002, 0xdccefc8c, 0xfe90df4b, 0xa3b57c42, 0x297d5f07,
- 0x6c1ff996, 0xeaffb4e9, 0xffa12e3b, 0x4e3e3421, 0x2be54f37, 0x002a9374,
- 0x0ae91bfe, 0x517c008e, 0x533d02bc, 0xccfe7a3d, 0x0795dc0c, 0xe1ff3c24,
- 0x2e3c4be7, 0x6a947704, 0x99f986bf, 0x6fdd6fb2, 0xf2b238c0, 0x9e82576b,
- 0x45e8509f, 0xb82b3cfa, 0x7953c787, 0x71f61676, 0x8eb07e04, 0xec8ae3e3,
- 0xff7debee, 0x65cf40c1, 0xf98462d4, 0x1d82f590, 0x772945d6, 0xbdef67ac,
- 0x94f0e61e, 0x2dbf87ef, 0xde3d83be, 0xf0cc3d21, 0x5c42341d, 0x931f28eb,
- 0xc5c84463, 0xb70c40fd, 0xb67d860f, 0xfbafca84, 0xacebf255, 0xaa7488dc,
- 0xce23e1e0, 0xb1c4aeb7, 0xc7ce3f79, 0x5d1f07e9, 0x82ff0aa2, 0x3f6c0924,
- 0xe7db028b, 0xbb3fc022, 0x90dba6ef, 0x4c88efde, 0xb7b076ef, 0x47efe1e2,
- 0x8cfa406d, 0x7bc7669b, 0xce494f2f, 0x7e8d38a8, 0xef74c3e4, 0xced067a6,
- 0xfd85fa03, 0x97fd1bde, 0x0893fd01, 0x74a3ef74, 0x853f5aaf, 0xfc5d280e,
- 0x7ca5f01d, 0x7285d3d7, 0x65e0a90e, 0x731cee9b, 0xe9e19daa, 0x8d5200ff,
- 0x8000b56e, 0x00008000, 0x00088b1f, 0x00000000, 0x7dbdff00, 0xd5547c09,
- 0xf37df8d5, 0x3332c966, 0xb2764c99, 0xa00c4930, 0x80490e2c, 0x084ed8b0,
- 0xc3884a20, 0x93a0d752, 0x364b0900, 0x94569510, 0x8b062081, 0xb62d1518,
- 0xef858320, 0x106d1b43, 0x268358a8, 0x622d1110, 0xa57fb1dc, 0x41459041,
- 0xed1fa822, 0xe73bf587, 0x33337bdc, 0x6a02266f, 0xefc7e1ff, 0xdf77dee6,
- 0xcf7ece5d, 0x6ec5f739, 0x843631d3, 0xae630731, 0x7d8c01e6, 0xf4bf3f8f,
- 0xa12d8c97, 0xcf3773e7, 0x8224715e, 0xf0f7cfd1, 0x5e79babf, 0xc776bd50,
- 0xe91c57af, 0xc5cfafe7, 0xffe0525f, 0x8967a671, 0x47f1558c, 0x89ef4cac,
- 0xfbc025b5, 0x6cd69d11, 0xe266b498, 0x03846319, 0x8319789f, 0x1c636ff6,
- 0x6faa3e54, 0x1f2bd3de, 0xe9cc31ca, 0x9b39a685, 0x998f1533, 0x1b3605b1,
- 0x27f967ad, 0xb0dd93d3, 0xc6c646de, 0xc59bbae3, 0xd9dd727c, 0x99c68536,
- 0x8f7329e0, 0x66678389, 0xa07b9e4f, 0x6607f9ff, 0x886d964f, 0x70a13ebf,
- 0x4018eabe, 0x7ec48c4b, 0x0c985563, 0xc9bf9fe6, 0x326533e4, 0xc49f05b6,
- 0xa3db2ac3, 0xfd329b7c, 0xccf4d9ef, 0x9633b7a5, 0x75a4cb6b, 0xb15aeac1,
- 0x646858ee, 0xdfbcc197, 0x9bb59666, 0x1dd5d1e1, 0xb081e2de, 0xef462d8f,
- 0x389989d4, 0x1c1af398, 0x9d629aff, 0x6a5801ed, 0x38a6cbac, 0x6992d007,
- 0xcf8fb65e, 0xeced9793, 0xeea1b2cf, 0x2db9e670, 0xf8128d8c, 0xc930ad62,
- 0x421c3f70, 0xd9e1c6f1, 0x20175e13, 0x1750867c, 0xd5e27e7a, 0x667d1ba8,
- 0x0144f3ff, 0x78632fbf, 0xd3c1adf9, 0x1d0e66db, 0x553e6027, 0xcacc6649,
- 0x5c554b3c, 0xdb6628ff, 0x773ff0e4, 0x1c2e628c, 0x57189a7f, 0x8ffacbb6,
- 0x10aeafa6, 0x78869afa, 0x22e88ead, 0xd053eaba, 0xbcc07469, 0x8bdd194c,
- 0xee98fac1, 0x80ac5eda, 0xbd71eaba, 0x29554800, 0xf6c7ebe0, 0xd7338d84,
- 0x01d99e23, 0x0cc9cb13, 0xcdb567dd, 0xd1b6e1c0, 0xe866fa30, 0xb865e097,
- 0x838bc003, 0xde3585e3, 0xdc6bf88a, 0xd7886268, 0xdc39636f, 0x68d953ac,
- 0x42b7f403, 0xc6f7247f, 0x57039ea9, 0xd931bd41, 0x9e6050e8, 0xc22e8613,
- 0xa0ab89fb, 0xadc3e88d, 0xbc4fbe20, 0xdf9ae23a, 0xa277bb40, 0x8bc0e58e,
- 0x05b08d5b, 0xa7bfc3a4, 0x482936f9, 0x27c42da7, 0xc1b2c7f3, 0xbede7826,
- 0xd5d11869, 0x052ce2ac, 0xe6ce76e9, 0xdb9f0558, 0x2a74d8c7, 0xd863eff3,
- 0x13e89542, 0x16dea0f8, 0xde618f80, 0xd5e1153a, 0x6c93ce3b, 0x11ec6588,
- 0x23e335db, 0x32ce81d2, 0xcc1b2459, 0x5f5043d8, 0xb46b7009, 0x4b1614bb,
- 0x0a7306f5, 0x236321f1, 0x0cadae08, 0xd518d4f0, 0x6045775d, 0x7f5e2cff,
- 0x86eaf1a4, 0x9ec63486, 0x22357189, 0xbb303e9e, 0x87f9c11f, 0x44a9d526,
- 0x7fae82e7, 0x127ece80, 0x2c2ed4bd, 0xe0f38762, 0x0e660ef7, 0x47901ba4,
- 0xf8066eb7, 0x9b3de895, 0xbd355d70, 0xc38e3e8e, 0x657cb6d5, 0x7ba184f4,
- 0x21788eb9, 0x8cc7d817, 0xaeef11f0, 0x7ecdcb53, 0x66c5b3b9, 0x52ed4c17,
- 0xfcfc5b26, 0x79eb7286, 0x593b9733, 0x98229a50, 0x7ec762d7, 0xac23a23e,
- 0xe5fae4c7, 0xdd62cad1, 0x3e185f78, 0xeb890d7e, 0xaccf9467, 0xf2ff7fe5,
- 0x1fd0a19b, 0x9f89577f, 0xc4fce35e, 0xc5a3f5e5, 0x3c22269f, 0xbdf09390,
- 0xeb1cc5db, 0xeadf3a97, 0x5fb9748b, 0x3ea09b65, 0x2af464d8, 0xe66db831,
- 0xf18a25b0, 0x945b0d90, 0xa820cb56, 0x2e614bff, 0x7fe9c3c0, 0xbfae54a9,
- 0x133e3dd7, 0xa1d9afde, 0x7e852e73, 0xf10a2d35, 0xf337b383, 0x371d0045,
- 0x31075947, 0xb770af18, 0xf68065d9, 0xc9044ad3, 0xd7009c65, 0x2feb9061,
- 0x8268cae8, 0xc02df5e7, 0x5d3d507f, 0xf5c6a808, 0x6c319dea, 0x83be1f80,
- 0x1fb47cde, 0x1bda00ec, 0x4f67c89d, 0x9ff1f245, 0x81f0cc8a, 0xbe528310,
- 0x4a0188e7, 0x6e825961, 0x62c67af4, 0x78504f00, 0x30b51cb1, 0x3c07a5db,
- 0x35e67a2b, 0x7546be00, 0x9f08aab5, 0x8e872eac, 0xe9f3fd99, 0x3bed18bb,
- 0x39d0ef4b, 0xd6d5f403, 0x7aabcfbd, 0x31d0eb80, 0x942af58d, 0x6f9e3189,
- 0x4623de10, 0x7b63d5d5, 0xf557b15c, 0xa57cff40, 0xe905b76e, 0x44e61aec,
- 0x24f92ab9, 0xc1b593ae, 0x81ec5972, 0xda15974e, 0xb5771c47, 0xc7fd800d,
- 0xe38299b8, 0x7c0dfd49, 0x0e9162c6, 0x44ca5de3, 0x3fe86718, 0x8e47c118,
- 0x68ef75b3, 0xbe3ef905, 0x18e28c63, 0x6be74a10, 0x38b7e398, 0xce9f77ae,
- 0x3475f889, 0x9406d733, 0x62ba7f13, 0xf64bc20c, 0xf5cb1def, 0xa78f48ca,
- 0xee154408, 0x1de70627, 0xb76fa37e, 0x6c33d601, 0xd1b77796, 0xd99fb011,
- 0xed4bc68c, 0x523ed2f4, 0xb10a780e, 0xd2c6b6cc, 0xb78e2338, 0x7e800db6,
- 0x1fb07549, 0x78ef4f68, 0xa6b8414f, 0x882875d7, 0x777badcf, 0x3ad37ad1,
- 0xf82979da, 0x176179eb, 0x5603db74, 0xdb23ed1d, 0xf2cdf5ca, 0x666f5c53,
- 0xadb27ac7, 0x2c7dfe09, 0xd724f42f, 0xf66bf8c1, 0x17ef7566, 0x2895eee5,
- 0x52e403e4, 0xc691ac6e, 0xe9eacbb9, 0xbdabfb8f, 0xd20f73b1, 0xdf7bf3e0,
- 0xb47f12b1, 0x137e13c4, 0xf84a7df7, 0xba485c48, 0x37d9ad98, 0xb179415f,
- 0xa67014a6, 0xca59c284, 0x7eb8358d, 0xf45b1fa2, 0x27cfa024, 0xd8829eed,
- 0xcca57b40, 0x20159d1e, 0x8f7be497, 0x19ee662f, 0xed6190b0, 0x16595be5,
- 0xb17ef7c9, 0xc27df201, 0x9122fbc0, 0x2e2c9a9e, 0x569fb617, 0xcf388dd8,
- 0xfb425833, 0x975e0633, 0xe0407af0, 0x52763b33, 0x870875b6, 0xf8e80d93,
- 0x4fde4899, 0x8dee8f2b, 0x83bb09d5, 0xe0eb0bd3, 0x08fb82f4, 0xc666bfb4,
- 0x748c3c72, 0x9cf48a79, 0xfee2a64e, 0x76f81786, 0x1b0edd23, 0xf48dddef,
- 0x9d04ce9f, 0xa274e78c, 0x63dbf7a5, 0x711d7cb9, 0xdc218bbc, 0x0ee615f3,
- 0xc654ef67, 0xbe29bb72, 0x0fd13463, 0xce1943f0, 0x4eb53437, 0x66dca035,
- 0x7fa809b6, 0xa0eb137e, 0xae05797e, 0x366f48dd, 0x79f89b97, 0xe9c6d9be,
- 0x07d39326, 0x1c273fbc, 0x3e436d3f, 0xa3e7e01a, 0x7347a478, 0x26de3d28,
- 0x011bf4e0, 0x3df1d0df, 0xf1f8e177, 0x02973a1d, 0x603b0c83, 0x3ae831f6,
- 0x49e8016c, 0xf40653e4, 0xcfb40b0f, 0x9f2215b2, 0x153956a5, 0xb302ebc4,
- 0xd7dc1efb, 0xf98d9472, 0x5f3acf48, 0x6c97bc3d, 0x7efe1173, 0x67689eb4,
- 0x90686c11, 0x2c40f59d, 0x9557e3b7, 0xfa7ebca1, 0x53ca235b, 0xbdbfe487,
- 0x01e5d1b9, 0x50c7f1f4, 0x0e123f7c, 0xa7395adf, 0x2e5fb7c5, 0x8039cb04,
- 0x0f8e5ad7, 0x77c7e76e, 0x7cb9502c, 0x3d6b9608, 0x3e4423e1, 0xc1fc3c08,
- 0xeb84daec, 0x4045c6cc, 0xfacd1de9, 0xfa4f7b61, 0xf358c5f8, 0x2f67b34f,
- 0x8c5f8fac, 0xc7d5084d, 0xd7ae88ba, 0x75478015, 0x6150ea8b, 0xec8bf50b,
- 0xfaffc42e, 0x7689c566, 0x9516eee1, 0xf2fd61e8, 0x729bd228, 0x8f6e5fbd,
- 0x84aec419, 0x6b3ff052, 0x5a7d258f, 0x5fe62b1b, 0xfcc0bf06, 0xbabc6da7,
- 0x3d79e6dd, 0x6fad0e50, 0xe11226f9, 0x71593fdc, 0x4abb411d, 0x85818fab,
- 0x84df7814, 0xd70829bf, 0x322a0dc1, 0xad9ef5d6, 0xf6f09526, 0x8c378e2e,
- 0x0a33be75, 0xa6a7f5d6, 0x7b40bad1, 0xaf8eeceb, 0xeb05dd6f, 0xfae68daf,
- 0xeb9a36b9, 0xcebbd3e7, 0xbb7a41f7, 0x9274e176, 0x9ef4c37b, 0xdce5038f,
- 0x730efd1b, 0x6d4acc39, 0xd4e3fb47, 0x68fbe52e, 0xa235a100, 0x0aed1e9f,
- 0x06a9ca35, 0x1c4415db, 0x1f0039f5, 0x145b5f84, 0x073eafc1, 0xd6932ef8,
- 0xd9d70279, 0x14b2316e, 0xfc0b3f68, 0xbae4fd88, 0xcf7ac47f, 0x9a6f5f84,
- 0xa0b468ed, 0xbebfd50b, 0x1e20bc6e, 0xa2d57c60, 0x669c7da7, 0x67c44e51,
- 0x10c5d1b3, 0xc283deff, 0xab78103e, 0xba773411, 0x0f01c865, 0x81fd6fec,
- 0x7fbe2734, 0x48d9c77a, 0x47ed199d, 0x7d876a8f, 0x565de9a9, 0x5bbb87d4,
- 0x39de5ece, 0xc19be480, 0xbb3beb0e, 0x33ddb0ef, 0xcfed47e0, 0xfd88bf6a,
- 0x0dcdead5, 0xaa227681, 0x1a945259, 0xda5a523a, 0x220ca9fe, 0x0f2863fe,
- 0x57cc19bd, 0x3e5efb0f, 0x54d3d050, 0xd7be40e6, 0xcdbb7be2, 0xe00f619d,
- 0xb736cddb, 0xf385d703, 0x3ed2e6a4, 0xe83eb0b3, 0x0679e9cd, 0x0c6fee1d,
- 0xed29bd43, 0xb44fb93d, 0xfd7323c7, 0x5ef693fb, 0xce73fef7, 0x68c7da0f,
- 0x74ec83df, 0xc52c740e, 0x282d5a73, 0x03320785, 0x784adff7, 0xacfb16a9,
- 0xaab7308e, 0xcdb62fb0, 0xca53b270, 0x7dd0ac83, 0xf3869e00, 0x780f387d,
- 0x377fcf10, 0x4e11eb3b, 0xda1b0efa, 0x91afb0af, 0x50560fb8, 0xf8708c96,
- 0x8c9aecc0, 0x2599fef2, 0xf4fae88c, 0x14f7ccb3, 0xbb4b7a6c, 0x0366e88e,
- 0xffe882bb, 0x5b99dd0a, 0xebe266dd, 0x7e7ef8b1, 0xe50ea347, 0xa1cf8e6f,
- 0x797ab943, 0x474eb347, 0x2f19e0f4, 0x0f5674e0, 0x54dfebeb, 0xba48fea7,
- 0x2e9e1498, 0xabf6f042, 0xb849bc40, 0x30f4128d, 0x3286e10a, 0xb27f4bb9,
- 0x370fc233, 0xb54b0bc0, 0x58c78e87, 0xa9c20667, 0x7d63c5ed, 0x9abc613a,
- 0x8add8f97, 0xabf9a970, 0xcc618889, 0x418f2f5f, 0x30b2ffba, 0x72735dbc,
- 0x0f5b9d71, 0x3dab78c4, 0x157be48b, 0xbda230eb, 0xaddd7200, 0xd2eb900f,
- 0xe867db8e, 0xf7f1c628, 0x12d9510d, 0xe759f380, 0x461624b0, 0x3f72c85f,
- 0x00396dda, 0xe155f47f, 0xfcc5e4f9, 0xda476e18, 0xb25afc83, 0x9678b7dc,
- 0xe7a18c7b, 0x8e0df6f1, 0xb14e7f24, 0xc87a1ec6, 0xa78dedce, 0x81cf5ced,
- 0x3ae17660, 0xe2c5fd4f, 0xa9d342f3, 0x0cadf7dc, 0xdb6a74e0, 0xa05e79bb,
- 0xe3ac53a3, 0xdf9097f6, 0xb9d336be, 0xfbf078ae, 0x7e2c4b79, 0xfb8abcfe,
- 0x2f55d852, 0x407569bc, 0xbb2de2ff, 0xf001bde3, 0xbfe98abb, 0x4ceba6ee,
- 0x8fef979c, 0x20fb3be9, 0x274bd83e, 0x16501d12, 0x3c6af8bf, 0x373803a7,
- 0x14ff450d, 0x633f8fe7, 0x5ddd8053, 0x3dc6b0bc, 0x1fc02f26, 0xf9922e73,
- 0x0efaeb02, 0xab891e23, 0xfda999cf, 0x9e25bb76, 0xd62f4de4, 0x8f4de50b,
- 0x7848baf0, 0x3c25db6a, 0x913e0df7, 0x97c5f681, 0x07c5d83d, 0xaf7ec1ec,
- 0xdc7b1637, 0xf5fc7263, 0xdea77dbf, 0x5ef30ee6, 0xacff188b, 0xda127873,
- 0xd6c6c57d, 0xe1f9c2cb, 0x0b5339e4, 0x57ce37a7, 0x7fb8e346, 0x1f1a6739,
- 0xeddb5d6e, 0x3fe69fba, 0x0aab07d8, 0xf44b0bb0, 0xdced379e, 0x326ab05f,
- 0x3f2e6bd4, 0xd9ce8e3b, 0xdc845e92, 0xdb798abb, 0xf4b57f90, 0xbefdf121,
- 0x4b2a5bc4, 0x693dbc45, 0x11ba7077, 0x43f920fc, 0x396d470b, 0xe13cc8c1,
- 0x75cf03ce, 0x799235c3, 0xbede1e41, 0xfe7a40c1, 0x4e1ff3cd, 0x3f7a03cd,
- 0x5b60d6b6, 0x5ace530a, 0x51ed3bb7, 0x360da7f4, 0x1fa814d9, 0x865eb473,
- 0x4eb95f7c, 0x1c3d2375, 0xe27b7b5b, 0x00bf2874, 0x7582adfe, 0x50306e54,
- 0x770dacfb, 0xc109fb50, 0x12eb95d7, 0x7cbca3fa, 0x4481fdb3, 0xeface3c4,
- 0xf11ebfee, 0xeb68c5b2, 0xaaca183f, 0x263dc526, 0x3673de00, 0xb7d50646,
- 0xdc2cd8e8, 0x532bc487, 0x1dcfdd3c, 0xdc631eb0, 0x6b63c44f, 0x18d51f88,
- 0x92ccedc7, 0x9aefb029, 0xbec96721, 0x8a27bddf, 0x662bc9f4, 0xd6c8ec95,
- 0xb7f3ffc1, 0xf45ea12b, 0x3649de9d, 0x58f3c09e, 0xce866781, 0x8a8fa040,
- 0x7a2f5e08, 0x68764f51, 0x78254591, 0x1d5c82b7, 0x65de4a43, 0x7efd0b1e,
- 0x4753df21, 0xfd0e1ead, 0x1818c6c6, 0xb45fa1ea, 0xa06629ce, 0x4e797f27,
- 0xc06769ff, 0x9733467e, 0x42e2ed1e, 0x5f6a0866, 0x0a7d6511, 0x4c185aed,
- 0x28b0fa8f, 0xd8f9f822, 0x813daecb, 0x5b58c4f6, 0xbfa4bb70, 0xbfa0389c,
- 0xb1b97efe, 0x8fe7cf7b, 0x567d804c, 0x9ec953ec, 0xde5c90be, 0x41cafb8f,
- 0xda51bf7c, 0x29bdef04, 0xf9e6f3a0, 0x9052cb63, 0x86140abe, 0xe763ae7e,
- 0x5ce5f3c3, 0x018c9f41, 0xf1f9fb9e, 0xbb39d13c, 0x7f6c8ebb, 0xeebcc15d,
- 0xe2ffae3a, 0xcb0fd9e5, 0xf73b4eab, 0x87f5686f, 0x53fe7f96, 0xf078a3fa,
- 0x0b5e19ab, 0xe585ff95, 0xfe5c2dc9, 0x5685e56a, 0x6975c85f, 0x4e7d5bd7,
- 0xcf13d20d, 0xd7e27909, 0xfe7a4617, 0x6b8f9e33, 0x9e8486e2, 0x219ec18f,
- 0xea877978, 0x760e5ce9, 0x6fd8edd7, 0x5711d980, 0x665a4b08, 0xb9468acb,
- 0xdcf164d6, 0x97e01719, 0xa8d4dfea, 0xedd1f943, 0xfb0431af, 0xf5f9e46d,
- 0xffbe389e, 0x875e38f2, 0xfb9d2bf3, 0x92794437, 0x2f6f38f5, 0x7e3033a3,
- 0x85fbcb25, 0xaf7690fc, 0x9da577b4, 0x7d59ed2b, 0xb367b703, 0x7e41dd63,
- 0x5fafd633, 0xed183f90, 0xef73e474, 0xe7da28ae, 0x107b8a67, 0x731569f2,
- 0xa017143d, 0x7c0deb07, 0xbcf5dafd, 0x13ec2716, 0x413b26e6, 0x1d1ccfb6,
- 0x8d6f9e5e, 0xc2ff53d3, 0x40ca6fc7, 0xb6b3ee3b, 0xce50339b, 0xfff1a67e,
- 0x0f0fc4f6, 0x507d7e0b, 0xe15893e8, 0xf9087827, 0xedc0ea08, 0xfef02dae,
- 0xe26ec58a, 0xbe2edfab, 0x1747ca91, 0x8fe7a42f, 0xfcd265c5, 0xdc77c2b6,
- 0x23a700d9, 0x17d2552b, 0x3eee8d33, 0x91def0b1, 0x1bf91d08, 0xc799d70e,
- 0x3b63336f, 0xcce5f3a3, 0xf26c27c7, 0x1f01f806, 0xe90c7dc3, 0x09af9f79,
- 0x9d2a5ebc, 0x2b4eb356, 0x7a6eadea, 0xb7a2103d, 0xa72f11db, 0xf6226759,
- 0xfa3a55ab, 0xf3a12934, 0xaf5cc83f, 0x2366bf61, 0xd37c8feb, 0x92f5c51c,
- 0x029bdfb6, 0x9ed0ab7f, 0xd433f285, 0xcce4615f, 0x7b5e823b, 0xc4ef5d5b,
- 0x9333bc91, 0x56eb4edd, 0x3ef44e29, 0xb4e707ce, 0xc639f10f, 0x975fd089,
- 0xc775b56d, 0xc779f855, 0x185c71fd, 0xfe4f5c7f, 0xee3aed1f, 0xd570e789,
- 0x296485fa, 0xc4c742fd, 0xd9c5167e, 0xe844fc82, 0x0fe70f0f, 0x48de3aba,
- 0xd510dbfb, 0xa8b8c5e9, 0x3e7e66f7, 0x55e51a4f, 0x5a95dfd0, 0xfe8858dc,
- 0x71c67fb0, 0xbc7da63f, 0xf1cf1927, 0x4e8d92bd, 0x2c5ce3f4, 0x76680e3f,
- 0x478138f1, 0xd358eb47, 0x03ec8de1, 0xf0ec4aeb, 0x34a11a14, 0xf8d226c4,
- 0x096eac49, 0x11fa0de2, 0xa3dbf230, 0x743c8a7c, 0x213c9743, 0x91a56147,
- 0xaddb77c8, 0xbc3c531e, 0x5d467437, 0x53edfa3d, 0xe23c78ab, 0x6de9e284,
- 0x1b8d0ecf, 0x5e3932cb, 0xbb88aff0, 0xd0346fe6, 0x3e37f2ba, 0xfcd1f146,
- 0x95eb578d, 0x1f943900, 0x27fea06f, 0x9bd39d5e, 0x851f18fc, 0x880ebf8f,
- 0x4662f4e7, 0x8a10e11f, 0xbfa58687, 0x313ff17e, 0xf609dcae, 0xef3cb050,
- 0x20243f17, 0x0cfaa16f, 0x3c7d73c9, 0xc07f23d7, 0xd358057c, 0x7cc8661f,
- 0x8fe40d85, 0xbe6c6add, 0xde51e306, 0xbc431d1a, 0x2bf9efb7, 0xcd676bc5,
- 0xb6bc5070, 0xcf7dfdfb, 0x3ff6c72c, 0x118362cc, 0x87be29fe, 0x7ccff415,
- 0xc9e3c91b, 0xb1326edf, 0xd9a5b025, 0x3c53376f, 0x8e954d78, 0xeed17ca1,
- 0xe832661b, 0xa0db5c78, 0x47f8e02b, 0x0ef12839, 0x7c446404, 0xfc21bc48,
- 0x6e3198b6, 0x5fad02fc, 0x7e80cbae, 0xc7dc04f0, 0x4e906b96, 0x15d9557a,
- 0x75c817f4, 0x4c9f485d, 0xfa69ff8a, 0xc3d467e4, 0x9c5fc5b7, 0x74819e1e,
- 0x5ac3d5ae, 0x7164dbfd, 0x0bbf6255, 0x4213e1e9, 0xd7894dfe, 0x7e3043c4,
- 0xc76f0616, 0xf00c1c84, 0xff19df8f, 0x1fe3fc23, 0xe3091ca1, 0xc8c67f1f,
- 0x9da36fe5, 0x0c2936dd, 0xe627bcbf, 0x32eeadd7, 0x6f8cfea2, 0xb3cac251,
- 0xc651ab6c, 0xfae05713, 0x2b44fc64, 0xb7c0c38f, 0xde5ffb11, 0x7b0bbad4,
- 0x165ec6e5, 0x15dbe68d, 0x37b9c3df, 0x046b3ccc, 0x30163b9f, 0xea3aa38a,
- 0xa82bc918, 0xb093b8fb, 0x0023f295, 0xb8e04f1f, 0x9d638a17, 0x1d9215b6,
- 0x8656e324, 0xf8f3e0d8, 0xcfd9789e, 0x6fc447f5, 0xe27a0f7a, 0xb05d624f,
- 0x5fb067ff, 0x141602fc, 0x9971919f, 0x62af3af8, 0xc47547cc, 0x3bdadfc8,
- 0xf304b3ce, 0x3386ba3f, 0x8f5053e7, 0xa215b529, 0x72cfb53c, 0x66fc61b6,
- 0x9fee29f9, 0xf98f3e5f, 0x79012a96, 0xca2c9e05, 0x05bc4203, 0x0a7607fa,
- 0xac53b6f9, 0x5fe4f41b, 0x5abaf9e3, 0xa4f403e2, 0x756e87c4, 0xed784aab,
- 0x02a7af0a, 0x43fedaf0, 0xf919fd78, 0xe48b9df2, 0x852f0fcb, 0x9171fe6e,
- 0x8c4bf374, 0x3b090c6f, 0x578867df, 0x67407ced, 0xbef88347, 0x78db3a07,
- 0xf9d2f189, 0xa7a89fe6, 0x5dfae142, 0x5c28427c, 0xfaeb1657, 0x5166bc91,
- 0xd57a70ce, 0x4ffe6096, 0x12d891e7, 0x1e7a5c86, 0x3b7bfac9, 0x1967888d,
- 0xd5eb9107, 0xf6c88fe6, 0x0f25169a, 0xbb859fcf, 0xe039d3cf, 0xe8bfdb74,
- 0x079a101c, 0x0f9de7c2, 0x39fc8de4, 0xdcd01d56, 0xa677fc0a, 0x752748c9,
- 0x377e3995, 0x7bf7fd0a, 0xa0e7cc0d, 0xffd811fe, 0x5ffbc60a, 0x03bcb4d1,
- 0x305757fd, 0x479c57bd, 0x1db9ef95, 0x7c7c8315, 0xf2955ec5, 0xfe66d8bf,
- 0x2c458ebc, 0x4c74ff41, 0x02398e81, 0x8aeb19e0, 0x78008e62, 0x07b78dc6,
- 0x7939e5d5, 0xc13798ae, 0xfde82bdd, 0x82b31ba4, 0xae78a7fa, 0x3a9e7a08,
- 0x9ea8372b, 0xa822375e, 0xa385ef7f, 0xde99ea83, 0x67fa836b, 0xaa0e4c37,
- 0x1cde34e7, 0xab18ffd4, 0xec147c7b, 0x5bfa3fb3, 0xebcc3f00, 0xd60cb8ea,
- 0xb7ac433b, 0xa0f29aef, 0x5afd81f7, 0x53381e31, 0xcf17c990, 0x00abdf8d,
- 0xff08671c, 0x39bee5ce, 0x55cfe341, 0x677e88ab, 0x048e1a36, 0xacf469fa,
- 0xc02a4f6b, 0x38a7c6b9, 0xb95ea15b, 0xecf9f826, 0xbde81b1d, 0xf6e0bed9,
- 0xeb839bb9, 0xd29cde83, 0xb901e79f, 0x4672bf29, 0x87dfb042, 0x9989d085,
- 0xb599f4e4, 0x7aa5ffdc, 0x24e86afb, 0x27ec5f18, 0xd0438dd2, 0x9839298d,
- 0xc11d226e, 0xfaf95374, 0x0708a1d6, 0xfba3fc2d, 0x0bc9e869, 0xfe007eff,
- 0x7d306716, 0xfb4ee169, 0xec567583, 0x95efd850, 0x6acfb850, 0x2a797879,
- 0x633b850b, 0x1fd7233e, 0x688fedc1, 0xd981fde0, 0x89ca18f3, 0xa8163bb3,
- 0xe3638718, 0xecff3c79, 0xed07af8e, 0x2f898473, 0x97c484e5, 0xf80425d6,
- 0xe97c647f, 0xaf19c634, 0x67111764, 0x844ffddc, 0x8f00c807, 0x0b11f301,
- 0x71dd119c, 0x3c7f48c5, 0x653f2b49, 0xb9e3fa09, 0xfe2bd204, 0xbc3d6c78,
- 0x03e6343d, 0xc653ae37, 0x8ebe64e5, 0x930a2bcc, 0x8497fc9f, 0xb40fcc04,
- 0x75f9e347, 0x3a7cfb4b, 0x22bcc977, 0xc302f226, 0x4fa4ffd8, 0x14d7f19a,
- 0x26760bb2, 0x0afebd70, 0x176dd78e, 0xa92fbc88, 0x471a7bd7, 0x2a7adfc6,
- 0xc52a5d95, 0x2894bb13, 0xf46153e7, 0x3f0947ca, 0xe685bf51, 0xa8147f8f,
- 0x38ee6a47, 0x0bf507bb, 0x6c63fdc0, 0x6f4058b7, 0xfdbd7e2b, 0xd12b68bb,
- 0xaaebd76b, 0x9c342faf, 0xd8c47089, 0x222d8e01, 0xe445afdf, 0xd6f5c9fb,
- 0xf4baa445, 0x9c1ed879, 0x8ae327ff, 0xc28dfdda, 0x3afe71fe, 0x976417bc,
- 0x76e5cf2c, 0x870169db, 0x276e160d, 0x9db91318, 0x1f39ab50, 0xfb7036d5,
- 0xacd7a40c, 0x8c718096, 0xdfea1689, 0x4c685cdf, 0xdf8471c4, 0x42a67965,
- 0x4572c576, 0x77e47b21, 0xfcf4d1b6, 0x868509cf, 0x6fffe844, 0x6011af31,
- 0x16636588, 0x93438f5f, 0xe892fe17, 0x68c252ff, 0x36898d2a, 0x5db67fe1,
- 0x6a91f481, 0x5da91976, 0x8aa71f0d, 0x1afbe44e, 0xb464f229, 0x42718071,
- 0xdfdfa26e, 0xe2d2edc4, 0xfe4189b1, 0xf18cf7fe, 0xd0afdfc2, 0x53942eeb,
- 0xef7814bf, 0xeaefffc9, 0xf1476b67, 0xaffff5ad, 0x7ffee48c, 0xf1081f19,
- 0x85c73bff, 0x1e23fff5, 0xfe7eeda2, 0x2dd893e9, 0x3e50d29f, 0xea7a30ed,
- 0xb5d5fcf1, 0x6878ec1d, 0xa4ebe7ee, 0x7dc0c0b8, 0x673c4ed9, 0xbb64cf2d,
- 0x4b6f482c, 0x7f3b4318, 0x696ea747, 0xe95f3c24, 0x3e7c3665, 0xbf3f2d7c,
- 0x3871ae55, 0x0e529b71, 0xfdc89d5c, 0x1f380687, 0xbdf1725b, 0x27186dc9,
- 0xd9953958, 0xb2350d51, 0xda2b22c6, 0xd8596b45, 0x4168e3f3, 0x770a134f,
- 0x4276fe51, 0x0fb7cf17, 0x7693a7ed, 0x73e2217e, 0x2ce79758, 0x7971cf8f,
- 0xcf112242, 0x5f3aeda9, 0xb27d73b8, 0xa46ae8ad, 0xf0be81af, 0xc29188e7,
- 0xbb32e64f, 0x03f8e227, 0xd87cf1b7, 0x677f294a, 0xf01e98e8, 0x75e0453e,
- 0xd79e5aca, 0xff7fcec1, 0x45ed2abd, 0x9433e346, 0x2d53952b, 0x5513f43e,
- 0x697a64b6, 0x99c56e5d, 0xe5a2f283, 0x2bd6376d, 0xe86df3f3, 0x9dfd7097,
- 0x91fb4729, 0xfcb8c9a9, 0x52a3b3d2, 0x8f1e909e, 0x64d438a7, 0xf1236f41,
- 0x72409cb0, 0xc034657e, 0x92ed72bb, 0xf3d7985d, 0xc5191ffe, 0x5da80e9b,
- 0x5fb07143, 0xe6167001, 0xa567a962, 0xa648b7e4, 0x718aa671, 0x7982ffbc,
- 0xfef3fc23, 0xda75e5aa, 0xf30301cf, 0x9d1d0046, 0x038379de, 0x09e5eeed,
- 0x93cfe411, 0xaa83da71, 0x42523ee7, 0x5c1aaefa, 0xd12d4dda, 0x9c83f436,
- 0x3a61f9de, 0xb93e4dc6, 0xed05ace7, 0xbbe87fd8, 0x7c2f982c, 0x16bbd17c,
- 0x93f1c017, 0x9de52a45, 0x86f42add, 0x897dfb84, 0x271fee1c, 0xdc2117ba,
- 0xddfc5b6f, 0x2a3cc0d0, 0xe88130b6, 0xa54fb679, 0x9cb75c90, 0x168d1cdd,
- 0xbabd774a, 0x2ea82e39, 0x89b540f5, 0xbf3b85d5, 0x69e824bc, 0x6306d376,
- 0xf7e703aa, 0x38fa42ac, 0x7474e7ae, 0xe7c59b7c, 0xa7aff4cd, 0x11b069bc,
- 0xb47f83ed, 0xea2b5898, 0x81877d33, 0x8abb49e7, 0x8f0ba015, 0x9d76bfc0,
- 0xa68e5e7b, 0xc63e66f1, 0xcc1947e5, 0xebe010b5, 0x724d9969, 0x998fbb41,
- 0x25c6389f, 0xae675c01, 0xe3fa1850, 0xc022ffb0, 0xfde1679f, 0xa5fda15f,
- 0x379967dd, 0xf9480e58, 0x3cf02955, 0x79f821bd, 0x696fcb65, 0x43cc199c,
- 0x27602079, 0x735f9e69, 0xd80af50c, 0x67ed4147, 0x519b66f6, 0x14496f8f,
- 0x6ca1edf1, 0xfef0f7d8, 0x18ec88ae, 0x927e184f, 0x36c5c9e5, 0x17cfd622,
- 0x7c795047, 0x5172a331, 0xaae3a722, 0x44efb796, 0xc766a97b, 0x738e2316,
- 0x9681f1c9, 0x999bd613, 0xe896ef5f, 0x1e21af3d, 0x28252cd9, 0xe1b3504e,
- 0x32ec91ac, 0xd1529f01, 0x00f08a5e, 0x1cc2dc3c, 0x503cf1ab, 0xc7f0655a,
- 0x5bffe0e9, 0x60c3bf72, 0xd1da80bf, 0xb5173991, 0xb94fb95f, 0x5abcf96f,
- 0xf30c7a05, 0x4583e4be, 0xd8cd1f42, 0x2f796938, 0xcefd5100, 0xfc9d1963,
- 0x78f649bc, 0x516bc091, 0x8f64fdc4, 0xe3d88517, 0xb7dc3dec, 0xe64ac7a4,
- 0xa5a23d24, 0xcc07493b, 0x23f7a06c, 0x4ddebd84, 0x120f2d6f, 0xcc3d245c,
- 0xe4685d5c, 0xc8c79be6, 0xb26f4aed, 0xa326d7f0, 0x30e816bf, 0xba063ec8,
- 0xed6baa0b, 0x9d0d2ff1, 0xb41f2819, 0xe7ccb876, 0x60e7c2d4, 0x9a5fcf22,
- 0xb38d70e1, 0x8073c00d, 0x85f9397b, 0x10ca46f1, 0x3dc6dbe4, 0x6edf2377,
- 0x0ff37ce4, 0x92b30f41, 0xf049113c, 0x9af4b3dc, 0xe77fc41a, 0xf2065312,
- 0x8a6967b3, 0x3dfd0f1a, 0xc39214ab, 0x18a697a3, 0x97d3ce11, 0x7c871e0d,
- 0x345ccb9d, 0x1638b4fe, 0x9c186ed6, 0x7947e5c4, 0x6319819d, 0xf4462908,
- 0x506a9f0b, 0x9a8c2fc8, 0x6be02264, 0xf557c096, 0xa4adb78a, 0x6ff01caf,
- 0xe01f5e28, 0x2aeab33f, 0xee701f09, 0x52c7cb08, 0x66b154af, 0x3b8c0a63,
- 0xd11b6567, 0x82479c31, 0x95b2d7fa, 0x66eaaf84, 0xd5dd7b4d, 0xb9d83f84,
- 0xb589cf11, 0xf79f823b, 0x8276124f, 0xbe913993, 0x225a773d, 0xb471af30,
- 0x4ad94f80, 0x6b7286c5, 0x84b6b2fa, 0x7d3ea01b, 0xed84eaaf, 0x8587c374,
- 0x1f2823fa, 0x1cdecced, 0x719c57f2, 0x9fb09238, 0x52edcac7, 0x8619ef45,
- 0x3ce2d3ed, 0xd8cfd0c3, 0x618591f5, 0x73a1df7e, 0x11e4732a, 0xfca20f95,
- 0x341b1b2a, 0x2fbec029, 0x3112d833, 0xf365e91e, 0xb83dc593, 0xd4f84088,
- 0x7e24ac46, 0x887e45a8, 0x34c3f3f0, 0xdda17b8c, 0x7942a2f3, 0x30476c84,
- 0x34709fbd, 0x9091c226, 0x9033efb9, 0x8a6f2e9c, 0xf971f3a5, 0xea2322b2,
- 0xb16df2d5, 0xf9c11f64, 0x86cbbdf4, 0x6879f1fa, 0x649ede59, 0x39bcb718,
- 0xe306a9d3, 0x19dcf431, 0x0d39ceb0, 0x8efe2487, 0x23bf80f4, 0x7807f0e1,
- 0x4f2f6a0b, 0xe0497212, 0x238a2d8d, 0xef3a5abd, 0x58089cd5, 0x48ba99d7,
- 0xe9ec93ca, 0x8c66c47c, 0xe903fca0, 0xabdf1abf, 0x7944cfdb, 0x0e57673e,
- 0xf169fc21, 0xd3dffe36, 0xcbbda187, 0x68616efe, 0x66cb4d67, 0xf6864db7,
- 0x6fce14db, 0x19afead3, 0xddc4768f, 0xbd9e5c49, 0xd5d07205, 0x41b7b197,
- 0x0e40ba0e, 0x11f20bbe, 0x4e2fefeb, 0x8b87faa6, 0xb47e541d, 0x47951fb8,
- 0xf25fbf84, 0xd102101d, 0x2e2492ed, 0xc9249717, 0x6482faf8, 0xffc66934,
- 0x3a21ddfb, 0x6c67de1b, 0x9d36309b, 0xc15cebb1, 0xa9c6f7fa, 0xd3b5fac1,
- 0x8c971b60, 0x0a15dbe7, 0xeee5a3d9, 0xe1fd4191, 0x7bc464dc, 0x9e5fac2b,
- 0x86f49dbf, 0xe81938c3, 0xb8e2a6f1, 0x37d7fea0, 0x9fd506a4, 0xfad07248,
- 0x0ecf8d26, 0xb4b9bf6a, 0xecbd507f, 0xa431919c, 0xf1014777, 0x679102cf,
- 0x8e770704, 0xfbef1b17, 0xa4b0dd75, 0x5fbd60bb, 0x73d033ef, 0x5e243e2d,
- 0x9951ac67, 0xbe9bc607, 0x2c1fe406, 0x74e348f1, 0x0e2fafe2, 0xb25ce858,
- 0x7f6f29bc, 0x350fd401, 0xe80f2819, 0x55b8b2d0, 0x6a1daf68, 0x2832b04a,
- 0x6155cb3d, 0x2c8cd8d7, 0x2d15de40, 0xa6f9425b, 0x93933e65, 0xef7697ec,
- 0xc0eeb293, 0x122e2af3, 0xd53de4f9, 0xfe10aad7, 0x67df045c, 0xe15ee922,
- 0xf127b071, 0x4ef4e12a, 0x0ae3aebe, 0x13f5865b, 0xb9f71f91, 0x6a71d60b,
- 0x0e856362, 0xbeea15fd, 0xcf9f9204, 0xb6e90cab, 0xf2819e74, 0xafbf660c,
- 0x533ac06e, 0xbe395372, 0x66a3ca55, 0x7c6898cf, 0x021405d6, 0x6d3c16fd,
- 0xae01ea7a, 0xfb7d78ff, 0x8203df40, 0x8e8e913e, 0x2c5732c7, 0xf5a1562d,
- 0xc276fe7e, 0x87ee7c06, 0xee106fa7, 0xfdc1bd7b, 0xefe01266, 0x20df0af3,
- 0x128b6f92, 0x70b4af88, 0xf2e4623f, 0xa07c8bcb, 0x9fa6e5f8, 0x7e9296cf,
- 0x26706e98, 0xe56e493a, 0x3adca0a7, 0x7640d2b2, 0xacbbd330, 0x3e8f4893,
- 0xe72c744f, 0x8c77a239, 0x691df5c3, 0x5f9864c8, 0xa552be51, 0x1fd20af3,
- 0xe7e3efef, 0x0f5587d4, 0xdbcc24d8, 0x525878a0, 0x3edcdd28, 0x5de5186f,
- 0x596ded6a, 0xeabc097e, 0xe64bb009, 0x8179e4ec, 0x3f53bf2c, 0x3ee06075,
- 0x3cf9f196, 0x4af94105, 0x1daf5955, 0x2ec8eb34, 0xc273c18c, 0xa254f789,
- 0x8d5913b3, 0x9f019343, 0x86bb7527, 0x2ff505de, 0xea8f7a26, 0xda223ea1,
- 0xeb842ff3, 0x0ccadd5c, 0xfaf30b25, 0x091aaf0f, 0xacfe7def, 0x2e6c49c1,
- 0xcf39fcec, 0x43fdeecc, 0x1bd815f6, 0xe1ddb8bd, 0xcffbc14a, 0x1acd1d73,
- 0xc7c3807b, 0x00204981, 0x056adb17, 0x7876376d, 0x3c01e588, 0x31d74f57,
- 0xe079e04f, 0xb1e3c8b0, 0xa873f324, 0x24a61bb4, 0x5d333973, 0xbd9be9c7,
- 0x037a70ac, 0x0f502afb, 0x173db948, 0xbf55aaf3, 0xbb72901e, 0xfe52358a,
- 0xdb99238a, 0x1f15b32f, 0x9835ddd9, 0x2bfd0289, 0x56683c6c, 0xf3e4d9b5,
- 0xb698d265, 0x7a60fb40, 0x73279732, 0x8e3ecf8c, 0x3ac95be4, 0xfd353ef8,
- 0x2af8373e, 0xf543323a, 0xc36d854f, 0x6f8d3b32, 0xb79fa270, 0x756bf052,
- 0x256be2a3, 0x51eb853b, 0x299d57e9, 0x3f56a8f4, 0x8d25e885, 0xd1a99a3e,
- 0x5831acbb, 0xe97ac2cf, 0xaf5cb2de, 0x68ee9d76, 0x0e61c10b, 0x6ff50bac,
- 0xa7b7c785, 0x38add684, 0xeb21a301, 0x31ee64a9, 0x780fb8b1, 0x5d08eade,
- 0x215f769f, 0xd4fb15eb, 0xf9c2bbae, 0xbbe62b55, 0x04293554, 0x243eed2f,
- 0x9c76b43e, 0x97854bc4, 0x45a2b7c3, 0xd67e7c21, 0xf2321f6d, 0x61ba4b6f,
- 0xe02ff0cd, 0xb047497d, 0x6f9412af, 0x1e41ab95, 0xd3d28667, 0x456cd61c,
- 0xad61a9ba, 0xdf9053cb, 0x1faf9b5a, 0xb5867e8e, 0xa9f9d36f, 0xa39aded4,
- 0x7a50058b, 0xbf8e5773, 0x17e74fca, 0x5cfc278a, 0xe9ddc3f0, 0xe01e9fa5,
- 0xeaa37335, 0xd4141c8a, 0x7a3fe44f, 0xbcb38e09, 0x63fa235e, 0xe53f0967,
- 0xab59d685, 0x2e5ff7e7, 0xcf015eb8, 0x0fdd7b9f, 0x7764f727, 0x76173f85,
- 0x3d1a5bdb, 0xfb81b1ff, 0xfe7ca55b, 0xff22ef5a, 0x3b0bb42e, 0xe3c6ceac,
- 0x9eb91a7d, 0xbd724f9e, 0x3979e842, 0x5b35d1cf, 0x13305e29, 0xf68080ed,
- 0xa56f56cf, 0xd9f1a578, 0xcbb45699, 0xbe99ae8f, 0x8f52f30a, 0xbd274d36,
- 0xa97bf95f, 0x40c63df7, 0x4d68a27b, 0x907bfad9, 0x5247378e, 0xdda2b15c,
- 0x2045ce23, 0x639fa167, 0x6cab970d, 0x95b39735, 0x90071fa8, 0xfd8bec7e,
- 0xf4f0acee, 0x68087e45, 0xe779bd27, 0x779fcf74, 0xfe77b8c2, 0x25e9da29,
- 0x755ad850, 0x5adbcf64, 0xcf563f51, 0xde20f0ff, 0xe07b01d3, 0x7b4b5ffd,
- 0x0645aa00, 0xea325b4f, 0x54076121, 0x6c321bab, 0xbd083768, 0x7f801ff1,
- 0xe7f87844, 0x11cbfc12, 0xdbf101fe, 0x9c381b4f, 0x7fe06ba7, 0xcbc72578,
- 0x2b6ca6f2, 0x6d3f2f9e, 0xebbb26c8, 0x821ca6d3, 0x00078cff, 0x1f5fdcfe,
- 0x0035776c, 0x817cf1fc, 0x96f587f0, 0xfc043bb7, 0x0dfe1c9d, 0x256cee1c,
- 0xc084672f, 0x57f94bd9, 0xe4d1fe77, 0x78e23b44, 0x57d92b64, 0xaca8b7c7,
- 0x932ec03e, 0xac37d176, 0xdfb449f1, 0xf767fc24, 0xf28418e9, 0xd7e1f4a7,
- 0xd98788ac, 0x3150785b, 0x95ccfe04, 0xeec7f144, 0xa8edbbf9, 0xdd5f116f,
- 0xe245d476, 0x19b986a9, 0xd796c7e9, 0x4239e00e, 0x45bf7171, 0xb66fbc8d,
- 0x19bef823, 0xda9592e6, 0x8ce2c5d1, 0xa4f5c088, 0x79d3ef69, 0xbebdc618,
- 0xd6eaf9cd, 0x5de7c4f9, 0x25b97941, 0xfe80d5ac, 0xd0acd636, 0x05eaed3d,
- 0x8642d685, 0x5a3ab571, 0x09453387, 0x56aecbca, 0x564f6475, 0x447c4519,
- 0x892455e4, 0xdc29497e, 0x629c902f, 0x2474f2a3, 0xda707d23, 0x7de1f462,
- 0x255f382a, 0x9ddefce3, 0x41dbc226, 0x5fc0135c, 0x333f0a35, 0xb7a442a8,
- 0xd3a7185b, 0x297bcc5b, 0x972707ae, 0xa71fa875, 0xc939342d, 0xa18f8dce,
- 0x42cdd2f8, 0x5e62ddde, 0x313d46ee, 0x61746ccd, 0x317ae309, 0x1a30d7f9,
- 0x0df987a6, 0xef748cbd, 0xf3a234b0, 0xdf123c59, 0x8ef87c96, 0x95ea5808,
- 0x1fa38e60, 0xf6dd7e18, 0x5e285c7d, 0xf609f8fc, 0x8546d74b, 0x170c8bf7,
- 0x2e5c5070, 0x609b3ff2, 0xc75828ec, 0x6f0714a8, 0x3fb8d877, 0xc9e02d7a,
- 0xb6afc7e2, 0xfc79799d, 0xb1f30ab2, 0xbc58f7f9, 0x5d541f24, 0xc8cabd50,
- 0x62794f9f, 0x34eaf143, 0x8e61dec6, 0x2ab78881, 0xee782194, 0x61f18b2f,
- 0xf43aef7c, 0xd4b1db87, 0xd64cbd13, 0x978eaf33, 0x0e3b660d, 0x25e3fdc7,
- 0x2abf9e02, 0x0031ad60, 0x83d7d6f7, 0xb437f3fd, 0x02fb5aea, 0xb7d3af7c,
- 0xea7d21b6, 0x1b061c22, 0xaf1ee3cc, 0xa539e2e4, 0xadc5e96a, 0xa689e2b7,
- 0xa0a3d5e2, 0xacf9e3ae, 0xfee6bf5d, 0x59805b89, 0xeab76e11, 0xcb9abb59,
- 0x52e100e9, 0xa978776b, 0xe2853cdf, 0x202e3237, 0x86183ff1, 0x2de3c40f,
- 0x4e307d62, 0x37df1583, 0x7cd7c786, 0x8ccc2f81, 0x15cfb846, 0xf257377c,
- 0xbf30535b, 0x0478823d, 0x2ed0553e, 0x22ddb806, 0xe2f89eca, 0x476e14a1,
- 0xcfc2943f, 0xe25cf7ef, 0x95dccc7c, 0x82797941, 0x7c4daa5f, 0x75ff397c,
- 0xc5307ca2, 0xf5cbe34e, 0x8a7ebd00, 0x0240e8e3, 0x691ebd20, 0x68fb27ac,
- 0xc3880b16, 0x49fbfa65, 0x77ad0eba, 0xf7dd11cb, 0x66bb1a58, 0x5f95e820,
- 0x8e513a44, 0xce6c62de, 0xf68733a9, 0x52e67193, 0xefa061d6, 0x993f4903,
- 0x55633fd0, 0x9535e533, 0xf41efc2a, 0x578b42e9, 0xc7e27607, 0x067bbe22,
- 0xa79c46ec, 0xfca15634, 0x773169af, 0x975f2096, 0x2c7a8d5a, 0xdff1163f,
- 0x8d17595b, 0x2b2d89ff, 0xdf8606e6, 0xe631504d, 0xa4f80b07, 0xadfb05d8,
- 0xebc3f947, 0xe4695d2b, 0x4ff5128d, 0x665c61f7, 0x03a079ea, 0x762e1faa,
- 0x5fa7bcc1, 0x91d9cf15, 0xfa7e7c62, 0xdecf413e, 0xe9de34e3, 0x53f3e4c7,
- 0xf90af9fc, 0x7f5e2bfc, 0xea2f8e50, 0x2f9e6b0f, 0x827f3cd1, 0xf89f5bd7,
- 0xf68bd8aa, 0xda4e68eb, 0x921423a5, 0x37214657, 0x12b6974a, 0xbb754b9c,
- 0xb59a3978, 0xdc2ff2ea, 0xdb8a64ef, 0xf7809298, 0x50588fce, 0xd533ff0f,
- 0x7e814c65, 0xfe79269f, 0x499ce586, 0x7288d78a, 0xe91f3df7, 0xf21e9285,
- 0xae428d27, 0xa6e5ea9f, 0x831ea5f7, 0xf1c3de71, 0xbb9c752f, 0xe4f9c743,
- 0x4d738cc7, 0x4738c86a, 0xfebecc7f, 0x24e1ca9c, 0x517691c7, 0xe94bba71,
- 0x663afc85, 0x70bf9064, 0x18cebdee, 0xcc314bf4, 0xcfd00377, 0x919cda5d,
- 0x7dcfe307, 0x0a8cc5ee, 0xbe849bb4, 0x32a739af, 0xdaa3c817, 0x5f950a73,
- 0xc4647db4, 0xdb35b37b, 0xa0e38cda, 0x45942d5f, 0x12aaeb01, 0xa77d04eb,
- 0xa7a01c9f, 0x4274bd8d, 0xf3cc3c6e, 0xa13b9e32, 0xd5ce7c47, 0x3dfd1f35,
- 0x4a11efea, 0x97f2f8d8, 0x7b077f62, 0xee611fb8, 0x6151e5c5, 0xee34576f,
- 0x390614f3, 0xfaa2fc60, 0xbf02f9f0, 0x1528eb12, 0x50fa6ffa, 0xe003844b,
- 0x1e3de43c, 0x9b58af5f, 0x62fe8b99, 0x04e8f263, 0x7e8f5b82, 0x67ee2ed6,
- 0xd67ee16d, 0x02c77b52, 0xbb994efc, 0xf883ec57, 0xbf09b2dd, 0x2c067c93,
- 0x378eef0b, 0x89bf7ac9, 0x3f714663, 0x7ef3d618, 0xf220f99f, 0x6e28decd,
- 0x361b4ecf, 0x43e50a30, 0xceb46667, 0x4facfc06, 0x4af7732a, 0xc6abf6c0,
- 0xc9a17b61, 0xe08ca7d2, 0xf42e88cb, 0xb8feee49, 0xfe8fec4e, 0x35b18f11,
- 0x87d806e1, 0xee950de7, 0x45067803, 0xcbc5c27b, 0xe5c5ef2f, 0x8d97bbb9,
- 0x0757b1e0, 0xaff5cceb, 0x760fce43, 0x180e82fd, 0x94d2c8ef, 0x30380fc1,
- 0x5d78531e, 0xfcff04af, 0xa33c92b3, 0xa23fe702, 0x68f07d63, 0x18ebb171,
- 0x1d71f02e, 0xf74a06c2, 0x80b7a028, 0x31e4def3, 0xa9f541d1, 0x15cc71c5,
- 0x9a9dbfe8, 0xb1bf541a, 0xffa83b34, 0x07fa33cd, 0xea689f3d, 0xb00bafc8,
- 0x97b67b67, 0x5a9f04bc, 0xed0a258b, 0xbe5a4fba, 0xb416e0f9, 0x4eaa3703,
- 0xef6759b4, 0x48c1f4dc, 0xf00675e8, 0x497e471b, 0x3ed1f907, 0x7a747997,
- 0x7e303e97, 0x50758a74, 0xd73ca2be, 0x68dc6c5e, 0xf29dadae, 0x78ae7f09,
- 0xe25ebcd1, 0x72cb9bfc, 0xa99e3f51, 0x79fc9f7b, 0xcfbe6635, 0xe21e2f53,
- 0xbd442ddf, 0x357f7402, 0xe2f688be, 0xc0fc1039, 0x0e3b45ff, 0x86cd9c51,
- 0xf7b44dc1, 0xf1e9e6d3, 0x942d64fe, 0x81c65fa8, 0xba018adc, 0x036368e9,
- 0x48de61b7, 0xe5db85a6, 0xbf90a6e7, 0xf7146f7c, 0x8c4decfb, 0xcc48efa5,
- 0xda86b86d, 0xd345ce6b, 0x1da96ff8, 0xfa2f28e3, 0x13e28505, 0x2da75313,
- 0x8decfdc5, 0x1db80ef2, 0xe7f89de6, 0xdc23c7ab, 0x7bf1b66a, 0x77d51302,
- 0x5941e7f2, 0xbd0d78d5, 0x7b65513f, 0x621fb015, 0xe342ddce, 0x001b444e,
- 0xcb50eaea, 0x5597a803, 0x3f9f6b63, 0x5a31bca0, 0x9ed4de48, 0x26f7a48b,
- 0xfdfd7114, 0x0c4f217b, 0x635d7c9d, 0xe7a24dcf, 0xbd7c2e92, 0xf7f282b2,
- 0xf51b090d, 0x4321bdf8, 0xaffd42a7, 0x4a9fd73d, 0xfa37dfb9, 0x2fbe91fd,
- 0x7af84860, 0xbe8de61c, 0xc8d8af11, 0xe3c8d12c, 0x62c375b3, 0xd5791858,
- 0x9e39cf3d, 0xc73a6c6f, 0x3bff8ff3, 0xe417f5cd, 0x9d4592c3, 0x31178c7a,
- 0xe10d8473, 0xd8305255, 0x67c01151, 0x8c9baeea, 0xeac31f88, 0xafa88db7,
- 0x0516504d, 0xf916af3c, 0xdd795a58, 0xfc83e422, 0x3fd49b8e, 0xd106792c,
- 0x4136ade7, 0x9e8f82a0, 0xdf2c7c16, 0x0e33a0ef, 0xf73b71e0, 0x79a6b7f3,
- 0xd13942de, 0x7c6ec851, 0x4767e49e, 0x7e69c606, 0x9e03f5ae, 0x1bb21423,
- 0xbeaf293b, 0xc3a1c0a4, 0xdd7bc0f8, 0xf3f3877a, 0x26d1f685, 0xca96fdf6,
- 0x6fb8e216, 0x1d97f2fd, 0xedaf182e, 0xd43cbcee, 0xcfde720b, 0x0b7bf17a,
- 0x1e75d6cc, 0x2fb587cf, 0xef903b47, 0x0ce1e227, 0x4d3ba2e3, 0x76816e74,
- 0xbed4778a, 0xef0a7a6c, 0xe15ad5bb, 0x17f30afc, 0x8ad912bd, 0x4af6dc74,
- 0xc7f51ea4, 0x9f3dbd1d, 0x5e8a7c21, 0xcf063be9, 0x9316ae8b, 0xe3fd919e,
- 0xb6f24a3a, 0x485ef587, 0x4ce9697e, 0x81a7a7f2, 0xa0994bf3, 0x7fc172d3,
- 0x6747c11e, 0x0f8892eb, 0x45822ecf, 0x91753c63, 0xda1b7032, 0x7d0b0e0b,
- 0xe5f24e97, 0x411f3c44, 0xb1fec4fb, 0xeaa18f74, 0x1f106c5c, 0x14cb9f56,
- 0xed471dfc, 0x05cadf92, 0x7d84989f, 0xb5d04331, 0x3f245bb4, 0x624f74b2,
- 0x6263ec2a, 0x95bdf03d, 0xc8f9fee2, 0x31ba7e4f, 0x80be90da, 0x022b926e,
- 0xedbea7f8, 0x8a768626, 0x744dde29, 0x40ca0333, 0xb766653b, 0x971b629d,
- 0x592feb08, 0x7bc3a996, 0x6a79f29b, 0x7fd1a5ea, 0x27c8aa44, 0xa0e6b730,
- 0x8ba86b5d, 0x9a7de274, 0x1e3cf133, 0x87057f34, 0xbb837ce3, 0xf98ced08,
- 0x3fe4284f, 0xe503fb43, 0x7503d0d2, 0xcabf40c6, 0x5106e74d, 0xb9ca7d3c,
- 0x2634a8cb, 0x38472e7b, 0x5ebb9d94, 0x8fd06be0, 0x710e3f8a, 0xc192bf71,
- 0xc86e7267, 0x4792bf44, 0x4f1f3c45, 0x0347b667, 0x546b7de3, 0xb8c98ff2,
- 0x9933f4a4, 0x804fdef0, 0xdf46fd3e, 0xa3df4198, 0x0a9dfad1, 0xb93ffeb9,
- 0xbffa40d1, 0xa19dedaa, 0x79fe783a, 0xf5092ba6, 0xa7837ac9, 0x6733f708,
- 0x0339efb2, 0xb83ee7d4, 0xe1dc3ad5, 0xbeb36787, 0x69f50735, 0xfd11c033,
- 0xd52bcd5f, 0xf76e3ef1, 0x1a38f344, 0xcf496fa7, 0x739f3a5a, 0x73e09b2e,
- 0x7a44ceb6, 0x2dd02ce8, 0x5243d00b, 0x2f3948ef, 0xeba48ff5, 0x5f973d6a,
- 0xca18e6d5, 0x9debf323, 0xa442ee49, 0x1f3c7ebb, 0x9e77afd0, 0xf902355a,
- 0xe53c74e0, 0x21bd4b5d, 0xc585e0f9, 0x244794c9, 0x03e492f5, 0x7ca5cf29,
- 0xf52f7497, 0xfd3fe8d6, 0xc3bfd6ef, 0x3cd293af, 0x7d02a577, 0xfae7ab5d,
- 0x85bd5aeb, 0xfc6c67e8, 0xcdd23d24, 0x43d1cbc5, 0x0a1e8e42, 0x3d35a392,
- 0xa94581e8, 0x1c5e7e52, 0x7c11cc1f, 0xedc4de33, 0x81f39448, 0x8da6b5e3,
- 0xb1f7087e, 0xd9eb953a, 0x3ddd6b9f, 0xa9d5ffc9, 0x97ff2697, 0xfc9c5ea4,
- 0xfe54efff, 0xbcad0a9d, 0xa3710fc7, 0xf3bd3fbc, 0x83ea1f72, 0x03f40c83,
- 0x6896c1ea, 0x0fa126c7, 0xc5445f48, 0x1f487ef8, 0xfe9ef614, 0xf5e1a9df,
- 0xff6c66c1, 0xd240fab1, 0xc91be497, 0xb42f9227, 0x62f9247c, 0xbce16fc2,
- 0x8b7a7888, 0xd6aa8fdf, 0x0e289b7b, 0x8c1e88e9, 0xc76dd9fc, 0xdf88536d,
- 0xe084f442, 0x04bf3f1f, 0x1fc90deb, 0xff245f92, 0x98fe0b54, 0xf243f829,
- 0xf9b56ec5, 0x0a9811d1, 0x08f9e690, 0x93e488e5, 0xfab5e7aa, 0x42ba47a1,
- 0x199b234f, 0xae90c75f, 0xa40ca1aa, 0xfc0f532b, 0xf512f070, 0xa48bbec2,
- 0xf3feafa7, 0x0f55f4f4, 0xa7e674f4, 0x1da853d0, 0x03be61fb, 0x1f3673d6,
- 0x9fa66de4, 0x8dfc26de, 0x9b21fb71, 0x46f6079f, 0x35ee7df1, 0x67ff93a6,
- 0xcf3cf7c2, 0x3303da57, 0xd241bf85, 0x01d81e69, 0xf8fc4369, 0xbcc0f3c7,
- 0x847b938b, 0x877c5367, 0x3327cf11, 0x03b40ca1, 0x537fb27a, 0xee4d2ed3,
- 0x17fe8a45, 0xb480f3c2, 0x1c6edd9f, 0xaf1e1690, 0x027ed303, 0xa262275e,
- 0xb22bf92a, 0x00a35c4b, 0xba890f3f, 0xc2094fb7, 0xf902faf1, 0x2e55b2fc,
- 0xd607ca3d, 0xf475ddfd, 0xcaa5bc77, 0x31fece7a, 0x8f099eb0, 0x1d1fbf32,
- 0x151d8f9e, 0x511fedd3, 0x717fbf98, 0x95fed65a, 0x451be7a4, 0x9ea74ade,
- 0x3d4483c7, 0x8096ea1f, 0xbea6817a, 0xeab7f796, 0x3e60593b, 0x928dd209,
- 0x0eecf1cb, 0xfa601fb0, 0x2fa8b3f6, 0xff430a6c, 0x86fc6d46, 0x5ca2cf57,
- 0x6c50a1db, 0xde0e1baa, 0xfa070481, 0x07d5383e, 0xc65d77ef, 0x78dbcdd8,
- 0x43b5f6fd, 0x132f7956, 0x1bdc06e3, 0x2e2b3432, 0x502847ca, 0xa199597c,
- 0x4d3dbef0, 0x1eb913ca, 0x0214f746, 0xaf9867de, 0x77ef2977, 0xd1674de7,
- 0x4ba6adfb, 0x5186ff98, 0xac6fefe1, 0xe4c6fd10, 0xfe7d84c7, 0xe1ca9a70,
- 0x3406fc2f, 0x694d343f, 0xff9f7f0e, 0x1d2fc109, 0x78213f18, 0xfe855a4e,
- 0x84a30eed, 0xc2157bb7, 0x41632c7b, 0x9f98347e, 0xbad71bea, 0x7cf41a4b,
- 0xbc0d2ebb, 0x77bf687e, 0x03db05a5, 0x5f069bf4, 0xf7801fa6, 0x77de61dd,
- 0xfadfbf04, 0x125af843, 0xdba0bef2, 0x5d8e9259, 0xa31ef441, 0xc67d1377,
- 0xb4362bc4, 0x91dc6ba3, 0xe0bcf12b, 0x12d2cfe7, 0x138c9b82, 0xb4dff084,
- 0xc8033192, 0x6fcf124e, 0xebfc855b, 0xe7f775d6, 0x1ae928fc, 0x5c0136af,
- 0xef07f5c9, 0xeb769cbf, 0x024ff42a, 0xaa73d05d, 0xadd603eb, 0x4d66c7e5,
- 0x7f86947d, 0xfc91ff05, 0x70007d40, 0x16f941ca, 0x08e8c87f, 0x044f93a0,
- 0x7c894e9c, 0xdcd18ef2, 0xe2c8ec9e, 0x3c6977e5, 0xa099f52e, 0x9e9253cb,
- 0x90e002a2, 0xf43f4416, 0xf60221f7, 0x29ba704d, 0xbdf3f25e, 0xbfc0c525,
- 0xfcfe761d, 0x66fed67f, 0x5fcd3795, 0xcff78ed7, 0x2096f7b5, 0xf7c7ba5c,
- 0x768fda2e, 0x6e024dc4, 0x67bdaddf, 0xc08077bf, 0xbbffa273, 0xf41f40ab,
- 0xa46a9e3d, 0x3e94250f, 0x2fa50d5e, 0xfa7de6af, 0xbd3d043b, 0x7950b7ff,
- 0xcfbcd2e0, 0x17107bf0, 0x5bc0beff, 0xe3af06b1, 0xa31d7835, 0xbaca97a9,
- 0x4afe482f, 0xe3be5cb9, 0xe312fbe1, 0xd0a9afd1, 0x3d3f2475, 0x3cf4483f,
- 0x77e926d7, 0x4fd5c115, 0x47ed0fcf, 0x2cdc9dfa, 0xf491b5e9, 0xc39424cf,
- 0x29f5fc23, 0xfea88728, 0xc5c60970, 0x91eafafc, 0x6fb72855, 0x1ffd9068,
- 0x2f37fea5, 0xa6ade393, 0x8c8f12e7, 0xeefa463d, 0xafa97ca6, 0x3fb9271e,
- 0xefbf85a7, 0xfeddff4c, 0x4687e41f, 0x6ad65c0d, 0xff4d5eea, 0x6fd017d5,
- 0x2fef34cb, 0xa95f3cd2, 0xd4d1afa9, 0x2fdf821b, 0x1f10a19b, 0x38f01596,
- 0xb52f96a5, 0xef4ae1f4, 0xf5ba73b6, 0xfb2662b9, 0x26af882e, 0xb5faf3d4,
- 0x1a4b1be9, 0x75f501cc, 0x5f384a9b, 0xf7016cc0, 0x7ae6419f, 0x4307a055,
- 0x20b3720f, 0xd9b907bd, 0xf9efab4f, 0xafe07ff3, 0x0a371429, 0xab764bb2,
- 0x5536f5c1, 0x75bbdbac, 0x810182ff, 0x4be7d5f1, 0x63dd5cf0, 0x5cdbc71c,
- 0x2ed02632, 0xae25cd62, 0xfeca7d80, 0x5efbbee3, 0xeb3cf9c5, 0xd1b25cfe,
- 0x114f718c, 0x12f3b4df, 0xfa8aa5f4, 0x6ff856ba, 0x2f1e61c6, 0x5aa293c6,
- 0x080fe673, 0xee6b27d8, 0xbb6cfb83, 0xb7dfe55b, 0x00fc07ab, 0x8398ca9c,
- 0x33a750f2, 0xb6a5e517, 0xfc2cc4c5, 0xf76f782f, 0xd442eadd, 0xc61707d3,
- 0x2bd35e51, 0xb17cfce9, 0xe277a63b, 0x45b7a84c, 0xb6f246df, 0x54b1feed,
- 0xcb5d52ee, 0x2d8c6cbb, 0x894af75e, 0x1e7c72f9, 0x3bba7043, 0x2592a5fd,
- 0xa6f7ef40, 0x8f7de83b, 0x03b896dd, 0x0c07eded, 0x0e043714, 0xe7e89278,
- 0x3c60d341, 0xe92d976f, 0xf2b1714f, 0xc38d26c7, 0xf7e5a47b, 0xd25e2819,
- 0x9f91b3a9, 0x58c0f3c8, 0xb19a93ca, 0xabde944c, 0xdfe57ca9, 0x7bc7ac7f,
- 0x14eb5da6, 0x55cd4efa, 0x6dff375f, 0x1b2bd410, 0xc67ee9b2, 0x9474e7cb,
- 0x9ae9fe17, 0x53cc3ebe, 0x47591c3e, 0x9fd0a5f9, 0x9e56bbee, 0xc92fec77,
- 0x0daafec7, 0x428e3853, 0x47cfda3b, 0xe14fa857, 0xab32ce3d, 0xbbf30a25,
- 0xc8c77e8f, 0x3ef473af, 0xe6ef7d13, 0xd6e7b353, 0x8f74f135, 0x767d2d09,
- 0x15587154, 0xf4dac380, 0x29c925fd, 0xf8126ed8, 0x032d6fdc, 0x75d32f3e,
- 0x93e90fd3, 0x5f5e588a, 0x92cdeebb, 0xa38fb04d, 0x7ca5f44f, 0xd70c84b1,
- 0xd78074ba, 0x93d70ce1, 0xd9fb8a54, 0xc79bfcaf, 0x593a5f25, 0xb5f4889e,
- 0xcbf5d059, 0x0313cae7, 0xc5416eff, 0xc1d13d29, 0x02c7462b, 0x5469eefa,
- 0x6ce782ba, 0xf43883a0, 0xe710cf9b, 0x85e7a016, 0x57d8c35b, 0x3db9d34b,
- 0x84dbf6d6, 0xba208e51, 0x29e498fe, 0xfea0379d, 0xa447fa62, 0x16988ee7,
- 0x77752e62, 0x1ddb243e, 0x34327049, 0x3322fa45, 0x1aea7fd1, 0x4ff3a2e7,
- 0x96c99f73, 0xfd143e00, 0xfcf2f13f, 0x3fa04fdf, 0xf13efb9e, 0x604b3ffe,
- 0xaff6433c, 0x68bc5ab4, 0x58b31c5c, 0x838f88f4, 0x3147c5fa, 0x9d62ad3f,
- 0xc540f481, 0x5d4584ba, 0x6e807f28, 0xdda6bfd0, 0xc0c32997, 0xc63d18fd,
- 0x192f3f57, 0x5e781693, 0xbbf24139, 0x377cbe27, 0xc6c944fd, 0x65f33d01,
- 0xa7cb8da5, 0xf7f8eb71, 0x58872b75, 0x7bbf74f4, 0xe89babdd, 0xc8bcf01e,
- 0x5157bc5c, 0xf844ceb9, 0xbc58b4ea, 0xbef12bb6, 0x0b1f4581, 0xae74a1e5,
- 0x0e19f54f, 0xca9147c2, 0x54b911f4, 0x190a3dd2, 0xf0b13c3f, 0x1d31c7d1,
- 0xbbe673f3, 0xefc0187e, 0xe9d38b8c, 0xf92a6d99, 0xc4f1b51f, 0x1ab7d7ea,
- 0x888fd90b, 0x4710f627, 0xe29d62ac, 0xe3e1e2bb, 0xe238da89, 0xbdc5d2bf,
- 0xa238eeb3, 0x5187be81, 0x4588e229, 0x7f5a156b, 0xbdfe42e5, 0xee38a292,
- 0x18b23e3f, 0xed2fa0e8, 0xc5cb6bdf, 0x7fae693c, 0x8be2992a, 0x5eaf5f80,
- 0x99fc8f3b, 0x5e1ce975, 0xb03be265, 0x199d2387, 0x58afde78, 0xae704917,
- 0x07f6727c, 0x7de3e44f, 0x81f189c0, 0xa09b6be7, 0xe19f180f, 0xce39683d,
- 0xd0f725b1, 0xd68b6777, 0xf31939c3, 0x73d963b4, 0xde226537, 0xde303252,
- 0x2e55fb29, 0xef0fbbbd, 0xd86ce707, 0x950ad977, 0xbb6b0f7f, 0xf021f489,
- 0xb80b327c, 0xd9633e2f, 0xd72346eb, 0xa8792c67, 0xfe1db3b0, 0xc29f6cfb,
- 0x4104fc73, 0x26b7b8ad, 0x5bef27e1, 0xf7f8e995, 0x0a754b36, 0x8902c3dd,
- 0x7e97f746, 0xa3fdc191, 0xcedc1979, 0xd270cb2d, 0x55ea9e3d, 0x4cd2e726,
- 0xbdf74e3e, 0x55e73875, 0x282a3aeb, 0x1317f9ae, 0x976a57f9, 0xad22ba45,
- 0xf9e31f3c, 0xad779401, 0xaa3c0237, 0xfc6e5c1c, 0xad63d042, 0x94d5d263,
- 0x0767ae9f, 0x5607eff0, 0xac9cb85b, 0x9bb8058e, 0x86e90139, 0x1939f7e2,
- 0xb8e253e5, 0xe6028329, 0x8c3b4457, 0xc7fab0e3, 0x0d63abdd, 0xfec1a7e8,
- 0x38420f97, 0x237f5dc6, 0x9559efae, 0xb4801af8, 0xbfed00aa, 0x3c3cd567,
- 0xd8ad9777, 0xf0e50e3d, 0xf1832ddc, 0x7b2b0546, 0x23d25dee, 0x3bfe0573,
- 0x395a3e45, 0x81bbf1d4, 0xb9706437, 0xdfb951e9, 0x2f0106e8, 0x79f20749,
- 0xf7030af5, 0x47bc83e3, 0xe4bd5301, 0xdab71a43, 0x728891d2, 0x81bb7ab8,
- 0x8cdf87ee, 0x973806eb, 0x751f492f, 0xdcaae800, 0x51df4310, 0x344ef2ad,
- 0x51aabd62, 0xbdffbaa1, 0xd3a40c84, 0x60bd962f, 0x1c39fa45, 0xfa839ad9,
- 0xa45e6ba9, 0xda29ee93, 0x8beedfb8, 0xaf743965, 0xc3ad8669, 0x9965df82,
- 0x8edb20b1, 0xada0fc72, 0x0fcf88d5, 0xb0ea6736, 0x46d9b2ee, 0xbfa5dd61,
- 0x885fea92, 0x41fa177c, 0x9e3852ba, 0x1b769aab, 0xdd2feff1, 0xd4e2e82b,
- 0x41f6efb3, 0x4675503f, 0x2fd41f47, 0x527d0740, 0x28cfce11, 0x9a6b9fa4,
- 0xa4bc1e78, 0x03a41a83, 0x8239bbe0, 0xbdb66a0e, 0x43f21770, 0x373fe20d,
- 0x9e808e94, 0xf9fda9db, 0x7f18e30d, 0x44e91dbf, 0x2fa833ea, 0xce3fa033,
- 0x058bebc8, 0x0c7da1fe, 0xe00ef76f, 0xf9dd75f9, 0xd07c4108, 0x66d77e13,
- 0x4c3e04e8, 0x8ad77724, 0xd8ae76fd, 0x9dfc456e, 0x1ef7767a, 0x3f54b78c,
- 0x11dada0f, 0x3c041f86, 0x56ff716a, 0x19d93f5a, 0xab5fb8b5, 0x74ddff7f,
- 0x96b0f82f, 0xfdc9fdf1, 0xfec5ead6, 0xfef173e5, 0x2acfb13a, 0xadb5e026,
- 0xc13be72f, 0xf4c7c867, 0x3fb121dd, 0xbbf83d8f, 0xfec5bbba, 0x6cc9449a,
- 0x0f8456cd, 0x0fe517e2, 0x28cb8fd0, 0x397409e5, 0xe50365b5, 0xc97c4bf7,
- 0xd7efbff5, 0x93fc2e2b, 0x9d8f1254, 0xb6f77c3d, 0xa1c9f045, 0x763292fb,
- 0xd8befc00, 0x240d9f4c, 0xcc07d57a, 0xce46e927, 0x49a7f457, 0x61bee2d7,
- 0x5f1c56fc, 0x1bd07bce, 0x0e71c7ad, 0x721fce32, 0x8b2f92fd, 0x3b5da7ea,
- 0x4efd8ad8, 0x5ed1b259, 0x3f7c7811, 0xbbef46c3, 0xf7806ed0, 0xf2143b5d,
- 0xe7121f5f, 0xbdf743fd, 0xe01f2d60, 0xc577f7a7, 0xe19d25ba, 0xe4c9fa0f,
- 0xb9daf77a, 0x6ebb583f, 0xbae48729, 0xe1bfee8b, 0xeb976c5a, 0x2051f8c7,
- 0x4a384a9d, 0xfaf7957a, 0x344b74b4, 0xdaaaf527, 0xa6d77d33, 0x9dfca21d,
- 0x78ed7690, 0x2c3a3ec2, 0x9ebbcdf2, 0xe77df956, 0x41edc965, 0x33188ef7,
- 0x259fea07, 0x15b6aef3, 0x49b73c62, 0x521e7ba1, 0x4acfc0af, 0x923e807d,
- 0xdef0c1f6, 0x36a57f3c, 0xf10275de, 0x63bc7559, 0x44927e1c, 0x7d57a5da,
- 0xa0c6aadd, 0xcf1b6aff, 0x53749383, 0xf89db275, 0x93dc5aa1, 0xeef15b2a,
- 0xf74861c4, 0xce281b4f, 0x58df7653, 0xb3fbda23, 0x8a1f4d37, 0x127bc0e0,
- 0x6c4fdf28, 0xe047921c, 0xebc4b661, 0xc6c4bef1, 0xbfc7af47, 0x87633a5f,
- 0xc1a1df4a, 0xcb8f9071, 0x7f23c8ee, 0xcec8e1eb, 0xaed02389, 0x436ab5ff,
- 0xa6e47ebb, 0xffb08b21, 0x58ef4b48, 0xc6d078fa, 0xf4bbaa38, 0xa427a431,
- 0x03f32c1d, 0x90bdc5eb, 0xaf9cdeec, 0x8a97757a, 0xefac0bc8, 0xaef9f183,
- 0xddf4910d, 0xa3a352a8, 0xdbe715b9, 0x8ee74499, 0x2526385a, 0x2b9ee9db,
- 0x8cb369d9, 0x9725222c, 0x453023da, 0xc74375f9, 0x5e4fa81d, 0x1832c3bf,
- 0xd4cb8bbf, 0xb9cb43f3, 0x90e3cd7d, 0x61dfc171, 0xeac8eb92, 0x3b57e9cd,
- 0x2f7f7c9e, 0x74ec2b9e, 0x3fde919f, 0xebe9ecb1, 0xd89e1f51, 0x7dc7639c,
- 0x4919db1f, 0x198e0bf7, 0x78e7bf82, 0xb4c2f7a9, 0x3de4a9f7, 0xc1defcd7,
- 0xfba49cf6, 0xb9cbde0b, 0x98f2d2ec, 0x74662e4e, 0x065cfc4f, 0xe8e4fee3,
- 0x7e62b6ef, 0xc9a34561, 0x8e64f786, 0x7c63fd20, 0xdf4abb6b, 0xdfbba201,
- 0xdb23af80, 0x703ee8f3, 0x5ebcc7c5, 0xf0f8acd1, 0xc3fb72fe, 0xc2fe53f7,
- 0xf137b04c, 0x3db7796a, 0xebe1fabd, 0x38ce0d91, 0x3bf1cb3d, 0xf3366700,
- 0xef908b7c, 0x75bebc3a, 0xffe38a4f, 0xfd2cfdbf, 0x077bd313, 0xf09347df,
- 0x57aae796, 0x720a2e80, 0x72fbf0fd, 0x9fb22cf1, 0x50f62e4f, 0xb4395a79,
- 0xb3d2246a, 0x15ee8625, 0x51e3b4bc, 0x5373bf15, 0x79f06dbd, 0x308f1f3c,
- 0x9ff7d0c7, 0x90bc5cbe, 0x17279a82, 0x8a3f89d7, 0x15f854b6, 0xb55e547c,
- 0xfbde8dad, 0x0b5e4772, 0xd97debde, 0x9ac5c31c, 0x3be820ab, 0x3dbf1299,
- 0xfb9657dd, 0x1cd7fcfa, 0x9fdd72cf, 0xc56e9e6f, 0x21fdb57d, 0xe23865ae,
- 0x86c63a37, 0xc8a56076, 0x86ba392f, 0x23c7d9db, 0x18abfe62, 0xed7c7cf0,
- 0x0efc4494, 0xa9b6ccd1, 0xc57b63d7, 0xe786c54e, 0x49cee703, 0x7dcf3c56,
- 0xe2b4efa6, 0xd6cfaa3d, 0x3e57fbc8, 0x237bbbfa, 0xd829b3c6, 0x9eab447f,
- 0x84293239, 0xfc32f44c, 0xcbee9ea4, 0xe4ed017e, 0x451f393f, 0x89f813fe,
- 0x99927cc3, 0x4bbf722f, 0x9c57f9f7, 0x7d8a46ff, 0xcbb6f7b7, 0x17b506f8,
- 0x63f6f015, 0xd096b76b, 0x68de4fdf, 0xbfbae1b0, 0xf1a068dc, 0x4db9c0e7,
- 0xbe3deb07, 0xb0839f99, 0x13e8e78e, 0x6779f99b, 0xef3f334e, 0xb833cf54,
- 0x60d2fdf8, 0xe80a2cba, 0xeb2ddf47, 0x7323bbe1, 0x737f7c5c, 0x7ee27f40,
- 0xb1bf442f, 0x9fee99ac, 0xa93e6a5d, 0xaaff7e96, 0x74dd1791, 0x08bd13db,
- 0x23ff22b8, 0x98ba4add, 0xf5c786b3, 0x0b83cded, 0x9d24fe91, 0x5803bf68,
- 0x3bfc646f, 0xfa28bab2, 0xb324f7ee, 0x62fa80c3, 0x18e77c4a, 0x075f4f04,
- 0x916aaf97, 0xe4f785ce, 0xec29bd58, 0x15dec477, 0xbc1a78f2, 0x7abbf74b,
- 0xcff7f8db, 0x59317dc4, 0x474abe82, 0xda293e7d, 0xba038dfe, 0xf2ffae74,
- 0xf5d03d3a, 0x3bf691a4, 0xd7809db2, 0x7af35ff5, 0x167b7d9e, 0x7def3fd4,
- 0xec3d3af6, 0xf695d26f, 0x2fa80621, 0x75cdf259, 0xc9b9e063, 0x3bd83ae1,
- 0x9b139e60, 0x7f71d292, 0xdb087ed0, 0x8e7a27a7, 0xee2b5960, 0xba569d8f,
- 0xf4cc2d06, 0xa77b7ff7, 0x0e4be0e5, 0xc0d3bd7f, 0xa73bbbe8, 0x87f5cb7b,
- 0xd70e9d2f, 0xa109dea9, 0xdd8ce5ed, 0x5e7cf947, 0x7e076f7e, 0x788911dc,
- 0x5dd38aaf, 0xd3c7bcb9, 0xe3c7b9a0, 0xe4d5f7e4, 0x7f792afd, 0xfdff72ea,
- 0x7297b5b3, 0x00ffecff, 0x4fb2f369, 0x00008000, 0x00088b1f, 0x00000000,
- 0x7de5ff00, 0x5554740b, 0x55b9e896, 0x2a493eb7, 0x54842549, 0xaa84a925,
- 0xc0902b7c, 0x310c7c25, 0x0403e548, 0x6a285888, 0xa205a0d4, 0x01148280,
- 0x55f4741d, 0x9a7c3061, 0x179f8ee9, 0x102d4622, 0xdd787195, 0x866db1d1,
- 0x3220538f, 0xb40e9afc, 0xd38ceb63, 0x68d1d01d, 0x38311b63, 0x6f360cf4,
- 0x4dce7def, 0x802a56ea, 0x6f7be7be, 0xf65e97ad, 0xee739f61, 0xffb3ecf9,
- 0x5f5bdf67, 0xa5eb2c19, 0x0f24c664, 0xa153ab63, 0x63595a74, 0xff7b9419,
- 0x68d2cfe9, 0xac839ac6, 0xc18f2e3b, 0xd3f5a35f, 0x7ccf5051, 0x2e504bba,
- 0xcd1a484b, 0x139960c6, 0x996fd062, 0x12aeb189, 0x6d3b26e8, 0x12d8c2cc,
- 0x019dfe09, 0x19caf9ff, 0x956c674b, 0x44edfe15, 0xf08742b8, 0x7f466683,
- 0x3f98059f, 0x1fd8c0df, 0x3925744f, 0x9d9d8cf5, 0xbb0c2e1d, 0xbc65fb18,
- 0x009ce6cf, 0x8ecd1ded, 0xbec634a6, 0xd4a4c37c, 0xd09eff43, 0x60f927df,
- 0xe67aa5fc, 0x6d9284ef, 0x24d8ce1f, 0xc3ea2f28, 0x61dfa053, 0x8db6f157,
- 0xa9cbbcf0, 0x3f9e0c63, 0xfce70aeb, 0x82c678f5, 0x32f2932e, 0x32777ea3,
- 0x9f1eeb80, 0x9dfb1c3e, 0xfe5d7d7d, 0x936eb03d, 0xec1258cc, 0x598c067b,
- 0x0030780e, 0x07c32fac, 0xb40e3442, 0xbea09307, 0x0e74f5c5, 0x2f307c23,
- 0x0dd8c89b, 0x06ebef8c, 0xf11fbc39, 0x196494c5, 0x6f9b37f7, 0x3283db0f,
- 0x3333a38c, 0x98bbae03, 0x4d3f5875, 0x8eb19800, 0x7f60c34b, 0x3263c066,
- 0x24c78096, 0xa1eaa6c6, 0xe9afac13, 0x0990fa97, 0x7884d7d6, 0x85d07014,
- 0xd72c7a23, 0xc58bf8c3, 0xbc8ecbbc, 0x58c1c46b, 0xeb07fe10, 0x5de62259,
- 0x3d7771dc, 0x9092cb9e, 0xc0b74ce1, 0x7ffa25f5, 0x72c79d0f, 0xf2feefd1,
- 0xe29c46ad, 0x7eda1dfe, 0xafa6d9cb, 0x52fcf0f5, 0xfdc46dd6, 0x6a8ceb2e,
- 0x0cf9a8ef, 0x977cbbd7, 0x99debeb6, 0xc2748698, 0x97b1b2c6, 0xe74d54f4,
- 0x99f448bd, 0xca746faa, 0x66e19fb8, 0x371304c5, 0xf4479f3d, 0xb00cdec2,
- 0x63ac7ec8, 0x8b4fd118, 0xb1e74f4b, 0x9cc49764, 0x7ebb18e3, 0x42731657,
- 0x61aefd53, 0xc85d2654, 0x5fcffaa0, 0x57de3639, 0xd75e7032, 0xc6ab6abf,
- 0x6aff5df5, 0x3aea9511, 0x4e1d049a, 0x867497d5, 0x2ce71d61, 0x9b800eb0,
- 0x8162c08e, 0xd66e9a7e, 0x99e11887, 0x57bfb199, 0x596bc72c, 0x424fa5df,
- 0xfd8a0e58, 0x3a24974a, 0x1f3c6484, 0x433d61ef, 0x031e627a, 0x79993bb5,
- 0xa05ca5cd, 0x398ebb1b, 0x24dfe063, 0x19ce2fce, 0x81ee9ccf, 0xfc583976,
- 0x87584ab3, 0x0941ae61, 0x5c737b41, 0x33e436d2, 0xe574f416, 0xe20d73c3,
- 0x4e38aeb9, 0x54ee0937, 0x1d2af3cd, 0xadfa2adc, 0x18769a4b, 0xb3c1b2e9,
- 0x5121e888, 0xc7acd4c9, 0x406a5fa4, 0x67d5b9fa, 0x623ba4f8, 0x585fa21c,
- 0x295e0dc7, 0x7378fc84, 0x50ddb683, 0x44ad75f9, 0x8e47d425, 0xfbf6d5e7,
- 0xd003d229, 0x717e103b, 0x9c0c3d24, 0xc3a3c583, 0x1224f073, 0xb9cccbbd,
- 0x5be012b9, 0xee181b0e, 0xf7cf14df, 0x97310e79, 0x0f80fd86, 0x8875e260,
- 0x2e4fa817, 0xc537e2d7, 0xb0e7c5a3, 0x867e2d3a, 0xb7fbb57b, 0xda6ae435,
- 0x35237c33, 0xcb8b59ed, 0xbfb67034, 0xc47fd342, 0xec0d6aea, 0xf4d4ce0a,
- 0xa37f5bcf, 0xbd682e06, 0xa8bfd35d, 0xbda6817d, 0xa69f7438, 0x268ed47d,
- 0xf9da5c0d, 0x98ffa688, 0xda6b8f5d, 0x6a3786c7, 0x7e1dc7da, 0xe84f034a,
- 0x7fe9a2da, 0x34db07cd, 0x5fba93ed, 0xdb5fb4d3, 0x9e0686f3, 0xd35bbbdc,
- 0x0385ca7f, 0x1d8ab81a, 0x31aff4d3, 0x4f0356ff, 0xa6abfeb5, 0xc7fb74ff,
- 0xce19f69a, 0x67da6a3f, 0xd2d1bfb9, 0x93973c6b, 0xa5ff2bd7, 0x9359ee79,
- 0x5f50dfef, 0xdd954b34, 0xebf48641, 0x35ba3e24, 0x0184a74d, 0x972a83fe,
- 0x1c9e1d04, 0xc1392561, 0xb78e59f2, 0x32b0e914, 0x6e7c7c8c, 0xe0f24497,
- 0x28bd28ab, 0x91ebd1ff, 0x4afd9da0, 0x22765e52, 0xc45d41dd, 0x331e29fc,
- 0x39d62393, 0x81aaceac, 0x9aed7b87, 0xa706b6fe, 0xe7c33da6, 0x2d67b4d6,
- 0xb6703456, 0x7fd35cbf, 0x068f6ac4, 0x34eb0576, 0x7bd6f3fd, 0x6b417035,
- 0x517fa683, 0x5ed34fbb, 0x69ac5a1c, 0xafc3b51f, 0x573b4b81, 0xd98ffa6b,
- 0x8fb4d415, 0xb4d7af0d, 0xaadc3b8f, 0xb5742781, 0xf35ffa6b, 0x3ed34841,
- 0xa6877ba9, 0x4e9edafd, 0x77b93c0d, 0x94ffa697, 0x5c0d610b, 0xfa688ec5,
- 0x6a4f98d7, 0x0fd6a9e0, 0xdba7fd35, 0x67da6b4f, 0xb4d73f38, 0x2cd076ab,
- 0x7adad7f7, 0xaf5d1761, 0x7cf359fc, 0x90c3dab0, 0x486f823e, 0xd613b34a,
- 0x3fe102eb, 0x777ce49c, 0x28ed1e9c, 0x8c14182f, 0x41ad2901, 0x420c92fd,
- 0x480ae90c, 0xe2a6358c, 0x20ac4028, 0xc15549b7, 0x4f68c9f3, 0x73aa9000,
- 0x1fa0fcb9, 0xeb5ad813, 0x1bb266a7, 0xdf40971c, 0x29bfc25d, 0xa0944b83,
- 0x85ebaa9f, 0x4ea166f9, 0x726f3a02, 0x582e3cf9, 0xaf9d7dcf, 0x6862cb4f,
- 0x705b0427, 0x9307a01d, 0x9e6f41bb, 0x79776388, 0x378f064b, 0x89780cc3,
- 0x5c48ef98, 0x32cca3ab, 0xcc33fcf4, 0xff7fa967, 0xae3e06b8, 0x8a6bfb04,
- 0xa0a7ff18, 0xfbb065ee, 0x37c0035a, 0x153d8c05, 0x4cfc12b0, 0x5b704ec0,
- 0x7b6549c0, 0x96e54dc0, 0x1ded4280, 0x5f827281, 0x0e087808, 0xdca8ea05,
- 0xfd52f016, 0xc10340f6, 0x547c04af, 0xa62c08ee, 0x9f80b5f2, 0x560677da,
- 0x40f3fc13, 0xc0ceca90, 0x237faa7a, 0x9bf04ad0, 0xdf827681, 0xdca8840a,
- 0xe541d815, 0xb52740ee, 0x22ec0def, 0x9840edf8, 0x30e070e0, 0x5d0207c1,
- 0x7c0c1f04, 0x40a1f040, 0x03879537, 0x0d1e543d, 0xf1fb52f4, 0x078205c0,
- 0x576b4bce, 0x2e576133, 0xd2c07412, 0x2f793db8, 0x85f6523f, 0xbb462d8e,
- 0x43a09177, 0x87983543, 0xcc867740, 0x2ecd6dc2, 0x13a06a3c, 0x71c9d137,
- 0x96af2fb4, 0x4070d04e, 0x33560d7a, 0x5a9bd237, 0xc9e954b6, 0x90ae0cfe,
- 0xbb732f42, 0x336feb88, 0xb537f553, 0x85283e37, 0x079b9ed0, 0xf811b276,
- 0x9f6123e6, 0xe5c7147c, 0xc1bf39f5, 0xa35f768d, 0x66c0af14, 0xb277fe01,
- 0x8c2fe03b, 0x5ed77fa4, 0x9fb456d3, 0xc235f5d4, 0xe7183a38, 0x5a2eecbf,
- 0x6c3b2357, 0xbd40f5c0, 0x72fc0f47, 0xe2dbe6c6, 0x2fbeba02, 0x2234175b,
- 0x85425913, 0x8cc644de, 0x48f3df76, 0xf7fce7e7, 0x17c1c21c, 0x9c429559,
- 0x78537ae7, 0x7f30adf8, 0xb2bd11ef, 0x5e3439cd, 0x00ceb796, 0xf6997de1,
- 0xa0773fb7, 0x17f75f1d, 0xe1cf0fbd, 0x21b12184, 0xe9dd7404, 0x3acf8892,
- 0xd94d3a5d, 0x02fdf766, 0xa26df9d7, 0xa01d4eff, 0x56ebdbf2, 0xb612b2bc,
- 0x20a2b8d4, 0xf055ed19, 0x5f680c0f, 0x034e61cf, 0x989b87ca, 0xea1c5de7,
- 0xf823e666, 0x52a41656, 0xe176f9b6, 0x21636ebe, 0xa6157d82, 0x8afb589c,
- 0x383bd75e, 0x752c70d8, 0xdd90f29a, 0xfbc70077, 0xeb43d136, 0x7a69313a,
- 0x5d4bee21, 0x49c33997, 0xdeb366fd, 0xdf7d7017, 0x53fafbee, 0x9d306f29,
- 0x61f488fc, 0x3fb06981, 0x3779c233, 0x38e0ef03, 0x214b0fcd, 0x3e9573a4,
- 0xa74cc11a, 0x7a851ff1, 0x805e9229, 0x4b7fd04e, 0x9399cdeb, 0x4dd2f448,
- 0x3e926ff2, 0xfa7b0468, 0x28542e84, 0x8c4e89e9, 0x5173ac12, 0xee49d01a,
- 0xc0f0f4d0, 0xe423287a, 0x17d9d020, 0xfe9fde38, 0xe2371ae1, 0x93dbf96d,
- 0x66b7889c, 0xd0079c1d, 0x9ea8f073, 0x442604ec, 0xd2dafebb, 0xb207f910,
- 0xc529cca2, 0x7172e373, 0x7ead9ebf, 0x4ddc863d, 0x74f4e5c8, 0x0ba86ec2,
- 0xef9cb8d1, 0x2e7d76d5, 0x2e7d473f, 0x15a6df3f, 0xc3d52d9f, 0xf81c4ffa,
- 0x8d2ce8dc, 0x3fd58fb1, 0x823f2879, 0x3aef97ae, 0x7e83cd3d, 0xb92eeb17,
- 0xbea07131, 0xd2abcc50, 0xe898de91, 0x5c896adb, 0xc75d3f57, 0xa75d22e7,
- 0x11e75d00, 0x768a7f5d, 0x33936cf9, 0xbb2856f9, 0x28613501, 0xc95a2f7d,
- 0x14c05c7f, 0x2f32172a, 0x0c808b95, 0xc1bd8e90, 0xf7888d27, 0xd52758fb,
- 0x777e503f, 0xbdf5d23a, 0xd9f91f3a, 0xd517594b, 0xb5bd672f, 0xaf37b478,
- 0x1daef35f, 0xeb537d56, 0x44915393, 0x7fcd0c6f, 0xdb39cb17, 0x4e834fa5,
- 0x5cec93e2, 0xe4b747c0, 0xe613227f, 0xd5677dbf, 0x3f505913, 0x85cfcf5b,
- 0xa2e7e31d, 0x7de891ca, 0xe0145f03, 0x78a6dff3, 0xa4fa5f68, 0x345f0d3a,
- 0x123cce3e, 0xcfbbd38c, 0x8ae6da14, 0xfbf293e0, 0xf28590ff, 0x13bdee4c,
- 0xdbf97bcf, 0xef3c54a6, 0xfbd718fb, 0xaf8d4792, 0x119efaa8, 0xe2cfdfbd,
- 0x85f7ec15, 0xb22fefa0, 0x17f7d119, 0x658a3812, 0xcb287603, 0xf2cbd9f1,
- 0x72f6f406, 0x88d1cedd, 0x95ebd027, 0x7df70e78, 0xd632d9dc, 0x9420fa85,
- 0xe1887683, 0xecd29335, 0x7617e8d2, 0x8d850129, 0x7f3e219f, 0x198ee38a,
- 0xfca92ebc, 0xeed19fd0, 0xd0591930, 0xce7c465c, 0x677f2226, 0x9abf891a,
- 0x3879b511, 0xb7e9d78f, 0x84ff1e0c, 0xefe1ef58, 0x841d3fb8, 0xc52cbcfd,
- 0x2feb879a, 0x3cc0fc53, 0x19d24724, 0x2e4773cd, 0x3e7563e7, 0xa076e966,
- 0xc1347e9d, 0x8f9e3b77, 0xfd52471a, 0xcfaec3c8, 0x667cf1f2, 0xe5506c57,
- 0xaec78d33, 0x84e972e3, 0xf84419c1, 0x014b9544, 0x6f2fd609, 0xa7ff286f,
- 0x371d700f, 0x8c612d98, 0xc34ab077, 0x35ff7ed9, 0xdf1f4077, 0xcae3eaa0,
- 0x1a8ef8a8, 0x018a61f7, 0x3ecc57d7, 0xf141f152, 0x0e4e551d, 0xb1b0bfd2,
- 0x889fc42e, 0x79c7f597, 0xce3fb9fe, 0x8d79c3a3, 0xe6328e42, 0xf8237b77,
- 0xae00d6d4, 0x307fc68b, 0xff8d7cb3, 0xd9c0d560, 0xffa6bb7e, 0x4d4ed588,
- 0xd6e82bbb, 0x57ade7b4, 0x6b417034, 0x517fa6b9, 0x170347bb, 0xfd34ea87,
- 0x6af0ed47, 0x06ced2e0, 0xbb31ff4d, 0xb1f69a7c, 0xf69ac5e1, 0x1afd8771,
- 0x6ad74278, 0x3e6bff4d, 0x27da6a08, 0xb4d7af75, 0xaad3db5f, 0xb6f72781,
- 0xb94ffa6b, 0x57b4d210, 0xb4d5bfb1, 0xd75f98d7, 0xf1c62fc0, 0xeb54e778,
- 0x9b9e683f, 0x81afdf6e, 0xf1e7885f, 0x23ce199a, 0xf9c5e7da, 0x278b6f06,
- 0x3ee5987e, 0xffdf69a9, 0x8dcdc8c8, 0x47a12fc0, 0xb67fe474, 0xc53d71d5,
- 0x1d39aa1a, 0xd7bef1c4, 0xe66a1f2b, 0xbaf7d1cb, 0x7a9d8e90, 0x75f2266b,
- 0x039cf97e, 0xd0ac7640, 0xc51aa2b3, 0xc9eebb9d, 0xf48e5803, 0x6c8d5ebe,
- 0xf270d253, 0x7da39600, 0x1903575f, 0xca716533, 0xf996583b, 0x70d8d6c7,
- 0xbce7ab89, 0xe0c4e583, 0xb3941a8a, 0xb17e2660, 0x3e7dd608, 0x846d9238,
- 0xaa652575, 0xd10f5e71, 0x1d0caaed, 0xdbaaf9f1, 0x4b37142c, 0xa322d6bf,
- 0xe81cdf3e, 0xec10791a, 0xd3a7f4dc, 0x69dc62d7, 0xa1f9d83d, 0xc017b022,
- 0x59f2c7ee, 0xe043ebb0, 0xbb046d1c, 0x604dcb1f, 0x73fd63f7, 0x9c23f760,
- 0x7ad974fe, 0xc9d56e7c, 0x6172ea7b, 0xca0f11fc, 0xd7533456, 0x0e2b7539,
- 0x0fec7ac0, 0x4b28ad1a, 0xe267ae8c, 0xec8eb09c, 0x0a8eb065, 0x51078b42,
- 0x3052ecfd, 0x1c39321c, 0x2becfd07, 0x1db81a74, 0x2eb045ff, 0x97cf8b58,
- 0xaedee93e, 0xb6f9f630, 0x8a1937b3, 0x5d799f61, 0x014d6db7, 0xe6799738,
- 0xf1d3be02, 0x93fc602c, 0x09cd8f79, 0x97860c96, 0x48ff7a14, 0x2cee4972,
- 0x16b53e46, 0xeb81947d, 0x85fd50da, 0x3ce2b3a2, 0x0839cc8f, 0x787e7eeb,
- 0x23e758bc, 0xaff2aa73, 0x79cf5c66, 0xef50ef94, 0x47218cef, 0xffe853fe,
- 0x2f5c7993, 0xe5159fc3, 0x08938d93, 0x949d81b3, 0xf376f20c, 0xd1a7d5a4,
- 0x41ad90a7, 0xbb23e509, 0x144fcf08, 0x7823c828, 0x1e44fc4a, 0x537947b2,
- 0xe733e454, 0x1f3678c1, 0xf1914ed8, 0x785ac5b1, 0x19e79c33, 0x0c7ac0c3,
- 0x3282e977, 0x92f0c1ec, 0x9e605157, 0x5fb0798e, 0xb51b3780, 0x8e9165fe,
- 0x9f717d91, 0x378beeba, 0xdda76829, 0xf0f5c797, 0xecbb8096, 0x7ffa0313,
- 0x4027d94a, 0xfd8b9947, 0xabe40f92, 0x04abd1ad, 0xd2e19fa1, 0x2237efdf,
- 0x3ac5df61, 0xfd639f51, 0x27bb089a, 0xb86b8c47, 0x19bc27a4, 0x6a4abd9a,
- 0xbd06fcc4, 0x618cefe4, 0xc9e69577, 0x4666b9fc, 0x1e7786ed, 0x5f309c96,
- 0xba486366, 0x4bf1c687, 0xc2dbd40a, 0xb1ab3ebc, 0xf0085a53, 0x3a4e791d,
- 0xac9c7507, 0x08feb0c5, 0xa0e5d93c, 0xede78564, 0xc425068f, 0x55eadd83,
- 0xdae22258, 0x52bdfc4b, 0xf57db4f0, 0x864fb2c4, 0x8abdbae1, 0xa59be717,
- 0xcadf9bf2, 0x2b1f3d70, 0xbd42a9bf, 0xc33d1bf6, 0x9c6f8cfb, 0x8c5a724a,
- 0xa9a5a87d, 0x973ccf5b, 0x729267f1, 0x9e93f11e, 0x2ce2ddbc, 0xf17dfe00,
- 0xd6c34b36, 0x47767418, 0x75b3a71e, 0xe2deaa99, 0x73d749eb, 0xeafaa93c,
- 0x1fa72b1b, 0x4cad6e55, 0xce3ab0e1, 0x24f1ecca, 0x8f5a8637, 0xf98e3dad,
- 0x19bbd622, 0xfde2b1e6, 0xac2b77cc, 0x21f03788, 0xcc9f34bc, 0xe7d6e9e5,
- 0x4637e4dd, 0x3e20cfd3, 0x5c9bd100, 0x1dd97486, 0x31ba066a, 0x682a33cd,
- 0x5bfeda2f, 0x2472848b, 0x284ab593, 0xb5d96d47, 0xe7d46587, 0x1bd8afb2,
- 0x12be8ec3, 0xa9e7a83f, 0xcf8325da, 0x2abbf9cf, 0x0c0d43b2, 0xe5c9b6e9,
- 0xa9f9e1b4, 0x6474da74, 0xe22faa78, 0x3a0bd73c, 0x7aad672e, 0xd60ad3e4,
- 0xeb256549, 0xd63af2a2, 0x5987a54b, 0x99ab2c65, 0xf32d6542, 0xf98d3952,
- 0xad63aca9, 0x9d64ce54, 0x2eb3d654, 0xa3bfc12a, 0xe4accbd2, 0x7608de87,
- 0x9973960c, 0x985bca97, 0x482dca9f, 0xfef013df, 0xdbe095a1, 0xbb952759,
- 0x459dff80, 0x53311f18, 0x39e417b9, 0x3c836f96, 0xf20c32c7, 0xf8c269dc,
- 0x83ca9b88, 0x43ca8501, 0x0f2a7281, 0xefd43c07, 0xca8ea068, 0x952f01e3,
- 0x540d0227, 0xd47c0576, 0x316054ef, 0xfc05ef95, 0x581fbe54, 0x8107e54d,
- 0x12ff9520, 0x91654f58, 0xe20ae411, 0x163ddddb, 0x8f9c9afd, 0xe8271e8d,
- 0x84f34fa3, 0xfdd1ebff, 0x78f1e2f7, 0x83ba3a8e, 0x94aed5b1, 0x6e6d1e90,
- 0xe504279d, 0x74937746, 0x4eeb9437, 0x64d63b70, 0xd93b244b, 0x724abed6,
- 0xa4bbb8c2, 0x9c027d6e, 0x0fbcdeed, 0x4f4198e7, 0x6b65ed54, 0x7f841413,
- 0xe819a4ff, 0xdfc1ab70, 0x7fda15bb, 0xcebfd2f5, 0xaece8331, 0xc7f53c48,
- 0xed4c38d7, 0x66b20e93, 0xf207c02b, 0x26993f4e, 0x10a075f1, 0xc7d2fe3e,
- 0xe3e4d673, 0x791cb93a, 0x368e05d5, 0x5b0f19fa, 0xdb18cfc8, 0x0eac667e,
- 0x2dab49e0, 0x471fe865, 0xf5b8a3f4, 0xdba2fd50, 0x563ae7d5, 0x1e2337a4,
- 0xee0a7dd6, 0x65e51389, 0xcf8c58f7, 0xbbab8e45, 0xfe99f9ba, 0xf647f332,
- 0x5e332e93, 0x54e79151, 0x7403ffde, 0x86df4d1e, 0xaebf1f4b, 0x3598f8a3,
- 0xf6faf515, 0x7a772e14, 0xdb43e3b3, 0x53dbdd60, 0x9f21bc05, 0x610eb5f6,
- 0x8dbad7d8, 0x6fc764b9, 0x1d36f38f, 0xd1bff6c1, 0x69a0db29, 0x636fbc7b,
- 0x14f9c131, 0xea9759af, 0xca5ea377, 0xb1fae049, 0x9c48f1cd, 0xffff8233,
- 0xe6eee422, 0xadaebeca, 0xd7ad4fe8, 0x6e7802b1, 0x1b05fadb, 0x4bce30dc,
- 0x022ec09b, 0xc2f27938, 0x9ed0050d, 0x513741bb, 0xae1e642f, 0x0b4da5e3,
- 0xe128d95f, 0x0b5323b8, 0x213cdc61, 0x7586733f, 0x74095d8f, 0xc6d466de,
- 0x63f5fa15, 0x8597e73e, 0xd019cc30, 0x5e2239bf, 0x1ac0d5b1, 0x4166f522,
- 0x35b7973e, 0x4c34bc45, 0xd33cf1e1, 0xe3d0f888, 0x11aaffb0, 0xbe93fe3c,
- 0x9ff14cd6, 0x9e7fc774, 0xe9ed0e9c, 0x4d053a1d, 0x74b6d95a, 0x9efd018d,
- 0xf22758db, 0x3f8956e3, 0x76e6cc1f, 0xb92c1832, 0x1efc2273, 0xf2ca37b0,
- 0xf6a7e223, 0x7184a086, 0x4b11aa8c, 0xa7378c25, 0x3093ee3b, 0xe0de91fe,
- 0xe8897c93, 0xfda9f927, 0x2b9f22ae, 0x6f67d61f, 0xf735e784, 0x3c0cbeb1,
- 0x81b79857, 0x566409f2, 0xecdf3916, 0x27878e22, 0xb43d2064, 0x691ad7df,
- 0x9af8d15d, 0x991eaee5, 0x1ce07c3f, 0xccbfdba3, 0xfdb8e7e7, 0xf9029871,
- 0x1f8f1260, 0x9339789c, 0x6dd9e5ec, 0x23f41ef1, 0xb2393c4f, 0x2aa7e096,
- 0x9eff683c, 0x1a62b978, 0x9a9fb396, 0x484efd49, 0x05c630ec, 0xbb753f66,
- 0x7939f58c, 0xef1c2eb0, 0x71e891b4, 0x89f753f6, 0xc5a91fe7, 0xf05d72f6,
- 0x2e9fd0ef, 0x012d7e6f, 0x891505e3, 0x7961646f, 0x6abdd742, 0x837fcc3f,
- 0xd51afd95, 0xda4377b5, 0x3fc1d4df, 0x6b993ce6, 0x378c78c0, 0xf3ce973f,
- 0xf031e626, 0xf92f077c, 0xba3b95b7, 0x8e8b01de, 0x5bd9d75d, 0x9ebad783,
- 0x5883d65d, 0x34158756, 0x61ed59a3, 0xa72c41ef, 0xd16bf975, 0xa0fba9bc,
- 0xdd9620f5, 0xc45e7d23, 0xedffabff, 0x055e3796, 0xab63c478, 0xe68768ac,
- 0x633dde3f, 0x0d2fc51b, 0x60a1f90c, 0x8f55bf92, 0xa6f66c04, 0xf6787ca2,
- 0xfa875919, 0x8d6ae4dd, 0x4f74d843, 0x4ce30eae, 0x175a53db, 0xe20bbed3,
- 0x28f1e219, 0x8ba421e8, 0x2a6f1482, 0x25f013f2, 0x829dc39d, 0x7e294d3e,
- 0x8bd60a6b, 0x7efe8e7b, 0xd85e1cf1, 0x4e35afdf, 0xa55279a2, 0x08cdc4a0,
- 0x42ec23b4, 0x7f33b79f, 0x96c3e206, 0xf18adfe8, 0xce2a82ad, 0xd3912cff,
- 0x996f7605, 0x10508f48, 0x3fd5bd3e, 0xe6c1cf0b, 0xe01bcfeb, 0xb06a0774,
- 0x25c93edf, 0x367fee98, 0x39061c4b, 0x3fc2eb43, 0x5ba4e78c, 0x51cec9d2,
- 0x806b6fd7, 0x0eec22f1, 0x968dc7dc, 0xba54e781, 0xf5f620db, 0xe60b2884,
- 0xf5d4f1f3, 0x7ae7cc6e, 0xd4edd61d, 0x62f47ae1, 0x5d0fb03d, 0xfa227ac4,
- 0xd7fafed1, 0xd23b14cd, 0x897e6305, 0x4729cc97, 0xcea17fee, 0xd71a3713,
- 0x615fd6ff, 0xe509295c, 0x67f3ac08, 0x919927fb, 0xf1f7a34f, 0xfb88be42,
- 0xfe8cbd80, 0xe71f4cc3, 0xbf46e6df, 0x0d94fe84, 0x43bfdc61, 0xd45c60f6,
- 0x0c926966, 0x39b5fb11, 0xd99e9eb8, 0x728fdfe8, 0x82796665, 0x8b3df482,
- 0x72b5ae75, 0x0f983efe, 0xfd622beb, 0x7136167f, 0xfe7c4ec0, 0xe24ef799,
- 0x67583a91, 0xcfea3155, 0xbca5eec7, 0xcc8fcd89, 0xcfeb8c3c, 0x3fb93f74,
- 0x7ef40615, 0x3e7dce2d, 0x77656f8f, 0x87bc9ac8, 0xc9acbf2c, 0xac58c88b,
- 0xd07a076d, 0xd95d2ac0, 0xa829d5a5, 0x2509746f, 0x9da06733, 0xf923a492,
- 0x9a4a720e, 0x8d1ed31b, 0x7f812ba2, 0xcdde7cf5, 0xb373a7cf, 0xb039f859,
- 0x737cc55e, 0x7aacd8a2, 0x336f304e, 0xd03279b0, 0x3ead737d, 0x8f1fa124,
- 0xb232f1fd, 0x26f70d97, 0xada73e0e, 0x19cce706, 0xd41fa728, 0x2aaf2959,
- 0x67a0af0a, 0x94fc99fe, 0x1da8d307, 0xc53365ea, 0xabd6233d, 0xcf6b058f,
- 0x3bfd4ae3, 0x0cce7858, 0x4cfae0d7, 0xa899dcc7, 0x32973367, 0xf6e8ff3a,
- 0xe7b547a2, 0x78ef7e4a, 0x50b1a38c, 0xe79c07f8, 0x5af6c74c, 0xcfa3efb4,
- 0x9cbba555, 0xc2f5b161, 0x2f5c0523, 0xa72824e4, 0x90aec8ea, 0x66f04ec9,
- 0xfd23c3cb, 0xb9f2efa4, 0x57e5301f, 0xec43d216, 0x1f087363, 0x3f5dc255,
- 0xa8738629, 0xfba1d3ee, 0x7e3ddec2, 0x5099e9e0, 0x7bf5fd4e, 0xdfa0c74d,
- 0xe32cefd4, 0xeb377eb0, 0xa081819e, 0xf90361e0, 0x7cbe6b8d, 0x440315a5,
- 0x414c8dcd, 0xe3ceabbd, 0x6efae028, 0x25e4218f, 0xb32c5af9, 0xd907246d,
- 0xf4114bc5, 0xe89e9002, 0x6f31b787, 0x91f92b63, 0x8612fcb6, 0xaccd3c79,
- 0x97d20ef3, 0xe30c8d67, 0x383637af, 0xffb0550d, 0x869d1b1b, 0x219f78f9,
- 0x23b43ab3, 0xa8506a6e, 0x8546a6fe, 0xfd799bd7, 0xd50f06dc, 0xf0f46dcf,
- 0x5bd40b7a, 0xd4290f30, 0x6f718015, 0x753aa4b6, 0xe8d01f78, 0x4c17ede5,
- 0xfc1c7ed4, 0x8c27cc01, 0xbc910b8f, 0xf1d1ed6f, 0x7c7f237b, 0x9ab58248,
- 0x3b0ecb12, 0xe8f77f11, 0xcc175014, 0x2b332d94, 0x7836cfc0, 0x7f687a43,
- 0x1032858e, 0x3617bb91, 0x7ea10b79, 0xe2b643b7, 0x7b8376fe, 0xc147f98b,
- 0x9de132a5, 0xbdde00fe, 0x3af741d8, 0x3efc455b, 0xf14cc4b8, 0x2875b066,
- 0x6496ccde, 0xb7863b0a, 0x86b02c77, 0x39031ed0, 0x7bd8e748, 0x00764c8f,
- 0x6ea3c3c8, 0xe6768bb4, 0xca9f182b, 0xb7e5aa5c, 0xaa0b85f4, 0x6646bc68,
- 0xbebd3f45, 0xbcd78f91, 0xa1d21753, 0x71b9655d, 0xf341d226, 0x3fa0a60e,
- 0x53c2ecfb, 0xee10c3b5, 0x3f2e1450, 0x79a172b4, 0x9c4753e1, 0xcebf1fb8,
- 0x79fd405a, 0x5fd9af1c, 0x0d2f5dbd, 0xb79d33f0, 0x0c7e4073, 0x61ca3796,
- 0x5e63271c, 0xc1f182b5, 0xc627d874, 0xbc8c3bf3, 0x4ca7783e, 0x0be92df7,
- 0xf475b0e5, 0x0b677f00, 0x1f23a614, 0xd17c9126, 0x9dc8d7f0, 0xc179f85a,
- 0x32efc0a7, 0x9db82bee, 0xd1673e51, 0x903f6d76, 0x57943a93, 0xfadaedd9,
- 0xe3fa8b5b, 0x443c1a02, 0xe7e6d9e3, 0x9f7a2f72, 0xc70afb03, 0x74bed115,
- 0xd7285f7c, 0x72d8bea0, 0x1b8bea80, 0x44e9c565, 0x0a79d779, 0x53b45ff7,
- 0xeb806166, 0x44cd9617, 0xa4dfaa7a, 0xf5c8f0a3, 0xc2e48bac, 0xc6adf695,
- 0x19f7a23b, 0xf2efbfbd, 0xa88e5cf5, 0x6613e0f6, 0x1edb07b2, 0x9ef0e8b6,
- 0x78adec15, 0x55dc2b8c, 0x402c1d54, 0x1dc8407b, 0x973d25c3, 0xa216cd27,
- 0x51ed8353, 0xa1fc6477, 0x13f55465, 0xd86fd405, 0x6e3c758d, 0x968efb41,
- 0xe3173f63, 0xe6d6ea4d, 0x13db5de3, 0xa63f951f, 0x729bc7cd, 0x7f2a3321,
- 0x7f2a2f2c, 0x7da6946c, 0x545c75aa, 0x51b5d8fe, 0x1a3563f9, 0x967b9678,
- 0xcaf5ffa6, 0x86f81a4d, 0xfd343bf2, 0xd6ee78e7, 0x7754dfb4, 0x66fda6bf,
- 0x7c0d4aef, 0x6b5fc36b, 0x6be6dffa, 0xb1dfb4d6, 0xf69a27f8, 0x2d49ff68,
- 0xf9701577, 0x3feed9be, 0xd06c0149, 0x3df791f7, 0x28de996a, 0x7b9e46f7,
- 0xa7b70252, 0xb9fdfba2, 0x8bfbd380, 0x058f9f12, 0x1c789aed, 0xf135d8f3,
- 0x854570ba, 0x71c61bb9, 0x21df951a, 0x0ee262dd, 0x6bb6bfbf, 0x3ff6d9ee,
- 0xbc60fd0e, 0x1b5cc4a6, 0xff8c3bea, 0x37b940fa, 0x5f747487, 0x4abf5b61,
- 0x69b83d22, 0x5cab8f15, 0xaf3c5230, 0x8eac1d7f, 0xdc46fbc6, 0xeceba96b,
- 0x2da47110, 0x85424718, 0xfd4199e4, 0x7ef1c656, 0xe3574d3f, 0x371a3e8e,
- 0xa418dca3, 0x7e85bcfc, 0xcdc0e309, 0x7bc5663e, 0x02cb7493, 0x069bff9a,
- 0x265d9925, 0xb016da2e, 0x67cc0f33, 0x635c155f, 0x527dbd84, 0xb3d4f7d0,
- 0xcfddbcf0, 0x5bd31e28, 0x1853edf0, 0xe143e98f, 0x219d7408, 0xf73f3c73,
- 0x5fcfeec0, 0xe6daf981, 0x5ca197a5, 0x5acf6e8d, 0x43ebf7be, 0x6e7f6997,
- 0xde1f5bd9, 0x1fe7b97b, 0x25ba75d8, 0x38c87da2, 0xf3264369, 0xe001d044,
- 0x80fde62c, 0xf9f5c85c, 0xc5230af2, 0xfc01aeb1, 0xbfbe0215, 0x89cff8aa,
- 0x3fb9e03b, 0x44eefb39, 0x65ea1d3b, 0x847e87ac, 0x9fe53fd7, 0x9c92fca3,
- 0xa3df6051, 0x9b171dfd, 0x7215c76e, 0x8d6d95ba, 0x6a0718bd, 0xd13a344a,
- 0xbb32cfcf, 0x07193eca, 0x7ee06d74, 0xfeffb475, 0xddbfbf5c, 0x9177fe49,
- 0x944b2718, 0x9e7f2b7a, 0x4e4c8399, 0x3114f717, 0x6a4fa1f0, 0x655e5097,
- 0x8d3f942e, 0x89fd8be4, 0xa4238a46, 0xc1dc445b, 0x171358b2, 0xfb06e350,
- 0x9095ef13, 0x4bc3d3ee, 0xf18f9e28, 0x5c6f1c02, 0x11d693a1, 0x32c82f1d,
- 0x86bad3e7, 0xd7f59f1e, 0xe6314827, 0x1a875a89, 0x279e889f, 0xea04f684,
- 0x64f16599, 0x7bef444f, 0x79556149, 0xd7e470e1, 0x51d393de, 0x90329f7e,
- 0x5e8a1c3e, 0x143ccf30, 0x42b4fe31, 0xfe63dfee, 0xe63d6478, 0xe3228787,
- 0xef41ccd9, 0x2a0c102b, 0x7bb18466, 0x77ce1143, 0xc277cf94, 0x1ec9d8a0,
- 0xfe87b504, 0xd7217d5f, 0x9730d303, 0x19f2386d, 0x81dbcbf7, 0x12dcb1af,
- 0xd67d92b0, 0xf087fc01, 0x9527010b, 0xca9b80a1, 0xda85016d, 0x09ca07b7,
- 0x21e0257e, 0x8ea04778, 0x5e02d7ca, 0x6819dfaa, 0x01e7f820, 0x819d951f,
- 0x46ff54c5, 0x9bf04fc0, 0xbf04d581, 0x0160f685, 0x53d7a9c6, 0x4ad03bb9,
- 0xed037bed, 0x081dbf04, 0xec0e1951, 0x8103faa0, 0x060f824e, 0x287c1176,
- 0x70f82610, 0x479530e0, 0x7f545d03, 0xc101f03c, 0xc93ee337, 0x15df58ae,
- 0x4f8578c0, 0xf77da276, 0x15a16fac, 0x7cfb6bed, 0x79c5159d, 0x04b74fbb,
- 0x8d1d1ce3, 0xef131efc, 0x040e3123, 0xed086876, 0x67fcfb39, 0xf6a54c8e,
- 0x19bed4b9, 0xc4a70487, 0xafdb82b6, 0xfa91996c, 0x0a2130d9, 0xda58eb9e,
- 0xdc03d218, 0xed4f185a, 0xf93215b6, 0xfce9cf6d, 0xeedc8529, 0x336df922,
- 0xa541fb70, 0x5c853583, 0xe429aede, 0x161f5cf7, 0xca4a73f1, 0x9e47ad8b,
- 0xa6ed542d, 0x7f7187f5, 0x3fb079f6, 0x55bcef5c, 0xb597bc66, 0x72b3a3dd,
- 0xcbdf937b, 0xb8bf603a, 0xc50f587e, 0x6e7cd985, 0xade6db2f, 0xe63975a5,
- 0xd6ed48df, 0xd05347a2, 0xaff76f4f, 0x6deb439a, 0xd9ae2994, 0x82903bee,
- 0x89cf6cf7, 0xf0db277c, 0x64a86f78, 0x8d9e7af0, 0xe3077f5a, 0xec03837e,
- 0xec63d7a5, 0x496ed303, 0xc71130cf, 0x331cd47b, 0xe829d78e, 0xfe7121d7,
- 0xc4ca0f63, 0xb0302f7f, 0x2db9e0fb, 0x5105df60, 0xb6bf540e, 0xbd55e302,
- 0x289dbe85, 0x8e779f37, 0x9c03203f, 0xcfc7c75a, 0x82bf255d, 0xf79c3476,
- 0xbf502de7, 0x5e4dbee1, 0x4db0ea5c, 0x6ec835ce, 0xcadff3ed, 0x4397f8c0,
- 0x5a8f9ed2, 0xf9f62dbe, 0xb78f8782, 0xf14c9565, 0x378adb64, 0xbcf9075d,
- 0x33ff91bb, 0xc38a3e8b, 0x5cde4c30, 0x86450ea7, 0x35fc9e63, 0xff7717ce,
- 0xcd423aa6, 0xdf3a8f26, 0x6aef9c58, 0xb1e234f1, 0xc62f9b5a, 0x279286ba,
- 0xbf239257, 0x81ef1429, 0x942cb164, 0xb819cf23, 0xe49e0adc, 0x052524f6,
- 0x8f3c1a4d, 0xe6a02f9a, 0x0be7440f, 0x29e05efc, 0xde62c4cb, 0x4fd67ee7,
- 0xd73a41bf, 0xbd1b3c17, 0x92e36794, 0x35874931, 0x7a12d819, 0xde2aa7ef,
- 0x3d0626ba, 0x2853e5a8, 0x1fc100c7, 0x2e713216, 0x38f8ea9b, 0x64ce3e3a,
- 0x2ae082b6, 0x4318358b, 0x33e5ab5e, 0x2b7f9c62, 0x759b74e4, 0x870dcedf,
- 0x1a8f7cf0, 0x8b6a3728, 0xfd01b42e, 0x3d09e084, 0x7d4cd7c9, 0x2257d6e7,
- 0x4117f5d6, 0xa18c5b9f, 0x6e87bc62, 0x504af187, 0x94bf22ae, 0xd582fc50,
- 0x7d5de047, 0x1d843fee, 0x75c5fcf0, 0x3cff7429, 0xda1c6d6f, 0x4ccced47,
- 0xf83360f4, 0xd046c653, 0x32e90d83, 0x8b387d06, 0xfc0e348c, 0xe226aa59,
- 0xcbd70cbd, 0x60972835, 0x2616fbdd, 0x99ac3e91, 0x31acdeff, 0xc9f65700,
- 0x65b2cf94, 0x9cd3cf29, 0xca3aeff4, 0x31fb7913, 0xf75df7ee, 0x9fbd2d50,
- 0x67ca2194, 0xb283cfd1, 0xc2533d72, 0x0b952e70, 0x99bf142d, 0x133e417c,
- 0x4851a7e9, 0x17fa3c7a, 0x6d735e3c, 0x0f79acaf, 0xb68f526d, 0x8f54603f,
- 0xb7464676, 0xef3edeb6, 0x6153d3cd, 0xfca5f69e, 0xbf8bf6e1, 0x7070823b,
- 0x24e28e95, 0x5064fbea, 0x4df14193, 0xf9819839, 0x8ccc1b9b, 0xbe6db9e4,
- 0x60f28ad9, 0xc93c7a7f, 0x2cdbf6bf, 0xcbae8764, 0x3b438a6f, 0x556f34d9,
- 0x8c23960a, 0x3b18adc1, 0x2dd5e6bd, 0x9127d937, 0x55f355bc, 0xec1cac82,
- 0xdc8dbb81, 0xf73e09c8, 0xe51954f4, 0x9967cf25, 0xa796eaf4, 0xadd8f983,
- 0xd4e1d695, 0xf9be4cb1, 0xba76f87e, 0xbeb896b7, 0x1da11a70, 0x7ca379e0,
- 0x7b4115d7, 0x3f705a46, 0x9cb66d36, 0x6b7ca469, 0xf982324c, 0xccfd0b0d,
- 0x658df588, 0x573e48e6, 0xf2fbe4f9, 0x87c63c7f, 0x0e595f87, 0x2bdc695c,
- 0x3e417bf1, 0xfca19be7, 0xf210d369, 0x1f8ff554, 0x8bfce029, 0xf57a4b6c,
- 0x7da6318c, 0xce22abf5, 0x9e46e567, 0x61bb32a7, 0xc3dd1d5a, 0xcc65bb04,
- 0xdc517be7, 0x27a7b50b, 0x7b713dd2, 0xbde30b2e, 0x8e817041, 0xf8d27bc7,
- 0xb98ded7f, 0x936a1f14, 0x3cc129fc, 0xb9f097cc, 0x01dafcf0, 0x7f308947,
- 0xeb970e5b, 0xe2b7e42c, 0xb38c357d, 0xe0fd7238, 0x74b505ef, 0xa61ec8cc,
- 0x789e85f8, 0x888c69cf, 0x1c5c63b7, 0xcfd117e3, 0xc2d5ee4d, 0xe1682e53,
- 0xc0d0662a, 0x3c2d6635, 0x3785aad5, 0x7d3b7115, 0x3f5b5dba, 0x1d85a9c3,
- 0x74e307d9, 0xc2dfcf3c, 0xf049e222, 0x447e5ef7, 0x68dd681c, 0x765f3efe,
- 0xcb8a52f7, 0x78f0e5b6, 0x3695638f, 0x42c591ce, 0x732fe212, 0xd63c5469,
- 0x863f66bd, 0xa30bed97, 0x5efc41e3, 0xa9a1f002, 0x7c8a3147, 0x9e68eaf0,
- 0xd23dde87, 0xce08bdb7, 0x5f0c60b3, 0x4d1dabc7, 0xdac53f74, 0x5caf88d3,
- 0xb0695f22, 0xe88a7cbe, 0xf90f1d40, 0x7fb11822, 0xf84887e4, 0x37be51a1,
- 0x8be41e70, 0x2cfea460, 0xfbd036e9, 0xa1be62ab, 0xcfe543f8, 0xa28f7172,
- 0x89f4dde6, 0x9bbcd4b1, 0x705f2255, 0x4ebe5457, 0x1936a39f, 0xaebee7fd,
- 0xf8b1f195, 0x682ef910, 0xe5887ce2, 0x837f9106, 0xe22c187c, 0xa6f5887c,
- 0x637856ef, 0x050b8bd9, 0x63bfdc5d, 0x224f86c9, 0x73acb7f6, 0xbe5e0685,
- 0x910de1eb, 0xe3f751f9, 0xbf08303f, 0xed7e519e, 0x2f9db152, 0x2bcbff4f,
- 0x48cd0ccd, 0xcf2807df, 0x319c1596, 0x5ea77bf2, 0x42eb9e23, 0xcc99ff61,
- 0x2fd1f2b3, 0xf2e211db, 0x37889d6c, 0x33155b34, 0x3b9981c6, 0x50c71355,
- 0x4b4d11e3, 0xd854b65c, 0x7c7f7247, 0x7ca56bc1, 0x14f9e1dc, 0xf1aa48df,
- 0x32c6cedc, 0x9c6453d6, 0xdd62066b, 0xc056c18e, 0xd957f9e9, 0xc0c74133,
- 0xf8174dbe, 0xb0fdc97b, 0x8f2467ec, 0xea68e42e, 0xa39c44db, 0x0b2dbf9f,
- 0x8b3e70aa, 0xb0fb49db, 0x1e1aff31, 0xd1c6d417, 0xe73de24c, 0x343be3c1,
- 0x7e226df5, 0xb5f1e572, 0x85d33971, 0x2fc621bc, 0x1adf1a8c, 0x7181fc73,
- 0xabbdf1b5, 0x714f37b8, 0x2e3a184f, 0xe9cdd236, 0xdfdd9d69, 0x83317185,
- 0x06667fe0, 0xf288993a, 0xe3e9ff80, 0xc1ae7e79, 0x198f8da1, 0xfa0baf30,
- 0x98b8973f, 0x3efa8ae4, 0x0599fdb5, 0x27cbca12, 0xa4e8fdf0, 0x5a24f2c1,
- 0xde44d88e, 0x811cb47c, 0xd37034f9, 0x36cf5cc3, 0xe50f8a4b, 0xfe7ef473,
- 0x7587f17f, 0xc8bbe389, 0x778eceae, 0x0f632e9a, 0x638205b7, 0xf175b9f1,
- 0x0778c5fe, 0x918ef77e, 0xe3944f69, 0xf88ceb7b, 0x298ec56c, 0xb60f3173,
- 0x13ebf04d, 0xa7a23a69, 0xb7d3dbf4, 0x29e823ea, 0xa173e8dd, 0x13ae9c3d,
- 0x87f85ff9, 0xd227b471, 0x318c6db7, 0xa9d76abf, 0xd601adb0, 0x6d8e7111,
- 0x9fee9ec2, 0xadcc8eef, 0xd27188fa, 0x34b1be4d, 0xa3fe7f5f, 0x87e5af98,
- 0xc459b7cd, 0x6cf9d4c3, 0x67f76a77, 0x7f69fa33, 0xd487a136, 0xfee336f9,
- 0x15d5f062, 0x75fe13e7, 0x69777cff, 0xf93367f7, 0xf5367f69, 0x7cea1b3b,
- 0x3e6c3f2d, 0x76cfe0bb, 0x3d97def1, 0x64377f9e, 0x9a23f7a8, 0xbdccf3fb,
- 0xed2f9466, 0xe850bc6a, 0xfa5173bb, 0x3be849ae, 0x6973f9f5, 0x3dff14b9,
- 0x7326f877, 0xfa873d2c, 0x933b098d, 0x09933b09, 0xd9e1133b, 0x0d57a735,
- 0xbbfc7a07, 0x95cf371d, 0xbecfaf41, 0x1cf8f4ff, 0xf1d9df80, 0xe832b98b,
- 0x9eafd9a9, 0x1e0b337e, 0xfbdbfe29, 0xe9f4fc38, 0x5bb4073e, 0xadcccf82,
- 0x18693805, 0xbaeacfd7, 0xb97779d5, 0x7cb95db9, 0x6f8f1e75, 0x3d459c82,
- 0x67e39cd6, 0xcafc7f18, 0x1f349bd1, 0xeecf2ffa, 0x03105f4d, 0x7cb96a2f,
- 0x1e7f2175, 0x9889c0ad, 0xaf48c6cf, 0xc7bea8dd, 0x8f7da752, 0x23692925,
- 0x2c7187d9, 0x96394564, 0xfbd0f660, 0x7316d797, 0x533370bd, 0xe15fb81a,
- 0x1c79102c, 0x4dcbdef4, 0x6b5c62e5, 0xfdb12fe5, 0x09e79d66, 0x79ff77f4,
- 0x68e1bcd2, 0x7379ab3e, 0x3bde06a3, 0xde7dfedd, 0xb1fd9e4f, 0x64e56dc4,
- 0x36998f1e, 0x7bdfc9ca, 0xa22b888b, 0x3e143c5d, 0xff73753f, 0x1e9f007e,
- 0x0f54cf8e, 0x37b5a7c7, 0xff9c0d69, 0xf4de94f2, 0xc34f89c7, 0x0835f131,
- 0xfbf851af, 0x7ea99b93, 0x88ed1ea0, 0xc55be12b, 0xd85f9aab, 0xc80b392c,
- 0x9a19675e, 0x14c660fc, 0x1e7bac67, 0x3d48cfa4, 0x197bb46b, 0x3486a3da,
- 0xeff98dc5, 0xc7d17fcd, 0x1573dbcc, 0x525ef88b, 0x367de53c, 0x1fc91927,
- 0x93349fdf, 0xb659fc61, 0xd4bc234c, 0x3e51d526, 0xeb187ea6, 0x3a357f44,
- 0x7c9f5d0f, 0xe909e53b, 0x4061e86d, 0xecc79fd9, 0xe95f2331, 0x5d92563f,
- 0x99570048, 0x295f2e87, 0x26753d0f, 0x324f43cf, 0xd85e313a, 0x998c689e,
- 0x9badfe87, 0x71fb5dfb, 0x1fb8697f, 0x886eff23, 0xe56c97d8, 0x9f58eef7,
- 0xab46f500, 0x5dfc518f, 0x615bffec, 0x4dfda907, 0xf9433f56, 0x4e2a37a0,
- 0xa9f45fb4, 0x77e07f5c, 0xe231dc5b, 0x0dbb5f28, 0xa3fdfcf4, 0x99cf5cac,
- 0xfb3eddb9, 0x27dfb137, 0x44962b28, 0xdd3624bc, 0x3737450d, 0x9dde78ea,
- 0x2d7397ca, 0x9c07ca46, 0xf7d3b16b, 0x2102e66c, 0xf446a4f6, 0xfe56eebf,
- 0xd8acb53e, 0x7b7e9e91, 0xfe5f94ed, 0x00b5e196, 0x66a7db97, 0xc2bde818,
- 0x28f31253, 0x5df383a9, 0xa994debd, 0xea1bccb8, 0x7645af4f, 0xc8c3182c,
- 0xc1757a4e, 0x4e95ad43, 0x8aea8ff2, 0x737d9e91, 0x770fa2a6, 0x77d8c363,
- 0x04f2ffb1, 0xfbd5cf2e, 0xfc09e5a5, 0x646bde7d, 0xffec6cdf, 0x4917c555,
- 0x725f48d5, 0x2bae0e6f, 0x33dd3fa2, 0x5b9ff445, 0xcffa813c, 0xf5ddafe6,
- 0xce3977d2, 0xc8f99da5, 0xec7ce8c7, 0xf429ecb1, 0xbde458b7, 0xe81f9086,
- 0xa3d64577, 0xce22c5bf, 0x6e505a53, 0x4f218eeb, 0x3ec332d4, 0xa042e46e,
- 0xb18c8cd7, 0xcff5aa54, 0xa175f47a, 0x90fce718, 0xec1fe738, 0x6ac3b4f7,
- 0x3df80e27, 0x843cefe0, 0xe172f8f8, 0xb0f1f4a9, 0xbf6a07a5, 0x6ec7bf26,
- 0x16ceffec, 0xb00371f9, 0x2db3bef6, 0xdf8c5bd0, 0x87886019, 0x8bf91189,
- 0x25f6bf62, 0xefd0526b, 0x20f4b381, 0xbc0476dd, 0x030d6b23, 0xe42cbfcf,
- 0xd2160b08, 0x2eb106f3, 0x0ceb5a47, 0x2c38bb8c, 0x6073ca3a, 0x6791aacc,
- 0xa6536a73, 0xbb0ba1a6, 0x2716299c, 0xe45df7fa, 0xfbe06417, 0x7c9f180d,
- 0xf78636e7, 0x9d69595f, 0xfd75da12, 0xc6f788f3, 0xe17b8957, 0xed2d5f3e,
- 0xefd6c327, 0x5ff23197, 0x507382d3, 0xc33df56e, 0x92f19457, 0xc691ddb6,
- 0x5dee1ff3, 0x02721f18, 0xed2d67bd, 0xb04f4fc2, 0x30f8700c, 0xa9719fa6,
- 0x7282d5d9, 0x140957e6, 0xe7b7d677, 0xfbc820b3, 0x1bfbecb0, 0xf9c877c2,
- 0x6c4f2e90, 0xb65b9e16, 0xb9ec9e28, 0x0675a976, 0xe8f731f9, 0xd178ac58,
- 0xa7ee62ce, 0x2b628ffc, 0x4fb5cfbf, 0x1f63f4e4, 0xb8e1723f, 0x77ffe7ab,
- 0x49f99e84, 0x7fde93b2, 0x4da3ed52, 0x8e47f843, 0x5f213a91, 0xf8115e84,
- 0x199f3333, 0x792f45f9, 0xc774b079, 0x96bdaf6b, 0x5b53e8ce, 0x841b4748,
- 0x138ea3fd, 0xc6a21f9f, 0xf243c578, 0xb87ab252, 0xedfab0be, 0x75af3841,
- 0xce63e9df, 0xfba085ff, 0xd90fd935, 0xd3ad7fb1, 0xfa32c6e7, 0x9c96983d,
- 0x3e78dd7b, 0xe9fb332d, 0x96baec95, 0x61dfce33, 0x28f0563e, 0x9fd837cf,
- 0xefc3685d, 0x1b0e5941, 0xe265d364, 0x27d046f1, 0x19d8cbce, 0xdeaf9146,
- 0x99e78072, 0xbaca58b6, 0xc5a1af30, 0x6a465692, 0x56f3c2d8, 0xcb16fed5,
- 0x1607d221, 0x5adfdf85, 0xb8487f50, 0x0947c04c, 0xe110ebae, 0x5077ed43,
- 0x128b5dc8, 0x5a5ef866, 0xfd4ad29c, 0x83d7b2cc, 0x34e6ca79, 0x6644f746,
- 0xe217f02b, 0xccc75f35, 0xbec9f431, 0x5a4fae62, 0xaabaca4a, 0x7e327d69,
- 0xd8b58eb9, 0xe7a4eccb, 0x7cf0ef11, 0xcf968673, 0x577813bf, 0xf91669c7,
- 0x4eae77b4, 0xc38ed609, 0x1bf79338, 0xcb16e7a4, 0xf5107302, 0xcbf8e25a,
- 0x391a678e, 0xd7fb78d4, 0x43bef18a, 0x2c4fae79, 0x0678e2b3, 0x8d15f7c6,
- 0x9c62e1f7, 0x7bfbd5ff, 0x47bd2cc0, 0x581d304d, 0x7deb1ed8, 0x13f3feac,
- 0xcfd1f2f7, 0xbc7960fd, 0x02871b56, 0x091eec79, 0x72565afb, 0xd53550e6,
- 0x0bd3f8f0, 0xfd519fc2, 0xf6317492, 0xbf7f120b, 0x2bc5283f, 0xe10c5df4,
- 0x69c7a4a7, 0x3ef030f1, 0x6f873f2d, 0xde1e781a, 0x7c4c6937, 0xd7cb4e87,
- 0x38ff1cdf, 0x059f9345, 0x7131ec7c, 0xde23c63f, 0x3888f5a7, 0x6f18c21d,
- 0x049d17a0, 0x89c7f7ff, 0xc33f9c1b, 0x4099acef, 0x5c60eb8e, 0xfa27e1c9,
- 0x5dba3936, 0xe239efc8, 0x78d10ffb, 0x2e48c9fe, 0x7a47a5af, 0x51af785c,
- 0x119bd69b, 0x7c5fdf8b, 0xee0642f8, 0xfd19c5e7, 0xdf743b79, 0xe769e2f4,
- 0xcbc402e6, 0x6ffbed11, 0x474df8ea, 0x22f8a7ce, 0xe5c0a5fd, 0x3a4b2fdf,
- 0xd92571b3, 0xddb80b8d, 0x7dfa7ff8, 0x73e617b3, 0xa497753b, 0x084fcf95,
- 0xfc141cb9, 0xd320bb60, 0x2aee43f7, 0x3a40adf2, 0x0bac936a, 0x3ce72e50,
- 0x9af2f3cc, 0xb3d55b1e, 0xb47f0628, 0xd5fdf28c, 0xbabf08c8, 0xe491bd7c,
- 0x3725b35e, 0x28f772f9, 0x9fbb9f43, 0xde7a94e4, 0x79988f55, 0xdb8f8abe,
- 0x7bbee9d1, 0x3a260f29, 0x7ea8653f, 0x449d23d5, 0x137f6a0f, 0xc5f28f8e,
- 0x15c52372, 0x818fa1ce, 0xb72b3b71, 0x59d7a233, 0xc098c889, 0x7d0663f1,
- 0x49607499, 0x106b8e1c, 0x6a0bdcfe, 0xcca1a45c, 0xde7889ec, 0xb9995b70,
- 0x9a4e823a, 0x8e0fcf19, 0x2337ff1e, 0xac22fb55, 0xa80c63b1, 0x94c6317f,
- 0x97ed9f26, 0xf278643b, 0x0395b4fc, 0x0ee3cc7c, 0xc5a3e743, 0x232dbe71,
- 0xf30dac7b, 0x5e0ec0d2, 0x0460b0d3, 0xf64db7e2, 0x3c0368bd, 0xa2687ef4,
- 0x0bdfea3c, 0x7c16ed3e, 0x05f9d43a, 0xd23001d9, 0x1d9c7b18, 0x80e297c4,
- 0x2327c64e, 0xebe7345f, 0xf63142ea, 0xf3ec5c79, 0x7878f632, 0xc7b3f7e4,
- 0x1afe890f, 0x6ded1c7b, 0x46fdd44f, 0xb6768c24, 0x7e3d8627, 0x05f11242,
- 0xc2742791, 0x0dd5dce0, 0x39313978, 0x5697be99, 0x5defc090, 0x527fa04e,
- 0xabc87e06, 0x7ed1f3a7, 0x7ff52d99, 0x43f84917, 0x47f0608c, 0x62f905fe,
- 0xb6bff30e, 0xe23e2248, 0x1b7835f7, 0x73e57e9f, 0xd19236de, 0xf9c036ba,
- 0xdb46fde1, 0x6233f9c5, 0x8ea467dd, 0x5037fd52, 0x13ef1165, 0x889d3c33,
- 0xf741acfb, 0x72f75174, 0x9fd36d78, 0xdc1fac77, 0xed7286ff, 0x8b86d9bd,
- 0x5a622e3c, 0x4b8f42c2, 0x6daa9798, 0x10cea9bf, 0xb9a82f7d, 0x6bd9bb4f,
- 0x7d0f5e88, 0xd621d417, 0x1f71dd9b, 0xcd4fbfdd, 0xa644f9e6, 0x04e28c65,
- 0xa66df7d1, 0x3d1e5db1, 0x8c0dcfda, 0x38e8fdec, 0x52a9e639, 0xb181b0fc,
- 0x79e5122d, 0x7973df6b, 0xfe73fea6, 0x3ad6947d, 0x760ec79c, 0xd1d3da10,
- 0xf7a849ef, 0x51f7ea5a, 0xdfab3c55, 0x4dbf4a8f, 0xc163eb47, 0xc6aed429,
- 0xb87bf1fd, 0xf911e955, 0x7f582be4, 0x2b7f7a7f, 0x9bdf7b18, 0xcf29eadb,
- 0x7fbc7320, 0xb29a186c, 0xc8784614, 0x6fc8c85a, 0xf2683c00, 0xdbd94c09,
- 0x16e79f69, 0x224c3633, 0x33da683c, 0xfdd3d340, 0x7e6d42c0, 0x0353ec01,
- 0x57abfb47, 0xd94d53f2, 0xf39597f9, 0x9a638a57, 0x94e4bdc4, 0x97fbe251,
- 0xed14aca5, 0x9edbf4a2, 0x0738f3a1, 0x5f7181e7, 0xdd629c74, 0xf1826e3b,
- 0x77fc8fd1, 0xe2cd2fc1, 0xaefd5b6e, 0xf4c8f30f, 0xce549b1e, 0xf30d2cd7,
- 0x12e97bf2, 0x8a6e7c46, 0x8fcc6667, 0x1e4c2a97, 0x04c9bbc4, 0x32596c30,
- 0xd4067332, 0x7b3c45eb, 0x8464c48d, 0xf3315599, 0x5dfaa3f8, 0x577d10a1,
- 0xd479a868, 0x20b22bef, 0x679d4e7f, 0x2ef577d0, 0x7bf93cf3, 0x6be7e8d6,
- 0xcea99e29, 0x87fe143f, 0xbfde8efa, 0x8137bcd5, 0x441d53c7, 0xf4038daf,
- 0x417cf04a, 0xca3cf88f, 0x66d5bb85, 0xfa29577b, 0x4c1e670f, 0x114a3650,
- 0xd2ce08fb, 0x7e03eff3, 0xd7faf1bf, 0xbc927761, 0x1897dfef, 0x8beefbef,
- 0xdae422fe, 0x09597c3a, 0x191a5ef3, 0xfba431e5, 0x29973faa, 0xa0f600ff,
- 0xdf111391, 0xd6f18049, 0x1fefce3d, 0x3e77e336, 0xc0e7fef0, 0x13edfe40,
- 0xd1f76c16, 0xbcd43677, 0x5da3cc5c, 0x3ef0325b, 0x837df472, 0x89c611bd,
- 0x99b26f98, 0x9f401305, 0x0531f4a4, 0xb9ecf3bf, 0x03a65468, 0xa07d6c7e,
- 0x93bf0150, 0xa5ee8999, 0x337ead2a, 0x0ae10eff, 0xef676916, 0xefa56e97,
- 0x64bf86bd, 0x3e14bf94, 0xc3ee88cf, 0x70c4c39f, 0xddf8ff2e, 0xcbe47afb,
- 0x7a5d7da9, 0xfb93f3d4, 0xf67fa4fc, 0xed3d4fd9, 0x9962e7e2, 0x751f9111,
- 0xcf545b1d, 0x979f8ae9, 0x5f27ea2c, 0xfdf86a30, 0x46a35eda, 0x5b17c81e,
- 0x65fd46be, 0x67aa89ea, 0xe3e33fd3, 0x2dde28f9, 0x53edb5db, 0xdbd03e44,
- 0xc35fdf2a, 0xbc73a1ae, 0xcf331698, 0xd5dce06e, 0x71e26e73, 0x79c7c674,
- 0x9ff7946e, 0xff404d46, 0xe87147c0, 0xd82fc464, 0xdd952917, 0x58798ecc,
- 0x8e994ce5, 0xf3b2bd72, 0xe487a41d, 0x3c0f3cb3, 0x5ffdfc7a, 0x7e8595be,
- 0x9dc99ec3, 0xed2f6859, 0x3d15f2f9, 0xd3d5578e, 0x193eb0cb, 0x58a41e4a,
- 0x10aa784c, 0xcf5033b4, 0xf59144e3, 0xe74a9eb4, 0xcfe4e565, 0x871a4e50,
- 0xd933df6e, 0x87e4c2c2, 0x3da02675, 0xfe7c7cc7, 0x57cab364, 0x70972fec,
- 0x9f81845e, 0x52ea54f6, 0x7b9f616a, 0x6c15919e, 0x46f3d3dc, 0xe7bfce02,
- 0x7acd39ec, 0xf322fe98, 0x5afbac45, 0x2b53ee71, 0x7efec97b, 0xf92bac4a,
- 0xa1c52f6c, 0x30de9553, 0xc3d4dbea, 0x37fefa7a, 0xc8bcf0b3, 0x38a14c61,
- 0xfc5eba9a, 0xd73e2a6e, 0x88de7282, 0x5632b3fb, 0x287eec28, 0x55832a33,
- 0xcc9a8f98, 0x6b484a76, 0x417d2b53, 0xa5e4e7a4, 0xad939e9c, 0xbf18c3fe,
- 0xa3af5e4f, 0x59f24538, 0xcbf406df, 0x0565cb92, 0xf84ae4c9, 0xb7f310ec,
- 0xf9d4f98a, 0xa88cf5d5, 0x7ee84bf4, 0x62e3b324, 0x132aaefe, 0xcc5abf8e,
- 0x59eb14ef, 0x2c3be8c5, 0x55ad67c9, 0x83272fe8, 0x33df419d, 0x9a79e2b8,
- 0xb745f335, 0x99d94f27, 0xb1e0e745, 0xe30ad91e, 0x365b64a5, 0xceb94154,
- 0x32ff23a1, 0x3c5187a9, 0x9d27a93d, 0x4f527de4, 0x8a2728a1, 0x0f4269fa,
- 0xd4933970, 0xaf2d50f3, 0xa4d2a16f, 0x3f8717ca, 0xda98fb8c, 0x717cb8cb,
- 0x98be4978, 0x517cb8d2, 0x9556b8e9, 0x325acc2b, 0x0ff7ea1f, 0x06b5acff,
- 0x73f77b9e, 0xbbe5fefe, 0xbcbe5cd9, 0xfbf725fb, 0xd3bf694d, 0x42aa5ca3,
- 0x4dfa05c3, 0x33edc0bb, 0xbaab1f95, 0x48113625, 0xe7839a63, 0xc8ba1f87,
- 0xd9843b9f, 0x63af00d5, 0x9529c912, 0xdd056b6e, 0x83eab3ae, 0x81fed849,
- 0x3477de89, 0x98e5ce39, 0x83fe1ec1, 0x7c41f7ae, 0x33f7f8ef, 0x415def7a,
- 0x437e82f5, 0x9a2e494b, 0xe4396c84, 0x3e416058, 0xae487984, 0xe918721e,
- 0x3a080ebc, 0xe9af673e, 0x5b3fc308, 0x69fcdfcc, 0xc1ffd43e, 0x9340eb9e,
- 0x1e973d4c, 0x885f2f41, 0xe82b3bf3, 0x7bdd29a6, 0xfc04c953, 0xcd1e62fe,
- 0x0dfece7b, 0xdcb27fbd, 0xc69f1ff6, 0x3aa72efa, 0x4f7cfa8e, 0xcf19a568,
- 0x1f9bd0f5, 0xabb4409f, 0x7b235fe3, 0x7ee3e4ef, 0xd0f89a33, 0x78cf3b12,
- 0xadf3fc90, 0x8b7f9688, 0xc80f864a, 0x91667abf, 0xe7121e79, 0x1e4259eb,
- 0xddb8554d, 0xe7e56f5e, 0x5fb25f55, 0x8b8afea6, 0xd2af55f6, 0x5ae4f28d,
- 0xf29b7fe4, 0x7d4bd124, 0xbd97a73e, 0x0a0f9e82, 0x63ecce7c, 0xed97e89d,
- 0x196e982f, 0xe23ef80b, 0x1cff13d2, 0x52c6bb19, 0x291dcf06, 0x024bf095,
- 0xd6c97a6c, 0xcf00a9b5, 0xa7a22452, 0x1dad92fa, 0x967fd04d, 0x03a94135,
- 0xb3f9e8f8, 0x0eaf3416, 0x9784bc05, 0xe3f872e9, 0x1b9e1754, 0xcaccd3c7,
- 0x4ffe8cb0, 0x8cbf63bd, 0xc46df6fa, 0x2ee311ab, 0x7567c11e, 0x6a571f04,
- 0x238fb82c, 0x2f2126a5, 0x5e51e33d, 0xd537cace, 0x7c75a18f, 0x1a4c6c7d,
- 0x506f77be, 0xa73c95f8, 0x7e82c9ff, 0x6b27ccea, 0xccdfa053, 0xd7196692,
- 0x912cd47b, 0xd7da3cfc, 0xc793f944, 0xd2ac393b, 0x74073d2d, 0x5b6fbc79,
- 0x6fb61273, 0xd53e4897, 0xe21d2f2b, 0xa7d38fea, 0x0b0f7e3a, 0x3077e1b6,
- 0xb7af29cf, 0xb1f53e60, 0xcccf05be, 0x7f1c3c01, 0xb8c43f53, 0xc0ad1f4d,
- 0x244cdf71, 0x356d9e3a, 0x8cb1f469, 0x5e84694e, 0xd36f1ead, 0x0d4af5c0,
- 0x29cfd3c5, 0x7806e592, 0xad5df3de, 0xd191397b, 0xbd77da52, 0xe14c7be8,
- 0xa1cc797c, 0xd63cbe23, 0x8a9cb8f7, 0xfb4659f0, 0xde769991, 0xb21a92fa,
- 0x5b29ceaf, 0x826744f5, 0x54f1d50f, 0x4f8a3e3a, 0x9ced1e23, 0x6df68fff,
- 0x1dbd20b3, 0xe323bf75, 0x89675d39, 0xa1d0571a, 0x5df0dfaa, 0xda9fa471,
- 0x7ef3fb51, 0x3851eb86, 0xd7946bfe, 0xd57d238f, 0xa7a2643b, 0x9afecaa3,
- 0x27bf8614, 0xffecd262, 0x9ac91dfe, 0xda7597f1, 0x5db47034, 0xdbfdcfb5,
- 0x0ec4cba7, 0xd847a466, 0x3ec2f947, 0xe0771fd2, 0x1768aefa, 0xf7e8eb29,
- 0x45d90649, 0x8a2edcf9, 0xbe5487b6, 0xb889d66e, 0x65c78eac, 0x58dff9a3,
- 0xf1eec3fa, 0x8e492ad8, 0xc65bbfbc, 0xbe9073ba, 0x8612a3e6, 0x75d01ef1,
- 0x15fc23a7, 0x078b6deb, 0xccad7c39, 0xbfbf6976, 0x3f37bfca, 0x1e77d4be,
- 0x367495e5, 0x6561df4c, 0x07e518ab, 0x9e786be8, 0xad665e11, 0x258bd488,
- 0x8d2df1fd, 0xd84ba45d, 0xac78859b, 0xf1e46b38, 0x38e89e8f, 0x851fea97,
- 0xae2bf225, 0x93ea2e52, 0xe67bb8f9, 0x7f6778f0, 0x938f3379, 0xe5fc0915,
- 0x5d691a94, 0xdcf7808a, 0xb59efb16, 0x41fa54a4, 0x07dfa2f9, 0xef8029df,
- 0x61e690af, 0xb1553d9e, 0xca5291d7, 0x9777b5e3, 0xa14af278, 0x15f12a2c,
- 0x3d5e2296, 0x77d35f60, 0x9f643dc5, 0x33bce3a9, 0xfd16e3ca, 0xbcc96146,
- 0xee8f0edc, 0x6863ed07, 0xe3d8869c, 0x7a38fb40, 0xf6ec6e7e, 0xfc39b843,
- 0x30fb237d, 0x0c0643d2, 0x52f2a664, 0x16e5e32a, 0x8846aefa, 0x1e0de7fb,
- 0x9146f3d2, 0x103788af, 0xf4c7fc91, 0x1cbe34f5, 0x58f7419e, 0x8325d82d,
- 0x7691f9fb, 0x6a84ac94, 0x6aade322, 0xdf94a8b9, 0x1528ce73, 0x604cf3ef,
- 0xa8afc813, 0xea3cfcbc, 0xc3cd43f3, 0xc85765ec, 0x63f35e7b, 0xc3fa49d3,
- 0xa55f27e4, 0x4a0e607d, 0x1f39df91, 0x4a89bf6a, 0xc28a1c94, 0x5cf350d3,
- 0x22dc79ed, 0xd76af6e8, 0xcc7a655d, 0x2ed1f94e, 0x056b07ce, 0xd5dbf57d,
- 0xbe3f1e3f, 0xfe861f3f, 0xfefbd9ca, 0x4a7ef893, 0x37a56842, 0x145e7ec6,
- 0xe531f9fb, 0xce70d3c1, 0xfba18c1b, 0x0799ded1, 0xd20263a7, 0xf1f2c77b,
- 0x9eb005f0, 0x2dfcc537, 0x6feb9596, 0x1c5b4785, 0x1ef998ba, 0x7a78fe6f,
- 0xd93f0da2, 0xdce395ff, 0xa7206dfb, 0xd07d1e5b, 0x7581b0ac, 0x15d96b30,
- 0xe347f9ce, 0x6d5d7513, 0x625e305b, 0xf7aabd4d, 0xaf5c5a14, 0x697de024,
- 0x764de7ed, 0xb4460efc, 0x43c6a03d, 0xc6a5bd54, 0xa4bb544d, 0x1fe3c1c2,
- 0x7bfced33, 0x69f6153d, 0xb20fdfa4, 0xaff21aae, 0x226d3b30, 0x19fd0ab1,
- 0xe4fb5add, 0x4657bf3a, 0x9eda2a3b, 0x45334da8, 0x7abd07d9, 0x1715df94,
- 0xfe54fdb5, 0xc454acf8, 0x17795451, 0xcf9a4765, 0xbb40499f, 0x670bedeb,
- 0x8d142e28, 0x5c2eeb9f, 0xaebd9fde, 0x83f74f5d, 0xb7ad71d1, 0xfdd2e42f,
- 0x1baf11a0, 0xcccad4c1, 0x808cc43f, 0x6b7b4c97, 0x18ec1195, 0xf82983a3,
- 0x58fc36dd, 0x8d0dc633, 0x7c9c7817, 0xd7fb9d84, 0x2fc18b89, 0x95335185,
- 0x78c17da0, 0xef48ce7c, 0xef5d99d3, 0x09bdbd91, 0x9e2186ea, 0xa6199ec7,
- 0x5307118b, 0xc08a63cf, 0xb7e66eef, 0x4d81efe3, 0xf7f78bb1, 0x59db462e,
- 0xa22d3cfc, 0x2d62e27f, 0x3ce22d3e, 0x435b8327, 0xd3ec79df, 0xe7116f3e,
- 0xfb1a596b, 0x63a3ec1c, 0x7aa2439f, 0xc5b6130e, 0x596c39e1, 0x758a4dbc,
- 0x2f8b990e, 0x845b0e7f, 0xefd2a95f, 0xb204acb4, 0xe8a6f7af, 0x7b41fbe8,
- 0xcb59c313, 0xb2fdfe31, 0xaccfde99, 0xb4367110, 0x6b9f10a4, 0x84bf97b7,
- 0xa371db71, 0x7b8e74f5, 0xbcffd125, 0x60feff8e, 0x1fea78cf, 0xf883b327,
- 0xfb0780bb, 0x1bbbe9aa, 0xd3bbfcd1, 0x33dd007a, 0x3db9ceb6, 0x839c016b,
- 0x9980fb25, 0xcf839bfb, 0x4a3fef07, 0x7b4bbe05, 0xa654b9f8, 0xbda3d49d,
- 0xec66f25e, 0x8fe351f3, 0x3a9da47b, 0xaa362b20, 0x98fc8baf, 0xeca33b91,
- 0x642db3e9, 0x47c65b67, 0x39c0f7d5, 0x9f8ebdd1, 0xa1d916ec, 0x87ebaf3d,
- 0x114aa738, 0x7d7f3087, 0xfb65e28a, 0x7e714efa, 0x25c6d1e9, 0xfe5df727,
- 0xe7135e9c, 0xa1c453b4, 0x00e22e7e, 0x7e7fc29d, 0xf2a4e023, 0xea9b80cd,
- 0x04280adf, 0x0b940aef, 0x77cfc161, 0x47cb3e56, 0x84aaaf17, 0xcf47edfb,
- 0x7f7dbf73, 0xbe83a862, 0x42de74ef, 0xbda417df, 0xdbbf144d, 0x2c727c07,
- 0x1fbf49ce, 0x4cdb3478, 0xa5a3b3f1, 0x8a7bfbbf, 0xd16b7cbb, 0xc70bb8f1,
- 0xeb4e7ab3, 0x6f184e70, 0xee8b855d, 0x47e036a5, 0xeeffa114, 0xffbe8932,
- 0x040e1b34, 0x3a5445ef, 0xf169f537, 0x65ff0f59, 0x1ddff195, 0x617f42c8,
- 0xa4e88b8c, 0x2273ef42, 0x4fba373e, 0x571e5f91, 0x871beed8, 0x7af18071,
- 0x14fbbe26, 0x3bac4534, 0xe0426f0e, 0x44895379, 0x0a1a73df, 0x86e5d1bf,
- 0xa32fae54, 0x3475ffeb, 0xdd1b83d7, 0x773ce8db, 0x50b2ba3b, 0xf913efaf,
- 0x2964b310, 0x285fbf48, 0x1cb1dd77, 0x65915bf6, 0xc011bb1f, 0x6853a32d,
- 0x4f4afbfd, 0xd8f81c53, 0x21c65785, 0x76b31dfd, 0x79ce305a, 0x53dfc9cc,
- 0xf9951387, 0xf29db77b, 0xa4f2312d, 0xe958f2d5, 0x95fdfa22, 0xef7cfc7f,
- 0xdf7cd1da, 0x0af5524c, 0xfb815b8c, 0xdef9424d, 0xc3f902b2, 0xfc83b998,
- 0xaa73e8cc, 0x88b35f70, 0xfc64f3de, 0xb6bf4f7b, 0x3f782c86, 0x0267ed1c,
- 0xff426c7d, 0x3d04f778, 0x5eadaf7d, 0xe782e7e6, 0x1fa4e788, 0x997e13a3,
- 0x65667c76, 0xc0fa633e, 0xde1d6079, 0xf13ad0d7, 0xadefaa3e, 0xf86292bf,
- 0xc9d683b5, 0xf9589efc, 0xcdcfd1b0, 0x9a20b276, 0x1615b386, 0x709fa176,
- 0x99c69f30, 0xcce3e56d, 0x9b7c7112, 0x1759ffa0, 0x81df9475, 0xcf80d6f4,
- 0x7927cc95, 0x50f5cc72, 0xb7ac1d57, 0x41c6ce1e, 0x569346fe, 0x5b39090e,
- 0xf745525f, 0x07dcc7bd, 0xbfbea3c6, 0xe1e574be, 0x9fc22732, 0xb74154d4,
- 0xd52fa529, 0x945a5d20, 0x4c2f8a2e, 0x5d74cb76, 0x36b97d78, 0x17afd14e,
- 0xb44bf4a3, 0x928fa8be, 0x54f7113b, 0xf9c4434e, 0x4b9f72cf, 0xab83a488,
- 0x2f1ccbc7, 0xd67baf7e, 0x1da71e05, 0xe9f7978c, 0x7803a573, 0xd8ef3e89,
- 0xa73e8978, 0xeaad3c01, 0x8c1dcbaa, 0xbf6f155f, 0x1ac9792e, 0x8d1be799,
- 0xaf8a1fb7, 0x4156d1e6, 0x579e5caf, 0x3b7dbe08, 0xb771443b, 0xeff94bb7,
- 0xff731d4b, 0xb3bfe296, 0x0d63a858, 0xcbe045ca, 0xe8f94239, 0x344ce423,
- 0xf4f8061e, 0xbf2e283f, 0x28b7f3fb, 0x21caaa2e, 0xea25f213, 0xea1fc113,
- 0x1f9099b9, 0xf02f6f91, 0x2d5e87ef, 0x457ca87f, 0x383f21eb, 0x1fcc8fa4,
- 0x5fc5dffc, 0x18cd717b, 0x52167617, 0xd1cab83c, 0xac7bc7a5, 0x3dd250c9,
- 0xd27f8892, 0xf5919c3a, 0x591c6e3c, 0xa12f714f, 0xa6b8d4f7, 0xbb3ebeda,
- 0x5518412b, 0xc24d47a4, 0xc4fd51de, 0x64538e7d, 0x54faaa7f, 0x57fef716,
- 0x08f74fab, 0xfb543a7d, 0x79bb73de, 0x43cbe7dc, 0x1c800f3d, 0xa46f9c9f,
- 0x0e4cb8ef, 0xa3dfcc3f, 0xfe498470, 0x9137746f, 0x69fb0c1f, 0xe604a346,
- 0xf3e64475, 0xf3bee5a9, 0xefd60a6d, 0x0af4bb95, 0x16ff07f5, 0x568603e0,
- 0x0d869dfa, 0x137d738f, 0xd651f457, 0xba83dee5, 0xe6994fb3, 0x61efc24a,
- 0xdf835f6f, 0x8c2a0b01, 0xb598ebbe, 0xee458bb4, 0xdc31a5f7, 0xff9c9daf,
- 0x68071dd6, 0x69ea1fdd, 0x035768dd, 0x9d964f9d, 0xcfe7050e, 0xfd23dbf6,
- 0xf7d97dec, 0xb7009dda, 0x086c697c, 0xa3c37ad1, 0xecf3017e, 0x078d5733,
- 0x73ed8d4b, 0x0bf5181f, 0x7346c7c0, 0xa3cc04d5, 0xdbdfb6ac, 0xdae51f3e,
- 0x60265bd9, 0xbcec1bfc, 0x83b7d456, 0xcdb7dff6, 0x5d3bbf8c, 0xd69f78ed,
- 0xabafa231, 0x5abfbf06, 0x48f7e0ed, 0x87bed1be, 0x7b404cc6, 0x73c1ec39,
- 0x0c9f344f, 0x164cdd22, 0x2f1765eb, 0xbd41fc51, 0x9e73d997, 0xf8ff47d3,
- 0x8fb80f40, 0x455cbf6b, 0x7db922f7, 0xa026f9ba, 0x3c7d75d5, 0xf1db0c7f,
- 0xbf58e07b, 0x001d8628, 0x4be75cf3, 0xcaebf3c6, 0xde8637ba, 0x36fbedcd,
- 0xf6e783e0, 0x44bc7064, 0xc31e6fb7, 0xafb882ed, 0x9272cfde, 0x7ff5c03d,
- 0xf312c0b0, 0xa9b7553b, 0x3b1ad2fa, 0x552d450f, 0x23daa579, 0x21b35f80,
- 0xc69bbf02, 0x7cfdff70, 0xf103a7a9, 0x7fe77df7, 0xe50b710a, 0xf6cf52f1,
- 0xae91c331, 0x97ad5f04, 0xee01c663, 0xc5a3f31c, 0x13416e2b, 0x73beabef,
- 0x86e96fe9, 0x7441dba6, 0xf8e95065, 0xffe3a221, 0xe27bf48b, 0x20efd0fb,
- 0x14fe7479, 0xd347c3dd, 0x03bf4ab1, 0x9be6c874, 0x79e80692, 0x7ec1ba28,
- 0xe806928b, 0xfb7ea87a, 0x931fbfce, 0xe9c607de, 0xabdd2cbd, 0xd059b7f4,
- 0x540f7a91, 0xfd79ce29, 0xfeec8cd7, 0xf5463da3, 0x7e35c677, 0xca3fe811,
- 0x72b0aea3, 0x37b47fb9, 0x3d19fb97, 0x9a9fba66, 0xbe295ee9, 0x235d0dbb,
- 0xf211adc6, 0x75dba67e, 0xeaaf3959, 0xfddf550b, 0x43777c4f, 0x00800098,
- 0x00000000, 0x00088b1f, 0x00000000, 0x7dedff00, 0xc754740b, 0xeebd6095,
- 0x91a93fd7, 0x16883e9e, 0xc085a092, 0xeb404616, 0x7d3d05ff, 0xa71f3210,
- 0x900b18c1, 0x04e08b4c, 0x60dd491b, 0x9e3d90e2, 0x123231a1, 0x1f62cd9f,
- 0xbd6678cc, 0x8c030d39, 0xc077b19d, 0x0b611c56, 0x3837e2dc, 0x71c6ec4b,
- 0x3c4c9c18, 0x6c0843c2, 0xc718d36c, 0xbc4ab243, 0x0f7adef7, 0x0b756bf5,
- 0xcceb43db, 0x40e75764, 0xaabd5ea9, 0xfeeb75ba, 0x7ad3d56f, 0xcecc6333,
- 0x53f817d8, 0x08acbc3d, 0x65cb191a, 0xfc05f3f4, 0xebf2e2db, 0xdf632b25,
- 0xb4cbeeb9, 0x2c93f943, 0x1e670adf, 0x355faf63, 0xb188acca, 0xf6e3a9ae,
- 0xfa87b3ea, 0x8c08758f, 0x127b4315, 0xef768674, 0x0077c154, 0x27d1311e,
- 0x7d1e9d2e, 0xfd4c9fde, 0x8795cdae, 0x9d32fab3, 0xaf7a6863, 0x59b18d3e,
- 0xca0e9bf8, 0x332d9320, 0x5aedcca0, 0xcca012c7, 0x9636f92c, 0xb12e624c,
- 0xf2933184, 0x6bcae99e, 0x39f015df, 0xfe831993, 0x56f595eb, 0x0d5d7f30,
- 0xcccf31c0, 0x3889f1bc, 0xc9c9d37a, 0x97cd5ed0, 0xd769e30a, 0xfe9fde1d,
- 0xe4f329a5, 0x572e3630, 0xfbcdf5a0, 0xf04cf98c, 0xeb6e756b, 0xe7033602,
- 0xd1cc7187, 0x1e60a9c7, 0x1d01e999, 0x2adb5ee5, 0xaa6b3fe8, 0xafe5e1c9,
- 0x6cdef84b, 0x3e1bdfc6, 0x4ac67ace, 0xe2d9c686, 0x54fac809, 0x4c498ec6,
- 0x6f5b2fe9, 0xf8e767c1, 0xb2857ac3, 0xcd6e533e, 0xebcbc455, 0x07e1c792,
- 0x860f6778, 0xcb1d6f8d, 0x55633a58, 0x8b9f699f, 0x387d6d0e, 0x58fb305c,
- 0x5f4fe5fa, 0x33467cc0, 0x5d398fc7, 0x5d79f847, 0x3e90fa32, 0xeed4ae2a,
- 0x4b189362, 0xfc87ec96, 0x992adcf0, 0x36053e1d, 0x7e53f633, 0x0402b8af,
- 0xc29fed04, 0x738014bf, 0x5aef6e9b, 0x16ddd027, 0xa21f4c6c, 0x4c0b2597,
- 0x2e96381a, 0x9bd4d449, 0xea69c79a, 0xd44f57cb, 0xdb736fec, 0x43fa9add,
- 0xea6a661b, 0x354a27ae, 0xd59d55f5, 0xef56f19a, 0xff69ab9c, 0x686feed6,
- 0x7f9e6bea, 0x747f5350, 0xe911caff, 0x885f1a22, 0x89e991b6, 0xd23b0579,
- 0x3a4d88bf, 0x9cc5cffc, 0xf7f7a3d3, 0x7ec27f21, 0xb7af6ebd, 0xd5fe82ad,
- 0xe78d3f57, 0xc5f4b4fd, 0xf90072bc, 0x17d956a3, 0x402bc798, 0xad528d7b,
- 0xf445be95, 0x4536635e, 0xee951be4, 0x11560ab6, 0xda66afc7, 0x6db0aafd,
- 0x7e47aebd, 0xebd01a2e, 0x3759be61, 0x2157fcb5, 0xc706fc35, 0xc7afcc67,
- 0xa5cb84f5, 0x9318eeff, 0x609e397a, 0xfc017fb5, 0x8cc9acc4, 0xa3c74795,
- 0x5db7a74a, 0x6f5f6337, 0xeafccadd, 0xa0582b7a, 0xda3ee90e, 0xfc3b67ba,
- 0x516b927a, 0x5ebe1dd6, 0x6feffe15, 0xef815f86, 0xf323ff5f, 0xdb1013ed,
- 0xe6fc88b2, 0xcfeb5ddf, 0x02402bb5, 0x7a1527bc, 0x278291a8, 0x0e908b12,
- 0x83650398, 0x51f99071, 0xc133d40e, 0x9652846f, 0x38af041c, 0x3034ef68,
- 0x7e71eb2a, 0xa6861071, 0x35eb45d2, 0x288dca0e, 0xa92c456f, 0xebc79cee,
- 0x875e068e, 0xd52ea8f7, 0x3ee7baf2, 0xea92875e, 0x43af275e, 0x5aefaa3f,
- 0xb8cef58c, 0x014489c0, 0x5825beeb, 0x5a1e0e37, 0x05ff4bca, 0xe4994a81,
- 0x5de83896, 0xec7ea7a7, 0x3707af22, 0xf2d0fa71, 0xf65e3183, 0x5f19b3f9,
- 0x813f3c3d, 0xfdc24dbf, 0x006fd75c, 0x828ad43c, 0xd5ef0ec3, 0x3f87320c,
- 0xe4d5f715, 0xe097d990, 0x3133a033, 0x8ccf886d, 0x4ab1982c, 0x0f793e20,
- 0xedcaadf1, 0xe968e3e1, 0x5af51eab, 0xfc3bec01, 0xe51931be, 0xfaa7a730,
- 0x2c12e0b2, 0xd013f9f1, 0xfc327b3e, 0x1f4e1e4b, 0x32a25c2a, 0x5fb5a55f,
- 0x32b6aa8f, 0x59b72618, 0x8559d117, 0xd92c9d79, 0x716dcb87, 0x2e2fe550,
- 0x56e1c22f, 0x1f39ade5, 0xfb1a6cf8, 0xb9967c3a, 0xaeb36a0a, 0xd9f0abbe,
- 0x933e30ba, 0x8496f7ad, 0x321019f0, 0xb7d9f0d3, 0x276e9e89, 0x83094e5f,
- 0x4f182675, 0x23e80cf6, 0xc05499ca, 0x3e244243, 0xb21bfb9b, 0x97c8a21f,
- 0x5817f037, 0x987e6e67, 0x5cf4519c, 0xfee7aab5, 0xdda2b3a8, 0x117a67e2,
- 0xc87c70cb, 0xd2313b2c, 0xbe3cb573, 0x6bba0609, 0x90f80ea8, 0x63be810f,
- 0x06dc151f, 0xcec99bcf, 0x805ab862, 0x31e2aac7, 0x71ad6e8c, 0xec909d2f,
- 0xecf505bc, 0x4e6e8518, 0xdf11a766, 0xc7bd76c3, 0xb59de442, 0x01f1cbe8,
- 0xc70937cd, 0xbf226673, 0xc6db40d5, 0x33fde182, 0x99f00fb1, 0x3e7cc835,
- 0x08eacf78, 0x46af5808, 0xf48d9efd, 0xfe51eacf, 0xe8095f57, 0xe5a5ea25,
- 0x00745b97, 0xa4013fbf, 0x517c8b57, 0x642e9c30, 0x7ee3d3e6, 0xaffdd57c,
- 0x90341fb6, 0xffdb0ebc, 0xcfb0419a, 0xd5394e00, 0x1afa20e4, 0xc8cf6464,
- 0x48c7c14e, 0xbc21acbe, 0xade3f6a8, 0x176826f6, 0x622e91e8, 0xf640b37b,
- 0xb36ca7d0, 0xf305f381, 0x867a55fa, 0x30afcbe7, 0x34ed1139, 0x7ed4f3cb,
- 0xfa23136c, 0x3c97b6a8, 0xb8476755, 0x44cc7606, 0x0abd24b8, 0xc7153f97,
- 0x70e260bd, 0x7f08daf9, 0xe4fe0ad5, 0x43331d41, 0x694fbfbb, 0xff5fa30f,
- 0xfcd3b720, 0x702bc44f, 0x43f0c8dd, 0x4ed007bf, 0xe5689306, 0x43ff03dd,
- 0x69dcf784, 0x01df3f77, 0xf028ae5d, 0x6e856ffc, 0x5124da3f, 0xf5cd3eb9,
- 0xc7a07cfd, 0x7c6e917f, 0x0fc866e2, 0xd5f74439, 0x9027cff6, 0xd9f1521e,
- 0x10f48637, 0xe8f84dc2, 0xdb8344b3, 0x387510aa, 0xe5bf0abc, 0x2a57c88c,
- 0x577c2a9c, 0x0bab7a7c, 0xe7b37bc6, 0xf61c135f, 0x454bf821, 0xfb847ee7,
- 0x674fc1cd, 0x92ef88b8, 0x34667635, 0xfc5266f9, 0x964ca488, 0x3ea2a62b,
- 0x85cc7388, 0x74cb8c75, 0x364cbad1, 0x02fd1da3, 0xf393274b, 0x82734860,
- 0xf7f08ccf, 0xd2ec37a7, 0xa9d6fb43, 0xfbc13322, 0x36bcb35b, 0x09fea75a,
- 0x9399eb86, 0xd60361e9, 0x6577f3e8, 0x9c11293e, 0xbf475083, 0xa2f1c6c7,
- 0xf8f4689f, 0xc75fb9e0, 0xc10a1cd6, 0xee02c1cb, 0xe7cd9d8f, 0x1e17dae5,
- 0x842976d9, 0xad0fda3f, 0xbdddd4d3, 0x2976dbdf, 0x106ede54, 0x3697dc44,
- 0xd9db8e85, 0x5ff404c0, 0xe13b455a, 0x903743a1, 0x2c6bf586, 0xae0a7e78,
- 0x008fe70f, 0x5be73fff, 0xd2ff3d62, 0x8ff650a9, 0xff69fee1, 0x0df91f24,
- 0x2b1ffcea, 0x5f38ffeb, 0xa6387317, 0xb3ba1e01, 0x9f70c5bf, 0x3f7c6c6a,
- 0x7a72504d, 0xf54372e6, 0x739e8677, 0x3ea55179, 0x73de3a0f, 0x1ce91d12,
- 0x994c76a8, 0x7de911f6, 0x71bbd227, 0x48b5bea8, 0xf08be8d7, 0x220573fe,
- 0x16c07bc1, 0xa15b3db9, 0x5c139d97, 0xdfe8d9dd, 0x6c73ab3f, 0xcbce2586,
- 0xe51e3adc, 0x7adb56fd, 0xe2e653a2, 0x38c058eb, 0xf4cbcebf, 0xd1e81978,
- 0x82b7fe79, 0x8dd62a42, 0xf886c2cc, 0xe70bf557, 0x01d13e89, 0xd7f2bbfd,
- 0x5ddd7199, 0x1c66f5b6, 0x82d684cf, 0xea3c386e, 0xe6ec0fba, 0xf4cbcef3,
- 0xb2e9e089, 0xc57bb9b9, 0xa33fa801, 0xee5e7bac, 0x6aaf6a3a, 0x09149ff4,
- 0x4367e07f, 0xf568e8dd, 0x87263ce2, 0x3ac246bd, 0xb2c66c73, 0xec89784f,
- 0x0dbf5513, 0x9dad4fe9, 0x91bafa72, 0x15d763e4, 0xf244cf9d, 0x07305e53,
- 0xbcaf9fde, 0x7b720d6d, 0xa3bf6bbe, 0x1cf7c45f, 0xf3e3f902, 0x764dbf73,
- 0x2e77359d, 0x56b3e7b7, 0x98549179, 0x3fa1f04f, 0x5bc54f31, 0x195f569e,
- 0xa0b7171d, 0xd4de30fa, 0x2c59d1ea, 0x2abe90c0, 0x70f3fcc2, 0x40bb3b7d,
- 0x5972d7b1, 0x2d2bda31, 0xc863df26, 0x420d960f, 0xe2a1c23a, 0x8e814575,
- 0x7c8620e8, 0x942667b0, 0xb465d95d, 0xd3ccfaaf, 0x5f980417, 0x4366df17,
- 0x8cdbd0be, 0xb31bc47e, 0xa80d1f8a, 0xffc24df3, 0xb7b22533, 0x2f848eb0,
- 0xfc79397d, 0x86c7966e, 0xb032eceb, 0xa7f248a6, 0xfdf380b6, 0x927e5907,
- 0x8ddad10f, 0x7bd2041b, 0x66377caa, 0xc237d932, 0x5c8cdb78, 0xd25f80ce,
- 0x3ebf402b, 0xffa017a4, 0xf7b35a17, 0x7ba205e9, 0xadf1e519, 0x12efb152,
- 0xfe1fb90b, 0xca898166, 0x547eca93, 0xc336717f, 0xaffc8235, 0x8430f2aa,
- 0xc7ca94df, 0xf1f26533, 0x732f224c, 0x2e3f7195, 0x5cdc7ce2, 0x5fb97b14,
- 0xfb7a339a, 0x8d7a4b1c, 0x90285287, 0x98dd79e8, 0xc52e4987, 0xa3396f12,
- 0x5da33788, 0xa7073fa1, 0x73fdb513, 0xaaffde45, 0xb274e620, 0xe51472b4,
- 0xa4e92c41, 0xde83cfe2, 0x79ff97cf, 0x68da47ec, 0x99a3e3ae, 0xe042d4f2,
- 0x2e9cbf93, 0x96e583df, 0xbbdb23d7, 0x772f63f3, 0x72801ed3, 0x37df04f1,
- 0x79b3e923, 0xfb97b185, 0x48bed14b, 0xf845f6e1, 0x3d15cbfc, 0xd2794b14,
- 0x11b36504, 0xff011fd6, 0xfcc28e8f, 0xef5073cb, 0xe5817b72, 0x0fa4b99e,
- 0x67e1dfb1, 0x3ec42eb2, 0x1c147b06, 0x0543b441, 0xeddd9239, 0x2d7efd8d,
- 0x643f487d, 0x5c61ccaf, 0x2ff3a81f, 0x7af8e12c, 0xb0e0147a, 0x25eade00,
- 0xc29baf6e, 0xbfcb50e0, 0x7dbd8c2d, 0xe043e92a, 0x1fbb0548, 0x444205cb,
- 0xd0a7af7b, 0x1a7e7318, 0xe2d9780b, 0xe4918d60, 0xefd8c9c9, 0xca0d9a4b,
- 0xd3cee9aa, 0x4b96d728, 0x5c60e787, 0x1ff8fbf9, 0x79d21be6, 0xc1a561be,
- 0xaeff45e5, 0xbc3bb24b, 0xac478c76, 0x7ccafaa2, 0x52af43bb, 0x94dfb63e,
- 0x6c05db7c, 0xe57d51d7, 0xda1f24ef, 0xd617dfc3, 0xf1c6c99d, 0xfb1deb36,
- 0x959dc618, 0xe78d837c, 0x9e36ac1b, 0x3c6d109f, 0x29b560ef, 0xcf1b0779,
- 0x4a6d583b, 0xf3c6c1de, 0x929b560e, 0xbcf1b077, 0xe4a6d583, 0xef3c6c1d,
- 0x7929b560, 0x3bcf1b07, 0xde6a6d58, 0x1538d3c1, 0x9e3691e3, 0x78dab077,
- 0xe36ac1de, 0x97980779, 0x3c6c1de7, 0xf17000ef, 0x722d83bc, 0x943ac1de,
- 0xf1ff2077, 0x67a49618, 0x547f5fb8, 0x7b06cfa9, 0x786334dd, 0xe76ab55e,
- 0x17182dfe, 0xfc7209ab, 0x5e783955, 0x77b414d9, 0x457e300a, 0x04dfb066,
- 0x114565fe, 0xb0d5f0c3, 0x13f3c3f9, 0xbde7d9dd, 0xb0a3fa02, 0x03bc2997,
- 0x18ea29e5, 0xfe7c3f7f, 0x3b577161, 0x65d6e78f, 0x3bf08b7e, 0x78482cbb,
- 0x8718e7c3, 0x13f253ad, 0xffad56b5, 0xb2e67f2a, 0x995f71f9, 0xf80899d4,
- 0xbb6d4590, 0x8c2ff988, 0xd7f15ebb, 0x6ab7dc61, 0x15771b50, 0xb8d41b33,
- 0x844bcf3c, 0xe1df39c1, 0x6b045f1c, 0x2a7f016a, 0xc1cfe601, 0x53ae15a4,
- 0xa45e7c12, 0x881bddb7, 0x453bbcbe, 0xaa6814c7, 0x9e606404, 0x6a2012a5,
- 0xc654d286, 0xf24cd2ac, 0xfe9d389b, 0xf1bdd4d7, 0x030f28d9, 0x6c04467a,
- 0xf9a83c23, 0xbf580485, 0x2bfc8334, 0x332aeff2, 0x3a47bffd, 0xcc82eb50,
- 0x5d8238f3, 0x2f80cd62, 0x5c266ef9, 0xceab9336, 0x45eb6f90, 0x73c335e6,
- 0x9b37e941, 0x2d4e2905, 0x76f28933, 0x6541ccb5, 0x695774d1, 0xcea3f011,
- 0x7ae175ec, 0x0966ecaa, 0xee3d85f9, 0xf148db3c, 0x32e97ae4, 0xf60049e0,
- 0x48da62f8, 0x2ec88a76, 0x451cf8ab, 0x2f1f48bb, 0xadc92278, 0x61ebd88a,
- 0x0a2a83b2, 0x2dc7c919, 0x7cfcb22c, 0xcfcb84ac, 0xdf5d4b37, 0xfbd73c44,
- 0x878fd516, 0xd0be8f2e, 0x6d9b794a, 0x5bc2f161, 0x6f628afd, 0x90e72447,
- 0xe901b93d, 0x8f04f17a, 0x1688e10d, 0xf62a78c7, 0x1b49ecf0, 0x767baec1,
- 0xd45aec14, 0x2aecb743, 0xfa9399fb, 0xb1ca3b50, 0xd0ba4f0e, 0x9092baef,
- 0xc3ddaa38, 0x8d67143c, 0x6979af1c, 0x9920e214, 0xfe13bfa8, 0xea639d0b,
- 0x87fb023a, 0x54bcfbe5, 0x428ef8e1, 0x634be387, 0xa0d317cf, 0x613e27d4,
- 0x771b8d0b, 0x970e0459, 0xf5c0d041, 0xfdff62b9, 0x78f624a0, 0x7d72812a,
- 0xf22efca9, 0xf974d561, 0x7caa5867, 0xbae1df3b, 0x2d29fc40, 0xf9024faa,
- 0x767f66bc, 0x0689ea01, 0x2ae35edb, 0x52d5f780, 0x3a22fdf9, 0x5b1ff46f,
- 0x1eb16e1e, 0xf7bc478f, 0xa3cb22b9, 0xc50911bb, 0x28de4fe4, 0x67e4fee2,
- 0xfe288784, 0x638bafe4, 0xea7b2fbe, 0xc9fc8673, 0x5b1ffe70, 0x639de3cc,
- 0x068e0147, 0xf1465728, 0xc28ca6eb, 0xbf5a8dfc, 0x443ebf6e, 0x854110ce,
- 0xdc6c69e6, 0xfc1163af, 0xba35973d, 0x147b37bf, 0xf310b1d6, 0xf591b571,
- 0x31c57dda, 0x7e96aff7, 0x3307ca03, 0xd0a9fd5b, 0x6f30bcc4, 0xb2be50da,
- 0x0fafd5c9, 0x383f738d, 0xe537e0e1, 0xb37e7008, 0xf272e638, 0xf91e9c7c,
- 0xe119bd75, 0x7e066ae9, 0x255fb08d, 0x9bffdc25, 0x9611e13b, 0x3a637688,
- 0xe411f743, 0x3637cf09, 0x83637e29, 0x2a767fa2, 0x2c53d472, 0xe52ce952,
- 0xe851b9f5, 0xfbcad7fa, 0xb69c4a8d, 0x2bf26251, 0xec7ff491, 0x38fce6e9,
- 0x71c6e728, 0xf30def38, 0xf453dfcf, 0xd3d89ec4, 0xa00c9ecf, 0x91b5b993,
- 0xf63075f1, 0x0274b174, 0xf6d4bfcc, 0xf8901cf4, 0x0d9b2fb0, 0x2e9c5f94,
- 0xef0c58bf, 0x57c28b6d, 0x69782b9f, 0xb03a3e86, 0x34a05bfb, 0x9010f942,
- 0xfa405481, 0x6fec55ed, 0x14308e01, 0xf1de0420, 0x3af4e7e8, 0xce7c1ee4,
- 0x7fe46d5c, 0xca1bc884, 0x3999569f, 0x83a774df, 0x0efe88ff, 0x9339d333,
- 0x9fcf20ae, 0xfcf26576, 0x6a3c3868, 0x456ff4fe, 0x71cf198f, 0xc4166577,
- 0xebddf285, 0x6f26989b, 0xe78575dc, 0x8a4fc185, 0xc949fad3, 0x8f8527e4,
- 0x74b9909f, 0x247fa85e, 0x021fdcc8, 0x5c50267f, 0xa917e43c, 0x7c98cffe,
- 0x7ff15cf9, 0xcd1dfd02, 0x4947119f, 0x07308b0f, 0x74ddff3e, 0x8f10dff9,
- 0x1fd3d023, 0x9fd3d0a3, 0x347fdfb0, 0x11cc627a, 0xf0cc68b7, 0x1eb2bb71,
- 0x708eb5b7, 0xd321203f, 0x54ce9119, 0x9b7a02fa, 0xe8763250, 0xb4f3217d,
- 0x4b136f4a, 0xbd3ebf8a, 0xf0bec05d, 0xafe1acef, 0xd149d6ec, 0x7ab59dfb,
- 0xfa0f28cc, 0xf19bd732, 0x99d4c49e, 0x6bce072e, 0x006c9911, 0x3e5cbb38,
- 0x007b9e33, 0x64bf2f3b, 0xcdc1bc84, 0x7e3f2e22, 0xdcffecad, 0x2aff9c09,
- 0x7dbe0b96, 0x6c4d7fc0, 0x4df70197, 0x4958ff7d, 0x7b88fdec, 0x35ee4872,
- 0xf7208c96, 0xe2f8565e, 0x2b5f0573, 0xe729d6da, 0xfb445899, 0xfdec5567,
- 0x942b348c, 0x45d75273, 0x745be3a4, 0x2285e787, 0xe21467ac, 0xe4c7e7e0,
- 0xcd4c3ce0, 0xfc406d2b, 0xf1c4563e, 0x7dfecd17, 0xb3fc146a, 0x4ad70089,
- 0xfd0199f6, 0xc7ff5969, 0x11e748ac, 0x39d9158e, 0x0390069c, 0x5995df80,
- 0xfc31b7ba, 0xb5a495d9, 0x67f7d487, 0x67aefe2b, 0x5267e414, 0xf1c3ce0e,
- 0x4c0e7e1a, 0x3ec5cf2d, 0x88b4b01e, 0x80ffb9fb, 0x73fc0efc, 0xe358a4a8,
- 0x64a8fee7, 0xb5f73f64, 0x1adc8f7f, 0xcba8e850, 0x7d9ed911, 0x40fbf621,
- 0xdd60e0e7, 0xb9157cef, 0xaa6f6e11, 0xdbd89ee5, 0x7a59697b, 0xd1c3879c,
- 0x24e7b4c8, 0x28dff16e, 0x8f5d2de0, 0x77e968f3, 0x5ffae325, 0x1a58c385,
- 0xe78c73f3, 0xff31e867, 0x7d79f9c3, 0x94be2ba9, 0x198f36ec, 0x07d837f5,
- 0xb95f6714, 0xcd1f2539, 0x6b67d82a, 0x93be96a9, 0xefa6474a, 0x403bd2e4,
- 0xfc9caadf, 0x534c6117, 0xa899bca8, 0xa5699bc8, 0x29afdfb1, 0x8e48af18,
- 0x632baf2c, 0x73dbe71f, 0x79744e77, 0xfb379eac, 0x4f1b4147, 0x8f25bd6e,
- 0x69474e63, 0x7921faa9, 0x7087eaac, 0x5e868d3c, 0x0bd10c48, 0xcce4510d,
- 0x3631c068, 0x9db51f04, 0x98afe502, 0xc0a6f98d, 0x39d89daf, 0x96c7dee4,
- 0x4f138851, 0xc87f8d0f, 0xa047af60, 0xb1a5dde3, 0xbca37fcf, 0xdb7c37e9,
- 0x47f9d236, 0x28c5d5a3, 0x3173623f, 0xb19fec3b, 0xf6f295b3, 0x94ad05c6,
- 0x029d6687, 0xf498fde5, 0xab79f92e, 0x30a7de6c, 0x9e5c367d, 0x5e398d6c,
- 0x97d8728b, 0x28c537f6, 0xf8ebcd7e, 0x37f93a4a, 0x153ca3af, 0xb347ee24,
- 0xf74ecc0d, 0xb97cafa4, 0x202f58fb, 0x9a2f3012, 0x763ee8c4, 0x7ac7e1a7,
- 0x051b47cc, 0xe65cfe3e, 0x974ff9e7, 0xf0a3fc77, 0x31a0e59e, 0x7f543b7f,
- 0xfb4d9a51, 0xcfe569de, 0xf39bf6bb, 0x9ea5849f, 0xc19e15b6, 0xa753e1f3,
- 0xec1c5327, 0x6b8f03c5, 0xbc5aecec, 0xdf7e80c7, 0x7e861e0b, 0x35d329a2,
- 0x9c3b2471, 0xae927f31, 0xa89a508c, 0xfa5e7a94, 0xf86d9d05, 0xf7f73bfb,
- 0xbd67e848, 0x724cc078, 0x9e81ea7f, 0xe32155f8, 0x3e719627, 0xfe3d06b6,
- 0x35af0019, 0x093273d3, 0xf92b1def, 0xce799173, 0x632bc2d4, 0x0f9d00a4,
- 0x6b5791df, 0x2ebba50e, 0x794cd6a9, 0x639d5ce4, 0xfceb1d8a, 0xf4fc431c,
- 0x4082fdda, 0x112edd7e, 0xe19aef50, 0xec7a86ba, 0xc3eb890d, 0x496b53a9,
- 0xe72a75ab, 0x2de4761e, 0xc7ef8039, 0xf1a7af4f, 0x7b64593b, 0xe5c658cc,
- 0x99068bf0, 0x80f17de6, 0x55c8e748, 0x7c69debc, 0x0f30cbd6, 0xa6dea3e0,
- 0xa7d87ba7, 0xe5114e8d, 0x8134e9d0, 0xdf2d82ed, 0xee8578e9, 0x0288ec99,
- 0xb94a2fef, 0xa96cca9f, 0xf7a77f44, 0x748f2e77, 0xbfa55f7e, 0xa96433c9,
- 0x49c0ed0c, 0xff94269e, 0x36e4b6cc, 0xdf24f17c, 0xe68743bf, 0xcffc03cf,
- 0x227fc17d, 0x6b21f70e, 0xf75c78cf, 0x6a76a507, 0x1f0f45bf, 0xb0f442bd,
- 0xe3efc8c5, 0x8e717578, 0x858eb003, 0xcf1101d6, 0x8352184f, 0x2a6de794,
- 0x8b74f2e3, 0x81630fca, 0x7d3de01f, 0xc507bf06, 0xcea9da26, 0x84270726,
- 0x559ea3de, 0x0597aca6, 0xc2f9f132, 0xd83777f8, 0xf6158c1d, 0xb08b37a6,
- 0xef8985fe, 0x7a86c86e, 0x5e78ef49, 0xb3f778cf, 0xb2b1896c, 0x9f5e0cde,
- 0x9367eef6, 0x9bd15ea0, 0x3095ebc9, 0x9bb078d4, 0xbd9ab37a, 0xa4be3879,
- 0x0f15bf19, 0xfd7f1472, 0x45d26f52, 0x28355f8c, 0x031f87eb, 0xfbece3ce,
- 0xe2ef3a47, 0x78fd5b34, 0x86c9832e, 0x3419f8b0, 0x6077dc85, 0xff2409a9,
- 0xf30bfbd4, 0xf63f7f45, 0x84fd99d7, 0x2759bbdf, 0xad8073d9, 0x7e145fdd,
- 0x5c2e7b79, 0xc8d96dee, 0x8c4e785c, 0xef0966b1, 0xd64c0833, 0x78e3c17d,
- 0x855f9c4e, 0x187f9d47, 0xc8b5b05c, 0x3d70439f, 0x70a8e34f, 0x7937cb5d,
- 0x6b7ade51, 0x0427ae59, 0xe084d74f, 0x456c180f, 0x0f1dacda, 0x1b5d3ee1,
- 0x40209c13, 0x1b7cb93d, 0xb1b5dbed, 0x8e081fc1, 0xef81ba90, 0x096f5b63,
- 0x289763ed, 0x9b9d21b7, 0x216ed68c, 0xb8eeb191, 0xe60c1984, 0xe5d631d9,
- 0x406e7bc5, 0xd8ef7477, 0x1c74659b, 0x8beb3800, 0xc7a1f9b4, 0x83fb3a15,
- 0x98e60f22, 0x01ce7976, 0x047bba5d, 0xdc70f786, 0xa88c3783, 0x5df616ff,
- 0xa4be6234, 0x11a2e7a3, 0xeb03bee9, 0xf3c74e30, 0x6ff988c6, 0xbd5eb963,
- 0x91e74a2f, 0x4f1c4bd6, 0x7aeeb2a7, 0xe9e0152a, 0xbdd02d58, 0x9247f5bc,
- 0x7d7d60e6, 0xb192ae2b, 0xe78755e5, 0x38b4b920, 0x72c29ffb, 0x95381b25,
- 0xccb4240a, 0x10f667a5, 0x4d62b93d, 0xe887b33c, 0x8a4f16c9, 0x1772bea6,
- 0x280cceec, 0xfa686637, 0xeafee531, 0x83f43632, 0x949a98e7, 0xdb665c7d,
- 0xeeb8c019, 0x3bc19732, 0xc2de3210, 0x3262cdbe, 0x1c11edc2, 0xcbd28d74,
- 0xe0ad3fcf, 0x1c52842b, 0xf7cf1f7a, 0xefc40af4, 0xba7a6d1d, 0xcbdcd3c7,
- 0x35e6aeed, 0x202ecf82, 0x0dbdf81e, 0xed40af77, 0xeba7deee, 0x1bef1193,
- 0x47000f00, 0x7d84f8da, 0x9347112c, 0x4ad5dce9, 0xdf775605, 0xb38e0339,
- 0xdd023be2, 0x9bbf5567, 0xb2bfc2a0, 0x91ce91a9, 0xa45e7c01, 0x4d9d754f,
- 0x5ce947f6, 0x9789cad5, 0x6187a80d, 0x3406977d, 0x5bd6d4f8, 0xcafada3c,
- 0xd1fada8d, 0xf29ee532, 0xf90d3634, 0x209978e9, 0xb52439e2, 0xf9d651fe,
- 0xe75ef1b7, 0x0a79d16e, 0xe8cdb3e9, 0x7efa819f, 0xbaa2e8b7, 0x3bcf0eda,
- 0xf89df118, 0xb1f100e1, 0xc5b9fc40, 0xf8354b20, 0x8176973d, 0xb60576e8,
- 0x0f67f3ab, 0xfd754fbd, 0x554dfaf0, 0x1b9c5aee, 0x4730bbe8, 0x90ed0905,
- 0x9316517a, 0x222f88f3, 0xbdf9779e, 0xa36f07c2, 0xeeb803f6, 0x7d852242,
- 0x44feebba, 0xbde6179f, 0x3a56cdeb, 0x215776e7, 0xf91d81d0, 0xd6e7475e,
- 0x2f79e3e6, 0x7903ef28, 0x2ef28168, 0x9226a1fd, 0x128d33ef, 0x9ce577c9,
- 0xe42f2a97, 0xb6e7b517, 0x219e67e6, 0xe7beeb3b, 0xb579d276, 0xc17239c9,
- 0x2d0fa8d3, 0x471dfe7c, 0x1866df04, 0x34ef23a7, 0x3271cfc9, 0x61d72f3f,
- 0x2f68e453, 0xfd7551c8, 0x50e3bfb0, 0x692261ae, 0x9bcd1e41, 0x5da9566e,
- 0xf8283926, 0xffe8756b, 0xdde6538e, 0x75a76d5f, 0x487a3da7, 0x316775c0,
- 0xe60166ef, 0x7c3a82bb, 0x55f950ec, 0xf8b5d7ed, 0x565de80b, 0x5b63b5af,
- 0x65e3d745, 0x6dbb5f30, 0x2dcfc8c0, 0x1fa88d06, 0xdef8e0ee, 0xf2c3e348,
- 0x50ee7475, 0x4730fbe2, 0x7680983f, 0x39a3face, 0xf608d8e3, 0xd3acde8d,
- 0x148311c8, 0xf33791a7, 0x67f2b573, 0x772b43a1, 0xa39651be, 0x4f245f69,
- 0xdfdfb4d3, 0x3fa9a858, 0xbcd4ace0, 0x9d5360ff, 0xcdb26ea6, 0xb16fbcd3,
- 0xe3d4d62f, 0xde6b9773, 0xa558e31f, 0xf5bd3769, 0xed0126a3, 0xc077b371,
- 0x06e87805, 0x1e4b28de, 0x12d323d2, 0xe32865e0, 0x2c562d0a, 0x744df3bb,
- 0x3c7bb64e, 0xec4497e8, 0x773a1dff, 0xc97c4e69, 0xdfe5035c, 0xfc5abe0b,
- 0xc9a00e7e, 0x3ddbf685, 0xf0e3684f, 0x5f38abc7, 0xb94365a9, 0x280ac1eb,
- 0x67b05ef3, 0x81e97bf0, 0xcc7f707b, 0x45db8c71, 0x2ec999af, 0x5376899a,
- 0xb071bf88, 0x397e66ba, 0xbe427bf6, 0xf582f917, 0xbc0a6932, 0x3b08cfb7,
- 0x35ee7a8b, 0xebcbf523, 0xe685d01d, 0xce597ff7, 0xceb3c1e5, 0xfc717bda,
- 0xb2d03e8e, 0x7dcf4fc8, 0xaebf4468, 0x013fafa3, 0xe70cd9f5, 0xcfb44687,
- 0x7a2b9e87, 0x61c60c4e, 0x0e1fe39c, 0x63de23e9, 0xa46e5edd, 0x722b4ff1,
- 0x7a3be5bd, 0xf78b4f3a, 0x864a6b37, 0xe1cb73e4, 0x63ef1fa0, 0x7bf3b4b7,
- 0x368e789b, 0xf9069c92, 0xbca861fc, 0xf41d367d, 0x4f1a4cc1, 0x97960fa3,
- 0x3edee9f9, 0xfbcd6fc8, 0x5c34972b, 0xc8257cc5, 0x4cf3ed71, 0xb1961e7e,
- 0x73fa0301, 0xed35d720, 0xfb95cb1b, 0xde58d39c, 0x2e072017, 0xdbdf2338,
- 0x9f8abb7d, 0xaae0b833, 0x16787da3, 0x47e789f0, 0x3f861d9f, 0xe1dbd78e,
- 0x81a465ed, 0x661bfd90, 0xff7157ff, 0x7228e5ea, 0xbfb2a2fb, 0x014084fb,
- 0x33b7550a, 0x8577e88e, 0xa5ed75b9, 0xcf97dc42, 0xdebfa2b7, 0xee8123f2,
- 0xffb2ffc1, 0xac3b34ad, 0x54f878df, 0x7697de1a, 0x86953a1f, 0x0cdb89f7,
- 0xcf68cdf6, 0x3dd07d03, 0x3f5e8ee4, 0xa87edfc1, 0xb79f1fb0, 0x140e0af7,
- 0xeb9eeec9, 0x364eb40d, 0xa3fd15b0, 0x3ae0517d, 0xabedce58, 0x2a76e5c3,
- 0x13982edd, 0xc98f7ef5, 0x1e9013e7, 0x5c213e40, 0x820fc047, 0xe66dbefa,
- 0xd4f648a6, 0x27df0565, 0xde1919b7, 0xfe836dfb, 0x59d38eb8, 0xbdf88da7,
- 0xb0c39685, 0x71d7012e, 0x1c7881ee, 0xa181837f, 0xf7c2a19d, 0x03e05671,
- 0xabfbff5c, 0x2dcf0c0d, 0x27ad596f, 0x81bfbf7c, 0x87fa27db, 0x0335bd7f,
- 0x2e80cbea, 0x270f3bf1, 0x9d38df56, 0xbfbee301, 0x7569db86, 0x2f881b0f,
- 0x6e13ad97, 0xa50e4bdd, 0xff6e956b, 0x70d3a146, 0xdba70dfa, 0xe6baf461,
- 0xdbebd1eb, 0x90ecb7e5, 0x61f7a819, 0x438ce7ff, 0x731efa3a, 0x1a7e401c,
- 0x0718613c, 0x2ada4f70, 0x63c3c039, 0xa7bef5d3, 0x9c6e50d2, 0x6df9ede0,
- 0x7f2e057b, 0x7d71cbec, 0x8646dd19, 0x2a2e08f7, 0xd95176fb, 0x0a0b3b37,
- 0x62cfc8f1, 0xa9ca1260, 0xf9ce256c, 0x1d35818a, 0xe452ff46, 0x8ffa67f2,
- 0x87b77b6d, 0x2b7fefd0, 0xcaab74e7, 0xe64669c5, 0xf7c56c3a, 0x045f8d0f,
- 0xe06cbce3, 0x282735e7, 0x09c94de3, 0x52822c36, 0xe4e5c157, 0xd438156f,
- 0x3e149ffa, 0x437f2760, 0xe6685cf8, 0xd1b79ff8, 0xf8eb8cdf, 0xbd75c999,
- 0x305fde1c, 0xea1b7ce1, 0x3f49eebd, 0xb9dfe3c9, 0xee1d9073, 0xa27ff056,
- 0x63cf37fc, 0x3532cfee, 0x72d7f68e, 0xe90969f4, 0x68a532d9, 0x30f148dc,
- 0xe66ccdf7, 0xbaba014a, 0x5aa54399, 0xaafc745f, 0x82fc8071, 0x2fc40deb,
- 0xb9e9d337, 0x0553efda, 0x8e46e9ee, 0x4a97d607, 0xb6e41b7a, 0x67921658,
- 0xfaa0f150, 0xfb2996e3, 0x5b1ebf69, 0xcfee28c7, 0x8f84d3d8, 0x84e76d15,
- 0x41e71856, 0x02b06c83, 0x3627cfbe, 0x8534bdad, 0x626c9fb1, 0x3a0b05cc,
- 0x5cccc9bb, 0x6c7d0377, 0xd81ea892, 0xbbfaa364, 0x5e54ec9b, 0xa2c738b6,
- 0xa4e079fe, 0xede20a67, 0x671ed644, 0xed73cc2d, 0x41f081ac, 0xfdf4063b,
- 0x376b4298, 0x0cccf4fa, 0x947a37ed, 0xf028adef, 0x8333743f, 0xfcbe40b9,
- 0x8e83e702, 0x467f1bed, 0xe6b1cf72, 0x49fa037a, 0xb7176df9, 0xf1bddd62,
- 0x5f680d77, 0x04fa007c, 0x7eec0ce9, 0x9e501366, 0x81da339c, 0xa66f9a0e,
- 0xeb2f38d0, 0x77c80d82, 0x430263de, 0xf7a0fcfa, 0xd71c71ba, 0xe12d7457,
- 0xe6744df9, 0x48ad2d9f, 0xfbb8fc22, 0x7f7c75f2, 0xf7a1748b, 0xf9effa29,
- 0x87ee0243, 0x9dfda379, 0x467fec4a, 0xb7af90cf, 0xa41306d7, 0x02f87208,
- 0xa3978b8c, 0x86581d70, 0xbd1937b7, 0x413cf053, 0xe1c74293, 0xfa158bed,
- 0x941b4c04, 0x213229ef, 0xc1239f8d, 0x5258169f, 0x41f93262, 0xe7e038fe,
- 0xabbabe96, 0x811e9622, 0xcff5a87d, 0x762187d8, 0xfc3a347c, 0x437e25b2,
- 0x4329c3e6, 0x4323f475, 0x1fa07fef, 0x82fbe919, 0xe3c9aca6, 0xb9778a46,
- 0x83bec007, 0xc300eafd, 0xf4829ec9, 0x4fca8d3e, 0x91d9748e, 0xc171cc7f,
- 0xd82fa83d, 0x3bf23a5d, 0x7b5abdda, 0x87e141a8, 0x7a1ec506, 0x3feb42b4,
- 0x5ed49f81, 0x84a4fdc1, 0x3fe34ce3, 0xff273f85, 0x057c8cc9, 0xfd834ef3,
- 0xfed22579, 0xc7aed554, 0x2ed8137e, 0x740673a2, 0xbe15f48e, 0xe0a8bfce,
- 0xebe5547a, 0x48d7c865, 0xaf9cbdbf, 0xa96dc7c3, 0x1c0bf9aa, 0x7b945b77,
- 0xf157f710, 0x139fdaf1, 0xe7ee5f08, 0x1f4f0852, 0xb59ce7b3, 0x031f9740,
- 0x2e80fb1c, 0xf19d39af, 0x9affd049, 0x6c9f19cb, 0x1d03921d, 0xbf53c5cf,
- 0xa717936d, 0x19fd42b4, 0xef187ba4, 0x8a3ade93, 0x1cf43e6f, 0xbe753fe7,
- 0x52cbfc0f, 0x0d8a9f90, 0xda03a341, 0x262efb33, 0x7c581da0, 0xe414fee4,
- 0x6e7068c3, 0xdce054ad, 0x4bdad8f8, 0xf01e9c29, 0x455aee1c, 0xf49fb9bf,
- 0x6bff111b, 0xdfa23237, 0xd97ed7fe, 0x49fc7c81, 0xfa84bc5f, 0xf1a3e3f0,
- 0xd7ff945e, 0x3a7c998e, 0x6f10fc81, 0x8fb5c822, 0x91f7030d, 0x2f4479bd,
- 0x3ee8ffa1, 0xc83ddbf6, 0x4cd7ee8f, 0xb5b1f968, 0x51d75d7d, 0xddf5b5ef,
- 0xf2c4557b, 0x87e5d1a5, 0xd38f8df6, 0x6ffad57a, 0x28ed9937, 0xb9113f47,
- 0xfbdb589c, 0x6bbfd92a, 0xc0cc6f07, 0x47c7ea38, 0xca094fff, 0x379bf735,
- 0xb99e504a, 0x8251b8df, 0xc71feeed, 0x2dd9227b, 0x84f4b371, 0x665f5557,
- 0xe26a27bf, 0xfa141b45, 0xd5dceec8, 0x57f00938, 0x03896e7c, 0x7b6ab6f3,
- 0x139d14f1, 0x79fe2fdf, 0x21c3ca7d, 0x22033afd, 0xce8a8de5, 0x0eafc7d5,
- 0xaa47cba1, 0x94ef9a0c, 0x0f38d57d, 0x2df7e2b6, 0x0275c56f, 0xec0efa3a,
- 0xbfc880b6, 0xf046bb2f, 0xf601bfa1, 0xb23f784b, 0x923daea7, 0x9910f742,
- 0xbd3f9ce8, 0x1c53eb08, 0x5628eddb, 0x8726a7cc, 0x02cb4bd8, 0xe809bf3a,
- 0xe4cfa9a8, 0x203f7b27, 0x62baa45e, 0xfd743d47, 0x85b26337, 0xdc9a7108,
- 0x1ca0e777, 0xc0d78f0f, 0x5b8418cf, 0xa7ceafb5, 0xa651f8f3, 0x042dd247,
- 0x993b9ab8, 0x161d7884, 0x4b9a69d7, 0xf8f0a2f1, 0xdbb03d8e, 0x93ecfd8c,
- 0xabc21275, 0x8fb8a5da, 0xc0e4113d, 0x7972565f, 0x6757f2a6, 0x3af5e780,
- 0xc9e6b503, 0x69577e50, 0xcc7491ef, 0xece9780b, 0xc600ffbb, 0x1f073a17,
- 0xf30e9f8c, 0x98b7be74, 0x9ae79e61, 0x829e6b54, 0x9ae706fd, 0xa21bc81f,
- 0x1af9f09b, 0x345db92a, 0xd6442f64, 0x5f0aa57f, 0x2c1e968f, 0xd0f3fcac,
- 0x579fe083, 0x7cff7254, 0x709f8f05, 0x7f5c3cff, 0x1d5972a8, 0xef82ad77,
- 0x2af972e1, 0x47e039d9, 0x5b5e5c93, 0x32f7a769, 0x90a516fb, 0x92defd7f,
- 0xf875bb14, 0x43a239f8, 0x7c379c97, 0x739ed57c, 0x6653e57b, 0x3d647bf4,
- 0x897ba7f1, 0x97fcc3e0, 0x9db9ff6a, 0xeee5d902, 0xdf0f8366, 0x2c0ae153,
- 0x07d8f1e1, 0x22cf8364, 0xaa89d90c, 0xddab791d, 0x6abb5021, 0x63f6aa57,
- 0xbbe3c9c0, 0xfb788a4b, 0x556b8b65, 0xa75c58e5, 0x97179e85, 0x398ce7f3,
- 0xf55fa14f, 0x918152e0, 0x4aec501c, 0xedc34e95, 0x72fb4fce, 0x438a4712,
- 0xa7d0af3d, 0xc21367ca, 0x63d543f8, 0x7e7054cf, 0x5e3d40eb, 0xf7fc7a88,
- 0x7c3cfb1a, 0x8fe3d05c, 0x463f5257, 0x2e7e8bfd, 0xebf9233a, 0xadfc6566,
- 0x4e05feea, 0x59bc20d6, 0xfd19b02c, 0xf5fa68cc, 0x139d8a7b, 0xc519fdad,
- 0x3f1dbc7e, 0xc8e4561f, 0xcbf3f168, 0x70f2b795, 0xf9f9a9ff, 0x8c687d96,
- 0xd557bf62, 0x1ffb86bc, 0x6a04f7a7, 0x97feff90, 0xe1eee281, 0xfaa53def,
- 0xecd3229f, 0xa32ca9cf, 0xf723fd0e, 0xe83f1e1a, 0x43bfb24e, 0x7a5bcc7e,
- 0x05ace386, 0xb8ed107f, 0x51266f47, 0x32f686d9, 0x385e2b94, 0x1588f947,
- 0x77f0b46b, 0xfb174c63, 0xf3a6cbaf, 0x9eac2d03, 0x7d2d4ce2, 0x5016d249,
- 0x0f63dd0a, 0xf2be469d, 0x0fdbd01e, 0x88ffbe84, 0xc799befa, 0xfba636e1,
- 0x661af728, 0xc278b40f, 0x7dad7eed, 0x8dc4a950, 0x6f09d9a2, 0x5cb85bf4,
- 0x3e27a339, 0xd378c0ef, 0x7d8cc64c, 0x37b82e5c, 0x474938f2, 0xfc04e6df,
- 0xd2bb6a08, 0x500c457e, 0x6bf28a1c, 0xbed5eaf0, 0x3ee8d3a7, 0x27cdac97,
- 0x39ffefb5, 0xbcf0cbc9, 0x970f7252, 0xbd36ee4b, 0xa12a4792, 0x83b797ef,
- 0xed0e393f, 0x1bfdbb4b, 0x8b807788, 0xc8de48f9, 0x3ecbb89a, 0xe9f4af25,
- 0x3f257f99, 0x2891c574, 0x79eea479, 0x7ca48f3c, 0x1e787727, 0x0ca9f4e9,
- 0x48f3edfb, 0xe8e7bd1d, 0xf2edcb1e, 0x5baaa649, 0x3b8a1c71, 0x7c79144e,
- 0x209f6277, 0x626abc61, 0xe9775f1f, 0xafb238b6, 0x3ab57e1b, 0xba81e505,
- 0xe22c9f4f, 0xfde4fdf8, 0x5fb06acf, 0xc944afc9, 0xe37aeb02, 0xcb3f0dfd,
- 0xd9bb75e0, 0xc436fd8e, 0xc9f33fa3, 0x23c7d6af, 0x1280df7e, 0x17c7e7f7,
- 0xc9f1c8c4, 0x667578a1, 0x959dc515, 0xfa08b578, 0x5c50cc70, 0x8bdfbc27,
- 0x746e5c55, 0x7142bb83, 0xef3c23cd, 0x9aee9ddf, 0x9ebff547, 0x29dff8c4,
- 0xfd1e2990, 0xc635d02a, 0x62c1a68d, 0x3ffd2f31, 0xe62758e3, 0xbac7ba91,
- 0xf47c427e, 0xf23b3ad7, 0xfca7f411, 0x9db0f793, 0x6a8623f4, 0x0333cf31,
- 0xf7405b3f, 0xdf295231, 0x8fb28f73, 0xa2cfe0e9, 0x2cd0095f, 0x34f43cc1,
- 0x2333df25, 0xfe38898e, 0xfb6b830e, 0xf52fcc54, 0xc4cd8e8b, 0x3c148e04,
- 0x779e196f, 0x2f9e6412, 0x6a4ff357, 0xfe5a3cde, 0x9479c049, 0xf3f056ef,
- 0xf980b296, 0xc4cf3574, 0xf9293a96, 0x43cca5b5, 0x807c42f7, 0xde73afb3,
- 0xcffc846b, 0xf21115c3, 0x982beb3f, 0xf3699f62, 0x5f73db8d, 0xaafd3a21,
- 0x78c3c679, 0xe68ee2ae, 0x0fdcecc5, 0x28bb830d, 0xf234d3e9, 0x6ff8febb,
- 0xfb67a409, 0xbc3e906e, 0x00b13416, 0x78071fc5, 0x40cfbddc, 0xe06b8671,
- 0xd10d8dbf, 0xf054efb3, 0xd5f78f71, 0x04f7fd11, 0xfdf1e3ea, 0xb7cf2bdf,
- 0x7ee4b7bd, 0x01bdf7b4, 0xc60b1dfe, 0x13d63fb8, 0x6ed18b10, 0xf2fb83b9,
- 0xf5846564, 0x7eb8e399, 0x52a3e70a, 0xab4aff85, 0xdeeb9e38, 0x7b987ee7,
- 0x48afcf03, 0x7b705c8a, 0x74fd5e78, 0xc6a09a56, 0xca45c7d3, 0x92091cbf,
- 0x447968de, 0x7cc9efa0, 0x33cbfcd9, 0xf1f391e9, 0x462f7a2b, 0x3634bfce,
- 0x168cfc90, 0x638f0ecf, 0xff2a9dff, 0x7638f3a6, 0xeb44957a, 0xd7e4f64e,
- 0xeb43638c, 0xb0fb83bf, 0x7d845674, 0x6fe383b8, 0xf1db1d9c, 0x3b63caeb,
- 0x1e3113fe, 0xc78c7b7f, 0x6c7961ff, 0x8abaebf3, 0xdbffc2d8, 0x1fdfc318,
- 0x57fffe09, 0xe78407cf, 0x0bcfc3ff, 0x30039f84, 0x17b0f5bd, 0x9d84badb,
- 0xefc33f41, 0x24d6bf8d, 0x93141c80, 0xce7dd3f6, 0x1f3ce505, 0xecdeadb6,
- 0x9d0c2bdb, 0xf5f1501b, 0x23f73568, 0x5eebbca5, 0x04d45efc, 0x829f5039,
- 0xfe72b2f1, 0x59ae4377, 0x898c5e78, 0xc9e63a52, 0xc5f4cde0, 0x5b749760,
- 0x5359e722, 0xe9a2f195, 0x35d58391, 0xe315678b, 0x7c8a3d1f, 0x4a87ff0e,
- 0xe5ea521c, 0x6899e9f7, 0xf34c5f4f, 0x1ed1d3da, 0x9fc93c4a, 0xbc99f827,
- 0x67b2e097, 0xdc7fe62f, 0x7be11b20, 0x26ffc946, 0x1b2bbbcf, 0x60c9d2e3,
- 0xf05e6217, 0x920fcc69, 0x7bd12b3f, 0x66977cea, 0x19ea3f71, 0x9f301303,
- 0xcfca9deb, 0xdf9eb139, 0xe6a6fd91, 0xfc1acef5, 0xca055a97, 0xfc23b5eb,
- 0xf3f9d53f, 0x442b65f6, 0xebcdf80c, 0xf8df2891, 0xe5dff976, 0x9e1e68ba,
- 0xe24c7be7, 0xbf409caf, 0xec78e019, 0xefd12168, 0xffe5e38a, 0xc7fe8cd4,
- 0x3cf09164, 0xe254afcc, 0x78941705, 0x502f1a87, 0xacff5bf3, 0xc03e49c4,
- 0x03940bf8, 0x72810f18, 0x9ddd2cfb, 0x67db4fd6, 0x67ffe045, 0xf21f1e04,
- 0x87c794fe, 0x9c8e8d0a, 0x7f94f3d0, 0x63ef8b35, 0x2fe79fab, 0x0fcf78d4,
- 0x7e14f595, 0xefc7ef4f, 0x9d6e15a1, 0x5f3d446e, 0x0e2b35b8, 0x4fb219cb,
- 0x5ef80697, 0x4eb0fab6, 0x7448bfdd, 0xe75957b4, 0xca4133b6, 0x961abdef,
- 0x8b34bff7, 0xa968679f, 0x097bfbe6, 0xd418a0ff, 0x6e229b1f, 0xb131f341,
- 0xca47d24a, 0x5f80b52b, 0x76b6708c, 0x7c55b873, 0x75edf8b7, 0x53c5cf38,
- 0x1658adc1, 0xa3aec9ac, 0xf5db7bb8, 0xb9bf68ad, 0xae9c6f07, 0xd19978a6,
- 0x43c4fe8e, 0xdbb8da03, 0xfe3cd513, 0xe01a2afe, 0x457bb788, 0xef0b8ff2,
- 0x927e8915, 0xbfe42c5b, 0xde981b26, 0xdc45f58a, 0x4c682a2e, 0x5b3ac3ad,
- 0x60f64492, 0xd27b19c1, 0x714379c3, 0x377be4b0, 0xdd3c458c, 0xc6aacf2e,
- 0xe45b2ed3, 0x5f9fb8e3, 0x7edacf35, 0x6f3a3df6, 0xc54baeaa, 0x8d2f9a8b,
- 0xcf556796, 0x3f1bb83d, 0x70d39cd3, 0x8c06c18b, 0xbd1e163f, 0x5fce5468,
- 0xa1ecb64a, 0x91e16c3c, 0x557f94eb, 0xcf6eadf3, 0xa1abb275, 0xf7fb119f,
- 0xd7f9e26c, 0x2c0e00d7, 0xb2dd617b, 0xdba1ef09, 0x7583eca8, 0x9b63f3e3,
- 0x6ff4a972, 0x7c795072, 0xf8951953, 0x64f4c999, 0xa75edbcc, 0x59d5edbc,
- 0x524dcec3, 0xe8b76f5e, 0x15f108fc, 0x7aa3f792, 0x1f4fde78, 0xee35e3c7,
- 0xbefa0633, 0x99acfba1, 0x5f4d77e4, 0x0ff444eb, 0x9ae73f3e, 0x60777088,
- 0x2e842dde, 0x961d913e, 0x9d83f424, 0xdbe60b0e, 0x1aaffb0a, 0x874c3cf1,
- 0x3c623018, 0xc0cf200c, 0x9eee8b23, 0x6fdcfceb, 0xf1058d5f, 0x58fcdb7b,
- 0x8fcfffef, 0x58fc957d, 0x273f3577, 0x0291caad, 0x8bde4ea7, 0xf2d919e5,
- 0xd89c8870, 0x94f9e4e6, 0x1127936d, 0x4e76ee1f, 0x321d5a4a, 0x8f23675e,
- 0x3bdf245f, 0xfcfa12d9, 0x1f3cd597, 0x67302c96, 0x33567924, 0xc7ddebfb,
- 0xd76e411b, 0x3ffbb244, 0xe5d029f9, 0x238ba04c, 0x90389edf, 0x343f19c7,
- 0x71adb71e, 0x2831c4f5, 0xd8982e9f, 0xd3af1e14, 0x5858e3c4, 0x5c5a2e5e,
- 0x4ea3456e, 0xa179d0b6, 0xdbd404e0, 0x2633f1e1, 0xbd702706, 0xbde0672e,
- 0x83319814, 0xf961b195, 0xdf305fb9, 0xfbc327cf, 0xa4751acb, 0x5d3cd42f,
- 0x36c8a341, 0x6c167d01, 0x3f28f834, 0xa45e28d7, 0xec6fc576, 0x90320a94,
- 0x6b383fce, 0x16ae3094, 0x34731f1e, 0x049eefee, 0x026d1dfd, 0x5dba0bdd,
- 0x073d4f1e, 0x3fdbd2de, 0xf96de307, 0x3d77576c, 0xac9fcff4, 0xf4fcf093,
- 0x3f1e7cf0, 0xd8a05dff, 0x3671e139, 0x4bb433a4, 0x1bf0e3c2, 0x38d83a15,
- 0xd7adeb9b, 0x1d537f14, 0x4e17ed47, 0xcd9d3f3f, 0xb8b46df5, 0xbc6551fe,
- 0x6d82c6ce, 0x177f7193, 0x93ea18e8, 0xf35ac6ce, 0x76f190e4, 0xdbe7e6cc,
- 0x60fcc19e, 0x907e686a, 0xf3c301e7, 0x2b9caa82, 0x037dffec, 0xc8377be2,
- 0x6e63d46b, 0x141fcf1b, 0x8339ab1e, 0x4e086372, 0xc377b7ae, 0xbec8079e,
- 0xbe312473, 0x457bfa2e, 0xc502a3de, 0x7c160ae7, 0xea1e3c76, 0xf74499cc,
- 0x2767dcb0, 0x3ca2b16f, 0xe316205a, 0x53b71ebd, 0xc26795b8, 0xeffdd27c,
- 0xbcefa1ac, 0x7f903e16, 0x81e5f70e, 0x0f9d0366, 0xfddef554, 0xf03534ef,
- 0xc64fbdf6, 0xe0ae7b61, 0x79f1d8b0, 0x763f7d23, 0xfa7e4bfe, 0x110b58bb,
- 0x81e7903a, 0xe44497b3, 0xd716cb9b, 0x151f23df, 0x4cf2522e, 0x3f4f5ccd,
- 0xc0c8b7d0, 0xead3cec8, 0x9f5913cd, 0x46e83c53, 0x8fe5215f, 0x43fcf052,
- 0x29be90de, 0x6c7a0a3c, 0x63d39dcc, 0x112d9d3f, 0x1e82673e, 0x17927843,
- 0xf87d3cf1, 0xf650effe, 0x8a5e9a3f, 0xff518726, 0xde63fbf0, 0x5c36c10c,
- 0xee31db8f, 0x3af68a53, 0xd3a2e394, 0x71661fdf, 0x628a4eba, 0xa149fdcf,
- 0xa7e7a8df, 0xcf27477a, 0x7fd987f4, 0xd563791e, 0x4df352ff, 0xa0f6bfaa,
- 0x65ab0f62, 0xbbfe5293, 0x72a037ef, 0x21bf788d, 0x86fdf239, 0x68090e87,
- 0x1bf7a8a7, 0xcd59194e, 0x4f3c54e1, 0xf277dcab, 0xe93b222d, 0x62fcdfd4,
- 0x78a98beb, 0x509049df, 0x3a1fb51d, 0x1dbe7a47, 0xa7b223ec, 0xe3cb7efa,
- 0xf9f887ad, 0xc8def6f0, 0xaddbdddf, 0x32f5dfd8, 0xaed1b923, 0xe86db79c,
- 0xb744f251, 0x8b8f96e2, 0xb74b71a1, 0x3d56303d, 0x7f23ebc7, 0x8cc71b4f,
- 0x60ecb716, 0xdbb73a41, 0xa07046b1, 0x39ddb87e, 0x79ca5ddc, 0x4c71a8dd,
- 0xb973e479, 0xb94c71e1, 0xb9c79b5a, 0xf7c4966f, 0x680825db, 0xce759aef,
- 0x7fb73a36, 0x9d22904c, 0xcd5a5ef3, 0x257cf4e5, 0xc8d0720f, 0x8560e3e9,
- 0xf06ff740, 0xfbee1e1e, 0x1efc63c1, 0x7e02c1ce, 0x7bcd470f, 0xa66bf7a8,
- 0xe83de50e, 0x2f7a9dfe, 0xc367bd47, 0x5ae08f98, 0x7d1c5cf4, 0xe1876bc7,
- 0xbddb8d90, 0x1a3f7e5e, 0x43e61065, 0x8913cc4d, 0x6bab6b5f, 0xef7a6ac4,
- 0x8f4fdb8e, 0x7bf04754, 0xe91f8a7d, 0x2fea8eae, 0xfad6afac, 0xf70f540b,
- 0xde54ee17, 0xecd98be3, 0x87fbfb4e, 0x9e8f1c63, 0xf1b63b32, 0xfb48ecc4,
- 0xfda2c5b6, 0x5e5aaf1e, 0xb0dfe456, 0xbb0dc5ef, 0x7af5c92f, 0xa7ff60b7,
- 0x1ba7ca4a, 0xcaae9f28, 0x7c31eed5, 0xe3291ffc, 0x294065a9, 0xd77ca3bb,
- 0xbc4a97f9, 0x7b944bac, 0x2f69ee10, 0xd397e368, 0x97e3690f, 0x35937b33,
- 0x78ff7cf5, 0x6785fbcd, 0x8bda6926, 0xda68f703, 0x68142f4b, 0x1503e5ea,
- 0xaf2bf79a, 0xb3ea6ad4, 0x65f8da82, 0x61c5cdf5, 0xb47d38f7, 0xdca01abe,
- 0xe6757ed0, 0xcbde6a6f, 0x575da358, 0xaebb4796, 0xebb51b89, 0xf6cdc752,
- 0xd397d76a, 0x325f5dad, 0xbef2e3e6, 0x7f2e3e7e, 0xc7c95db6, 0xdfb058e5,
- 0x2d938d33, 0xf7a9b768, 0xfef7d5a9, 0x5866372f, 0x007f40df, 0x00000000
-};
-
-static const u32 csem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0xe4b3ff00, 0x51f86066, 0xb97bc10f, 0x726e1818,
- 0x0143f821, 0xd08667cf, 0x0c0c2c6a, 0xc6cc401a, 0xcec0c0c4, 0x717ebc44,
- 0x1d7b044e, 0x4cc30307, 0x31c8de20, 0x481afef0, 0x7e879d7c, 0x42f3a976,
- 0x81c15968, 0x570837f7, 0xb430310a, 0xc430330a, 0x0cf84088, 0x55f2a8a2,
- 0xa9b60842, 0x39766524, 0x0003f502, 0x3471cc24, 0x00000380
-};
-
-static const u32 csem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd554780b, 0x733ef0b5, 0x7993331e,
- 0x0f20f264, 0x0084f102, 0x021842a2, 0x27088784, 0x01a8c421, 0x54bc8083,
- 0x48433c26, 0xbfa81132, 0x2677bd6d, 0xb5ad1104, 0xbc1b6951, 0x14101de8,
- 0xd1a07515, 0x40e81c06, 0xdbdab114, 0xd5a8f8a8, 0x40445076, 0x8bcbc248,
- 0xaf7fd52d, 0xe649cfb5, 0xd4484c9c, 0xffffbff6, 0xdbf3f1fd, 0xd9cfb3ec,
- 0xdaf5ed7b, 0xf6bdad6b, 0x9a32c11e, 0xe4224e24, 0x65a3f85b, 0xf4842784,
- 0x0adb2ce9, 0x64918fda, 0x8b2ffc42, 0x108e36f2, 0xf08e77ee, 0xbc8451a4,
- 0x980b99b5, 0xcfbc3d69, 0x9fad0846, 0x603d34de, 0xff6422ce, 0xef02b308,
- 0x8f9ade9f, 0xbd2fc9f5, 0x7b6814e7, 0x00bc4bd5, 0x13bed375, 0x109d88ce,
- 0xa1e5b9af, 0xf6f3e96b, 0x85b27897, 0x93fc450e, 0x9085244d, 0xfec21663,
- 0x52fab22e, 0x6d56ab2b, 0xf4077fde, 0x2664de5b, 0xd54fda56, 0xaed365ee,
- 0x8765f5a5, 0x54af0244, 0xfa95ab6d, 0x00f2fad2, 0x9afa8417, 0x71c67f7d,
- 0x79480ada, 0x27212870, 0x5f22167d, 0x96ceeb49, 0x79f45994, 0x11676045,
- 0x83b15fbc, 0xfbe89b73, 0x7ff69b15, 0x3457fd0c, 0xda79038a, 0x36ed8aff,
- 0x63610f22, 0x1e604b7f, 0xbc01a64b, 0xc4886f55, 0x97e5eb4c, 0x70044956,
- 0xa54bd424, 0x61ff180e, 0x38c07649, 0x0d1c7087, 0xd0cf559f, 0xd577e871,
- 0x986e702f, 0x7889b55a, 0xddd69e00, 0xda4f39d6, 0xd2b55e61, 0xf77ef860,
- 0xb7bc127d, 0xb2f6502c, 0x36f80655, 0xe700454b, 0xd2d2cda6, 0xadfd9da1,
- 0x0ea6fed8, 0xd90d63ae, 0x76a89ea9, 0x47d27963, 0xacee6c88, 0x04a21057,
- 0x407700ed, 0xf3ac3e9a, 0x812e79f9, 0x3fd0d190, 0x674b644f, 0xc83094ff,
- 0xe8f7fe07, 0xf60f813f, 0xb2db023a, 0xd2b5e93a, 0x772dff45, 0x4bacebd2,
- 0x9ed09fa5, 0x56bfdd17, 0xa074043e, 0x5cfbd4f0, 0x4be23e58, 0x4f8372c3,
- 0xcafdbc46, 0x06cb0437, 0x3f9f1b9f, 0xe58b1be6, 0xe5829f26, 0x2c62be13,
- 0x7c52be03, 0x0e6f8b6f, 0x1e7d5b96, 0xaf94fe7c, 0xbeedcb1c, 0xacfe7c1a,
- 0x772c6eef, 0xfcf8fcf8, 0x2c7adf05, 0x2c7abe83, 0xb01af977, 0xf005f46c,
- 0xdb7d97bd, 0x05f26cb1, 0x5f1ef9f1, 0x5f219613, 0x407dcb18, 0x7d865a5f,
- 0xf01e582d, 0xabe5887d, 0x777e08be, 0xcb1c77d0, 0x3bbc5507, 0x817c9027,
- 0x10a9cde2, 0x92171517, 0x8be4a258, 0xca589eb4, 0xf9b729ea, 0x4f5a25f3,
- 0xc53ad0f1, 0x70cadf63, 0xfbd699be, 0xccf6b0d6, 0x8581487b, 0xacfd33d6,
- 0x4a83c07d, 0x07d69581, 0xc1f6b3d4, 0x7105fc9b, 0xc0383eb4, 0x11deafda,
- 0xfad1b02e, 0x9ed641d5, 0xed932213, 0x66139eb4, 0x94b7dcf5, 0xcf5a0ec9,
- 0xbcf5616d, 0x9d93fd8f, 0x61179eb4, 0x153f8fdf, 0xeb4f1c9e, 0xfb59dbe3,
- 0xd0a44bc4, 0x0913eb45, 0x7b02f587, 0xad02617e, 0xbd58b817, 0x20995fa8,
- 0x7dbfe0c7, 0xa1116462, 0x7fddb0bc, 0xd3a422b3, 0x455914ba, 0xfe9f14dc,
- 0x8b0f5839, 0xbfb43164, 0x84532fe5, 0x912eb471, 0x17fed0d5, 0x1fb6057f,
- 0x6f6c6510, 0xf6c2aff7, 0xed8c9203, 0xb07bdaa6, 0x60a8aafe, 0xbded727b,
- 0x92abfef8, 0x6b83ed82, 0x41fac21f, 0x63ed83d1, 0xef8d7f6b, 0xd83c941f,
- 0x80dac8fe, 0xffeb4852, 0x00b679c1, 0x9e71d75f, 0xfc0d9272, 0xa52b4c1a,
- 0x238ebafc, 0x1e3e4073, 0xf2a6a600, 0x525d2eb0, 0xfbedbf40, 0x3c93de47,
- 0x3276f2a7, 0xf53e97d4, 0xf3f61640, 0xd223f61c, 0xfb9ef87e, 0x58cdf899,
- 0xbf133f5d, 0x69fad729, 0xaceaf784, 0xdf67ebbd, 0xf0f5e337, 0xf5a1537c,
- 0x71fb17b3, 0x135e6ef4, 0x87a09dbf, 0xad4adbe7, 0x4fd8839f, 0x09e0ef42,
- 0xfd74638b, 0x5a65c584, 0x7ec47f3f, 0x1e0ef4fa, 0xeba71a45, 0x6b969147,
- 0xfd887cfd, 0x9faef7a4, 0x1ead74b0, 0xd685691e, 0xa7ec11cf, 0xa5e6ef7f,
- 0xc3d3af98, 0xfad2ae63, 0xcf748939, 0x073f5dea, 0x1cfc7a1c, 0xe7e07470,
- 0xa833c21c, 0x702af377, 0xe053f1ea, 0x25cfc0ec, 0xdeaae7ec, 0xa9c073f5,
- 0x6701cfc7, 0x0e447e07, 0x77ac35e6, 0xd7882af3, 0xbe20a7e3, 0x0e4e3f03,
- 0x3bd119e0, 0xa3ed5e78, 0x7dabcfc7, 0x8a93f03a, 0x1dee8cf0, 0x7a29853c,
- 0x74a614fc, 0x784647e0, 0x9faef5c6, 0xf8f45357, 0x03a53579, 0x3f61573f,
- 0x5e6ef5d7, 0xfc7aa985, 0xe076a614, 0xc9fb1727, 0x78476cf7, 0xd1c7ed08,
- 0xfb073f7d, 0xb073f1eb, 0xae7e077f, 0xd0a67ec5, 0xee7bb27e, 0x8f5328a7,
- 0x0ecca29f, 0x9e2214fc, 0x3f5de86f, 0xf8f53307, 0x81d99839, 0xcfd8a99f,
- 0xabcdded4, 0x7e3d0ae8, 0xf860ae8a, 0xc08c2499, 0x9dae8675, 0x727e9e6e,
- 0x857cbf7d, 0x2ef3efa3, 0x6e5de756, 0xaf0f7602, 0x45a433d9, 0xf6fbe9e1,
- 0x0fb9091d, 0xa6bb6890, 0x8fc076e0, 0xd1795a83, 0xd8fc4d76, 0x951d9d38,
- 0xeaea24a0, 0x757dc549, 0x1d29f7ef, 0x9d4f6ba0, 0x3daeb573, 0xabab93dd,
- 0xd78f9467, 0xa6bfdfbd, 0xe2bf5740, 0xef751bee, 0xd16ff967, 0xcfd7b3d5,
- 0xa83fbdd3, 0xfdaea17e, 0x5d0a86ca, 0x958155fb, 0xdb35faba, 0x7f7ba27f,
- 0xae8d7058, 0x03d3787d, 0xe111f6ba, 0x91f57447, 0xbdd31e87, 0x8b65ba3f,
- 0x87cc7dae, 0xc7daeacf, 0xeae97645, 0xa3df1ed7, 0xf6baff7b, 0xa4faba03,
- 0xbdd7bf8b, 0xd5de4f9f, 0x3f96dbdb, 0xe29fdeeb, 0x7ed74cfa, 0x0697da7d,
- 0x3aeed53b, 0xe75a8d76, 0xfa08ae41, 0x0974fe25, 0x43b0d5ed, 0xd7d4bac2,
- 0xc714fcce, 0xe528f952, 0x22c0e91f, 0x92f91939, 0x21bb51fe, 0x95f96fbf,
- 0xaefcfa11, 0x5d2b9ef1, 0x925df9f4, 0x862bb867, 0x8df9437d, 0xca506923,
- 0xed8d2826, 0xdf8c89f7, 0x0d2e320b, 0xf7bf423e, 0x2707da9a, 0x3e70fad0,
- 0xf1f2083f, 0xbb426732, 0x35278e3a, 0x999c5ef0, 0x5f74dfa0, 0xfe93de56,
- 0xdf587928, 0x5c19da9f, 0x45ebbf67, 0x51da1a4f, 0xc1f89fb5, 0x9fd759ce,
- 0x212fabce, 0x849f70af, 0xf7e903fd, 0x79a697fd, 0x89667f68, 0xe3d119fa,
- 0xa1fc744b, 0xe4187e38, 0x3f8c20e1, 0xe6f8ebba, 0xe3756301, 0x75cb325b,
- 0x3a245be3, 0xdf908bbe, 0x8eae7ed7, 0x9e30894f, 0xcfb93790, 0x66737c71,
- 0x9f7f8e39, 0xe8aefd44, 0xc63ae3f1, 0xbff9816f, 0x07fcdddf, 0x3fcfd78c,
- 0x7f3f42b3, 0xa3ffcd89, 0xf8ead3da, 0x3fff3871, 0xfcd9a773, 0xfcd82b33,
- 0x8edfaccd, 0xf81d9df1, 0xc7f8c08f, 0x9cdf19ba, 0xff3f413d, 0xf3f52a2b,
- 0x4ff1b337, 0xc7505ed6, 0x5ff8e3b7, 0xfcd81772, 0xf1c4a8af, 0x0dc7b325,
- 0xc46523fc, 0xf8e804d5, 0x7c551fa4, 0x742ec0a9, 0x2487281c, 0x6421a152,
- 0xe100371b, 0xf18e2bb8, 0x947157db, 0xf99f50df, 0x500939f1, 0xfd4799cd,
- 0x57d79546, 0x4097c8ec, 0xf53b61ef, 0xa0a896b7, 0x91e26e2e, 0x7306c9bf,
- 0xb7851060, 0x43f789b5, 0xeb86f17d, 0xbd5fa002, 0x14a0b266, 0x184813be,
- 0xcbfe7f9e, 0xe7a25b61, 0xd4972c65, 0x5122c78b, 0x07e1d6f2, 0x35219016,
- 0xc029be14, 0xeb3ba304, 0x0e3f529f, 0xa98fe31c, 0xffa843df, 0xc6c899f3,
- 0xf7f50bfb, 0xfea11ea0, 0xa4ce3a1e, 0xdda3bf16, 0xf0a34e1d, 0x7ff0aa97,
- 0xfd79302a, 0xe02e36f4, 0xd5f9f2a7, 0x7fa0478f, 0x1b6ee0bd, 0x1c277a45,
- 0x5d24fe65, 0x0fcbce9d, 0x6ddf6a74, 0x10e16c0e, 0x6be032bf, 0x21268a3a,
- 0x5067d68b, 0xffbe775c, 0x07a9bec1, 0xb7212739, 0xa54c4512, 0x9abedfef,
- 0xe3a2efeb, 0xb9cc52ce, 0x32521d6c, 0x24d7284c, 0x909634c3, 0x88471a5b,
- 0x5d3207b4, 0x448d3f11, 0x58a33b8d, 0xaa559f5f, 0x8a8ab7af, 0xb570a268,
- 0x66c8e74e, 0x39ecefda, 0x9c6d76fa, 0x4644a681, 0x52bc7567, 0xfa74938a,
- 0xb9943668, 0x7485d8f0, 0xdf62e39e, 0x1778f06a, 0x7e8c2489, 0x010fbfbc,
- 0xf193faba, 0x362e79bd, 0x73bc236f, 0x4a528b44, 0x8ca739e7, 0x1b7f000f,
- 0x9f68ffe1, 0xd0e5314d, 0x22a3fd72, 0x8f9d7531, 0x1eb9fe11, 0x22827ce3,
- 0xcbf3f3ac, 0xdf19cf8d, 0xffe9531c, 0x2d07f029, 0xa0fe00bf, 0xf9551ff0,
- 0x32af53a3, 0x3d9af0fe, 0xda1f80d3, 0xe904f237, 0xadcbf2aa, 0xa92cbf2a,
- 0x2105f3d7, 0xb8e8111e, 0xfb970e6c, 0xcc1f1440, 0x5960f956, 0x6e6f9e83,
- 0x3d317e27, 0x6ee65d06, 0x9a6f7cd8, 0x9f7e75dc, 0xff337ca8, 0x9f88fdc1,
- 0x7464f3ae, 0xd3a543ba, 0xf6fa35ed, 0xdeba555b, 0x4e75d2ae, 0x51afc3c3,
- 0xc9e641f5, 0xdde41101, 0x9e8d53fb, 0x3d3d1d11, 0x708d3d2a, 0xf3d2a1de,
- 0x7a331f8e, 0xa88de11a, 0x9c348cf4, 0xae80c913, 0x5be11af0, 0xf9977770,
- 0xccab5c60, 0xde9e9b1f, 0x4755fca6, 0x05579ea3, 0x3475586f, 0x6c56ce4a,
- 0x2fabae9f, 0xbdd5cc0f, 0x4ca1acbf, 0x7ea4bed7, 0xd17daeb9, 0xf5753bfa,
- 0x758fff32, 0xbbb82fef, 0x7b7ed756, 0xf6bafdcd, 0xeb0fe5f9, 0x1b3d73ea,
- 0x9ecfef75, 0x3ed759b3, 0x5d19f4ab, 0x9de28cfb, 0x6574faba, 0xd37deeb7,
- 0x066eabbe, 0x3deb7cfe, 0x713d809e, 0xc605fdc1, 0x45b82f33, 0xd473bc37,
- 0x1f5f2327, 0xf2c10df3, 0x7c8dcfb8, 0x1637d27f, 0x66a6d6cb, 0x7413ac3b,
- 0x124a5c5d, 0xcd326908, 0x0fdf5dab, 0xeb8269d6, 0xa9e4c869, 0xb37ad3f5,
- 0x28794649, 0x78489069, 0x2c1c2124, 0xed1c2a36, 0xa47b547c, 0xaa06f687,
- 0xb6ba93f8, 0x3f624497, 0x76523ef7, 0x7765f005, 0xcbfd03eb, 0x4da7bb00,
- 0xed8debb5, 0x8d291c95, 0x1ac84e7e, 0x626ac384, 0xc4a54776, 0x5772bfe4,
- 0x4271017a, 0xe6b83c3d, 0x2905e372, 0x9f02a793, 0x78e4eb64, 0x3a35c359,
- 0x9a204efd, 0x6df807dc, 0x8af9eea4, 0xbeead7ed, 0x479fb53b, 0x5741abb8,
- 0xb165838c, 0xe81333f4, 0xe67370e1, 0xa700618c, 0x4deb1472, 0x3c2ed07d,
- 0x755e2be5, 0xafd01074, 0xbee3cb14, 0xf31e5839, 0xea3cb079, 0x53f2c72b,
- 0x11960d5f, 0xfe58dddf, 0xf2c7e7c5, 0x2c7adf63, 0x63d5f23f, 0x01afa1f9,
- 0x017df7cb, 0xb6fb0f2c, 0x2f8ef963, 0xaf8b6588, 0x9f56cb09, 0x7726a582,
- 0x71ddf13d, 0x093e1d75, 0xcf8317fc, 0xed7f3aa4, 0x7c9d09fa, 0x87dfc716,
- 0xb9e1a67c, 0xf2acc1a4, 0x1f8e8a43, 0x4397c012, 0xbda1eb3e, 0xb0f95441,
- 0xb763efbb, 0x6bfcb77b, 0x0fea6df8, 0x7e4eb7e4, 0x53f030ca, 0x34fc4f76,
- 0xa7e28f8c, 0xb31726a9, 0xfa7e547b, 0x8623cc19, 0x8c0f315f, 0xf6513e90,
- 0x826f929a, 0xbaa56c75, 0x601f420f, 0x763aacfd, 0x05b77d1d, 0x10c0baed,
- 0x0ece3758, 0xd860dbf9, 0x21fb3847, 0xf7567e25, 0x49f233f3, 0xd05778f7,
- 0xa01a59bf, 0xdaea4f44, 0x78638d6e, 0x31489ab5, 0xfddaeba1, 0x2f729e83,
- 0x81758a1c, 0x01f7c224, 0x8c4774f7, 0x0cada97e, 0xaf09edf8, 0x72af8e75,
- 0x8f63bfa0, 0xca0f3dfd, 0x2f6626a9, 0x68f335c7, 0x93f093b7, 0xc76fc06e,
- 0xa77664ba, 0x7dbdbc41, 0xbb42e490, 0xe3d64c81, 0xc3a05fcf, 0x4714fddf,
- 0xd6eeb82d, 0x06fe21a7, 0xbd38357e, 0x49ebf817, 0xcf84f7bf, 0x7fef3085,
- 0xd27b3e01, 0x45e93d8f, 0x342fc8a2, 0xedb7f9d1, 0x80fb961b, 0x1e5ee30c,
- 0x9afedadf, 0x7e5f9e11, 0x4b6e3e47, 0x25b8f8d1, 0xa41f8093, 0xc6d9cbca,
- 0x2e81e32b, 0x40f4fd1d, 0x9f77ee4f, 0x7eff8264, 0xdfdf4b3a, 0xe2fec67d,
- 0xa70dc225, 0x89243ae3, 0x92bf53c4, 0xd1e36cf7, 0xfc47719f, 0x67d83710,
- 0xe0c9d773, 0xaffc9e37, 0xeb3d0cb0, 0x0f670be3, 0x3f04e93d, 0x5f1a656c,
- 0x1d063473, 0x982ab2b5, 0xf68f6355, 0xf5f49a57, 0x715cf5b3, 0xc725e710,
- 0xeb061ccf, 0xa8e6ab8c, 0x0d3f7a08, 0x959fad4b, 0x738e1269, 0x3c767b72,
- 0x4c02fff3, 0x4048ec9f, 0x67d2737d, 0xd9fff7c1, 0x8fd774f0, 0x8d210f06,
- 0xe80b33e4, 0xdd96da73, 0xcaddfbfd, 0x825e7083, 0x890929f8, 0x69bf815f,
- 0x3b7fffa5, 0xb015fa00, 0x0debf5ae, 0x70f37ef2, 0x3743be78, 0xd64efd1e,
- 0xbbe18cf6, 0x204ee5ee, 0xa7be34c7, 0xbaabfbf4, 0xbb62bdbf, 0xc76f46b5,
- 0xdeeae826, 0x9d1af4a6, 0x00ff0b5d, 0x1386bdc3, 0x54ab0960, 0xb04db0d9,
- 0xda7e07af, 0xf049c103, 0x5ef6385f, 0x79222595, 0x16971464, 0x6385d3e0,
- 0x6797fe35, 0xa9ea99ff, 0x048a6f13, 0xa25c8ce4, 0xaea9e550, 0x899bf220,
- 0x917d6898, 0xc6c2f6fa, 0x6eb02515, 0x26f9789d, 0x931643f4, 0xc7f82752,
- 0x0f3ea4e5, 0x89a7b5e2, 0xf3e418a9, 0x39c77934, 0xad1e4a32, 0x2e9d8482,
- 0xe3b7af5a, 0xabaf7fa9, 0xd7d06b2f, 0x525b9297, 0xe97edf60, 0x38049106,
- 0xf6fa1bd0, 0xf61779af, 0xacd48cbb, 0x57fb7583, 0xa16bbc6a, 0x5419088b,
- 0xf6fd556f, 0x0a32bcf1, 0x71604b87, 0x7a1f6d16, 0x7ff32279, 0x2406662a,
- 0x59ffbe85, 0xa95bc8e3, 0x07dfa206, 0xbc7ec1d6, 0x6f713a7f, 0xf7e95d23,
- 0xc237e15d, 0x5d03d9ab, 0x3855c3f6, 0x4a73b792, 0xcb1e8620, 0x67263814,
- 0x102bbeaa, 0xc7b8ba5c, 0x7bfd4334, 0xd13253f3, 0xde1ed3f1, 0x668c2793,
- 0xc0fc03fc, 0xe792ed09, 0xd69ff487, 0x7f82ffa5, 0x68fdff6a, 0xfeba79ff,
- 0xfb53fda7, 0xfe05d81f, 0xaffab179, 0x2ff3edfa, 0xa93ea9fb, 0x4e97f178,
- 0x13c9d742, 0x9b8a7d42, 0xdb72b5d2, 0x96854ebd, 0x13bf05c7, 0x8044f5f8,
- 0xef458e2f, 0x154e0587, 0x41cec542, 0x49fe0ddc, 0xecf93ffb, 0xf11e30cf,
- 0x85d136d5, 0xe6edb4f1, 0x61ca99b0, 0x12f2e375, 0x23f58392, 0x19df7eac,
- 0x7a4dea1e, 0xfa78abfe, 0x1f902997, 0x8d453942, 0x9ed1852f, 0x79fadead,
- 0x5e4fac11, 0x64728ed2, 0xbfc60efc, 0xaffa8898, 0xdaef8a4c, 0x38c4e14e,
- 0x8bc55781, 0x6767f1b7, 0x37942778, 0x82fa017c, 0xc7e8227a, 0x572bbf1b,
- 0x8235d4ed, 0x8d98f923, 0x190c7bfe, 0xc3517a03, 0x3b30090b, 0x5f99eeb5,
- 0x70a11ce7, 0xa6fada9d, 0x97c28b93, 0x83674f26, 0x8f73fe8b, 0x6ddebddc,
- 0x6d16f2a5, 0x96eb690f, 0xd7daa4dc, 0x8a565621, 0xf3e42761, 0xdd166e54,
- 0xf2b8fa7e, 0x7a9f27f9, 0x7f99e20c, 0xd107bb32, 0xff3c57fe, 0x69e3fbda,
- 0x314ec57d, 0xc34d84b9, 0xd274a5ce, 0xbfff4bc7, 0x1e93b73b, 0x4d79bf15,
- 0xe7b18792, 0xd27624f7, 0xfdcec565, 0x15d61912, 0xfb83931f, 0x063d88a5,
- 0x8a47827d, 0x7ba85ec0, 0x8825bfe6, 0xc7d89e33, 0x18acd491, 0x1afcdcf8,
- 0x278003da, 0xaf4aa7a4, 0xde19fa0e, 0x80ba52f7, 0xcbd236de, 0x5522def8,
- 0x90bf40bf, 0xfbf94167, 0x07903d85, 0x0dd991f5, 0x617f2878, 0xf3e61395,
- 0xf8c35085, 0x537bf1fc, 0x8b959f40, 0x961714fe, 0x13f979ec, 0x5bfe423f,
- 0x528ff6f6, 0x9444be30, 0x45ae1374, 0xe79874fe, 0x70b34d92, 0x07894b9e,
- 0x71fcb0f9, 0xcb4034be, 0xde29020b, 0xac4e4319, 0x2f939322, 0xd2e250b6,
- 0xfe017e79, 0x77efe824, 0xb436c0f8, 0xa024efbb, 0xcea47e0f, 0x580c5a85,
- 0xf46160bf, 0x2ebaabfa, 0xa33eb010, 0x7deb77f9, 0x93a7402d, 0xd85495fd,
- 0xc112f177, 0xfb83e2af, 0xbfcbf696, 0xd195253d, 0x9e42c889, 0xf75d1dfa,
- 0x7873c327, 0xac5445bf, 0xc8efba39, 0xe39d59b7, 0xa7c756af, 0x7ac1c770,
- 0x6c4a45fd, 0xd44f35fb, 0xb75d00f4, 0x4a2cf8a3, 0x6ffc99de, 0xbbc99fbd,
- 0xe981ff26, 0xfe7ed0c5, 0xf8239330, 0x0a43d60e, 0xdb153857, 0x50e4cff7,
- 0x3a3f503f, 0x156f9c96, 0xb7d73955, 0xc285f91b, 0x51f1702f, 0x24e3037c,
- 0xdf701d22, 0xfa06e965, 0xf51e947d, 0xaeceb8c2, 0xbc726afd, 0x455bf34c,
- 0x9b203ebd, 0xdee81e98, 0x9e23f2ae, 0x53c0c52a, 0x52fc818f, 0x20cbf579,
- 0xcc2962bf, 0xcd1dcbff, 0x72a3cfef, 0x935065fb, 0x355ebd5b, 0xaef96dca,
- 0xdc9624d1, 0x9377697e, 0x9f4b7298, 0x7b5b94c7, 0xfff9f904, 0xf0d55eb4,
- 0x78f00c38, 0x351e274d, 0x3e1dd93d, 0x90f27a8d, 0x8d5e2320, 0x1dfe927a,
- 0xf95d7926, 0x8d43e351, 0xab9e2aff, 0x51f402ba, 0x7c6a9f07, 0x1aa7c1d8,
- 0xef89761f, 0x6c68f0ea, 0x34fb00bf, 0x96f9ae14, 0x528ed38d, 0x4ed2d257,
- 0x7f26df70, 0xaafb8f26, 0xe584f396, 0xf3111081, 0xd5303f43, 0x753b068c,
- 0x3d6fdfe2, 0x7785177d, 0x2c8bf13e, 0x445ea02f, 0xb7d2ffbb, 0xf3a04edf,
- 0x79e2a799, 0x54fb453e, 0x0239974a, 0x70a38e17, 0x3f8815ce, 0xb7e2113e,
- 0x0a34f91c, 0xfae5f98e, 0x4c4dfc3a, 0xa7a7ece9, 0x9fabbff7, 0xb7cb7df2,
- 0x1d3f5d29, 0x50bbc844, 0x10bc388a, 0x81d357cd, 0xde7f14ae, 0x00605c51,
- 0x5088a9ea, 0xbd77e51a, 0xf3fb3220, 0xa319c2ed, 0x9fc9bec1, 0xf19e2c3d,
- 0x7bf460fb, 0x3b3eaabd, 0x41e397eb, 0x650d9fcf, 0xf67b7fa3, 0xac4722d0,
- 0x9566d0bc, 0xf7535ecf, 0x5cecda5d, 0xbff94f3d, 0x7da3b48d, 0xc95bb7e3,
- 0x82fb18b6, 0x5f4d451b, 0x7fa374ab, 0x8e7f1d3c, 0xe97387ca, 0x51b9f1a7,
- 0xf5399b74, 0x4aece084, 0x34fbf807, 0xa1fb0fca, 0x06be05f8, 0x235b36fc,
- 0xe231a545, 0xf8a9cf79, 0x6be0789b, 0x0c2dcfcc, 0xc7800be5, 0x8baf3b42,
- 0xc9a93c83, 0x143250eb, 0x60789ae0, 0x5347cff9, 0xe21ef63e, 0xeb8f90dd,
- 0x3c919d0d, 0x2361fc31, 0xb07fa13e, 0x2e888f33, 0x627bd7c4, 0xebc012e9,
- 0x04acb37b, 0x95df35f6, 0xe0b155dc, 0xf5b3332c, 0xbd292e66, 0xbffb8a30,
- 0xb3f9bf0f, 0x8a02e11d, 0x9676b38f, 0xff95ddf7, 0x759fdc98, 0x0e5a8171,
- 0xf56790f8, 0x71002e64, 0xf9e222b4, 0xe50e04f9, 0xfeb4527d, 0xfe9a6fca,
- 0x54f5e43c, 0x89973887, 0x110b57b6, 0xdbd8f809, 0xfb0053b4, 0x289926fd,
- 0x6a108f18, 0x8a8ccd86, 0x05111d7b, 0xdff357c4, 0xf80edde6, 0x4cd3373d,
- 0xe8652e00, 0x01d82719, 0x512342e7, 0xd79bba0e, 0x5a647c1f, 0x10fd08a1,
- 0x3f230fe4, 0x74db2514, 0x499359f5, 0xdba5373f, 0x95647344, 0xeafd063b,
- 0xbd67c624, 0xff966fd6, 0x04dbf4cf, 0x5f18dfaa, 0xedfad18b, 0x7df18926,
- 0x8d4b7e94, 0xd656dfa5, 0x17c0a9ca, 0xa766f72b, 0xbe575d02, 0x2c4fa4b1,
- 0x8fbaf6fd, 0xa86ff7f9, 0xfd6de679, 0x1e1b7ea8, 0x51fadfa5, 0xae2316fd,
- 0xa5ea5a3b, 0xcffcb37e, 0xa0ebdfc8, 0xb7cc62df, 0xa69fc558, 0xb5438adf,
- 0xfb8adfa8, 0xa97cbaf1, 0xfa4f5249, 0xb397ecad, 0x6dba2eb0, 0xf007f831,
- 0x0dedfa0a, 0x38c1cf55, 0x5dfee7a0, 0x3d277d72, 0x3d5bd557, 0x67843ff7,
- 0xecadcf4d, 0xd33da1cf, 0x9e990f95, 0xf4c5995b, 0x4cbdcadc, 0xc41cadcf,
- 0xbf519cf4, 0x6fd17415, 0x21eafbec, 0x23f47bf4, 0x1b7d7eb3, 0x23992f6d,
- 0xfdf42dba, 0x9f3b5912, 0x5a3a3351, 0xd4bbfddf, 0x9f73be8d, 0x3d2e73c1,
- 0x823fbbe9, 0x7a841bbe, 0x91c8206c, 0x1c6e3f91, 0xd3e5d368, 0xb1f5f7bd,
- 0x79045ee7, 0xfe8f03f9, 0xe62607f7, 0xfafbed27, 0xbb9048d8, 0xaa1e00f7,
- 0xf9519eef, 0x47e7d5af, 0x28793a7d, 0x7baaf793, 0x1baafe18, 0xd5df3639,
- 0x7586407c, 0xd1176fe0, 0x2f7dbe8f, 0x9b67a3f3, 0xc0d8fa5b, 0x225fffcf,
- 0x2bfd25ca, 0x87e28b29, 0x302b1739, 0xce2bb9ee, 0xccfc05b9, 0x80b10239,
- 0xd0e0bb1d, 0x7ec0278d, 0x3d71705d, 0xe00bbdda, 0xc8e92279, 0xa1db98fb,
- 0xebf6f527, 0xaf9da6bc, 0xf9ae9065, 0x8ccd1310, 0x7157132e, 0x5d59cd81,
- 0x5da823f3, 0xc62df986, 0xabdf893c, 0x47cd9ff3, 0x8fe45f10, 0xe5f8cc7c,
- 0x72788def, 0xad54bc33, 0xaa78f5e6, 0x89e262e1, 0x2ca4ba52, 0xb72f13a5,
- 0x975914bf, 0x39cbed01, 0xf38cb7f4, 0x9c66f0d6, 0xcd4786bf, 0xbea059bf,
- 0x24743f3f, 0x86889e66, 0x22f92ee7, 0xf80dde1a, 0x33d34b78, 0x206190d7,
- 0x3c981f97, 0x7c0d1f3f, 0x178a7bf4, 0x73ade70a, 0x2bcee907, 0x65e2a3bd,
- 0x6148e7aa, 0x24780c8a, 0xf367c035, 0x96be77ca, 0xb377e742, 0x210b9592,
- 0x937f59f5, 0x688f103c, 0x1ea3b6b6, 0x9470f8d4, 0x5985c999, 0xf5ef2bd5,
- 0x7ae21575, 0x50b9c4d3, 0x3d06c2be, 0x7999e6a7, 0xd7f261ef, 0xbaf7fdcc,
- 0x6788518c, 0x91482e58, 0x5d015eb6, 0x86a73fe8, 0x40bc5d18, 0x69cffa17,
- 0xe020fda4, 0x73993abd, 0xa6fde187, 0x3f02f79d, 0xcfa56ebd, 0x39cbce41,
- 0x0e8616f7, 0x65ca7a7b, 0xc58858f9, 0xc8cc18c7, 0x173f5ceb, 0x5d897bc0,
- 0xe68993ed, 0x8e00f796, 0x366e5489, 0xfd00c3c3, 0x46fe8a2f, 0x07c8c5fb,
- 0x7503e53d, 0x2ab9efc7, 0x3a075f9e, 0xeddf01d8, 0xde43d812, 0xb47f5b30,
- 0x1720af76, 0x3a34de22, 0x65f5d134, 0x2983a314, 0xd66f9e06, 0xbd9e2aea,
- 0xef844e21, 0x6ffea06f, 0x7ebb0712, 0xf8d41f5f, 0xc5772cdd, 0xd215c413,
- 0xe806f4a3, 0xcd7de8b7, 0x11b7a6ea, 0xa6ae375f, 0x15dc99e6, 0x407d1a5f,
- 0x6f0e5e0f, 0xd34fcadd, 0x61799891, 0x467e55df, 0xb3f2f599, 0xe6fedacf,
- 0xedab8870, 0x90af50e5, 0x7e2e8250, 0xecccd330, 0x07ab6696, 0x0dfdbcf9,
- 0xee45bdd1, 0xa8a67faa, 0x257f0174, 0x64e27cfa, 0x4de80898, 0xa67c9597,
- 0xe3007bcd, 0xe0f5e8b7, 0xe907ab75, 0x33ff5dd7, 0xedfecccc, 0xead31ece,
- 0x9078c3d7, 0xc7eb28d7, 0x5a47ae33, 0x79a7a95c, 0xbf71d479, 0x71b4bcef,
- 0x84beebbe, 0x3c60b497, 0xd89fdb4e, 0x89767bc3, 0x73163f60, 0x0a107dba,
- 0xfe6fee39, 0x59bffa13, 0xff7ddd1a, 0x530a3f10, 0xe3bebf3c, 0x9f638c49,
- 0x34c8f67e, 0xaf159f90, 0xe542c4f0, 0x838775af, 0x889e5984, 0x45427604,
- 0x5dfb8f23, 0xcde70844, 0xa833b288, 0xf1f0c327, 0x5ef503a2, 0xa0732ec5,
- 0xf15f7e84, 0x103967f2, 0xc35d6b7f, 0x59ff9ff4, 0x91fd1f95, 0xa807c81c,
- 0xbcfed810, 0xa88f3e91, 0xb76a79fc, 0x6fe80e6d, 0xc73b3b6e, 0x2d9c115b,
- 0x0ce2a39a, 0x16459bf7, 0xc36ddee7, 0x33ff6c3c, 0x0331e61c, 0x48e7d17c,
- 0x53d0fcb5, 0x5cbd30cf, 0xe00624d1, 0xf6c5703c, 0x1710ad9d, 0x8cd0f8af,
- 0xfb77abf6, 0xd3ec0919, 0xcf3e2fc9, 0xf1371bce, 0x976878ba, 0x3e76e438,
- 0x59f8866c, 0x01ea1563, 0xf5823f5a, 0xfbf71aa0, 0x15b2718e, 0xd97dee2f,
- 0xe2b8514f, 0xf13b4f37, 0x36cb705c, 0xb723c627, 0xa05f7e5f, 0x7831dc4b,
- 0x9c771abf, 0xf5c105fa, 0xf1dc7621, 0x2127caa4, 0x48ee3eb3, 0x3c6127b6,
- 0x5799c292, 0xd17e231a, 0x5fcfffc1, 0xcdf60278, 0xf2faed4e, 0xf2bb8009,
- 0xfc4f739b, 0x2a93e294, 0xdbac1720, 0xc3df67de, 0xbbed067d, 0xd27d55f7,
- 0xb8d3ccfa, 0x27fad34f, 0x6b7a1bb3, 0x2645fbdd, 0xeeb453ec, 0xe2053afc,
- 0x4ef7abb8, 0xf56d7f41, 0x4953934b, 0x2b407f0c, 0xbd037f81, 0xd23227d8,
- 0x39b1b9ad, 0x4d3ce013, 0x77eb0ee9, 0x58393c47, 0xb2f4e2c5, 0x11de471a,
- 0x4bae5f7b, 0xc671b8dc, 0x3ac1d7cd, 0x65ba28de, 0xf1f88bd2, 0xe1cf4a61,
- 0x0ee3a0bd, 0x38209f75, 0xe3f1b2f5, 0x4a0ff0d3, 0x7d660baf, 0xe342fe1c,
- 0x0c7cff92, 0xba931ada, 0x7b871f8d, 0xdf6d3f81, 0x2159bf6f, 0x5da39016,
- 0x1edc61cf, 0x0f7d47e8, 0x85fcfad2, 0x1cbb884c, 0xc0efdb17, 0x66bdebfc,
- 0xd8aaa3cc, 0x53ca01fb, 0xe36f4beb, 0xf7511abe, 0xc7495adf, 0x5127db1f,
- 0x56ef3a7d, 0xab3b8b07, 0xb4b88074, 0x6ae7c4ec, 0xb5f199fc, 0x2eee9716,
- 0x32d63d1e, 0xabbfed80, 0x5b5591fb, 0x43112cff, 0x0b1b9fbc, 0xd9723af4,
- 0x0f0d547d, 0x98c3c02e, 0xd896fde8, 0xfd8efff1, 0x80dd0316, 0x758f609e,
- 0x7ad0a7ec, 0x07ab883f, 0xed620fb8, 0x666eb5df, 0x62ad34fb, 0x6d45bcec,
- 0xc5a465ff, 0xe812efb0, 0x4f4bbedd, 0x78aef8f3, 0xb42706ca, 0x9d7c574f,
- 0xbf5b14ba, 0xd4e16adf, 0xe7be037b, 0x67257ebe, 0x05981bcc, 0x78d5597c,
- 0x4a7b0244, 0xf9b4df5b, 0xe7fd529e, 0x78f2cf53, 0xb05d644e, 0x51bbf519,
- 0x1613547f, 0x5bc23437, 0xab7a616e, 0x1fad89ba, 0x023976a7, 0xa9cfda76,
- 0xaf91bb03, 0x911c77ab, 0x83bfb4fc, 0x45237fdb, 0x60acf2a2, 0xc14408fd,
- 0xfd85ea7f, 0x897f6c39, 0x71c6ebf9, 0xf1c752ee, 0xe38f6286, 0x374671dd,
- 0x507f0ace, 0x2e7ee762, 0x4149de3f, 0x9dfd0d99, 0xe409116c, 0xf20c9ffd,
- 0xe31881c5, 0x5a88b5cf, 0x0fc98b3c, 0x1cf1475d, 0xbb9d83a6, 0xb42513e4,
- 0xc63b57bb, 0xfde7087e, 0x19243b57, 0xb57517e2, 0xeeb52f2c, 0x4069dcdf,
- 0x5b84baef, 0xdeae3f71, 0xb2575f80, 0x1ae21f2b, 0x51d2c2ae, 0xbd46aec0,
- 0x7498a093, 0x1476aff0, 0xce14caa7, 0x469daab5, 0x0b9e3704, 0xc5459de5,
- 0x65de1f30, 0xec635972, 0x52f6883b, 0x8bc289e2, 0xe39fd2e8, 0xca469724,
- 0x7f968fd0, 0x39696953, 0x052e8d88, 0xb1858c53, 0x99fcddec, 0xdb779c2e,
- 0x507fd50e, 0x614aec88, 0x8eb06479, 0xcf8aedb4, 0x43f1c321, 0xb47e50a2,
- 0x1db9cfa9, 0x5e83f7fb, 0x4a24eb5a, 0x8a339502, 0x86cf9955, 0x2c23acf3,
- 0xe9f0365c, 0x857aff99, 0xf10d6bf6, 0xd9b457e8, 0x25527cb5, 0x46cce401,
- 0x41bcc41e, 0x936fe560, 0xe634e13a, 0x25781213, 0x298d3eea, 0xa1fd1dbc,
- 0x7c589bb3, 0xff572780, 0xcf8b027a, 0xafc00091, 0x542b2fae, 0xe212cf38,
- 0x3bfbc30e, 0x580f181c, 0x9422c6f6, 0x3443a01f, 0xf58a92be, 0xac1b5ee7,
- 0x67f01cce, 0xbf555a36, 0xc0b4afc6, 0x6ac59b39, 0xf54a7dbf, 0x18a962e7,
- 0x975e41fa, 0xe5faf2a8, 0x9843a2d2, 0x8a59e68f, 0x8e753e7a, 0x31acdcfe,
- 0xaa204b4f, 0xfe601c9f, 0xadbc9773, 0xb708cda6, 0xc56b7f31, 0xc35d7d76,
- 0x37a027e3, 0x127402af, 0x80e2e5fb, 0x3237e23d, 0x4613d7f8, 0x9afc777d,
- 0xb5f8f4d3, 0xdafc7aca, 0xa7f11886, 0xadc3afc7, 0x97e697c7, 0xf8df8776,
- 0xc873fab1, 0x8afc2aff, 0x548ed556, 0x4aff4af1, 0x654c292d, 0x42e9dc03,
- 0x28c2e518, 0x30f61947, 0x9feeff07, 0xafc5a81c, 0xefd40edc, 0xb87cea69,
- 0x1b3becc5, 0xf00f11c8, 0xe08e51ba, 0x79e82024, 0x75d8f91b, 0xfac40acc,
- 0x4d7b7c8c, 0x355cf4f7, 0x0b23d5fd, 0x809b57e9, 0x3f23877f, 0x89bef3b0,
- 0x05975024, 0xc176ea72, 0x59f41dfa, 0xb8458bdc, 0x17b885f7, 0x5efb820f,
- 0xa43e585c, 0x0db4abe6, 0x306e7825, 0x029f3e18, 0xdca1e9fa, 0xf7a069f6,
- 0x29484bbc, 0xc51fc1e8, 0x0f03f3b1, 0x38bf65a8, 0x85abd549, 0xef824c6f,
- 0xe70ca243, 0xdb42dbd5, 0xdea0832c, 0x2a3de3c4, 0xabfa84de, 0x90d6fc60,
- 0x6c5ae0c8, 0x38820c09, 0xc7115ec8, 0x013c5d6d, 0xd87665cf, 0x2f96216f,
- 0xccfa16d2, 0x9f4a28b9, 0x7a3d36b7, 0x36b9c415, 0xa9e7629a, 0x7e9ab14c,
- 0xec1bfad8, 0xc537b792, 0x1eeaf2ca, 0x51e7401a, 0xbaacfd3d, 0xb879330e,
- 0xabf3a556, 0xf9c46f4b, 0x64e214bf, 0xf88a4758, 0x461a6edb, 0x3dee39e7,
- 0xb0cf8d41, 0xf528e578, 0x2fd03afd, 0xdfeb5fa8, 0xddc3e9e5, 0xe7020547,
- 0x2cd546f4, 0x15eb7f45, 0xca73e527, 0x704a7917, 0x616df024, 0xcdef0128,
- 0xd04c7ef1, 0x22dd1fae, 0x4f33f8e8, 0x22f3575d, 0x44c05e54, 0x3edf50f9,
- 0xec18222e, 0xfc0f00a0, 0xfd71ed75, 0xd55685f3, 0x149272ee, 0x970df3e0,
- 0x5ef20e78, 0x7b89dadb, 0x6dbb850d, 0xa3845f71, 0xfa9c3ced, 0xbe25e5a5,
- 0xbf7ad638, 0x62f8caca, 0x9d7044a3, 0x8ed4b8d9, 0x4b03c5f1, 0xf580ae2b,
- 0x7b1fabfd, 0x8e7588ae, 0xc53f4a3c, 0x252c7cb3, 0xfe058c9e, 0xbc31cb5e,
- 0xc697a7d7, 0xf8d7f7c8, 0x8d6fe359, 0xc697d3af, 0x35e56279, 0x7665637e,
- 0x21d2c15a, 0xdafe049c, 0xe38f0e3e, 0x5cf1aeb6, 0x9f8ddcf6, 0x7800c9ac,
- 0xd0e74dbc, 0x3884b6ee, 0xb1bd9625, 0xfec4eac1, 0x6bf8d75b, 0x2eef8f21,
- 0x27a09c2a, 0x0377efbb, 0x813f5bfa, 0x677c2ca0, 0x73c32fa9, 0x642c4bbc,
- 0x85bbc40b, 0x1c5bf4fa, 0x6f93ffc0, 0x7de14758, 0xeb84d4ac, 0x8dd146eb,
- 0x08abfbf0, 0x1a83f8c1, 0x8d37edcf, 0xcf3e8e6c, 0xff3584fc, 0xc7a52b59,
- 0xd21756b3, 0xe6e3c925, 0x3ff77e00, 0xf209dbfe, 0x8cd176dd, 0xfaabec74,
- 0xaf77da43, 0x36dd9959, 0x0ad94e33, 0x64f293df, 0xc7b71394, 0x123c5ee9,
- 0x78a04dee, 0x4ea3928f, 0xbbf1f9fa, 0x71d50f44, 0xbb449e14, 0x2892f909,
- 0xc5d2ec8a, 0x4728fd29, 0x30905c9a, 0x4d8f2047, 0x885cabd3, 0x1ca83b0b,
- 0xc3d8b28c, 0x962477e0, 0x105379d3, 0xfac2c4ac, 0x754e116b, 0x3cc6cb9c,
- 0x7997ca79, 0x608a3870, 0x71121448, 0xdf4d7fa1, 0x6d7a7a6a, 0x59794102,
- 0xa810b0fb, 0x126cfda3, 0xaf885622, 0x01722964, 0x0a251aa4, 0xef179e32,
- 0xff304e5f, 0x78fd96d2, 0x42dd8742, 0x37c47e85, 0xfb5882fc, 0x869c7c79,
- 0x401fcf2f, 0x6a1ce46f, 0x8de6003f, 0x73c6cadb, 0x3b4166bf, 0xa87f43bd,
- 0xba9158f6, 0xdcfb8efe, 0xc209f2c4, 0x3ef44893, 0x687f519b, 0xebb8c9f6,
- 0xbf606b22, 0x189fdc68, 0x055bb49c, 0xcead1bbe, 0xa89f43b7, 0x1098e6eb,
- 0xfbf427d5, 0x66c8d0dc, 0xf72b07b8, 0x5dc72663, 0x3f21c9f4, 0xbefbf80f,
- 0x17c8c47a, 0x2e54c223, 0x32a1f6d5, 0xeae1a7dc, 0x19fb43a8, 0x9e49de83,
- 0xed152a3e, 0x8cdf955c, 0xdbe4d678, 0x77b9f728, 0x0ccd9bbb, 0x1a47e62e,
- 0x275c21c6, 0xe836721c, 0xb078b7a5, 0x29f2dbf7, 0xbf5c281e, 0xf4a3f902,
- 0xb81f384b, 0x21bfe601, 0xe415bd74, 0x27af7be4, 0x5475fa21, 0xbcd3f69e,
- 0x0fae3e27, 0xc04e27ae, 0xf3fef543, 0x46127aea, 0x01c8777a, 0x78e89395,
- 0x46ffc689, 0xa3e4d77e, 0xc8de2e0e, 0x047673c6, 0x0b9e59d6, 0x663065e2,
- 0x7805c9b2, 0x3aedecd5, 0xfe25bed5, 0x56ffb474, 0x1eba88bb, 0x4f800665,
- 0x5ecd44ea, 0xe3a25b77, 0x051dab53, 0x4fdb97a9, 0xfea45ef5, 0x1b39d459,
- 0xfe8ed0af, 0x84a2f79b, 0xfe37bfcf, 0x7914289a, 0x898dfc3a, 0x7f15dd1b,
- 0xb08471f1, 0x9ffec2fb, 0x230cdf9f, 0x7727dc7f, 0xe25aefce, 0xf5422579,
- 0xf5aade47, 0x3f193675, 0xd7969c39, 0xfb682f55, 0x01e9dd9f, 0xa98fbca3,
- 0x70c66fac, 0xeef20f4b, 0x25f8a9b5, 0xb3e80664, 0xb76a61f1, 0xff957564,
- 0xbcfceaf3, 0xb6f78636, 0x8307db5b, 0x3de7ad3c, 0x2f687135, 0xb0264c46,
- 0xb413762b, 0x8ffbdc7b, 0x5bde513a, 0x4feb7492, 0x8fc0bb57, 0xa7d9a9f2,
- 0x7c6a5d9a, 0x552ec3af, 0x3e2d1bd7, 0x795135ca, 0x193cf0a1, 0x1c03f1e7,
- 0xbfe62e75, 0xd05701c2, 0x3d584f63, 0x365fc075, 0xd838973a, 0xce12192f,
- 0xb096f162, 0x93bb3e4e, 0xde419b47, 0xb03f1482, 0xfae9f9fe, 0x1eeb8837,
- 0x0971b19e, 0x85aa5e0c, 0x97e9bec0, 0xd560d847, 0xfbc7f304, 0x6bfbb0e5,
- 0xfbb2e5fa, 0x31c73732, 0xa18b65fb, 0xfa5ac27c, 0x144bcc18, 0xfb9cdf88,
- 0x5006e1fd, 0x64f90e21, 0xf800d29c, 0x382b14b0, 0x71170c8f, 0x19de9473,
- 0xbc839042, 0x994ac489, 0xd247f163, 0xfb48ffb9, 0xf39128cb, 0x06323f81,
- 0x9a373c12, 0x9e7d8a11, 0xf13895e8, 0x8debd987, 0xbcc1ce5d, 0x41cfcaa2,
- 0xa937ce89, 0xe9839d84, 0xf050fb88, 0x8eadbf01, 0xadb2715b, 0xab3ed817,
- 0xd9e1813f, 0xc101bfe8, 0x5a825e60, 0x822257bf, 0x2bfd1135, 0xdfaff03f,
- 0xcaff4164, 0xd041dc46, 0xb1c41fb7, 0xce3aecf8, 0xbfea1ebd, 0x702dda10,
- 0x37268fcf, 0x343c3c9a, 0x40b716e1, 0x775e755f, 0x5f7c0736, 0x00ef172a,
- 0x9c275b9e, 0x6716bc1d, 0xf8c99ed2, 0xf975e14e, 0x9afd1af6, 0xacfd1d44,
- 0xd6895710, 0x08690ef3, 0x5cadedd8, 0xaafc1b9c, 0x831ce5d6, 0xe7a8b397,
- 0x3cdd0411, 0x1fcc6cd3, 0xe7f55369, 0x90b2e3df, 0x84f5b51f, 0xc63d6fce,
- 0xe8f30d7f, 0x386a8738, 0x973c6a77, 0x11dd969a, 0x7cc74a07, 0xee0952dc,
- 0x43672332, 0xbce3b436, 0x124cf6ce, 0x6a64bce3, 0x5cf31ac4, 0xbc5256b0,
- 0x4b780d7d, 0x40126b15, 0xcedea71f, 0x1f1188f4, 0xc47f9c6d, 0xfb47d841,
- 0x1f331883, 0xd2d32b45, 0x4c584a6e, 0xbf4b4fdf, 0x79ed4b01, 0x19885d83,
- 0x71b24c57, 0x64dcec3f, 0xfc18b103, 0xed1b24cd, 0x9de7b4ef, 0xff1415f7,
- 0x37bb8c76, 0x37bc31c4, 0x37bc31c4, 0xe53e1a48, 0xcebf9078, 0xf7975bba,
- 0x4967c1b4, 0xd10f2010, 0xb9f28e9f, 0xdde8c5c4, 0xf682bef9, 0xdca21f4d,
- 0xc4941730, 0x436c9106, 0x21f167be, 0xafc87ced, 0x4024cf7c, 0x96db94be,
- 0x16fbfaa5, 0x0604df46, 0x530df9f7, 0xb214dc70, 0xe2983ac6, 0xc9a96979,
- 0xd3a3710d, 0xc2723f0b, 0x1985e991, 0x0f20792d, 0x1b8f79a7, 0x984a97e6,
- 0x8e6cb85f, 0x2ed30814, 0xc2a81b93, 0x01ba7462, 0x4ccb3bf7, 0xc7aef331,
- 0xe9fed8d8, 0x961738d1, 0x90d36969, 0x92f59d4e, 0x8c4bf004, 0x35e54a7c,
- 0xcea8f17d, 0x6f94cc73, 0x790c5b14, 0x1349136b, 0x185beb87, 0xb1ac95f1,
- 0x35b7aab3, 0x39064979, 0x52ab7d84, 0x3a3547aa, 0x4d5f500f, 0xfe28b8c1,
- 0xbfd7a171, 0x79c37f06, 0x45ea015d, 0x10c88e4d, 0xa0ade7a6, 0xa1e2a377,
- 0xe83f7b6d, 0x9f8efb0f, 0x0739dbfc, 0x55fd3bec, 0x9e807768, 0xbbcf7e3d,
- 0xf4c7380e, 0x2e2c3dc9, 0x4fc18772, 0xfa63645b, 0x74ad8f7f, 0x8177e01e,
- 0x9e791fef, 0x77257e28, 0xe593fdb3, 0xde70de01, 0x506f7f5d, 0x70c93055,
- 0xf11f908f, 0x1fdea55a, 0x46c7a466, 0x2cb78b1b, 0xca59b1df, 0x4f7c6190,
- 0x5c7f8c25, 0x378f43f5, 0xd1dfd03a, 0x63b859e0, 0xd9be0484, 0x7566435f,
- 0x6445bdff, 0x025287eb, 0x151e67fb, 0x0f38466f, 0x2f6af7aa, 0x8fcb25f9,
- 0xdd63a329, 0x27b0f54d, 0x187bcec4, 0x13e4b1e7, 0x129528b9, 0x1cfdc96f,
- 0xfef0ddfa, 0xf33d743d, 0xee1f7ddc, 0xd9e719b3, 0x051f5ef5, 0x2a65b3fd,
- 0x6de78dbd, 0x3ed88597, 0x41e262f8, 0xfe72ecf9, 0xc5cec436, 0x678de318,
- 0x00db650f, 0xa9b0bf0f, 0x323cc4f1, 0xef6dce06, 0xfe20343a, 0x9f56f772,
- 0x828bef52, 0x3ca1bb7b, 0xce5823ee, 0xe2902303, 0xf6f432bf, 0xd55fc05d,
- 0x3ef13b4d, 0x8faaefb4, 0x9c2742aa, 0xe9ad4b90, 0x6e876a25, 0x8b20f903,
- 0x5a7d9d39, 0xc49cf9bd, 0x9f866afc, 0xb7e7d4db, 0x20723e01, 0xd9fe5bdf,
- 0xdbef4a04, 0xd1f3c52a, 0x6f3da5f7, 0xf7c3efd3, 0x3cdabe76, 0xed6b79b5,
- 0x9c5e6a55, 0x0e4d3bf1, 0xb97ca9e6, 0x75f4eb78, 0xea8a297d, 0xa9917ef6,
- 0xf3c3939e, 0x2d9f1a42, 0xe945a523, 0xa349f831, 0x84df076f, 0xd3f38e7e,
- 0xbeb8bae8, 0x3f83c54c, 0x4c4fdd4d, 0x91957883, 0xa73a7a8f, 0x32462add,
- 0x7c8dbe41, 0x7dcddad2, 0xb31b2128, 0x4acb162f, 0xa8cfc411, 0x15cebbf9,
- 0x171cdf65, 0x14fe0fea, 0xe32b6ee4, 0x083d0efb, 0xf7e8314e, 0xff5c4537,
- 0x54e43a57, 0xe90fffb8, 0x13f20e37, 0x4f787ecc, 0x4f98e71b, 0x808a0651,
- 0x4f2c62ff, 0x81954afa, 0x97db3a83, 0x04e73c6e, 0x086dbbfb, 0xab51b8c1,
- 0x69ef0f43, 0xe37a8f1b, 0x4a8f4ab4, 0x3f9be5a1, 0xdadace83, 0xc7177982,
- 0xa771a92e, 0x58e2e64b, 0x39d8b4f3, 0x7778bddd, 0xf9a872a8, 0xfa540b35,
- 0xfb6211dd, 0x4d370be9, 0xc9747a47, 0xa1fd54bf, 0xf50e46b2, 0x4b3e918e,
- 0x3e63d7dc, 0x3e40a2da, 0x5e85df7e, 0xbba441e4, 0xda776e91, 0x371eec5d,
- 0x7b8246a1, 0xe26d8eed, 0x8571ff70, 0x73ff7b10, 0x9df4ddb6, 0x479c63e6,
- 0xdb2ff077, 0x2faebb5a, 0x908ff981, 0xf08dcf80, 0x425ff36b, 0xd4a7a614,
- 0x2f3776f9, 0xf2c49912, 0x7f75d434, 0x815b9c39, 0x790793fd, 0xc6adcf96,
- 0x35f834a1, 0x28f38d78, 0x7cf12be2, 0x8f035b41, 0xf877d979, 0x77067dd9,
- 0xfd70e5ac, 0x9a4e8eed, 0x7bf6d15e, 0x30ca9baa, 0xfb43cb6f, 0xedb63b01,
- 0x29f6c263, 0xcf7873d6, 0x0cf4b75b, 0xeea57cb1, 0xa30849e8, 0x374a62db,
- 0xdebb3ff0, 0x0caf909f, 0x0a27de8c, 0x8c0ca0dc, 0x4122b7de, 0xb15957cc,
- 0xf9eeba7d, 0x8e35768d, 0x9ef5eaa5, 0x24d48fe4, 0x696f8cc4, 0x9fc9a6f2,
- 0xda778f26, 0x0a6f6665, 0x59198381, 0xd1879f80, 0x7afaa1bf, 0x3df99d9e,
- 0xafa5cd0f, 0xa73c6f54, 0x3258a7db, 0x096bd196, 0xbbcf825f, 0x0f14bbd3,
- 0xd8bdbd3a, 0xf8c3cfae, 0xe6d1f3a1, 0x3689c9a1, 0x189ca33f, 0x43d237bf,
- 0xe919ef8b, 0xc007a462, 0x5bc67e09, 0x35816d7b, 0x38b7ce14, 0xaf7fb706,
- 0x4d6ee115, 0xb9c0ac9b, 0xf9f4eacd, 0x3e01fe58, 0xb0fb074c, 0x768eceb4,
- 0x8d87eaae, 0x225c5dea, 0x5ecbb557, 0xd9232ab2, 0x24d2a7b9, 0xb58993e0,
- 0x17161991, 0x583e8f21, 0xa4f7045c, 0x32387c4e, 0xbff14203, 0x5646f07e,
- 0xd77916df, 0xfcfb86e2, 0x690a8a4b, 0x2fd071fd, 0x95fa2fa0, 0x6efbe0db,
- 0xf973c4eb, 0x1fdeccba, 0xcf9d2e65, 0xed66b1ee, 0xb33ed495, 0xf2aef5d0,
- 0x4157e0f0, 0x4a5b2b7e, 0x542e218a, 0xba781109, 0xce2955de, 0xad872db0,
- 0x7be9e3fb, 0x4f3cd91f, 0x76ee21d9, 0x8bae2d71, 0x94058795, 0xc588722f,
- 0x573a0567, 0x6d6efd2b, 0x2993b51c, 0x5a26d77e, 0xd317e0dc, 0x97f07ee7,
- 0xb22a26d7, 0xa35cf51c, 0x70077c1f, 0x7cb135ac, 0x0c6ffd82, 0xc65c8f8e,
- 0x23efd82e, 0x34cfe025, 0x1a582cfb, 0x1725f3db, 0x37c8e79e, 0xb18978b1,
- 0x76bb6dfd, 0x00ce49ae, 0x243ea8be, 0x1fc3fca1, 0x84559fd8, 0x613549c9,
- 0x0eaad0e7, 0x53773c13, 0xcf08a87d, 0x84b9c0dd, 0xe07a754f, 0xa6ee735f,
- 0x9e18af93, 0x44ae040a, 0xd0b71a88, 0xf9d5d56e, 0x9810d354, 0xdce3e10f,
- 0xcf846e70, 0xa2ecd530, 0xa0afe7f3, 0xe087c525, 0xff70f372, 0x89e4fd4c,
- 0x559fdc3c, 0x2d79aa27, 0xbe3e7626, 0xe557dd63, 0x39fb2b4f, 0xdd028f4a,
- 0x25b1ff4f, 0x53f6c6cf, 0xe6d6afd0, 0x8429c75b, 0x35ed7f03, 0x7219e782,
- 0xe0334993, 0xb19446cf, 0x47166fc0, 0x6c97caa2, 0x65fe9b3f, 0x9b36e940,
- 0x7e53237e, 0x9fc1faff, 0xe3bbff22, 0x68b2ab4d, 0x59f8739d, 0x2e74c33d,
- 0xef30b28b, 0x6bf565a8, 0xd006e74c, 0xc358e8ba, 0x4af1b0ea, 0xa3b33e17,
- 0x143fc8ae, 0xba3171c6, 0x01ae50ee, 0x2c4c16fe, 0x901c23ae, 0xcb477f70,
- 0x794b5957, 0xe2d1f806, 0x5d747a60, 0x3673c16d, 0x28179b88, 0xec4fe432,
- 0xfa41ef51, 0x5786a5be, 0x7f4266de, 0x7fc04a09, 0x53e183bc, 0x54690ba3,
- 0x5e3c81ae, 0x81ae5412, 0x0e7ebd7d, 0x7e83a24f, 0x96adf23f, 0x1bcfa089,
- 0x0f28f9df, 0x82bf73ef, 0x2df233f5, 0xf9d243ea, 0xff6dfe9c, 0xe4fbd1cd,
- 0xa9f91cfd, 0x03251df0, 0xec9cafda, 0x3951b722, 0x2c8853ac, 0xad9f8365,
- 0x091b2ff7, 0xd91f4fd3, 0xa070af4a, 0x3ae3093e, 0x67bb13f6, 0x7e8dd400,
- 0xec496933, 0x949dde55, 0x17ee3773, 0x7d346625, 0x85d610b8, 0x4a7bb1df,
- 0xfcc14538, 0xee3b17d3, 0x9718236b, 0x373891b2, 0x9b898dc4, 0xd453f9a4,
- 0xf1899af8, 0x945e7255, 0x87ceacff, 0x79085f7e, 0x2c6c63f2, 0x8fce81bf,
- 0x823afd07, 0x848e58c8, 0xa0365938, 0x3df583d8, 0x4fe1f824, 0x588fff69,
- 0xb2ca7c59, 0x8fe2e89d, 0xb7160e65, 0xe2c9c079, 0xf062718f, 0xe22bb016,
- 0xd81710ce, 0x4b8f6d15, 0x0bcfee02, 0xdf709bae, 0xe309a0ee, 0x018b4fdc,
- 0xb517ec17, 0x5bc8255f, 0x6d7f6748, 0x7eb5dd2a, 0xabe4911f, 0x0bf7ee20,
- 0x9d3fab27, 0xbb8f304f, 0x801484fd, 0x0cc4dcfd, 0x3c744d4b, 0xd9839e69,
- 0x1573bfbb, 0x043a04cc, 0x1811c6f7, 0x38becc7f, 0xb9e3d013, 0xe056b91d,
- 0x4701178b, 0x66890f14, 0x5fd09dd7, 0x6f0a39e2, 0xf9673e16, 0x223c82fd,
- 0xfc77e29e, 0xee19768d, 0x1ada7ad1, 0x56f311bc, 0xbde1379f, 0xee4a2fc1,
- 0xf17f50e9, 0x3d02ecac, 0x305674fc, 0xbcf3e70e, 0x62f3e709, 0x2bd5fb5c,
- 0x0c0fdc29, 0xc12ef161, 0xcfd00446, 0xbe40a982, 0xae5f3e93, 0xafa6b1f2,
- 0xd11c8137, 0xc11c23fa, 0x29820c73, 0xcb48e51f, 0x276b6a27, 0x67d44f98,
- 0xfc0f0b66, 0x8b5d371c, 0x8879853b, 0x25284d17, 0xb04dcf68, 0x05ce788b,
- 0xbce199f2, 0x0f5544db, 0xb2b8fc4f, 0xbb07e584, 0x9ebdc30f, 0x7ef576cd,
- 0x739f7530, 0xd727ca92, 0xa16f0891, 0x245dd7ed, 0x4d27886e, 0x8fdfa8ba,
- 0x5f60ca78, 0x57fb514e, 0xf0855dda, 0xede89f38, 0x450d29bf, 0x2c3d6027,
- 0xfc008a20, 0x6862d934, 0x09d23b07, 0x9febf0f7, 0xfd50e03f, 0x19924cdc,
- 0xeda6c79d, 0x87e14d43, 0xb5fb446e, 0x5e037258, 0x0f95da76, 0xdfc03f20,
- 0xc5cb9222, 0xb1f29f25, 0x1721c37c, 0x2cae046d, 0x8769fca4, 0x50dd5cf9,
- 0x79d2b7ef, 0xf5903d5f, 0xfa087c0f, 0x93c7cae5, 0x8fdf4093, 0x95a5e957,
- 0x7f01df1a, 0x7f19e2b9, 0xca7786b9, 0x2c8ed3e7, 0x37934f7c, 0x67e83be0,
- 0x1f98188f, 0xf29bbf6b, 0xafc0d3eb, 0xfd04ed3b, 0x5ba59fb8, 0x699c80e6,
- 0x7caab4e3, 0xd5d72c6d, 0xbf0fdcae, 0xc0bfe4fb, 0xbec28dd6, 0x75e8a517,
- 0x83024fbf, 0xcfd72bd7, 0x68790698, 0xccf31176, 0x5173d452, 0x1e92fcd1,
- 0xdf1a2fc5, 0x9c59dab5, 0xc99fe348, 0xe1e5dfbb, 0x840be4f9, 0x8748b2b8,
- 0xcff1a2bf, 0xf7187f44, 0xe6122781, 0x67f9189f, 0x93fc3757, 0x40165e7f,
- 0x9fe1756f, 0xba7f8c43, 0x0fda1be3, 0xe4616bde, 0xaa1c779f, 0xff2dddbd,
- 0xfcf3c25c, 0xbe4ef7ab, 0x93657eec, 0x6a9f9f4f, 0x62d9c72c, 0x54bb2fe7,
- 0xea96efbc, 0xbd01ca6f, 0xcec4d531, 0xe32409ef, 0xeeef0a16, 0xfcdeed38,
- 0xefa86c9a, 0xda1e9814, 0x1ea33219, 0x78f769da, 0x669b7e30, 0x0557e761,
- 0x23ce044f, 0xe45afbb8, 0xd921dfe8, 0x587660ee, 0xfb8f0c50, 0x37f1ec02,
- 0x9d8c1f18, 0x2a43cb9a, 0xa662fa5a, 0x971d4617, 0xcfefc336, 0xbfccea3d,
- 0x06967c00, 0x79dfa3b8, 0xcf784a8f, 0x0951f552, 0xf76fe3f5, 0xf1045dbd,
- 0x79cf2d51, 0x8bb79ecc, 0xfbc2860a, 0xa1fedf8c, 0x8ead65ea, 0x5f404047,
- 0x1fddee1a, 0x4b1e71d7, 0x297e6f7f, 0x674e51f0, 0xf93ef1bb, 0x3fdb1c60,
- 0x11644d99, 0xb4719886, 0xdeb85ef4, 0xfcaf78cc, 0xff3b30ec, 0x27b0f336,
- 0x2af2bdf6, 0x37ef187f, 0x8a77f6a7, 0xe7efec13, 0x6841f65a, 0xdd6cc884,
- 0xd7354a0e, 0x26a33f30, 0x9349f81b, 0xf8a3fc43, 0x44327e0b, 0xb706bbf7,
- 0xd07ff3a9, 0xa9fbb02d, 0x4bee1222, 0xefb09cfe, 0x363aea82, 0x40f4c9ca,
- 0xe617eaee, 0xcb239c03, 0xcba06695, 0xd7162eb3, 0x5b0905f9, 0x6e6e81b2,
- 0x8253f701, 0x0bf93ca2, 0x223df3ae, 0xd3b10e94, 0xe27d3df6, 0x8ff8c246,
- 0x9c633d3a, 0xed099f60, 0x31bbe087, 0x824773e3, 0x588fb71e, 0x9aeb049b,
- 0xab853706, 0x13bd9b78, 0x81ae0d0e, 0x8f97c64e, 0x00c6cb3a, 0xd03be01e,
- 0x8e474d4b, 0x8d7be059, 0xcf7b821f, 0xe2883e30, 0x4e83e00b, 0x4016e0be,
- 0xa283c35d, 0xfdb7cfae, 0x8b42f88b, 0x17c8f46b, 0x7e70b710, 0x0b98be2f,
- 0x05f23578, 0xce3ce7b5, 0x505cf618, 0xc6937962, 0xe7b13fe7, 0x896efbe3,
- 0xd913de60, 0x6bbf6567, 0x7dc049e8, 0xd8b8df90, 0x1c9f6d98, 0x28a6a4cb,
- 0x7664e559, 0x2a3bf6bd, 0xda1cc223, 0xa2a8239f, 0xbced0db8, 0xdd27a87e,
- 0x31c8fe2a, 0x46fb838e, 0x033e3731, 0x1270d0ec, 0xcc236bd8, 0x87906125,
- 0x1989b65d, 0xdae63f60, 0xfcc36426, 0xfab21e5f, 0x5ed2584d, 0x9bfe5bee,
- 0x7da772ad, 0x66c3e9a5, 0xfc6d5bb5, 0x4c7f2a35, 0x2779d852, 0x70d1ebd0,
- 0x9003eb68, 0xc2e0e009, 0xdadf4db3, 0x22878f50, 0x00936f14, 0xfd878a0e,
- 0xfb04691c, 0x24a4df21, 0xb03b064f, 0x3800584f, 0x9d7ef6db, 0x92cef109,
- 0x021febd0, 0x3eda25bc, 0x0fbf5bac, 0x35b7b46b, 0x3ff3487b, 0xf3497b34,
- 0x82aec17b, 0x1fd532f6, 0xbed99971, 0x05b084d8, 0xe47853ef, 0xa2957cac,
- 0xe740b3ca, 0xe3cea251, 0x7082d266, 0x4ca9f769, 0x7251f153, 0x39abfa88,
- 0x54c84ed0, 0xeaa9878a, 0xdd532a7d, 0x6e22fbfa, 0x3efb1b1e, 0x9e9fad15,
- 0x1bae37de, 0xa3f61ad7, 0xc879687e, 0xf94feec7, 0xc3f98fbd, 0x7ef007e3,
- 0xb1dfd601, 0x09feec59, 0x21c3c317, 0x763af629, 0xf1eb9551, 0x9c0e48a6,
- 0xe7bfdec7, 0x1e6eb8ef, 0xf7f7f3d8, 0x771c8ec1, 0x97902042, 0xa8c4fe3b,
- 0x180fcc78, 0x695f232b, 0x6f3f7afd, 0x9cf611b4, 0xccdeff44, 0x728f0a41,
- 0xc167c025, 0x8f5395f2, 0x9dfd0a3c, 0xe8902a3f, 0x92451f73, 0xe5c42067,
- 0x1ddfd48b, 0x7b31c83a, 0xa83f6b4a, 0x11c7defe, 0x21216f95, 0xc567bb43,
- 0xa9e7451c, 0x1a1ffdea, 0x2f1ea75d, 0x74e4213e, 0xfdfc0fa5, 0x5a10e233,
- 0xaa9ce1fc, 0x9ff3490f, 0xf5ce7cf0, 0x600a778d, 0xc69f5fbf, 0xdc6a2513,
- 0xe9ea641b, 0x4e21c547, 0x6ff60d3a, 0x4e8f33f3, 0xb7e5bc83, 0xf4814c78,
- 0x99be7686, 0x3e16f503, 0x462abde6, 0xba1f5efc, 0x9955ef13, 0xa3e4cf1b,
- 0x5fc7f1a7, 0x3864f94d, 0x3b309dd0, 0x4bdd8f30, 0x81efa462, 0x1491ff3d,
- 0xbe3dda19, 0x91bfa3bb, 0x2a9caf0e, 0x9eac7dc0, 0xdbe461e8, 0xfe9e747d,
- 0x5377e12b, 0xbf8fc42d, 0xfac2ea9b, 0xac34beab, 0xddeafc6b, 0xd81264fb,
- 0x4e9f1a79, 0x337c6249, 0x49a3f76e, 0x2f49dec4, 0xc586de23, 0xc97ffe33,
- 0xee25d9aa, 0xa3e8d359, 0x843ae977, 0x2d27ea8c, 0xaa563790, 0x70fb3ac2,
- 0x4425da11, 0x5c62cf3d, 0xb7f366df, 0xda75014d, 0xccfeefd3, 0xf57acb94,
- 0x6fc5397b, 0x0eb00bd5, 0x99ab0916, 0x78ed531e, 0x9d231e0d, 0x08a523df,
- 0x19f0777f, 0xe708c0f9, 0xf6f91d4b, 0xda07ae0a, 0x18cce0ef, 0xc6262598,
- 0x8f868798, 0xc7ae8499, 0x8f5fbdd9, 0xdbd78c6f, 0x178ee7ef, 0xdad011fe,
- 0xe919bc9d, 0xf4d76c66, 0x900c1147, 0xec1fa58b, 0x29f1b993, 0x8ba2df48,
- 0x3ae85112, 0xcfe9fa43, 0x2b9293f5, 0xb956df91, 0xf8eeb3d8, 0x4f22faad,
- 0xf93b233c, 0xd87a6c4e, 0x5bb77c06, 0x1c41b7a8, 0xf4fb3af5, 0xc2bd103a,
- 0xe2660bcf, 0x131115fd, 0x94dad081, 0x886699d0, 0x243f7833, 0x20a1be78,
- 0xf0327fb4, 0x0b42abe9, 0xe76d59fa, 0xca387909, 0xd50a6cee, 0x6b2ec0d9,
- 0xf3e7664a, 0x5d10260e, 0x78c5f4fe, 0x8e9a6fa6, 0xc4a69d9e, 0x62ee1f68,
- 0x28833cfc, 0x9ff439c9, 0x7f29eb45, 0xc7dc1f80, 0x42927181, 0x325afdce,
- 0x39732dd8, 0xf6da23f4, 0x992d798e, 0x7b7adbc2, 0x2999ea02, 0xe9ddf74d,
- 0xfe0884a2, 0x6f3e2463, 0xfef0e32f, 0x8dd92284, 0x59c5a2f5, 0xf98df7e8,
- 0x09466926, 0xa220dfb4, 0xaf8533df, 0x755e2014, 0xabc38d3a, 0x9170f63c,
- 0x623df85a, 0x0e3674ff, 0xc093f971, 0x24a77d3f, 0x66fe0469, 0x07d5ac9e,
- 0x122eefe1, 0xfab6ff83, 0xcdfb73a5, 0x2cf57db4, 0xa78df30e, 0x3f8832b8,
- 0xd68a7f8a, 0x5baf384b, 0xc005a942, 0xf58a33d7, 0xaac31ee7, 0xd4ab393d,
- 0xfbd10246, 0xe50b9cf9, 0xfdb5a0fa, 0xf11dfc56, 0xf98122bd, 0xa37e7269,
- 0xe7b3efca, 0x9bbee924, 0xa9dd984e, 0xaa4dd5c9, 0xfaa8ddfc, 0x193d73cd,
- 0x094bf1ba, 0x40fe87b3, 0x64810bda, 0x7ed8b8f7, 0x96f6b4f4, 0x25e1f3c3,
- 0xd068dfbe, 0x310d3787, 0xe57cbdf8, 0x348be45a, 0xc8f78dce, 0x37edf5b8,
- 0x8dd7d58f, 0x0fd46bf2, 0x8f8b20b3, 0x3427aaef, 0x2f6b307d, 0x683c422f,
- 0x33c53e56, 0xbb7ac5da, 0x317d27bd, 0x7d1bae26, 0x17be4971, 0xfa2e90cc,
- 0xefe2e3e2, 0x4b7e2fa5, 0x54b196dd, 0x578edfae, 0xa4fecdd7, 0x298de83f,
- 0x81478efc, 0xbae8da8f, 0x47c18e69, 0xc5a3bada, 0x1ca88a01, 0xc5381ea3,
- 0x5ca663f6, 0x91fe274c, 0x0e80719d, 0x12ed423d, 0xa97b0c77, 0xe51b3e35,
- 0x68ef43ab, 0x2eca257a, 0xb87ef311, 0xda85325d, 0xc02e52a3, 0x2be10fd7,
- 0x2925ef52, 0x882b8482, 0xc19da61f, 0xa0579038, 0xcfae2cfe, 0x817f224f,
- 0x3b12e3fe, 0xaf68c3e5, 0x0ae87168, 0xe94f6697, 0x1e23a5f9, 0xc3dd9339,
- 0x1149f1aa, 0x7fe413e0, 0x04fb8f26, 0x7fd41bff, 0x8000b303, 0x00008000,
- 0x00088b1f, 0x00000000, 0x7cc5ff00, 0x55547809, 0xf579f096, 0x55492d5e,
- 0x146caa92, 0xb612f08b, 0x84582484, 0x5916ec80, 0xa014a358, 0x8168cb80,
- 0x9a126b0b, 0x69ee9c71, 0x0242a6ff, 0x83b74343, 0xe8cedad2, 0x3ad857f4,
- 0x08b41a83, 0xd09d0301, 0x584c5015, 0xf82e0834, 0x1a6d1ad9, 0x84490ed1,
- 0xbfbb46d6, 0x739cffcf, 0x2aaa4bef, 0xffff4d85, 0xb49fdf3f, 0xdeefb97d,
- 0x67b9ef77, 0x979ee73f, 0xb3559bdb, 0xf6e008ad, 0x14078a99, 0x77f1d000,
- 0xe042c022, 0xadacc37f, 0xc78ef016, 0x69fcd7be, 0xe7f80d87, 0x9c2ffc3b,
- 0xa42cfc90, 0x900bcf50, 0xce54b009, 0x7d57fc5f, 0x3c5e3d33, 0x52fe7a27,
- 0x92b9fd98, 0xf81b700c, 0xf71c30cd, 0xff8ec5f3, 0xc7154bec, 0x7e8b2e97,
- 0x4a4ce99e, 0xff8790bf, 0xbe230118, 0xd4ca0153, 0x22b79dba, 0x5527ddbc,
- 0x334c558f, 0x390ffed1, 0x350ffec5, 0x7c800c97, 0x1674df80, 0x3db1f8a7,
- 0x1c2111b6, 0xd1bad00d, 0xec71edc6, 0xefc5f107, 0x3c66e7e8, 0x21fc059f,
- 0x52b4b607, 0x4801b721, 0xc4ed1805, 0xff602745, 0x0d3f9e2a, 0xc02486c7,
- 0x5c2473ef, 0xe7af00d9, 0xf104e798, 0x5eb8c3bd, 0xe30dd700, 0xf75c01fa,
- 0xf72746c8, 0xe6e8db5f, 0x442e0dfe, 0xfac0066a, 0x37af2714, 0x8776f72f,
- 0xe35bdf1f, 0x50e7e6cc, 0xf844da3e, 0x7b2fe036, 0x1004086a, 0xac77afdf,
- 0x807494d0, 0xb1e2b72a, 0x01d1f566, 0x8e58e34f, 0xbe25cbf3, 0x102ab72b,
- 0x1fe5e7c4, 0xc4072bae, 0xee33575f, 0x2aa9f887, 0xfc368355, 0x63d34967,
- 0x0cdf453b, 0xdefa08d6, 0x33028e22, 0x86cd16b5, 0x28f02cfb, 0xf1f7151e,
- 0x6ff78936, 0x1d412af5, 0x278b79ff, 0x63871e9a, 0xae58bee8, 0x0ffe80b3,
- 0x47305bdf, 0x9d718609, 0xdfa29305, 0xd6757c5b, 0xfed8cae7, 0xe898b47c,
- 0xbf3fb63e, 0xb7744edc, 0xc1863fe3, 0x95fba230, 0x8d6fa58b, 0xc5ba3e85,
- 0x8e74b1b6, 0x9d16bf1d, 0x673a27ef, 0xc6ce9b5c, 0xce8b7ffb, 0x904e110f,
- 0x1bf470be, 0x30049e8b, 0x1a07e9bb, 0x55f679d1, 0x32add78d, 0x861433ce,
- 0xd4fe79d2, 0xb76ff859, 0xaafcdf42, 0xfe2d2fa6, 0xe79f6b82, 0x22bfed6f,
- 0x69fde745, 0xdf7e6f5f, 0x8034f3be, 0xf9ce78c1, 0x8df8d139, 0xbd2c6ba5,
- 0x62f7ca16, 0xe635b5e9, 0xa05d061c, 0x60689913, 0x555fbc1c, 0xd16b8e19,
- 0x162e97ad, 0x7e4f08ff, 0x5f8071ff, 0xd6fab9f3, 0x76827493, 0xe02057cd,
- 0x03c84732, 0x052075f2, 0x0ade5be9, 0xec0444e1, 0x3e738b96, 0x28f5a8d7,
- 0x39c469f0, 0x8353e7e8, 0xfadf6ace, 0xb2075765, 0x96fb19fc, 0x14b01069,
- 0x972173d2, 0xd255f0b1, 0x7e69233a, 0xcb68f980, 0x10b2d32e, 0x05ba639e,
- 0x9b51f5ee, 0x4e03da28, 0x9d1a07a1, 0xfbb75e26, 0x6e099b2b, 0xf0e57804,
- 0xf8406280, 0x09e7563c, 0x33218bd2, 0xc945fbf0, 0x9cdfcf3a, 0xdc048104,
- 0x9b76b41f, 0x2b44f90f, 0x3941c806, 0x825906d3, 0x9d64b835, 0xdc91f616,
- 0xa8347b75, 0xd1bbb946, 0xe048ef78, 0x6c92402e, 0xa99474fe, 0x0fde8b26,
- 0x79c54fb7, 0xfa6a1537, 0xb2e29c36, 0xf1a03fea, 0x93ab66ae, 0xf83eebde,
- 0x5a662dcf, 0x20f02be7, 0x335af084, 0x4f8e1532, 0xa4839873, 0x93d4ca37,
- 0xddfb09aa, 0x8fa4003d, 0x970b2da6, 0x3a6dd200, 0xb138d7b4, 0x8c74429d,
- 0xd0bfbf43, 0xde843379, 0x9a74881a, 0x4334e921, 0x6692abea, 0x4946f595,
- 0xac841a92, 0xb374fd3e, 0x408cd1a4, 0xee0a497b, 0x3c53433b, 0xf9bfd835,
- 0x8fc516aa, 0xba3e932f, 0x951f4fb1, 0x3dbdf5c9, 0x019686ba, 0xff344266,
- 0x3d0a3596, 0x798b6254, 0xbe0fed2e, 0xe6557cc9, 0x429f1e8c, 0xfbf913ba,
- 0x825e8c62, 0xa653fb18, 0x03b935fe, 0xc58af0f1, 0x8454defb, 0x19b4e7bb,
- 0x70e7c59e, 0xfb933b11, 0xc631a7e3, 0x07b6c51e, 0x757a270f, 0xe215eb84,
- 0x07f50723, 0xd7b1f579, 0xa3b63f9e, 0xf18e98a7, 0x0d22dd4a, 0xcf2d99b2,
- 0xf0fb33ba, 0x92bf0fde, 0xad78b10e, 0xdbde7a97, 0x8e8d7ce8, 0xad8f0fdb,
- 0x979ed8b3, 0x48d749fc, 0xf8bdfdf5, 0x95e5e434, 0xe25e890b, 0x0c2e57ff,
- 0x4afdb2f2, 0x0c3e59d2, 0xfe783879, 0x51e92272, 0x21aea7c4, 0x6cb8f49f,
- 0x9f99679e, 0x06841c85, 0xc36e0a8e, 0xc12485fe, 0xf624aff7, 0xbc23cf1c,
- 0x3cf262df, 0xeb68db4b, 0x202a2f87, 0xd175b9fd, 0xe2803379, 0x2887e505,
- 0x84ee8a4f, 0xa00db1bb, 0x05ff113c, 0x72482152, 0xd0108662, 0x785e35be,
- 0xd319da9a, 0xfbc214f4, 0xddb35c65, 0x29e9eb41, 0xd7f0f7c4, 0x057d132b,
- 0xbf5ff1fd, 0xee1a7c11, 0xe6d1b0d3, 0x1c2f50d3, 0x7ee4e8d8, 0xb73746e3,
- 0xdcea3687, 0xfc913a6e, 0xaa1ff243, 0x169f16bc, 0xa5e657a1, 0x0330fd0a,
- 0x35c10ef5, 0x00609403, 0x23c66f79, 0x7288f2c0, 0x10a4dc10, 0x393cf0bd,
- 0xfa44f87d, 0xe888ee5c, 0x3b56ad43, 0x82a59321, 0x67985ee9, 0x09d1f7e2,
- 0xd59f3e08, 0x3fd23e7f, 0xfc8cbfaa, 0xefc38416, 0xb0b996f2, 0xb37c390d,
- 0x7adf885d, 0x4bd1e965, 0xf4b9fdc0, 0x43b95ebc, 0x8feb84bd, 0x1f84cf0f,
- 0x8f18bda2, 0xe2bc2184, 0xff045dcf, 0x100b1684, 0xb2b0d07d, 0xf21a167c,
- 0x5ca2b5f9, 0x8448fdc0, 0xef8c1bbe, 0xc4c3cb59, 0x23a0074f, 0x645ef08d,
- 0x7e49d9f3, 0x3f04b997, 0xdddb9578, 0x3937ae0a, 0x0951e2c3, 0xf1bee1b4,
- 0x2d7f11eb, 0xce21b819, 0x1cc9696f, 0xb713e7a2, 0xc93ef1bd, 0x08e6d7b7,
- 0xcc986cab, 0xf6111d9d, 0xe33c007c, 0x74927f24, 0x476877dc, 0x0e4e3f5a,
- 0x6abb9eb0, 0x6b5e9209, 0x09ec933d, 0xafd33ee3, 0xacbfd8da, 0x6e5117a7,
- 0x8f26270f, 0x42133d65, 0x63f2430d, 0x6d98e713, 0x3c23aff6, 0x7a3e65a0,
- 0xedfbdf0a, 0xafd20065, 0x543fdbd3, 0x312d0fc9, 0x40e80ee5, 0xa32a8f38,
- 0xf27da853, 0x6e7ce4e3, 0x127724cf, 0xec9b0e7e, 0xcefbed3a, 0x0474bd46,
- 0x8da9cbf2, 0xf9023a50, 0x368dade3, 0x746f4f6e, 0xa3667b72, 0x38a3db9b,
- 0x3af3fc4e, 0xbd7f138e, 0x6fd4e381, 0x4f6a71c3, 0x7ad43ae0, 0x489872df,
- 0xe5bc677e, 0xbc2da8d0, 0xfadb892b, 0x742c933b, 0x50c9c38e, 0xfc4fec67,
- 0x370c4e14, 0x2ee50780, 0xdb53fdd5, 0xad3f680d, 0x1c6502fe, 0xf754d4c0,
- 0xae3a6d5c, 0x8fe87b3b, 0x19f1c2be, 0x6a7ec3a9, 0x3b6f7843, 0x893868e3,
- 0xf5c7d2fd, 0x3f883a9f, 0x92a2244f, 0xb7643c24, 0xc7365179, 0xc418d293,
- 0x24c2f768, 0xfd19a7ec, 0xc8a5b9ec, 0x3a4a4b0a, 0xb005c0f2, 0x73e1b1f3,
- 0x25df886d, 0x513fff76, 0x9b6812df, 0xfa9d3a53, 0xbc927010, 0xcb20e62b,
- 0x7d2510fb, 0xadbfda11, 0xd4c4ff0e, 0xabc07f08, 0xf48d21fc, 0x02af44c3,
- 0x77a674ae, 0xf7d2a470, 0xd5b798dc, 0x15313651, 0x2ed7f7f9, 0xc269f995,
- 0x741bc534, 0x635f97f4, 0x7af384de, 0xe26fd129, 0xd4b559c5, 0xe2e3982e,
- 0x4dd96fbe, 0xa5ff24b5, 0x5fbd6b8e, 0x5c87efc2, 0xc547d666, 0x638bce1a,
- 0xe3798d17, 0xffc8c991, 0x0c4b69ee, 0x7d7c4b3e, 0x84935fd6, 0x567732fd,
- 0x34752aa1, 0x6bb5df70, 0xbf978d1b, 0xe572c0de, 0x59e8f249, 0xa5ed8ac4,
- 0xd33e3869, 0x24c278a1, 0xa93ed32a, 0xa771a34d, 0xcdb421e2, 0x553b8ef4,
- 0x5423e344, 0x9fea4ccf, 0xd89d4bd5, 0x4e66d19e, 0x66f384bd, 0x6c78a4e7,
- 0xf099def8, 0xff10ae8f, 0xf249ccce, 0x1714e824, 0xa4ae9f04, 0xa9eac7be,
- 0x8f1ce9d6, 0x3ad32495, 0x6131e2ba, 0x92d6febf, 0x147045ff, 0x514052fb,
- 0x91a5dc68, 0xc7e4fb1f, 0xe275293f, 0x0aa1fabc, 0x099cfc90, 0xe091fee7,
- 0xa89ad99f, 0xf5402027, 0xbd296716, 0x9c516f57, 0x2befb89b, 0x5181f9a1,
- 0x5c79fd66, 0x769de4f7, 0x6fe507b6, 0x745fb3e5, 0x6cc1cef2, 0x9adfca17,
- 0x49ed4c56, 0xcbdbf093, 0xc39f2adf, 0x930826e3, 0xebbf2952, 0x1dbdf81f,
- 0x4d293f25, 0x0c4ff5c7, 0x416eb173, 0x116a953a, 0x83e70d7a, 0x55dfef42,
- 0x945bf3c1, 0x8f3a3f01, 0xa7e4aff3, 0xff715a14, 0x5109e959, 0x710ce7f3,
- 0x8de7f545, 0x45aa5818, 0xfcf2b1d8, 0xadfea8ac, 0x88e94a45, 0x69bef988,
- 0x45fd5109, 0x11d2aea5, 0x2b6ff311, 0x5fd5181f, 0x54565b72, 0xb269a67f,
- 0xa11b1fd0, 0x7dc854bc, 0x9bfb2979, 0x0a87acd9, 0x1bee629d, 0x8e3f7e38,
- 0x7f09b617, 0xfe85d0aa, 0xb4a5d214, 0x80fd88ad, 0xc68f7c36, 0x8f52ec8b,
- 0x3ddda005, 0xfc80ec91, 0xf62fe209, 0x6677658b, 0x6305fa3b, 0xb768ae89,
- 0x752fe023, 0xfaf1db44, 0xcc27e144, 0x0bad7f01, 0x75a739e9, 0x6557fb1e,
- 0x6145d5e9, 0xbf467c20, 0x2a370b1f, 0x13779dd1, 0xac6ab61f, 0x890ce737,
- 0xd4adafd9, 0xf48c7ec1, 0xb7c8e6ef, 0xe0217d8c, 0xc6ff276d, 0xffb18738,
- 0x4733ceb5, 0xe17ec69d, 0xacd73adf, 0xa9a5859c, 0xcf5fe171, 0x9c2c4cfe,
- 0x4f32a979, 0xfb15fe81, 0xeca9ad85, 0x7a4fe22f, 0xf0c13f3c, 0xcf51ca7f,
- 0x9cf522b9, 0x585f4943, 0x673d6d70, 0xff2d7bac, 0x78d758cf, 0xde54ea1f,
- 0xf7bf78df, 0x7fc4aeb9, 0x27e71bbe, 0xae9e79c5, 0x5cfe7fc4, 0x9a19fcf4,
- 0x7940e35e, 0x278a0e3e, 0xa93f7840, 0x959ae46b, 0x52d6f59c, 0x5fa1f65b,
- 0xf670b723, 0xb52d40f9, 0x27833b53, 0xb9fe78ad, 0xf94eaa39, 0xea2fc307,
- 0x0aa56717, 0x55f8e47f, 0x78e3aedd, 0x53b7407d, 0x88ff51dc, 0xaaf8a76e,
- 0x28730bde, 0x370ef48e, 0xc438a7ad, 0xf62d879b, 0xfa154def, 0xdf7c857e,
- 0xfea90f68, 0x857f0415, 0xf251e3ad, 0xe9bf2a49, 0x1c5f10b1, 0xbf2f7f27,
- 0x5c77bfbf, 0xbf683a0b, 0x1d048fe3, 0x7e7d08be, 0x22defebd, 0xe20ca662,
- 0xa917c553, 0x096c4a4f, 0x51fd48be, 0xf54574e6, 0x83ff93c7, 0x0f76cdef,
- 0xae6f7a8c, 0x0f35159e, 0xf21cd8fd, 0x902c6a87, 0x353e91a3, 0xcfc87a25,
- 0xefe3c58b, 0x0e3df9e5, 0x6051b927, 0x7f55d74e, 0x29e4fb1c, 0x7d8bf811,
- 0xc4553dbe, 0x9ec88373, 0x52273ae3, 0x556b6e75, 0xd0e6709f, 0x887e267f,
- 0xbaac63ed, 0x95c3d68c, 0x1e77c4dd, 0xba0ae9bb, 0xe3d2f0e0, 0x686ae7f3,
- 0x4de33dff, 0xfb1c38ff, 0x215f1ec7, 0xfb4d53fa, 0xfadfb1b2, 0x7fa27df8,
- 0xd9bc69a3, 0xb819ec83, 0xf9296e7f, 0x7fbee90b, 0x9b75fa27, 0xd4155b1d,
- 0xa8099503, 0x4cd5b0d7, 0xf7a6140a, 0x2ddbc7c5, 0xc0915f68, 0x175e6cc8,
- 0x156ec0d2, 0xc26574f1, 0x13d920d0, 0x13abd8ad, 0x0c132ade, 0x9264777a,
- 0x09da879d, 0xdd9d7151, 0xfbe1ef82, 0x0bff3665, 0xc9c26f82, 0x87a5ea3a,
- 0x200d960e, 0xea9138fe, 0xede43c64, 0x7d26ea9b, 0x21edf085, 0x01fffefb,
- 0xf078e6be, 0x3ec59ad5, 0x2579f59d, 0x86f38f64, 0x3e947921, 0x3a6a15fa,
- 0x21084f3f, 0xeebfb0ef, 0xb1fe5375, 0x90f165c6, 0xf2427eff, 0x35b6f5ef,
- 0xdaa18f32, 0x29a91f05, 0xb17bf5a6, 0xcff25b7d, 0x6a2fb919, 0x910ba1be,
- 0x33d9c03f, 0xe8815174, 0x6aa87f13, 0xe1f90f61, 0xe490ff3d, 0x83f9f8a1,
- 0x183f8144, 0x8fd1f3d2, 0x777bf9f1, 0xf1b679e7, 0x65a78173, 0x0e9aecc1,
- 0x06b38fec, 0xe3fca06f, 0x47ff34a1, 0xad3b8784, 0x87cc91c1, 0xb449f58e,
- 0x8e05e28f, 0x0ff88c53, 0x32dd3ce3, 0x705c7fbc, 0x46c1fded, 0x64e96576,
- 0x7f637781, 0xe88db1c4, 0xf124def1, 0xe10780dc, 0x303e26e8, 0x0785eae0,
- 0x8f393886, 0xd4ff2200, 0x2e8be325, 0xa7ec8f5a, 0xdc7910ea, 0xff38983f,
- 0x8ac24552, 0x4de77dfd, 0x791a0f1c, 0xfb1022e0, 0x49b53e4d, 0xf803e065,
- 0x96a2513b, 0xcb5c695e, 0x7684fdf1, 0xf6fe262d, 0x2a9d3db2, 0xd5a9bfdf,
- 0xf6a0e25f, 0x5379e8fd, 0x093f1c65, 0x59c52a82, 0xc6623b93, 0x467fe71b,
- 0x18bd4feb, 0x4d293cfd, 0x3041c3da, 0xb24f3228, 0x974dc641, 0x10a7664f,
- 0x2b186b1f, 0x8b0f48a8, 0xd4a4c2ae, 0xb0d33d3e, 0x4959e711, 0x2db8da9f,
- 0x8fbceb38, 0x88dc69f6, 0xf49a3f0c, 0x435b9baa, 0xc2ce0aee, 0x623630bd,
- 0x0617291f, 0x2fbf2f1e, 0x23ae38f0, 0xb0d397e7, 0x43356e6f, 0xc3c3ef50,
- 0x0c2f8914, 0xbbfe38df, 0xf6c1d17c, 0x62db626b, 0xead9e495, 0x711e8136,
- 0x113d04be, 0x6c7d08f4, 0xea8d49cf, 0xb59e92ab, 0xca7ed109, 0x924fb978,
- 0x7ad45067, 0xd062bf86, 0xacea50f3, 0xc663f256, 0xdfb1563b, 0x3b293292,
- 0x93a2fd6a, 0x042ef8d1, 0x63e2979f, 0x71c087cf, 0x5ab3c4c0, 0x29327f94,
- 0x63f983bc, 0xcfd187d2, 0xee8f9ca7, 0xfcc9a697, 0xaedd2c56, 0xfb184f85,
- 0x7fe969cb, 0xde5d3e3f, 0xcda67c68, 0x8667c689, 0x039f1a2f, 0x6be34596,
- 0x1f1a3fa0, 0x898d5783, 0x7d61bf1a, 0xd87f5461, 0xcd44a70f, 0x198342cf,
- 0x75be1fd9, 0x91fcd45e, 0xf545163b, 0x67753f47, 0xe0dcfcd4, 0xbcf1a88a,
- 0x2efe6bdd, 0x368417fa, 0x3427cd44, 0xfe87be9b, 0x4bfe3637, 0x53ff7ed4,
- 0xa18daff4, 0xe7d256ff, 0xa85e8813, 0xecfb0b37, 0xa425b919, 0x6f4d5d3f,
- 0x9b79437c, 0xf9ceb140, 0xf03cc0aa, 0x2fd8e0d4, 0x7a429f54, 0xdaa2306e,
- 0xd6a37a84, 0x1ec8ab04, 0x71326a3c, 0xf390d31e, 0x3f84d317, 0xc89a62f2,
- 0x7b78197b, 0xd922ed1a, 0x43ea5541, 0x248efa73, 0x935453f2, 0xfec9da09,
- 0x1fd61e69, 0xbe101ce7, 0x0755f719, 0x4ac5e701, 0x982d2792, 0xbea8fc88,
- 0xa9fc72a9, 0x8e83f20e, 0xe4e6a4f6, 0x9f8453ce, 0x4e9b0e2b, 0xfaa6ab7c,
- 0xf0df6403, 0xa1e7a19c, 0xdef39fbf, 0xf1495846, 0xe65fd196, 0xe699bf5e,
- 0xe67bbb2f, 0x7b7f8a48, 0xacaddf9f, 0x43a08d2c, 0xc51739e4, 0xa40eabf1,
- 0xd867fb09, 0xdc7ec313, 0x3a6bd569, 0x538c3ed0, 0xbb407d85, 0xf10d2071,
- 0x88f281f1, 0x0169f859, 0xed1f9d33, 0xb827df2a, 0x80df21d0, 0xdd9f4a6d,
- 0xe643bfd2, 0xda3b20fa, 0x00937d6f, 0xf74438a3, 0x1de33df0, 0x955dfe86,
- 0xecbbf8cb, 0xf97f9e88, 0xaf02e1fe, 0x90f620f7, 0xe22ce70e, 0x17fc063c,
- 0x42fe5ea5, 0xd24ee5ea, 0xebf911c7, 0x2676bb55, 0x2e7e7f91, 0xc6e3f847,
- 0x3a49dff3, 0xe54d2eff, 0x9dddaff3, 0x047cfeb0, 0xae422ade, 0xe3557ea8,
- 0xf991f5c0, 0x39c6b5cd, 0xe7468afc, 0xa8e52758, 0xf923b5a2, 0xfe7f604e,
- 0xb75c34c3, 0x7b95d772, 0xa6fbd00e, 0x67614c9e, 0xd2dfbc03, 0x82e380f7,
- 0x28817fa5, 0xcd33b6bf, 0xa67570cc, 0x09613889, 0xbbe44e36, 0xb803e825,
- 0xda637da8, 0x7c3fe22c, 0xbfb0561e, 0xa4cc15a0, 0xb3fa16bf, 0x33f484cc,
- 0x3f6779e0, 0x69cfed1e, 0x1b73ef3a, 0xfb7ef8f8, 0x922a7bdd, 0xd6340fd8,
- 0x8141d633, 0x3def3f20, 0x499cc057, 0x0ae99f79, 0x9fb817fb, 0xeefb9e8d,
- 0xec99bc1e, 0xbbdfb1b0, 0x0ef4bfe0, 0xf022c5f2, 0xfac6baf0, 0x1134d740,
- 0x4b03f97a, 0x44ed1d2f, 0xa66d0dbf, 0x3685e530, 0xbdf2b39c, 0xcf75774a,
- 0x9c230fcb, 0x66f9af1f, 0x7f7082bf, 0xbfe7bcb4, 0x3bf3e00e, 0x4741529e,
- 0xfdd9f1be, 0xbc447a5a, 0x2bfeee79, 0xafe86f2c, 0x2924ff3c, 0x1eac97a5,
- 0xd60f9392, 0x322a34bc, 0x9f4e485e, 0xf74e9099, 0xe2d2933b, 0xc6c46fde,
- 0x3f886ba5, 0xf6757e59, 0x5cbe0d4b, 0xc372f92d, 0xf9f9a30b, 0xf3dea486,
- 0x2af3fe88, 0x3436c1e7, 0xf1af395b, 0x3587e48e, 0x31337e2f, 0x8f57cf32,
- 0xa95ba97c, 0xf74b7275, 0x09fa3aa6, 0x1e5e4efb, 0xeaab71cb, 0x1e73a2cf,
- 0x3269fabe, 0xf9bdf7f5, 0x6e079f2d, 0xbbf83ebb, 0x78917911, 0x79ea4aae,
- 0xc54af497, 0xf94eab01, 0xb90392ac, 0x7ec2ee27, 0x1fea2b65, 0x5725cf3c,
- 0x29a7b1c7, 0x00a83b1e, 0xc32ab7e5, 0x2be4ac09, 0xe520941b, 0xee34d6c3,
- 0xfb1832dd, 0x1616ea6b, 0x2556bb11, 0x59567d0b, 0xb13704af, 0xe9873e1f,
- 0xa365285c, 0xbfee50e4, 0xd778e3e5, 0x85feb171, 0x3cf6b08d, 0xf55d9dc6,
- 0x38205e5f, 0x395a35d6, 0x292176cf, 0xfb8c196c, 0x84abda5e, 0xdc9f7a02,
- 0x1c44b976, 0x98f42ab6, 0xf55df685, 0xe411c2dc, 0x381d7636, 0xb93d216d,
- 0x59b1e1aa, 0x309179f2, 0x8b9641ff, 0x9595bbb5, 0xd5ac7991, 0xa4420ee8,
- 0x02f842fd, 0x40eafb13, 0x2cfa494e, 0x435e1a6b, 0xb6bd42e8, 0xf58569ff,
- 0x97e242da, 0xf9ef0e0f, 0xdf686fdd, 0x923dff83, 0x7d745ff1, 0x805f07f8,
- 0xb94a8bfd, 0x633c5c0f, 0xb2b2f8a1, 0xde217cc1, 0xba6352fd, 0xcfda1eef,
- 0xfd638f88, 0x10162dee, 0x10d93ff7, 0x82ec9e7c, 0x1cb2c7a3, 0x9a57f9e1,
- 0xce68f080, 0xec0acb1e, 0xc8ce48db, 0xc11db85e, 0xbef57178, 0x84f18d74,
- 0x78fac4b1, 0x3921a0f7, 0x5877a25e, 0xe9579f28, 0x5f10b4ee, 0x173f8657,
- 0x9f8dfff7, 0x89c6f2cc, 0x574e5fb7, 0x273f33a4, 0x6437de4a, 0x30b9618c,
- 0x90c3daf7, 0x60bee58d, 0xa9d90f45, 0x3b91070d, 0xbfb7a214, 0xec0ee087,
- 0x7ce9d04f, 0x9f3e0725, 0xcfb111d8, 0xf47ca51f, 0xf95e59e6, 0xf099ac64,
- 0xb193efb9, 0xf3df525a, 0xaac74cae, 0x97997978, 0xdedd85d3, 0x18bbec9c,
- 0x9e09072d, 0xd95bee30, 0x147be764, 0x2d2d8394, 0x70729145, 0xc45daac7,
- 0x07aa4de7, 0x1b2a0225, 0x79abfa17, 0xc887927e, 0x0cce36a3, 0x4eaa1f10,
- 0xfc27f31f, 0x289bf715, 0xff508fef, 0x3ff74dcd, 0x39ac724d, 0x1e646560,
- 0xf1d4d2a4, 0xe88516ab, 0xa26bc3ba, 0xf5810afd, 0x75f0ea96, 0x94553c70,
- 0x7bdc53a9, 0x202cc274, 0x59bcfd3c, 0x39afbce1, 0x8b35bfd5, 0xe55c7be8,
- 0x2fa396f9, 0xbbbee804, 0x11141c6b, 0x7f79c67c, 0x2a0c2e3e, 0x00b9b3ae,
- 0xe6edb43c, 0xc4dd4b83, 0x38cf3fbf, 0xdd867ec6, 0x2bd20213, 0x503fe835,
- 0x1f9ec7de, 0x093ad30a, 0x1522be39, 0xee9359f7, 0x58b4be64, 0x27ca1efd,
- 0x36fb203d, 0xe08ab7cd, 0x8a27a5b3, 0xf5c87bf8, 0x48baf9e5, 0x6f74cdfe,
- 0x4b7ce7e9, 0x69f05997, 0x71c00dd7, 0x4cfcd722, 0xe32f21a6, 0xb83b06cd,
- 0xd6546aad, 0x44d7da46, 0x79e8dbf0, 0x1ea5c1d7, 0x2d9cdf82, 0x91333df9,
- 0xff7622e5, 0xa99f888f, 0x62b4c0ce, 0x99e1166b, 0x9ff7a6f0, 0x7be4a1f7,
- 0xf9a01f03, 0x115e4873, 0xfcbc6f54, 0xf8bd3f92, 0x7375d12c, 0x95c72faa,
- 0xc2bcd7cf, 0xc6277629, 0xff9c3b95, 0x31b7c901, 0x89f095bf, 0xfcd16fef,
- 0x51efc236, 0xc5b35f89, 0xfe593ba7, 0xdfed3a7d, 0xf141be7b, 0x3c8df7cf,
- 0xff6c96df, 0xcfef9ef7, 0x54e67cf2, 0x2f5a37e4, 0x399e7819, 0xfe201839,
- 0xa2824dab, 0xa8f8f84d, 0xe49b966b, 0x6f91cb6e, 0xd7bc9286, 0x40dc7926,
- 0x9be6b179, 0x6fdc9196, 0xf3277419, 0xe42f17ff, 0xfb11aa16, 0x7f17a724,
- 0x2f3be745, 0xe2c5b1cf, 0x7c73a1cf, 0x9c69cf2c, 0xefba496b, 0xf911e92f,
- 0x7e921826, 0xd7b3fc5d, 0x7194d7b8, 0x61da479e, 0x8f38f38c, 0x5c890dd8,
- 0xfa57b67f, 0x98f81ae1, 0xd1e0ec7f, 0xc2f2bfd9, 0xa92baa09, 0x36c13169,
- 0xb5253e3a, 0x92fdee22, 0x0c119355, 0xb2186d7a, 0x8d3435d3, 0x39d89f3b,
- 0x3ee116af, 0xf8550108, 0x0cf9d169, 0x255e2af0, 0xdaf18f32, 0x63cbeb9a,
- 0x21afe33c, 0x63cd8d79, 0x969b0e4c, 0x23ae525b, 0xbcdaf19f, 0xd18cf9b8,
- 0x5171d119, 0xc0ce8641, 0x7f047285, 0x4189c286, 0xf1833791, 0x26eabf94,
- 0x9fe3855b, 0xde5999e3, 0x9b1cae95, 0x13e0ed0b, 0x3adb6c4f, 0x8470e50d,
- 0x6bf503c0, 0xf1f5c988, 0xe6f507ec, 0xc31b5e47, 0x3dea387e, 0x4e02f395,
- 0x1d0c4b09, 0x137fd08b, 0x2a27a541, 0xf63e12bf, 0xdbf1326d, 0x2dfd549e,
- 0x9b4f4fa2, 0x092875ca, 0x15c5875a, 0x900eee47, 0xe076807f, 0x3e84339f,
- 0x7b8a35b7, 0x65ee9b4b, 0x74e0993d, 0xe423538e, 0xd8432f24, 0x1f638aa5,
- 0x2ca0b50c, 0x4c9d325d, 0xd7f5c7ce, 0xa64fafed, 0x73dade34, 0xd2a44f6f,
- 0xff353b9f, 0xff3c0c82, 0x51aeca17, 0xb75bf236, 0x7e12c706, 0xae6ce142,
- 0x20d02ccf, 0x87f615a0, 0x3c29eaa7, 0x9504ba14, 0x5b71a54f, 0x257e34d0,
- 0x58555ff1, 0x30f6979c, 0x6dcc8aa3, 0xd5dfb854, 0xeb4a9358, 0x79b6fd55,
- 0x97afe910, 0xf39f8432, 0xf13cd5e2, 0xcd1a06be, 0x25c33fbf, 0xa2682a99,
- 0x324be37c, 0x5575d94f, 0xfec679e5, 0x55338d05, 0x7e41f227, 0xce11c778,
- 0x7559368b, 0x73c26fa2, 0x94d1f020, 0xd5687ec0, 0x7640d9e1, 0x1e05dbaf,
- 0x24f7c705, 0xfc447cf6, 0xd56cd3d0, 0xc1373ee9, 0x715203b9, 0x1eb23dfd,
- 0xb619172c, 0xdcf7d1de, 0xe9a12fd8, 0x24439497, 0xe57be0be, 0x4c076d04,
- 0x3be24477, 0xc959d849, 0xc3127b57, 0xe967ba26, 0x59efdf41, 0x4e0fab86,
- 0x380d7de0, 0xec0ed973, 0xf85cf4b1, 0xe5c33a71, 0x05c83e24, 0x8d342701,
- 0x26af49d6, 0x8e7cbd38, 0x09eea704, 0xaae1fd28, 0x208e8b1a, 0xa4a3cfca,
- 0xc9f4a6cc, 0x5f625577, 0xb0b286df, 0xfca41b27, 0x9d2b6eb7, 0x8547d916,
- 0xfdefa933, 0xf8e278ff, 0x9c21dab6, 0x48a80bff, 0x49b63b7f, 0x214e74a9,
- 0xde122857, 0x0781428c, 0xdbb40baa, 0x7cef78c4, 0x2a4773e4, 0xe79e7fdb,
- 0xf3ed3ab1, 0xf85e58b2, 0x0ff0d17e, 0x17c2521f, 0x76d2466e, 0xc94be63e,
- 0x9a7573c7, 0x875c3c8e, 0x3cb8fef3, 0xfd8c2a34, 0x79ffab16, 0x3f57cfe2,
- 0x80bdb15c, 0xb31eeff4, 0x4ff49ca7, 0xf671e047, 0xeb345fcb, 0x0ee422db,
- 0x7264f486, 0x3ecc61dd, 0x3d36e755, 0xf776fe4e, 0xfba74541, 0xcf736ef4,
- 0xb2bb8250, 0xd50b33e9, 0xfc1d5663, 0xb2ebfd84, 0xda5eff4c, 0x3563526f,
- 0x864dcfd7, 0x873f5c1d, 0x20eb917a, 0x4fa16e43, 0xf51d9f2e, 0x1d04756c,
- 0x06f293de, 0x6461fe3d, 0xbca49abf, 0x1c38a61e, 0x772dfddb, 0xf7f5a70c,
- 0xf180fccb, 0x191c355e, 0x04df784c, 0x3c6b71af, 0x5c6a0eef, 0xaef79cbf,
- 0xc46f5eed, 0xfe52d3fc, 0x56fdcb4f, 0x20dffa67, 0x7cb6d778, 0xc2d2a16a,
- 0xa1a1f3aa, 0x3486f714, 0x4719c53d, 0x6fcaf48f, 0x69553c8c, 0x5f9a163d,
- 0xaf581175, 0x536bbd20, 0xbd2f7e90, 0x396638db, 0x348fdf3e, 0x8b3b2149,
- 0xe3d92af1, 0x60df66fd, 0xcefd5f9a, 0x8f4963d7, 0xf020241d, 0xaf375f7f,
- 0x4378461d, 0x244e2ffe, 0xac0bdb39, 0xcd390cd7, 0xf7c53927, 0x8bff89f3,
- 0x7acb9fa8, 0x7da58f79, 0x7ee5cb1e, 0x225c9013, 0x203cb3ff, 0xdfc93bff,
- 0x3ca277cb, 0x59a3fbf0, 0x9bb4f7ce, 0xa337ecbc, 0xfdc91f5e, 0xdfd4c5e2,
- 0x64ea5ed3, 0x843aa739, 0xf0d79242, 0x04275e11, 0x45f2d740, 0xfd22f80a,
- 0x648cbcff, 0xf1242f71, 0xd8433939, 0x9e8e5083, 0xd873c1e2, 0x3e4a3555,
- 0xe8a5ec22, 0x9a5a7b4b, 0xbf6d97f9, 0x26524698, 0xda5384ed, 0xd678ff49,
- 0x6d28fffb, 0xa7d786d5, 0x73c3a82c, 0xf2a5386e, 0xf71961f8, 0x1c9f2585,
- 0xb21af991, 0xa89a7a1b, 0x13e7a61f, 0xe5f54fb0, 0x4bebbd13, 0x9a4d1cc8,
- 0xb528e3b3, 0x12a17c53, 0x2da6db72, 0x166a3f6b, 0xfc479e62, 0x6e6470d7,
- 0x75e3d51e, 0x0242b39f, 0x6df0d882, 0x222f47cf, 0x8c3e1e1e, 0xa7638ff8,
- 0x7fcc38f0, 0x060d7fe8, 0x6ef1ff77, 0x4091ea45, 0xc7e27cd2, 0xafb506ae,
- 0x2254808f, 0xfddf5363, 0x007b7da4, 0x677fe76d, 0x2267077a, 0xf00ccf3e,
- 0xfa7ddb73, 0xcb124cdb, 0x5c4567fd, 0xe6f160df, 0x6434ff11, 0x871ba863,
- 0x2299ad4f, 0x856453ef, 0x379cf7b8, 0x18390a67, 0x0aed8015, 0x33aaebc7,
- 0xd4bf7488, 0xe82d7aa0, 0xc0845d2f, 0x6fa4a992, 0x01f75e64, 0xfc5e3f90,
- 0x283cfa45, 0xdf900fbb, 0xc1eb7682, 0x11d6c45f, 0x316fd978, 0xeb0058f2,
- 0x2b5fc44d, 0x0ff8149b, 0x67aac5c4, 0x93afe7a2, 0x1babf275, 0x8c1b1d77,
- 0x5cf35d74, 0x2df938cc, 0xe211ff7c, 0x5d5d7878, 0xcdc33d74, 0x197fd299,
- 0x7fc9c30e, 0x3d62be41, 0xd5a0d661, 0x60ac7c8a, 0xf6224314, 0x0be04992,
- 0x67cb2bf5, 0x8a6f61be, 0xb9ea5e85, 0x94a75c04, 0x94743bbb, 0xd4a681ea,
- 0x8f687965, 0x9f189a29, 0xee2598d2, 0x4aa0b4a7, 0xbc930c75, 0x77ec59fe,
- 0xa967bc07, 0xd49564de, 0x5fc4e097, 0xd3c8fbca, 0xddfe92af, 0x9d6c60ea,
- 0x9553c0a8, 0x8219379c, 0xcaefb435, 0x69dea2dd, 0xf9e8eeed, 0xeb4f1255,
- 0x8c7d3a9e, 0xa11585d2, 0xa7897198, 0x3a98c6aa, 0xdc38b116, 0xadef299f,
- 0xf5fb7d64, 0xd1fc5bd6, 0xb78dfc2c, 0xf8c63ae5, 0xef914ce6, 0x1063c4ad,
- 0xd505d77d, 0x2ad1f120, 0xfc2c9025, 0xc72c705e, 0xb067ddf3, 0xbdcfac81,
- 0x3ee9e25f, 0x7e7c3fc9, 0x19e2bf7c, 0xfdc57df1, 0x7f868b3f, 0x832cf80d,
- 0x0d83f9f1, 0xde50b03f, 0x56df9631, 0xffd999d5, 0x13f1235d, 0x7a6b5fcb,
- 0x858767f9, 0x7f2c5bec, 0x6b95fa55, 0xf6fc2fc0, 0x0df85bff, 0xcb91af3a,
- 0x398735ac, 0x09f6b53f, 0xabf943c5, 0xf7ab9d6b, 0x7f7cf23c, 0x359eb9ef,
- 0xc6063de8, 0xa4e7bd30, 0x63bd175d, 0x96bdedfd, 0xe726bcde, 0x66b72f05,
- 0xe0dd3e73, 0x6675d8ab, 0xf67dbf49, 0xbd7fc253, 0x276258d4, 0xa4fba3ff,
- 0x9ce8a3c9, 0xc02e4caf, 0x566f8ff3, 0xee91fc81, 0x033be1a6, 0xa9e17f08,
- 0x5f94c5a2, 0xed0a7f1f, 0xb707dd13, 0x0257fd16, 0xd27b07df, 0xb667ee48,
- 0xbdfb488d, 0xfb61d783, 0x70b27dde, 0xe9e93967, 0xb445a593, 0x54e382ae,
- 0xed285e9f, 0x42c9f554, 0xbd84477b, 0xc8a64dfa, 0xff716fcf, 0x1b8a51fe,
- 0x7b35ef66, 0xdb323f28, 0x8094dfec, 0xa0be15f0, 0xb771aa78, 0x9e47ed63,
- 0xbe5175a4, 0xf38acd28, 0x8d08e9fe, 0x1851ed57, 0xb2a6eefe, 0x3f643dbc,
- 0xec87aa83, 0x7dd37762, 0x1f920ff9, 0xfe40fcd4, 0x1dfb117d, 0x66fa154b,
- 0xb6660df6, 0xec839dd7, 0xbca72ebf, 0xeb1777a8, 0xfb43ce8d, 0xc37dfc2c,
- 0x78dc051e, 0xa3ee63ce, 0x3a1e132f, 0x50b69c0f, 0x70d25010, 0x4711d2da,
- 0x25ed1b7f, 0x9cc2f30c, 0xe161ddaf, 0x7ffdcdfa, 0x2b79d0b0, 0xf384fb9f,
- 0x7e286b6f, 0x19ef3f20, 0x3a77bf95, 0x85aafcda, 0x4eb2b4f8, 0x91590181,
- 0x271e66e3, 0xcffd4afd, 0x369e84ea, 0xe4857ff8, 0x0dff8377, 0xf5215879,
- 0xe35b7dda, 0xffa1bbf3, 0x96ef041e, 0x03deb841, 0x0eb9cb75, 0xd11d81e9,
- 0xfc5257f3, 0x17cd237a, 0xa9f2befc, 0xbdd5f1e8, 0xfd601e7c, 0xbf47ab1f,
- 0x2e7ff433, 0x5f9f12e4, 0xa618af0e, 0x7d7d3ca1, 0x8830cd7a, 0x293caf93,
- 0x6ec306fd, 0xd89b0e5f, 0xebcec5ee, 0x2162bc6a, 0xfad55b7b, 0x6773f627,
- 0xf4c97d35, 0xe16a6f28, 0xc05bd97a, 0x79f08ebf, 0x49dd934b, 0x877976fe,
- 0x9af303d0, 0x42a0c1ac, 0xa25aa1e3, 0xf161f773, 0x90e049bd, 0x4816fec2,
- 0xe252b8bd, 0xe3c4a575, 0x06e38c4a, 0x8c8c7d53, 0xbc652be3, 0xd7673abe,
- 0xa9292a31, 0xdaebe394, 0x1e13268e, 0x5bd081e7, 0x6f4242f3, 0xec31f419,
- 0x40beac50, 0xd10f770b, 0x95936d77, 0x4be7d6eb, 0x0ebf35bd, 0x5fd296f5,
- 0xb40f747f, 0x7ef1fc8b, 0xddac7701, 0x9e886cad, 0xfc201aef, 0x7fd2cbd8,
- 0x4d101c2e, 0xb01ef297, 0x9e7f7e53, 0xfc827aae, 0xfb46bb56, 0x7e458eb7,
- 0xf55bf5c3, 0xeaf129e1, 0x4df68cb5, 0xfd181719, 0xc3679405, 0x0ee721f9,
- 0xffdc6447, 0x7f84039f, 0x1ab266b3, 0xc446ba20, 0xb30a0b49, 0x7349c6e2,
- 0x8637f409, 0x71b3f7dc, 0x77927191, 0xb7e228d7, 0x2cef757f, 0xaaa6baa7,
- 0xba2fa13a, 0x29bae126, 0xfb03f7e4, 0xd67555d1, 0x5533c520, 0x7dfc2fc8,
- 0xc909f11a, 0x46529363, 0xc671827c, 0x42feb4ed, 0xf3c4eaba, 0xfb446c2f,
- 0x2c2fcb8e, 0xabf992fd, 0x3738846d, 0xbc406de2, 0x3788c3b8, 0xbf0aaf2a,
- 0xa95e78d6, 0x51dc7075, 0xb5ea24d9, 0x337c8e1b, 0xede10b34, 0xd0f3fe6e,
- 0x3e4f54e5, 0x86e7d840, 0x54a7d0e2, 0x1ef5f457, 0xb5ff5c5b, 0xb52bff57,
- 0xe6950f2c, 0x6bf64c8e, 0x791fa20e, 0xb7d1ea13, 0xa538e0bf, 0xbdc248e1,
- 0x5aebcf94, 0xfce61fe1, 0xc3553a1e, 0x3783f626, 0xe4b72d41, 0x8dfa451f,
- 0x4ea29d2b, 0x3f6941e9, 0xf208ffa9, 0x773883f5, 0xf97f6146, 0x8549f437,
- 0x10d5ebe4, 0xe95532d8, 0xa42a07af, 0xdfcdacdc, 0xf6ae85b5, 0x0aa7fd63,
- 0x31184f29, 0xf58cbdb0, 0x8633fe9f, 0x4edfab5f, 0xbbb8ff64, 0xae52754d,
- 0xabfbf119, 0x6227e441, 0x271d905c, 0xe485fb5f, 0x7f794ecf, 0x65493d5c,
- 0x8b2699fc, 0x10b7f0d6, 0xdd37cc8f, 0xb2411da7, 0x5f87796f, 0x583e26cd,
- 0xdefa3bbb, 0xe7e8e889, 0xc8a0b1ba, 0x7cec8547, 0xbf8c6517, 0x31d5f874,
- 0x6fd56fc4, 0xd04a3b7f, 0x96519be7, 0x67c36bf4, 0xe2228ab4, 0xe2229366,
- 0x475afde6, 0x556bc532, 0x645f5507, 0xef41bf3d, 0x813ca597, 0xf503f226,
- 0xabe67403, 0x1fc126ea, 0xe2d166a6, 0x7e444bfe, 0xf7fbccc8, 0xbe462f1b,
- 0x067b1ef9, 0x40f21704, 0xf987b995, 0x89b4eaaf, 0x7d3aa9e1, 0xc4447339,
- 0x775a017b, 0xeabfe900, 0xc4fac075, 0xe76fa40e, 0xd891f7d3, 0x027eff9f,
- 0xb2c761fb, 0xfb8b97b7, 0x7f48152f, 0x9af6fc3d, 0x60f691d1, 0x2f7100e2,
- 0x3707840e, 0x10bf3f79, 0x6c3c4bfb, 0xbf324582, 0xaf79f820, 0x2e309b8c,
- 0x9c40737b, 0xfd7aecb8, 0x2b66eae9, 0xeab9fe50, 0x19d72b03, 0x92bcdd7d,
- 0xeab87ee3, 0x06fa4d1f, 0xa91bfefc, 0xcaf0f87d, 0xebfcf4d1, 0xe46fabc3,
- 0x29b2a97c, 0x2011cf2a, 0x5fe4dcf8, 0x5deef57d, 0x69b67fe4, 0xb6149fec,
- 0xee977d9d, 0x9835f769, 0x8ad1dbf9, 0x067613fd, 0x2aafc892, 0x11df4f9c,
- 0x98d56bed, 0x32dfd0ff, 0xfb3b2bfc, 0xd88aa757, 0x7c75c2bf, 0x4e8b6e41,
- 0xa7bad394, 0x9a688b8a, 0xd7a4e382, 0xe57f93c6, 0x0cb7f3e8, 0xf8933e78,
- 0xe0496eec, 0xd9028bbc, 0x4460cf82, 0x1aebdc14, 0x64ff675e, 0xf51aa35d,
- 0xdef188fd, 0x7b88065f, 0x3e0cef87, 0xe65e290b, 0x5da2bda3, 0x932fb8d7,
- 0x1cd6b1ce, 0xaea93e62, 0x3df18b33, 0x07ba05a2, 0x411fc09a, 0x273f0807,
- 0x65d211e8, 0x8438259e, 0xbdbdfafc, 0x2eb28af7, 0xf5ea2824, 0xf3875a6a,
- 0x5b974c77, 0xb3c7a5f7, 0x9ee92743, 0xe3be1d07, 0x8a1e2259, 0x5badff1d,
- 0x9f8e41e4, 0xf8f1fa13, 0x78e8ff4c, 0xc500327a, 0x48a05f22, 0xef8835fa,
- 0x35e763ed, 0xfe787ad3, 0xc70243dd, 0xf73b8f89, 0x63fdf026, 0x75e44ba7,
- 0x34dbea4b, 0x6d661efa, 0xec813283, 0xf79cdad2, 0xec197bf8, 0x5c9e9117,
- 0xf7c83e1b, 0x7b7515af, 0xc0e37967, 0xec2dddb1, 0x9df93cc3, 0x7cf8ec72,
- 0x3c067e39, 0xdb9e3219, 0x673ef74e, 0xf14ecdca, 0xeef89bdd, 0xd7a956f5,
- 0x6662df17, 0xe80cea3f, 0x227f7166, 0x481639ee, 0xd4ab7dbd, 0x63dfb1f7,
- 0x76fdfa1b, 0x67c2ceb9, 0x73dd3360, 0x7d9f7ec4, 0x170ff4bb, 0xefd79781,
- 0xf4bd5df7, 0xfeff6313, 0xea5b8942, 0x8a3051f5, 0xed087af4, 0xe45bd70d,
- 0x9eddb026, 0xae32305f, 0xa9df41df, 0x753bf2eb, 0x57fa0d6a, 0xf6c7bee7,
- 0xb9cb78f0, 0x86fbf997, 0x1d900973, 0xcfad9ee7, 0xe47a1a1e, 0x79774136,
- 0x14e151ef, 0xbff41a30, 0x645a1184, 0xffa0cd7e, 0xff0e9283, 0x394575c7,
- 0x63e645a0, 0x07fea90e, 0x475419dd, 0x38fec9dd, 0x21ed809e, 0x3ca86b9e,
- 0x846b50d7, 0x7034bb9d, 0xee3e5c79, 0x406a5f3b, 0x6e7493d8, 0xecad725b,
- 0x14845637, 0x22b0eefe, 0x9b7fa20c, 0x51caf9c2, 0xbf5c2d0d, 0xf154a4b1,
- 0x3c5a8578, 0x7c19f04b, 0xfc26c0b4, 0x7a5f8303, 0x88f925f1, 0xb85fc9c6,
- 0xb10bfa55, 0xda1a34fc, 0x4bfad167, 0xea878abd, 0x47c9af36, 0x4ebdc6cb,
- 0xf8b5eee1, 0x4cd2f908, 0x9f96317a, 0x1ffb735e, 0xb775fc25, 0x80525e5f,
- 0xfdcf1feb, 0x4ff1286c, 0xe8e435e5, 0xddbf4945, 0xae71c08e, 0x7597a963,
- 0x8db9f504, 0x5697841d, 0xd3b2bf60, 0x8365bed5, 0x8eb9b7f0, 0xc09c22a0,
- 0x4d15a5f5, 0xad6efe76, 0x713aa1a2, 0x26e3e90c, 0x7ec763d5, 0x52e9c379,
- 0x179423ca, 0x2a973a89, 0xabbba8bb, 0xbbba8bb2, 0xe7fee9b9, 0xeff813dc,
- 0x11d74403, 0xb57e3a58, 0x3ef87be1, 0x9335df56, 0x7fe1370f, 0x4b350f4e,
- 0xbb686cfc, 0xc4863992, 0x887fdd34, 0xfd7eeee0, 0x8a7d0b45, 0xd5e63551,
- 0xd6825459, 0xde79d6ec, 0xb52d752d, 0xe0365694, 0x429dbbb7, 0x43839aef,
- 0xbfcd6fd8, 0xea9b7abe, 0x258c6f83, 0xd2d5d5fb, 0xc112d636, 0x501b9def,
- 0x63a1c76f, 0x1ca49835, 0xca2adc6b, 0x0947e922, 0x3e6aaeb9, 0x8bf9499a,
- 0x7ce7924e, 0x1e49df6a, 0xdec56d81, 0xc923c933, 0x5a2fd99f, 0x4d4bbd63,
- 0xad03cf2a, 0x49edd463, 0x666df091, 0xc4852ef8, 0xa31d003a, 0x8e441716,
- 0xd6bffcd7, 0x3e851707, 0x07d288e8, 0x16429e06, 0x0388efe0, 0xa75cad87,
- 0xae3ff740, 0x036a3a08, 0xc26efd05, 0x76e48a60, 0x0f7bdd32, 0x834f9727,
- 0x41afa9bb, 0xfba54b58, 0xea2ab0e9, 0xbeb086fb, 0xbff7289f, 0x50b70b49,
- 0x7964f03d, 0xda053a5f, 0xe80cde79, 0x4e0bd6e1, 0x18ba0efe, 0xb24edc3c,
- 0x5a53e785, 0xe2143f2b, 0x99c27bef, 0x4d82eb9a, 0x871d6f7e, 0xd3787dde,
- 0x0f8182e0, 0x44d5ee95, 0x79ec533d, 0xfc28186e, 0x42bc9bbc, 0x414b910f,
- 0x2093c0f5, 0xd3f9f7c4, 0xebde43a1, 0x54c73fc7, 0x1ee90b8c, 0x31ba3a6f,
- 0x208f8c89, 0xe7469fcf, 0xa79de351, 0x19933e63, 0x9f049d4a, 0x7d34ce12,
- 0x73febf67, 0x28355374, 0xebefbde5, 0x5171fae9, 0xa7a83ddf, 0xa9f78de9,
- 0x7af1597e, 0x43d9beb9, 0xfc538ddf, 0x7b3ad613, 0xc03659f5, 0x722b8198,
- 0xfbe84e06, 0xc0fc046e, 0xdfb12475, 0x277c448d, 0xfe231702, 0xe751922e,
- 0x48b83bbb, 0x65913aa7, 0x7bfe36e9, 0xa1b6853b, 0x79af29e3, 0x339fcd28,
- 0x7dea8330, 0x62f246eb, 0xfb02705a, 0xecbf92b9, 0x78449de0, 0xf7c6bc50,
- 0xd37cc02b, 0x320bf7fb, 0xb227bf81, 0x3e77c55b, 0x6d1f91db, 0x3a052ca9,
- 0x23c35fd5, 0xd3f93a25, 0x0f365c5b, 0x256c477d, 0x707dedb8, 0x1d44d8d7,
- 0xd44d8d48, 0x72f51879, 0xb1ad78b1, 0x8f4e7919, 0x98f1fd8d, 0x627e90ef,
- 0x7842dff3, 0x98a9287a, 0xde530eff, 0x5cdcd32b, 0x7fbf250f, 0xf03049aa,
- 0xe7e36c50, 0xec94f57d, 0x3d52d667, 0x9359c237, 0x78ff5c01, 0x0a546934,
- 0xb4d565d5, 0x9aee7a89, 0x77eb008c, 0x7d615fb3, 0xd25ad35f, 0xb2e2f64a,
- 0xdd75c2c3, 0x07512e35, 0xd080c81f, 0x3d347af3, 0xa0f419a6, 0x8f594bfb,
- 0x5c65d064, 0x7bd0943a, 0x91dec2e3, 0xdb429384, 0xfdd037cb, 0x7470b8c2,
- 0x69d2197d, 0xf7a9d135, 0xc9cd1e3b, 0x7d061ef5, 0xd9987190, 0x06ee929d,
- 0xdfc69cbd, 0x516af023, 0xa0c08f7f, 0x4144f6e3, 0xe055332f, 0x7577e70c,
- 0x4e96375a, 0x14e11bff, 0x4bb0bac1, 0x00004bb0
-};
-
-static const u32 xsem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x93cbff00, 0x51f86065, 0xd2f9c08f, 0xbcde0c0c,
- 0xc4b462a8, 0x0c0c5c0c, 0x0e5c4041, 0x7b401ac4, 0xdbe9016f, 0xcdce1c40,
- 0xc40110c0, 0x1ff881fb, 0x6207ff10, 0x04d6200d, 0x79405fe2, 0x5b1ba845,
- 0xda181898, 0x8803b880, 0x875880bb, 0x97418191, 0x93fb7891, 0xde181984,
- 0x7af82389, 0xcd0c0c12, 0xfff3f452, 0x5631c360, 0x29efb5f4, 0x174e3ed0,
- 0x19c73f04, 0x505c2498, 0xe0bb70d5, 0x4d078337, 0xcf8d179e, 0x9e7f4787,
- 0x5cbf2a21, 0x4d3f950b, 0x23e18187, 0x2d0a9a92, 0xc7416efc, 0x0c0c468a,
- 0xabc4464a, 0xca8c60df, 0xd081300f, 0xb1adf900, 0x0003a809, 0x00000000
-};
-
-static const u32 xsem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c09, 0xf37df0f5, 0x66499996,
- 0x0d909326, 0x8a027108, 0x081380a8, 0xc3b44069, 0x8e22a222, 0x260dc55b,
- 0x1037d902, 0xfdaff0fd, 0x2d361032, 0x4682d0d6, 0xa0c0748b, 0x0d0482c1,
- 0x00e02418, 0xd52ff82e, 0x5b7bbfd8, 0x16c34a0c, 0x7e1b8092, 0xce7fe5b5,
- 0xef25f7b9, 0x6d80264d, 0xfdfb5fbf, 0xe6f169bf, 0x5ddf7bbc, 0x3dcf76ce,
- 0x14fbdcf7, 0xf89628db, 0xe0cec663, 0x2cabd20f, 0xdd51b18c, 0xa0db6ce9,
- 0x74fa87a1, 0x6559ffe7, 0x4287ead3, 0x6ed0ab1e, 0x9cfdd61e, 0x7e5485b1,
- 0x386b8c40, 0xf4d31cbb, 0x8f0e1b10, 0x9616c96d, 0x6e7dd8cc, 0x0901bf46,
- 0x912974be, 0x5615ceb1, 0x780cbaf7, 0x085c7aae, 0x20c8f7df, 0xf7c25077,
- 0x1652c93c, 0xbaa23fe4, 0xbecc01d7, 0x6cb3233f, 0xe0da66c6, 0xc3fc0f6f,
- 0x7cbea07a, 0x63106cac, 0x059969ea, 0x77ea7fa0, 0x3403a512, 0x00efc336,
- 0x6c2df978, 0xfeeed0dc, 0xecfd13b9, 0xe8b78073, 0x5b7e89f9, 0x097f90c0,
- 0xecffa893, 0x5faa4afb, 0xf2f16f6f, 0x073e6c5b, 0x8d941636, 0x7f963bcf,
- 0x8be7c2e9, 0x7aa16e9b, 0xd82c5318, 0xc8b772cf, 0x635cfc4f, 0xbbfaee96,
- 0x76a214f1, 0x04d3d874, 0x3188feed, 0xb6bfb5e9, 0xd543c032, 0x0563d556,
- 0xaad84cbc, 0x700c7f86, 0x84295ae9, 0x9d9765b0, 0xfb4bc031, 0x9d870e6a,
- 0x9fcb0f9a, 0xaa1805a8, 0xff36b728, 0xdbc40afc, 0xa3ad9956, 0xf784fc66,
- 0x3bc71b56, 0x9e70e46b, 0x6ba5839d, 0xf7c74f77, 0xccad1a0b, 0x6e95f50e,
- 0x057a9fcf, 0x54fbf9c0, 0xd74a4586, 0x01fad02f, 0xea92185c, 0xcf18ee11,
- 0x36e0fda8, 0xca1eb439, 0x939ab877, 0x1ff1836f, 0xcf31b4ab, 0x676fd0c5,
- 0x80adf273, 0x96d0a287, 0xd15ef849, 0x2c8bc946, 0xfaeb6134, 0x7bc2fb37,
- 0xaf241ba5, 0x5c52f015, 0x433ccb17, 0xc0ce1f78, 0x3906d6bf, 0x9fc863fc,
- 0x1964e30b, 0x49ead748, 0x57f6c64c, 0x37671e68, 0x0e558e9e, 0x376b1e61,
- 0xda01ba5c, 0x5ecaf781, 0xc438bc94, 0x200b0b32, 0xb76fb65f, 0x81d67b4f,
- 0x0da05be3, 0x96b8e276, 0x3f2e586a, 0xeecdbb94, 0xd5adfec1, 0xd17e4126,
- 0x9e5ab5ea, 0x75c5fe81, 0xcd8f3197, 0x419aafd0, 0x88fe4629, 0x9b018f4c,
- 0xc453fb18, 0xf91eaf98, 0x37690944, 0x9fa2e419, 0x2ef44f14, 0xf54d93ae,
- 0x4b192603, 0x007eff82, 0x82be027f, 0x57849d3b, 0x05736e9d, 0x3b74e91f,
- 0x2987e425, 0xfac6d99d, 0x48e7f4f5, 0x754fe807, 0x5fd29ba5, 0xba52a654,
- 0xf443d2b2, 0x07f10279, 0x6fd172e9, 0x4e3658d7, 0x3e5d7681, 0x4b3146e6,
- 0xa71be298, 0xe7e09c02, 0x01ddf270, 0xf19673c9, 0x6a13e9eb, 0x72651720,
- 0x53e49b15, 0x05ac02fa, 0xb42f30e6, 0x9be8dcaf, 0xd7b19a38, 0x1c71e059,
- 0x502922ff, 0xac657480, 0x740fd53e, 0x1e812259, 0xc52d7c01, 0x961e0241,
- 0x067e05f4, 0x4f713d3a, 0x24b2b3f6, 0x70889ac6, 0x668f73de, 0x54353d50,
- 0x0cf50a8f, 0xc93d773a, 0xf54c73d3, 0xd02f4f24, 0xf54b59eb, 0x9eafcfd8,
- 0x318fa627, 0x917a67f7, 0x580bcf5e, 0xfcf3916e, 0x633c95c6, 0x333fb9ac,
- 0x949ea84a, 0x002cbdbb, 0x7f9d65e5, 0x864fb358, 0xf8c6c77c, 0x23328f11,
- 0x86df8d1f, 0xaa4139f5, 0x97147c8c, 0xa7926313, 0x09825f78, 0x9fb933ee,
- 0x7f927ca9, 0x653f29a0, 0x7c11a5da, 0x5eb770e9, 0x54e86026, 0xfea35e38,
- 0xd234fd6a, 0xd9fae33b, 0x9fa07e08, 0x03cef483, 0xbb170263, 0x57d8dfa1,
- 0x407ff406, 0x8eee5c0b, 0x2e3037c2, 0xea62a589, 0x991a60b1, 0x78e554bf,
- 0xfbffdf1b, 0xfde107c1, 0xe0e74b72, 0x4bff8078, 0x8e21f71a, 0x4ca88ffb,
- 0x32316e81, 0x3172c0ab, 0x6ffa4656, 0xb3f64669, 0x975e0341, 0x917e000d,
- 0xa65debba, 0x1f915206, 0x4115825b, 0x3025cfe4, 0x8c7eb041, 0xe115641d,
- 0xfef085e0, 0xc454bc80, 0xfd0355bf, 0x835f6c61, 0xfb5287f6, 0x5b7ed8ad,
- 0x075bed2f, 0xb7da98e6, 0xda9817a5, 0x3ed069b7, 0x706747c8, 0xf01f68be,
- 0x93b18637, 0x6fb53e6c, 0xf6a02f4d, 0xc0ac6a97, 0x574c7ed4, 0xbb60dffb,
- 0x49fb63df, 0x703fc651, 0xe9fc798c, 0x6bf1e645, 0x416cfc7c, 0x431fb450,
- 0x20a497e3, 0x117a7f1f, 0xd795bf1f, 0xabbed5db, 0x049aff0b, 0x5ea43aed,
- 0xac683fc6, 0x9417fc79, 0xe56fc798, 0x2c17bbed, 0xa83bed13, 0x196978fd,
- 0x2505ff1f, 0x0d66bed4, 0xb48f9178, 0x211531fe, 0x40d34f9c, 0x07485280,
- 0x921d28fa, 0x93e818c0, 0x8481b2df, 0x38620787, 0x03137ddf, 0xd6e8e6fc,
- 0x12042ca7, 0x9970f308, 0x8de2e9e0, 0x3f3e34e3, 0x9f5e6907, 0xab3aba2d,
- 0x8cf9a651, 0x2e86b4ad, 0x37b6fe82, 0x678441ca, 0x2432bcad, 0x760a7cd3,
- 0xb0a7be02, 0xf3ff3e30, 0x8ceb61aa, 0x674c8ae3, 0x2dadab57, 0xd2eab906,
- 0x90d9e3ef, 0x055fe80a, 0x6ea8c132, 0x34f415b8, 0x39fc3d03, 0x0f4c63e8,
- 0x392edcab, 0x5d9c7a04, 0x059b946c, 0xb2092edc, 0xff4087f7, 0xdffa227f,
- 0xb77c70aa, 0x884293ce, 0xcc566fff, 0xcd9f50d1, 0xa4058eae, 0x5ca3f777,
- 0xbb73a9d0, 0x14f64435, 0x9f88074c, 0x191449db, 0x1baed3fb, 0x305c94de,
- 0x31f4d63f, 0x0b3777bd, 0xf2854e2d, 0x0ee79733, 0xeff8c370, 0x211d669a,
- 0x7cc4fce3, 0xc7242dfd, 0x8725bfac, 0x2b0d69b1, 0xdc00fed4, 0xbcfd4d3e,
- 0x1dfef0c5, 0x577c3301, 0x576e1981, 0xed05aa43, 0xad894299, 0xa9ef7a85,
- 0xedebe730, 0x3812964c, 0x3f7b455d, 0x85f41c01, 0x3a60f747, 0x89bb1f02,
- 0xfcddd3ae, 0xe53fbd5d, 0x4c2ca90f, 0x124b71f3, 0x5127fa23, 0x8f9b80b9,
- 0xd3bfb23b, 0x0fcf9b55, 0xa0fe99fd, 0xec8cf84c, 0x58aecb7f, 0xd9ec059f,
- 0x552f9a96, 0xf1c8c164, 0xc67ff644, 0xb8f1c8fc, 0x721f9c35, 0x39cf9183,
- 0x53f2449f, 0x5fb8e379, 0x53f0321e, 0xbfb5fd69, 0xaf78643c, 0x1326eeb8,
- 0xc3ba185c, 0x26bf3e54, 0xbb3f94d7, 0x3f94d0ba, 0x131cd973, 0xd07c1b9c,
- 0xfcc67e54, 0x7bfca605, 0xe5311e2a, 0xc2b055df, 0x7811df04, 0xf6fe54ca,
- 0xf94d6b69, 0xdc975d96, 0xf5547288, 0xde70cc81, 0xfad1daf8, 0xbf37b473,
- 0xa45e2876, 0x57b011c7, 0x818e0e50, 0x7b6982bd, 0xabb248e3, 0x31e60f41,
- 0x4b56a130, 0xc6cb83fb, 0xa4665ea2, 0xefd2433f, 0xc634c183, 0x843c979e,
- 0x6346b93f, 0x89616061, 0x71f17425, 0x6fc86ca7, 0x0d7e4739, 0x9ec8fa08,
- 0xf44b72f9, 0x72ebe5e7, 0xd3bd402f, 0x5f803e9b, 0x3ae79c7f, 0x99103d84,
- 0xbf31225f, 0x7ebeb9f1, 0x7ae25cba, 0x53ac44be, 0x3bea5e4a, 0x0e10b99e,
- 0x5b38ae0f, 0x5480f57b, 0xfd6893d4, 0x803f2127, 0x51e81814, 0x24c8375c,
- 0x65bb6ddf, 0xea1957ea, 0x99abd004, 0x4257bfcc, 0x9bde133d, 0xec30cb7e,
- 0xd475ef87, 0x8931acfb, 0xcab6f5e6, 0xa43cbfc9, 0x94fc7d22, 0x469ca91e,
- 0x80656b69, 0x059543d2, 0x595e7e94, 0xe54b6941, 0x540f4a7c, 0x63fd2906,
- 0x3f4a32e5, 0xf4a6acad, 0x4a1acae3, 0x510cac3f, 0xa3e95eda, 0x2e879754,
- 0xf617ebfd, 0xc0b758b0, 0x8b0f6e03, 0xb2822cb1, 0xdee724cd, 0x53f39454,
- 0xa3066f8e, 0x63ea7fbd, 0xde8ca260, 0x6fc915f1, 0x47d1d3bd, 0x085e4af6,
- 0xcf4fa798, 0xa70c7b7c, 0x26c2dd93, 0x8f47d033, 0xf79cf45c, 0x2b04a1de,
- 0xa9c032c8, 0x519c9bde, 0x0fb985ea, 0x3a2e75e9, 0x70e75f31, 0x3eb7675c,
- 0xac6c97fd, 0x206972f7, 0xcaf7879f, 0xf0b30f34, 0xd7a45eb3, 0xf49bc50f,
- 0x5bd29fda, 0x2e89dca0, 0x33a735fc, 0x6e48e748, 0x8354ffaa, 0xc7882995,
- 0x2e10d8a6, 0x7bed4f8d, 0x38f285d6, 0x3eae5537, 0x7c77b234, 0x5467d695,
- 0x29e30c3b, 0xa7c3346f, 0xdcc9a5aa, 0xbb89e07f, 0x95f21875, 0x45d0fabb,
- 0x4a54ff48, 0xa6e67af5, 0xb1ced46a, 0x7c7141ba, 0x79f10efe, 0xf13c6370,
- 0xa93bac2b, 0x3fbb3ffc, 0xf7a3d5bd, 0xf606b187, 0x01f50d85, 0xf73a0de4,
- 0xdd07a8fa, 0x3f34af95, 0xfd49abd2, 0x1885ed06, 0x206677f8, 0xac10abd6,
- 0x2f5e5bd7, 0xe397ad07, 0xf6a68df3, 0xbe8f3de0, 0x7af7c7a6, 0xb5855be7,
- 0x7d04e3ea, 0xe7f0a575, 0xabd9d714, 0xbc4af3cd, 0xec6f2e09, 0x679a6d5b,
- 0x7f900ff0, 0xc8292156, 0x9b82253f, 0x32c7143a, 0x6a97fa09, 0xe5bd50f1,
- 0x6a572f12, 0x1e02d16b, 0xb466c762, 0xd1cdee33, 0xfb73cff9, 0x1fdf401f,
- 0x1ecaadfd, 0xd7e17cc5, 0xb06cf551, 0xe7e82d6f, 0x0dbdd011, 0xef5053c5,
- 0x3d76dd1d, 0x98b327d9, 0xa48b85df, 0x8d9d5602, 0x6609ce76, 0x7ffc8c99,
- 0x35defd82, 0xc8deb0d2, 0x9fd468b7, 0xf3cccb99, 0x2667d82c, 0x0cc6bf38,
- 0x939bb1e7, 0x56f3df91, 0xa0b730aa, 0x6ff39a5c, 0xbe49b8b7, 0x12c559f2,
- 0x3f08ef5a, 0xa66ebdd8, 0x2fb907f4, 0xec99e57d, 0x87e8a1dc, 0xf75bfae0,
- 0x7026140f, 0x3128a53b, 0xff20f9a4, 0x3f91868b, 0xfbe182b9, 0xa7a825a1,
- 0x5de64e82, 0xefd27acf, 0xb23ff687, 0xd27cfabf, 0xfa214fc3, 0xbe49d721,
- 0xda759450, 0xd84916c3, 0x974a415b, 0x76eb718b, 0x5c044d6b, 0x47d7011b,
- 0xbf377fc0, 0xbf133225, 0x35025aa5, 0x5fce2496, 0x4a482f68, 0x47f816a7,
- 0x51ed4fea, 0xb53fed7f, 0x3fa834fe, 0xfd7f54db, 0x0bfeb53f, 0x29bff47b,
- 0xafa5fd5a, 0x0416da6c, 0x79b4537d, 0x3cc18b95, 0x4ea95474, 0x4bdd02f6,
- 0x21762fd6, 0x82511c1f, 0xa3e7e42e, 0x34727921, 0x22d2f87e, 0xe7cca2fc,
- 0x855d7090, 0xc7fd427f, 0x54d9f85e, 0x59bee7b4, 0xbd69baaf, 0x5b0d6754,
- 0x1acb4e41, 0xdfa0a70a, 0x1c83e017, 0x46527a5e, 0x9fccd1b8, 0x4aafcf45,
- 0x701eff46, 0x844f588a, 0xab2a5ec9, 0x9c24f3fd, 0x2759ca87, 0x7be459c9,
- 0x04e9fed8, 0x5ab98fd2, 0xe87ccf5c, 0xe5f9d927, 0x0de52f02, 0xbb293b3f,
- 0x30f6bd30, 0x4cb013ea, 0x7c8f0ec8, 0x41d840af, 0xc4ce2c87, 0xb1425856,
- 0xa11fb11f, 0xc2f1d4de, 0xaa0edc42, 0xf0e4f0da, 0xb6afd083, 0x24badfda,
- 0x7974be03, 0xf33f553b, 0x7a7aafd7, 0x62edcbd7, 0x5efdd7bd, 0x34f3de88,
- 0x89adfb0a, 0xd86a25a7, 0xc971f685, 0x841bd55a, 0x9e9b25c7, 0x5c69ee7d,
- 0xf5627eaf, 0x17f5045e, 0xc3e37a6f, 0x6f170031, 0xf0a71351, 0xe4a43861,
- 0xc394fa6e, 0xba23f9bf, 0xf2f451e9, 0x18679a1b, 0x4270fe7f, 0xb78a5d37,
- 0xb0d8d6ec, 0x5098f89e, 0x716b5bbf, 0xfd4fa144, 0x676849c1, 0x56f86d55,
- 0xd1e575c3, 0xc94b125d, 0xb5cf8288, 0x80bd906f, 0x0a7a2278, 0x2fd1757a,
- 0xd0397ca2, 0x247af505, 0xbdcb22bd, 0x1465fa81, 0x93fd17af, 0xbe2fdfc0,
- 0x4fec7e8a, 0x43c45ead, 0xb9f78bc1, 0x95873c70, 0xcfe7ce0a, 0x3f464e2c,
- 0x4c1a817d, 0x9fca5376, 0x9fb9ac17, 0xbdff2ff8, 0xfaf993fb, 0x42d7d7d0,
- 0x2fb05573, 0xeaf6738e, 0x799c68db, 0x587c402c, 0x0fec8cf0, 0xc2b5fa41,
- 0x22896f26, 0x9732c527, 0x80ebc393, 0xc3ce30b8, 0xbf414eb8, 0xd0e5efee,
- 0xcc8ff27a, 0xee0fa861, 0x6cf1fdd7, 0x8b5fc12e, 0xb27184fd, 0xdae75f45,
- 0xbb5bfc4c, 0x74e919b4, 0x052f806c, 0x4ce56afd, 0x487c0a09, 0xf95ea067,
- 0x3853abbd, 0xc947989d, 0x5d81ef16, 0x639f0130, 0x67d566f9, 0x8f7a6e1f,
- 0x6ee8c99d, 0x1f689e7f, 0xf3831dfa, 0x5664e1f9, 0x7c651f50, 0x07aeb235,
- 0xf0375e60, 0xb9de4199, 0xc23ed7fc, 0xff975de5, 0x31934dd0, 0xb9f7abff,
- 0x387be11c, 0xc2bf425f, 0xfbbf9429, 0x83f48956, 0xc9a38595, 0xe42aad79,
- 0xc91f9cdc, 0x457fd02f, 0x0df0338a, 0x744093b6, 0xde5abf20, 0xa8df784a,
- 0x575db157, 0x39757acf, 0x20fa17ce, 0x707d064f, 0x603eb759, 0xe81eb9ab,
- 0xf20aeedd, 0x7a1a9bf5, 0x5f9469ee, 0x07a0d790, 0xe3f557e5, 0xdc6f8ff8,
- 0x209de1fb, 0x75ebc7b7, 0xd5eb35b9, 0x782db948, 0x7c84bd69, 0xc7b7291a,
- 0x894ac00b, 0x3cf0b726, 0xb416dcaa, 0xaaf44bfc, 0x65c7c78e, 0xf5d55eb3,
- 0x8cf86f64, 0xca9793d4, 0x127aa89e, 0xecb3ef7e, 0xf3a8fc9e, 0x457fcea1,
- 0x80bd29bf, 0x9f3a09fc, 0xc5d87cea, 0xf61f3aa7, 0xf098cff0, 0x3b7f9918,
- 0xc10c04f2, 0x7f255dbf, 0xdf134962, 0xdef7838f, 0xf8459fec, 0xc734d1f2,
- 0x9fecdfaa, 0x11438468, 0x79447d70, 0x8fec045f, 0x80881f28, 0x4be54c2b,
- 0x8c6af71a, 0x2a6c20f8, 0x2bff9d67, 0x759445f6, 0x950f3eac, 0x82d49c37,
- 0x9d691fc8, 0x753fea1a, 0xe8a89821, 0x9329dc3f, 0x7003b0ff, 0xe9da04bc,
- 0x0a1198d8, 0x6c591e82, 0x0ecdebe7, 0x012ba777, 0x1cf1c5d2, 0x96d24cee,
- 0x9fd41ea0, 0x1fb9da77, 0xe9dfc3a4, 0x31f8378a, 0xa4c9360e, 0x6c425bc7,
- 0x093f3472, 0xdf8434cc, 0x3e5bd616, 0xe0768ff7, 0x87b633be, 0xcf40cefb,
- 0xfa4765ab, 0x56bf5c7c, 0x23605ecb, 0xedc16b36, 0x77a1742e, 0x71ba0d34,
- 0xfd9f3c1a, 0x6db7ccb6, 0xafa53e82, 0x8471dd61, 0x2b189f05, 0x72de7ee1,
- 0x4d999fe2, 0x6b321d7c, 0x28797479, 0x39e5ef12, 0x77a869e6, 0xb9f0fd61,
- 0xd7ac0fd1, 0xe23ab053, 0x42f5d379, 0x3d69aa6e, 0xce6b5458, 0xd4f5880f,
- 0xc9feba37, 0x7fa49964, 0xeb84a170, 0xafb7a17a, 0x38de8796, 0xb1d3e80d,
- 0xbfb8664f, 0x2649aa7a, 0xc8da9cfa, 0x305953f7, 0x8cafe489, 0xd4be9275,
- 0xf286d6f1, 0x7aef7175, 0x9feb6dac, 0x3e421fb2, 0xe187f6da, 0x6db482bf,
- 0x778327db, 0x47cafc20, 0x3d607fe9, 0x65d84fcb, 0xc7733f27, 0x7ff1272e,
- 0xa5dfcec7, 0x76f0843f, 0x3af7f92b, 0x1c3b7d76, 0xa163b1f9, 0x60f500b5,
- 0x7ebe00c7, 0xedf9daaa, 0x7f9a16f0, 0x331d1117, 0x7de88d14, 0x072fe9aa,
- 0x54e02e30, 0xed0a8c13, 0x24b15d8b, 0xdaafe55f, 0xb1d11fc9, 0x80ecdbf3,
- 0x9e379fe3, 0xd3ffb132, 0x5ed364e1, 0x73c5fec2, 0x8ef979bf, 0xc02ecfd1,
- 0xdd86f1fd, 0x9fc84cda, 0x875fdaf0, 0x78ed7ea3, 0xed4ddb89, 0xdc1acb6a,
- 0x48ba18df, 0xbd02a85e, 0xfac851da, 0xd16fb631, 0x4728f1c4, 0x57f2f13d,
- 0x2f9cb3f2, 0x7c28263e, 0x8feffb3d, 0xf5c7c90f, 0x9364339f, 0x1ddfdc70,
- 0x89ea03f8, 0x4be2565d, 0xebc7bc7d, 0x733d9017, 0xfbdf71ae, 0x52dc6e3f,
- 0xbdc67cf8, 0xff9cdfe0, 0xfa878aad, 0x3d072917, 0x03e77cf9, 0x7a726f04,
- 0xc9e7bfa9, 0xa7ff6bef, 0xa025fdd1, 0xe3dcebbb, 0x4b3fff0e, 0x0ba7b7f7,
- 0x3e31bbba, 0xbfb5fca0, 0xa87eff52, 0x37f96b9e, 0xe36f7ba7, 0xb7fdedd7,
- 0x33f79e2c, 0x5664fca1, 0xe2c340ed, 0x6f3dd2da, 0x5bee4267, 0xb1e37b69,
- 0xf623e3bf, 0x5e34f47b, 0xf1b6fee5, 0xed03efb8, 0xac4978b2, 0xab3af917,
- 0xfa2fb0bf, 0x3b23cbcf, 0x63da7fa4, 0xc5304f64, 0x2bf712b3, 0xe99f4adf,
- 0x360bd8a5, 0xc200e3e2, 0x6c052bee, 0x4afe6f5e, 0x4adc3e62, 0xfd7e9fed,
- 0xd373b43e, 0x83b264d2, 0xf7fb2521, 0xfe64d775, 0xad3344bc, 0x98f5ae87,
- 0x129347d7, 0x89a8ebcd, 0x19abbea2, 0x0ed5ffef, 0x3c021429, 0xcbf01f8c,
- 0x8ea7f444, 0x126548bf, 0x605893c0, 0x263bae11, 0x9df5cc3a, 0x836c7dc0,
- 0xc5eff1bf, 0x3c2ec4e3, 0x47e95c0e, 0xc9900e3c, 0x3c4e7aaf, 0x6f09bf62,
- 0xc78c2199, 0xe3978a61, 0x4bd4a131, 0x1eb16a7e, 0x1da26ec7, 0x349638a3,
- 0xb82b3ca3, 0xa078e69e, 0x9ebeb875, 0x4cdf0dee, 0xd115cfac, 0x257f8ea4,
- 0xcdd9f64d, 0x5cfad1f5, 0xa50fcba7, 0x7fc74e87, 0xaac92e94, 0x8e692e99,
- 0xebca0a39, 0x8c3f5c64, 0x1c99f2c4, 0xb42a0b4e, 0x0fd624df, 0x28e678d7,
- 0xa4278041, 0xaf482a65, 0x22f6db7c, 0x79b51f8c, 0xc5c7ea25, 0x1f9a166d,
- 0xe112596c, 0x428d487d, 0xf7167bf0, 0xd4f7a428, 0xfe395e2b, 0xbb3f4320,
- 0xba06e34f, 0x7c97ef9f, 0xd8cce67f, 0xf0c7f46c, 0xde7fc61f, 0x59b7eb00,
- 0x063859ab, 0x615b34f0, 0xf404b8c1, 0x73ec4b93, 0x0cdc9f93, 0xe4aaefe3,
- 0x55ce7aee, 0xf2bd37be, 0x015f4ecf, 0x45f9f63d, 0x94c76d8c, 0xc6288a6f,
- 0x9a8ff6f5, 0xf7cabe38, 0x1e40d0b3, 0x0dfb2187, 0xab2f8afb, 0xcaf33fdc,
- 0x891a5f1f, 0x1d71dceb, 0x7eb8e343, 0xa971e2cd, 0x8a70bd62, 0x0ebce279,
- 0xe283afd4, 0x9f74bf68, 0xe7168cec, 0xbfac41b8, 0x28f1837f, 0xb2d47690,
- 0x57d7196a, 0xbefc93ac, 0x5b1b5ac1, 0x661e251f, 0x7e116a8d, 0xf8374122,
- 0x7fb8d9c9, 0x0d9fdbc3, 0xe919c6af, 0xa8e536d6, 0x1d27bc32, 0x61b9f7f0,
- 0xc51feaff, 0x11f7ae2f, 0x2dec1bbf, 0xf451fc93, 0xdfc0bd47, 0x91df3dd4,
- 0xa6d2f49f, 0xdfe416b5, 0xa62d6b4b, 0x553ad8fd, 0xb04631f8, 0xa9afd811,
- 0x2cceec7b, 0xd93ecba4, 0xe5a5f18b, 0x40b5274d, 0x48c47d94, 0xe8fd627c,
- 0xdd556f7f, 0xb50eeed4, 0x75e2267e, 0xc31b09c7, 0xad76f575, 0x3f5a38ba,
- 0x7ef2b4ef, 0xf7f566ce, 0xf7f8cf0d, 0x0eb8efc3, 0xae3c7847, 0xf0996b3f,
- 0x1ff24483, 0x553e3e23, 0xbf3842c7, 0xf5157ae2, 0x8c8da9c2, 0xc94077e6,
- 0x06feb863, 0xd1b1ff79, 0xe37173af, 0x5da0df96, 0xb924d650, 0x4ca24b71,
- 0x8fd0d169, 0x2f18de5b, 0xe99c3ce3, 0xdd6fe3d1, 0xc8356ec3, 0x10aaab45,
- 0xd98ef6be, 0xfbb61771, 0xd0c69b65, 0xdebdf14e, 0xfc79c2e9, 0x2491a6cb,
- 0xeb8dbd07, 0x34564ae5, 0x841ce311, 0x87e48c3e, 0x4c631ba1, 0xa07215f0,
- 0x54d7ca1f, 0x6f3ccb6b, 0xd32dfa14, 0x788fb124, 0xf42dfa9e, 0x7b7e99ff,
- 0x016fd75f, 0x23906fd9, 0x419bc0bf, 0xd344a5bf, 0x4f25736f, 0xee7de20a,
- 0x482941ce, 0xab6fb9d7, 0xdbf4d149, 0x2fbe4aa6, 0x4dc459ba, 0x7e803477,
- 0xdfa0dcbb, 0x45bf401a, 0xa3191f89, 0x73fa7ee9, 0xbfd0b7e8, 0xa136fe46,
- 0xde328b7e, 0x74fe041b, 0xe9bc36fd, 0xe1b7e920, 0x3c53160d, 0xf84d44f0,
- 0x6fd57a9b, 0x68add252, 0xbd53ef1f, 0x67f851b1, 0x37c7b093, 0x6c46388b,
- 0x955cf507, 0x5cf4c3f6, 0xb9eaf9de, 0x759e117f, 0x2b77373d, 0x9ee8b8a3,
- 0xdcf5c87c, 0xe7a0eddc, 0xae47e424, 0x64eee6e7, 0xa1172fdc, 0xd0f486df,
- 0x97ca8c6f, 0xe5fbf985, 0xde4f198d, 0xf08df50d, 0x941b5ea9, 0xefadd11f,
- 0x5df51946, 0xbe8bd695, 0xfa7e77db, 0x77d0ab6e, 0xa206c7a0, 0x0fe48d7e,
- 0xde39936f, 0xc3e8c77c, 0x79465f1b, 0xfb4c9df9, 0xf859ef92, 0xa33bd1fe,
- 0x7f21670f, 0xf3fa2a7d, 0xd9e9c6a2, 0xfaa4195e, 0xc7cebc27, 0xfb91ba57,
- 0xb81acbcb, 0x2b56587d, 0xe7f03c87, 0x69df31a4, 0x9dc2ffd8, 0xf8014b12,
- 0x13f56b26, 0x9febb40e, 0x1f589957, 0xf034c94d, 0x629cacc3, 0xd957fbf2,
- 0xfcf0eb5d, 0xd9852cd1, 0xec5fbfd0, 0xed147498, 0xbe1ce2e0, 0x9e2c501f,
- 0xb3b071eb, 0x4464f4bb, 0x9ce3483c, 0x9eb3fb37, 0xad531671, 0x9f53ae9c,
- 0xb7184295, 0x22ee33da, 0xb8a17a44, 0x5dfcfcce, 0xc9377f21, 0xf62f842d,
- 0xee351cae, 0x85d72f43, 0x4f027da7, 0x9e131780, 0x3c545242, 0x64a7a501,
- 0xa5e37726, 0x4b2d77f0, 0xf0a05f70, 0x91f68929, 0xe3adc723, 0x3afc722d,
- 0x773f751e, 0xbf2fa8b1, 0x6b9d2d69, 0x8e8bc48a, 0x747c48e7, 0x1f023de1,
- 0x7e5d69ef, 0xd71891ed, 0x7a437c04, 0x809ff826, 0x3fc76817, 0xf9d322ee,
- 0x5e048f9b, 0x9b8f5646, 0x370fe180, 0xe43a1c61, 0x79ccd5e7, 0x63e02fb3,
- 0x119ec7d4, 0x315e9d38, 0x7dc01ac6, 0x4ef60dda, 0x1f3a83d2, 0x3e72b30e,
- 0xd95e84d4, 0x3c62afd1, 0x251bf3ad, 0xe521da37, 0xb5e13b61, 0x0ed1f81c,
- 0xf53ef645, 0x578124cd, 0x6aaf9d37, 0xd013f314, 0x26eb82c1, 0xf10abe7d,
- 0x9b2358f3, 0xebca5d38, 0x58b25d38, 0x94c7ed27, 0x30de48d5, 0x71aca78c,
- 0xeba1c50e, 0x0e7e19fa, 0xf0a29d23, 0x7f8d12af, 0xb39b3a19, 0x62cde7bb,
- 0xb5aa6e51, 0xe7dc43fa, 0xb1f20a99, 0xfe10d896, 0x3efe1677, 0x2450fc57,
- 0x78132ebd, 0x757884db, 0xb93afe20, 0x8efe15fd, 0xf9e969ce, 0x84d04ae5,
- 0x9f4f09d7, 0x53b7fce6, 0xac5fa0f2, 0xcfc86f0b, 0xc74a3f90, 0xd233f21b,
- 0x465729a1, 0xddf00f38, 0x78e7a327, 0x28d4bf71, 0x0f3b85f7, 0x919ffaf2,
- 0xb8ca2cbc, 0xff7f307f, 0x4deebe40, 0xc55987de, 0xf7f0413a, 0xfdcef63b,
- 0x77bf9123, 0xd12fdc4a, 0xf7da6f14, 0xd7cac1bc, 0x20ec1b4d, 0xf6dfb807,
- 0xe75deab6, 0xae1fa9e9, 0xc03972b2, 0xe0c784f5, 0x0704baf7, 0x75a6f182,
- 0xa4178a36, 0xf6e40c7e, 0x6f5f51aa, 0x5ba4b3b2, 0x7faf7ab3, 0x37bfa88a,
- 0x8787497b, 0x47a87b61, 0x21bda11b, 0xce45eddd, 0xe0ffba17, 0x43bae35c,
- 0x3bdfcff0, 0x1f9dbd2e, 0xce554f1a, 0x4c5f699a, 0xb54aab8f, 0xd1515e04,
- 0x992c9bbe, 0xe7a0b7e2, 0x70ffce82, 0xa36ab7fd, 0xa59faf7a, 0xd08ec8da,
- 0x2d5ecbcf, 0xf010583b, 0x254fa5f6, 0xe32b0179, 0x7f38b183, 0x1079878c,
- 0x8ff72f92, 0xca6ee8fa, 0xed9f6997, 0x29f5dfc6, 0x1bc87dc5, 0xbb1d0c79,
- 0xfb225331, 0x6cac3de1, 0x36e1da34, 0x268ab3e6, 0x47e73f21, 0xd73c21f1,
- 0x3d5b5992, 0x3d7203c1, 0x85542ea2, 0x674277a9, 0xaf483be2, 0x7a433271,
- 0x4cfafb35, 0xbef7f9c0, 0xdc4cb33f, 0x813b078a, 0x8fb119ea, 0x31b96125,
- 0xce5a24be, 0xeaf86e8c, 0x7fa05bfd, 0x5ecbf7a3, 0x69bb940f, 0x7281c3af,
- 0x85b56436, 0x19780c05, 0xe85542c3, 0xc87d1a77, 0x83ea0b77, 0xf07bb002,
- 0xd341497c, 0xc2172ada, 0xbf7a25ab, 0xe498183c, 0xaa6dfe82, 0x32e93939,
- 0x0e500bd4, 0xcd5f29ab, 0x4ad795cb, 0xce710c5e, 0xf1415a6b, 0x12b57948,
- 0x14dc601d, 0xd78d9892, 0xbd41b21b, 0xfbc3569b, 0xc17f3859, 0xed6f58fb,
- 0x416ff7c9, 0xa4fd03bd, 0xfdf237f7, 0xcf783cfa, 0x3b527283, 0x5c2bea87,
- 0x073c312d, 0xcf91b053, 0x55fb054f, 0xec37e62f, 0xdde68a7e, 0xdf5ed029,
- 0xc28f9c0c, 0xd13ce913, 0xe74dc948, 0x80be1f38, 0x0e0756f4, 0xa5f05f18,
- 0x4909f8f3, 0xa3fd62c0, 0x6dfd7fdb, 0x9e535cfc, 0x07d68177, 0x272779ea,
- 0xfc42c329, 0xe1f69274, 0x03be010f, 0x79379c56, 0x9cdecb3c, 0xc316b42f,
- 0x1b6398fc, 0x6acfef44, 0x1e71471c, 0xe29f99b3, 0xe68ea63c, 0x57bbe776,
- 0xefe843da, 0x4ced577b, 0xaf7be7c3, 0xf6f3d2b4, 0xb70f5c4d, 0xbf21680f,
- 0x2ad5e1fb, 0x552ff3c3, 0x13d265ab, 0x74aa3787, 0x867e576e, 0x6fe437c7,
- 0xdec876e2, 0xc3debcd5, 0x9b7edc75, 0x936dccf0, 0x5fce1e70, 0xeaf9cfcf,
- 0x875f5a7a, 0x4d0bb9e6, 0x9ea45bf3, 0xa970f5d5, 0xf54147c0, 0x8f4fda5a,
- 0xfaa5bbd4, 0x6fa1187c, 0x9d9f714b, 0x24c3d3f6, 0x91f5a547, 0x6e8e65f1,
- 0x43f20dbf, 0xefe23bf8, 0xc32afdb2, 0x45f48d75, 0x678a24db, 0xf21ef9c3,
- 0x3e493747, 0xf8287b8c, 0x7b221ad8, 0xe33b943c, 0xf99e703f, 0xc8f0cac4,
- 0x03d22b48, 0xb58e54f4, 0x84bf8ff3, 0xb3df47e7, 0xf010e461, 0x5fe12e4f,
- 0x5ace138f, 0xb27ee3cf, 0x8c995bde, 0xc4d98de7, 0xf207a43e, 0x3016646b,
- 0x92a38de8, 0xf93b96ef, 0xfb46e0fc, 0x966ba747, 0xf3879d56, 0xeb8d916c,
- 0x957acf47, 0x0bc78bce, 0x3e0bd618, 0xb70a77b4, 0x0cd648af, 0x73b850fc,
- 0x0ea83245, 0xcbc444b6, 0xe6738954, 0xa76f1a85, 0x5ee49770, 0xaf47686b,
- 0xdb57af47, 0xb41bdfce, 0xd5bda793, 0xa3fd885f, 0xa1ad7e71, 0xa7ac88de,
- 0xd4bdfb47, 0xa75ff393, 0xffb9e257, 0x0a65779c, 0x62f9cf76, 0x3ee320ca,
- 0x7eea9e8f, 0x2df7ece6, 0x5fc067cc, 0x98631fce, 0x86ef40cf, 0x40ff2051,
- 0xb91a1bbf, 0xea30d73d, 0x459a56a0, 0xbde51bb0, 0xcba3f84c, 0xbbfdf226,
- 0x16f7cc86, 0xc94ffca1, 0x581f8892, 0x49f5a030, 0x83cdfb24, 0x59f900fb,
- 0x787cfdfc, 0xe1b2e51f, 0xa0a72e29, 0x4fa83c2f, 0x98af56ca, 0x256be544,
- 0xb0dfd60f, 0x92ec9736, 0x51991c82, 0xb241ed7e, 0x0f1a0a93, 0x833ca226,
- 0x7b44aefc, 0xd5ac6ca0, 0x9758ea8d, 0xdfce5d4b, 0x9961e715, 0xcf0c3dcd,
- 0x5876e077, 0xf796f934, 0x72b76133, 0xe1cf2cb9, 0x26eefb72, 0x3e784715,
- 0xad724e72, 0x728cb1cb, 0xc72dd59c, 0xd04f577b, 0x870fae50, 0x99a38a24,
- 0xe5007a80, 0xe71e837c, 0xf3d8edc4, 0xd973f395, 0xbf20a599, 0x72ea5f38,
- 0xa475cbae, 0x2d2b373c, 0xee3f62b7, 0xe34ed2bb, 0xf6d57098, 0xfae3ef0f,
- 0x275ff68a, 0x3260f55c, 0x853cc7ea, 0x78e979c7, 0x5c78552d, 0xad7e8f60,
- 0x3df5a05c, 0xf445fe9f, 0xd9ab33e3, 0x8b6f125f, 0xb5eff1e7, 0xb9fdf12a,
- 0x9c87b3e4, 0x9e7ca79d, 0x4b9d5caf, 0xe5f6f53e, 0xe27ae69d, 0xf5476991,
- 0xf01dafac, 0xbe3c0618, 0x8a59f1b5, 0xc2f13e0f, 0x8748a9c1, 0xe7c01de2,
- 0x9d1b5fc8, 0x4e7a8c2c, 0x55bcd109, 0x39d320d4, 0xb384a603, 0xe51a716f,
- 0x1575c798, 0x3f12766f, 0x0d64bd15, 0x8bf7814d, 0x9c317db6, 0x76166ae2,
- 0xf05adc52, 0x072f6105, 0x1ca3865b, 0xbe3c2914, 0xfc2f522c, 0xe7edc6da,
- 0xd3b1edb6, 0x1d527c70, 0xa8a2dfbf, 0x6ad576fe, 0xc278a7d8, 0x50bb52a6,
- 0x8379f68e, 0xfe78c7c0, 0xbc67fb17, 0x2b8f4157, 0xf5c0db6b, 0x1aa35144,
- 0x8a327bc2, 0x63b4b6ea, 0xc7d171bc, 0x957ff256, 0xf3a49dd7, 0x6f361314,
- 0x794aff22, 0x8fda6ca3, 0x59df11eb, 0x18ad8727, 0x4a50d897, 0x1f0090fb,
- 0xc45eb824, 0xf8c0fe53, 0x3bcde2c3, 0x850105b7, 0xef3f2fc5, 0xac72fd42,
- 0xf10bbd79, 0x359ef50e, 0x3c47bade, 0x2223fd67, 0xc386f39e, 0x2f4b6f74,
- 0xf0c79cf1, 0xb794100f, 0x4e78e66d, 0xec87d756, 0xb667e84b, 0x47feca3f,
- 0xe9be7d97, 0x1e7835eb, 0xe3a5eda1, 0x25dfb06b, 0x0d72fb7f, 0x5db189c6,
- 0xcaf79a76, 0xe280f85f, 0xbef7f5b7, 0xc87f09b0, 0xfe29e786, 0xab13fdbd,
- 0xdf6b6b17, 0xe31d3879, 0x7cb7db06, 0xccfe8c97, 0x26af3b79, 0xadbcef7f,
- 0x94585213, 0x914f4379, 0x11e7437f, 0xb7491f7f, 0x297b0dbd, 0xd004ed9e,
- 0x5760f51d, 0x297d6e9c, 0x88f67f8f, 0xd18ddcf8, 0x88f43bcf, 0xe5b86dc7,
- 0xff512bc6, 0xf27b7037, 0xefb9719c, 0x3f2f3d03, 0x146e3a0f, 0x37f5d7f1,
- 0xf72e359c, 0xf401fe04, 0x74cdd8b2, 0xf661bafc, 0xbcc69faf, 0xc6bd3e86,
- 0x03cf86e5, 0x8a79fa7f, 0xa73e6c77, 0xa5e8e51d, 0x343c50df, 0x078a6fd2,
- 0xd3afa3e7, 0x11ca3cf1, 0xce3a73b5, 0xad3b9d3f, 0xd14fdf74, 0x9e488fce,
- 0x47beb7da, 0xce266a7e, 0xaeb3b435, 0x973f8f1f, 0x9d6b78c4, 0xd0579e3c,
- 0x3d7de301, 0xe22e7a2e, 0xeb5f397a, 0xc5bdbef1, 0x1f6d5ef9, 0xe00fee28,
- 0xb5a5c8f1, 0xb3f1107f, 0x729374dd, 0xcf075e90, 0xe3ad471a, 0x72f42dc1,
- 0xf47b1c77, 0x38aeeab8, 0x21ba08f6, 0xea9e713d, 0x3807538a, 0x49f9046d,
- 0x2e768a3e, 0x8f2d7da2, 0xa3576f7f, 0xe3d6379f, 0xf4117dda, 0x9bdbc7d6,
- 0x7b72e8bc, 0x50fc71ae, 0x4266d13c, 0xb57c4f52, 0xbf5d1f7d, 0x7f4bb4cf,
- 0xebbefad7, 0x148954bc, 0x5eeb1e79, 0x86d2cbe4, 0xeccfe483, 0xf18b7f5a,
- 0x7bff09b6, 0xc5320bdb, 0xdfa92f39, 0x523dfa4b, 0xbde1947f, 0x7bfa512d,
- 0xe7d85dbf, 0x68fe7c8d, 0x7219c97b, 0x7b6d3d40, 0x975f13b6, 0x71483c6d,
- 0xbdd66fd6, 0xe218b5ac, 0x08fe7027, 0xf6d3c619, 0xa4e1eee2, 0x30fdc5cf,
- 0x8954ed91, 0xa29bca76, 0xf1be53b7, 0xe29da9a4, 0x76e6bd60, 0x63bdbb9c,
- 0xac76ef8a, 0xb73358ef, 0xcbd58f13, 0xf6d14393, 0xd8aaec69, 0x29e6afef,
- 0x0f74a3cc, 0x7bdf938e, 0xc862bb23, 0xcce79cee, 0x112e38f9, 0xbae28d53,
- 0x388816aa, 0x537a9fb0, 0xce55de91, 0x77f618eb, 0xe0d7e231, 0x01dd51ff,
- 0x9aaaf686, 0xbf42cfea, 0xd1dea443, 0x642c2d12, 0xe73cf7a0, 0xed0f14e4,
- 0x90d3848b, 0x0f32079e, 0x67ef58ab, 0xcfabfe11, 0x0524b614, 0x5059f7fa,
- 0x7a802ef2, 0x0c5ff7d9, 0xd67b3bf0, 0x8781c3af, 0xa9bf9365, 0x0079dacc,
- 0x35ec2bd7, 0xc847ed3b, 0x7f74ecbb, 0x3b1af948, 0xd6ef778d, 0xbb239f6f,
- 0xc656d7fb, 0x556087f7, 0xb996f783, 0xb7871d79, 0x2fe6bb7e, 0xcbe35768,
- 0x1afe7ed0, 0x89eb8f28, 0xfeb4b18d, 0x8e2978e9, 0x7fcb51ee, 0xa8a9a1ed,
- 0x3963f2d7, 0x4e6fe63f, 0x7d415509, 0x6e1c49ad, 0xee8034dd, 0xc97e28ab,
- 0x7ba5f149, 0x8652beb7, 0xe6fb54f3, 0x60330c58, 0xfb09afed, 0x7ee237ff,
- 0x63d51aad, 0x642f338c, 0x2e78c78a, 0x536118a8, 0x3f23135c, 0xfa11c906,
- 0xe8e31ab1, 0xc5d8113c, 0xa84e7aa6, 0x89780f9d, 0xf8fd838f, 0x3f70aa39,
- 0xe59107d4, 0x76fdfcf4, 0xdcbd8e7e, 0xba39ef0a, 0x9d6b97cb, 0xeeae1c79,
- 0x3349f5c7, 0xe744ff95, 0xb3df9173, 0x23fe5e5e, 0x7aaedebd, 0xe265fbf8,
- 0xfe489b7e, 0x57a5d43d, 0xb4717afe, 0xf4a25bfb, 0x2fdf9e9f, 0xed05a0b1,
- 0xba762d96, 0x67ef0bb7, 0xdb0e73c0, 0x55ffbe34, 0xfdd30ae2, 0x3e843b39,
- 0xd309892e, 0x44fd3e7d, 0xc23cb03f, 0x22f2d6cc, 0x15f4bdd2, 0xb3f8c33b,
- 0x3e9cd7d2, 0xb6e977a4, 0x957f5b6f, 0xb18bf185, 0x7d2bd7e4, 0x1f117fed,
- 0xd3c35a94, 0x2dbcfee9, 0xe7f78656, 0x3b796db5, 0x4db5e51d, 0x9c27a70d,
- 0xb4af5f65, 0x57be6ade, 0x58e38c40, 0xbc42e865, 0xaf3f4177, 0x9e8bd45b,
- 0xdb8632b9, 0x9f18f6d7, 0xdde48635, 0xb1d44f7c, 0xc641c6ca, 0x9e45fbf3,
- 0x7fb17ae8, 0x9d8ffa8c, 0x38f47743, 0x263fdaf7, 0xe699ed09, 0x96407464,
- 0xfa8e3d81, 0xe4eea8bc, 0x7c1ff430, 0x6fdfa316, 0xf9c389e0, 0x73ad33e8,
- 0xcfbfea18, 0x19873bd2, 0x952399e7, 0x92a28f36, 0x8ed2875f, 0xfaf327b5,
- 0xb5378c31, 0xf7a68b4f, 0x12c4c586, 0x8e1e8afe, 0x7a8e7a8d, 0xabe70c4c,
- 0x531f6834, 0x43e5176c, 0x2d33f76f, 0x31b87a44, 0x49ebc3c6, 0xbcf8690b,
- 0x20fb6eb8, 0x950a1e23, 0x72072a6a, 0x642cf84a, 0x832cb52b, 0x2bdbd6fe,
- 0x28f0ef9c, 0xf2813f74, 0x55f8ba7f, 0x3933a6ee, 0x518e3191, 0x5c6614e0,
- 0xe7eb33f2, 0x6fd51448, 0xcc69fc43, 0x646456ef, 0xf7926a95, 0xa94f5618,
- 0x7e2ecc03, 0x43055a5f, 0xec44793d, 0x0c1fa3ef, 0x3d7c6ed3, 0x383f7a48,
- 0x328bb180, 0x4f09bef0, 0xbf80db9c, 0x3eb3706b, 0x2b69e309, 0x5317d718,
- 0x488f68dc, 0x033b00c1, 0x595554fc, 0x03df8837, 0x2f187cc2, 0xf42c2649,
- 0xf37ee5cf, 0x8083b43b, 0x843df94f, 0x1550b157, 0x86c318a0, 0x9e3aefc9,
- 0x96f3fbf1, 0xeb8ccc7d, 0x0741128f, 0x7a4ddc16, 0x7fbac1cc, 0x5aa3009d,
- 0x155b7d45, 0xdc1cb7f7, 0x59b8739f, 0x58c3ed18, 0x42c70b07, 0x1caa18ea,
- 0x2bbfca33, 0x5f03600b, 0xf39ac7ba, 0xf402e523, 0xf5bb445a, 0xf7a83f84,
- 0xbf7a88ab, 0xabf7a88a, 0xe3abd5b3, 0x2836dca9, 0x58a5ef03, 0xf02f595c,
- 0x09b3dbc6, 0x867e01bc, 0xcc7f3de0, 0xfb15e312, 0x18d784e6, 0x962b1bd1,
- 0x8e6eba07, 0xfa7e20c9, 0x4eaedc59, 0x8966978c, 0xc3d70c35, 0xbefd248b,
- 0x1877e64f, 0x1b6e63de, 0xa223e1c9, 0xcf02cd9d, 0x55bf748b, 0xb276f28f,
- 0xb7947abf, 0x263e56f7, 0x6f67797a, 0xde8d89fd, 0xea5ef89f, 0x5a8d8eaf,
- 0x4bd50fff, 0xf47daf65, 0x76efee0e, 0xa03727e9, 0x6e676cde, 0x1a54fd46,
- 0x16b7fadf, 0x4cedc27a, 0xde999a5b, 0xc0dfc831, 0x9a17316f, 0x49f2479f,
- 0xf472fe14, 0x29df7185, 0x61f3bbda, 0xe74d5e7e, 0xbe315c83, 0x9f7cb589,
- 0xdc79eefc, 0x46cb078f, 0x25dfe61f, 0xe1aeeff2, 0x0fdde3f6, 0x1b0fb4cb,
- 0xc1d5bf79, 0xe1efcdff, 0x801f07b8, 0x5f33ddbc, 0xa233850a, 0xdec5dbdd,
- 0x677a878f, 0xde44fe88, 0x9e601583, 0x68e4cb49, 0xbe7160f7, 0x45e1cfd4,
- 0x8b317fde, 0x66fdc5f9, 0x3159e7e6, 0x22dbe26e, 0x0f55a425, 0x82c79eed,
- 0xd1ef802b, 0xc7be04fe, 0x9c592ffd, 0x8d2e66c7, 0x9adfd7c7, 0xa77fd260,
- 0x70e27886, 0x8baf66be, 0x7cfe6ee7, 0x149eb5ee, 0xe54579e3, 0x1ee9ac74,
- 0x9bd52aa0, 0x3d4dfa8a, 0x80f33d7d, 0x07a76a1c, 0x1f218f31, 0x7e1256ec,
- 0x3d24f30c, 0x5084aa95, 0x3f6e2a2f, 0x37bb47cb, 0x5eb3f39e, 0xaebc4b5e,
- 0x177ccecb, 0xe6461dfe, 0x5dcfff81, 0xdff3a1e1, 0xa7fc3957, 0x5d95fe71,
- 0xa380de39, 0xb7043f27, 0xe15771f2, 0x8e7a33b8, 0x7af34aa7, 0x0ebedec9,
- 0xcbf245e6, 0x3fd86d79, 0xc8f9ead9, 0xadfbfd83, 0xd30fd0ca, 0x23de3f13,
- 0x153fc821, 0x24714fea, 0xc194dc72, 0xbc72fed8, 0xfff4146f, 0xe8bf7132,
- 0x52264aa2, 0x08b7571e, 0x34a51fef, 0x913ea447, 0x8f72a64e, 0x974a7b8a,
- 0xd5297a54, 0x56f36bf1, 0xb6983dd3, 0x36fb790b, 0xa25fa0b7, 0x402fe045,
- 0xb52d97f6, 0xed1df682, 0xde308aee, 0x60d2c727, 0xb961c1de, 0x9abf09ab,
- 0x13bf919b, 0x456c13ca, 0x66b55218, 0x7149d10a, 0xc87cb057, 0x0604754f,
- 0xe37da2c7, 0x6987df31, 0xd6711d4d, 0xf8bb31fb, 0xfbc7136d, 0xb7e71263,
- 0xa63fbc48, 0x6e307b36, 0xbb6bb1e2, 0xbc22abee, 0xe38872c3, 0x7ef93ffd,
- 0x37bc4f6e, 0xc0699b4f, 0x327b33bb, 0x0267fde1, 0x5e054bcf, 0xaa1d04ab,
- 0xc4ab3e04, 0xe255afbd, 0x812adcde, 0x3bc42adf, 0x7b888fa4, 0x3d23177b,
- 0xef119520, 0xa1d6bfc0, 0x7b432641, 0x520f0f7c, 0xb75be087, 0xb2a4fc85,
- 0xbc43efc3, 0xde39135b, 0x03a00e6d, 0xdde035f1, 0xc241f983, 0x78e0eaa7,
- 0x0e9cf286, 0xef105602, 0xa739f123, 0xb6fde007, 0x87d424d8, 0xd6784c63,
- 0x1f9fc712, 0xf3e29fde, 0xf390a25b, 0x6a25fc48, 0x5d605efc, 0x8fb37bbe,
- 0x765c44ab, 0x1197b895, 0xcd7688f1, 0xbb0fc02a, 0x3f93e398, 0x2f60221f,
- 0xfd6249a5, 0xc074055f, 0x3d8527fc, 0x74c67884, 0xb75f2c67, 0x762a5a24,
- 0x04a788ab, 0x4b0fdf7e, 0x6cb4b20c, 0xf18043c6, 0x1e641a97, 0xe1fdf584,
- 0xc8ff335a, 0x7ee2256e, 0xc893cf49, 0x56df2b6f, 0x2f7fb82d, 0x74debfcf,
- 0xe69e5bae, 0xfe10f78b, 0x35da1203, 0xb872133f, 0xfa85f902, 0x8bc3d7c7,
- 0x152c1f05, 0x223f06f7, 0x2131e7f8, 0x7ceb8fcf, 0x48e7e5e3, 0xf1e64f96,
- 0x1699898e, 0x9862bf71, 0xe309e319, 0x834cf5bd, 0xc6dad17e, 0x9fdd2943,
- 0x92b63ec9, 0x650ec6dc, 0xf8afe43e, 0xf10c1f8f, 0x7dfd70fb, 0xd78a1ed1,
- 0xeb1dbfef, 0x0e83bf89, 0x711587b4, 0xd7cca4cf, 0xef51cd93, 0xeef2ad8d,
- 0xa65fa1b1, 0xbeecfeb7, 0x73f11b69, 0x1e44e5de, 0xbfe027d6, 0x8ec03663,
- 0xc157581a, 0xc81bd62f, 0xa57a8c5e, 0xebfc49c6, 0x1be7fe80, 0x17b624f8,
- 0xc754ceff, 0x5f501bb5, 0x240680bc, 0x6a2fc130, 0xcf11d906, 0xfa0f7380,
- 0xfea956b1, 0xac2f38be, 0x8fee8f8a, 0xdf2c65fb, 0x5d657087, 0xac2bf26a,
- 0x9ef47d54, 0xef59ac7b, 0x44f314ac, 0x9cb344c2, 0x4fc2f3e8, 0x39577d45,
- 0x5fb13b02, 0x9227a7c9, 0x1cde273c, 0x52a89e7d, 0xf7de20b5, 0xcb8c3551,
- 0xe3573077, 0xfd0f73f6, 0xe49f68c3, 0x3af06054, 0x7ce983f4, 0x7d7190b6,
- 0xaedc6417, 0x04f5c7d4, 0xe715bdf2, 0x3ff13703, 0xcb0807ce, 0xdefc6a17,
- 0xe42dbbe3, 0xe4225887, 0x672151ed, 0xfd7c85cb, 0x8acbe51c, 0x297b58f7,
- 0xab9085fd, 0x90872895, 0xe0cd8f1e, 0x3fb8bcf6, 0x2ccf5f4c, 0xfba08db4,
- 0x161cab22, 0x4f94179a, 0xae0721ac, 0x768f760f, 0x7647ffa3, 0x4e03b966,
- 0xfba2cfcc, 0x2cf8a5dc, 0x37cdf237, 0x9c1759ce, 0xc8161e2d, 0x2b16f74f,
- 0xea4bf72a, 0x8957c8f7, 0xf75408fb, 0xd5fd0ccd, 0xd856264f, 0x9635de29,
- 0xe4d787c7, 0x81de1366, 0x86b19d1e, 0xb4ca5a75, 0xfbeebaeb, 0xec9feac3,
- 0xef835ee5, 0x6960de85, 0x41a17641, 0xfb88d44f, 0xc8279924, 0xc5f41886,
- 0x31268bc2, 0xd4f5eff4, 0xcde8bd13, 0x2e6f5cf5, 0x4deba292, 0xf5d78edd,
- 0xd17ea466, 0x4c17c5d3, 0x54bf9d36, 0x7a465e1d, 0x3f744867, 0xcac3b242,
- 0xd7992ff7, 0x33d19b9b, 0xec95f01f, 0xed0be030, 0xf16fdd21, 0x89e328e3,
- 0xae4793d4, 0x00d7e7d3, 0x4b343bdd, 0xfa393cf3, 0x79abf3ac, 0xfd3fc85e,
- 0x794fcd08, 0x5a5347a7, 0xd92d7350, 0x69770c23, 0x1c2ef70c, 0x0bbf7d5e,
- 0x46b87be9, 0x56af9fec, 0x74bf1843, 0x197166b8, 0x0f76d5c1, 0x2fdc66d2,
- 0x3de1741e, 0xc8d6b34d, 0x247e9fb4, 0xf14e9826, 0x399fdf9f, 0x63e21b23,
- 0x9a5dac16, 0x6b38fc8e, 0x373a52dd, 0x37c1247b, 0x59806fd8, 0x79ec8796,
- 0xbcc6fefd, 0xb43ead67, 0xdbe37bc7, 0xfdd1d5bc, 0x27f8553d, 0x779853ae,
- 0x7643ae08, 0x8674c6bb, 0xfc8e0f81, 0x82eb4ec2, 0x8ed82d2a, 0x58bad570,
- 0x2555837c, 0x280fbf44, 0x0fb571d5, 0xf0ea94e9, 0x73298b5d, 0x4f7ed024,
- 0xdbc472ef, 0x3b5f456f, 0x2d3ebbee, 0x3a0245ee, 0xbbf264dd, 0x56d77df2,
- 0xb66347e1, 0x4463f25e, 0x7c97a7be, 0x62938f17, 0x7ff9e8ee, 0x6869ffb7,
- 0x315df58f, 0xe6b4bf8e, 0xe84f92f8, 0xa11f7989, 0xcf8bc450, 0x5a1b175a,
- 0x66ce4518, 0xb3c7f389, 0xce997ec4, 0xebd7858f, 0xe3e739f6, 0x5e973e48,
- 0xfaf884b8, 0xcd2a7dcb, 0xafc0656b, 0x17a5efa8, 0x507dd346, 0xe2bb9e0b,
- 0xfc0b8c71, 0xf94cbf6a, 0xc4eda725, 0xf53fedc7, 0xce8239d2, 0x9df4a9df,
- 0x5df6af88, 0xda01e74d, 0x3ad3fdc5, 0x7c9cd29e, 0xc1c6bc3d, 0xe9de50f5,
- 0x743c919f, 0xa66857f1, 0x779e7286, 0x5e5ce7fa, 0x31d9fef0, 0xdeebec38,
- 0xe0a1771c, 0x2cd7806b, 0x2169349f, 0xc2df9bd4, 0x0d8d8ae5, 0x7b1f9196,
- 0xd1f7ac6d, 0xc6bff228, 0xb5f931e1, 0xf3965bf2, 0x4caec0f7, 0xcc99c434,
- 0xc87bdf12, 0x65efcd3f, 0x4b20ee65, 0xfa127945, 0xcc0e5bb0, 0xdbb772f7,
- 0xd3d4e3cd, 0x79c6bb17, 0xd6fd6985, 0xe8abce3d, 0x53b09e79, 0x13465bf2,
- 0x5f9e3ddc, 0x9e368e8d, 0xa58c71ee, 0xd1f1edf2, 0xb450ffdb, 0xc0595adf,
- 0x8b4fa07c, 0x79bffdc4, 0xd434fba1, 0xe3ab791f, 0xb8c32413, 0x4d8a6bf2,
- 0x35794ff1, 0x5fdf74b9, 0xed5ceafe, 0x76bc835e, 0x36cd85d1, 0x4743e5d1,
- 0xd532e880, 0x40e3dfe1, 0xf0a17cb9, 0x583d4f81, 0x11d3a72f, 0x82bc382d,
- 0xae7ddbf4, 0x3ea7e768, 0x8d53a48c, 0x1fac13a0, 0xd2740cb2, 0x7ef913e9,
- 0x07d2faeb, 0x8bfdc53e, 0x45edf8a7, 0x08b1ebbd, 0xc74465fa, 0xf383a75f,
- 0x0fd82b6b, 0xdfc2f381, 0xbbf8a665, 0xe827f15e, 0x7f47e3ad, 0x51dff60e,
- 0x944efb94, 0x1f5851cd, 0xe17387e7, 0xc17dbbad, 0x8fa2e30f, 0xf3a9c527,
- 0x04167cc3, 0x71aa3e01, 0xf1f7a3fb, 0xb682c43c, 0x974f18f3, 0xf1362e9c,
- 0x01738a43, 0xff415397, 0x211e7ba3, 0xc50d6ebe, 0xbd19ed7a, 0xd9c5278f,
- 0x185c1f0b, 0xffb34364, 0x11c1f1ef, 0x29f837cd, 0xde60479c, 0xf0bd79c2,
- 0x1b86c7f9, 0x18ea97fb, 0x79c4e697, 0xf6fcfaa9, 0xbde383b7, 0x1e1d70fb,
- 0xab7b275c, 0x8e254860, 0xbf7c60c0, 0x37f4f5c8, 0x145bdfe8, 0x68f0c4ff,
- 0xcae2f476, 0xdfa0977d, 0x99b2aab5, 0xc5d85552, 0x0ce2ed0c, 0x688f5dfe,
- 0x2b5e05f7, 0xcae2ebf4, 0xb5b7ee66, 0x70db9905, 0x323b00cf, 0x8ad8fc92,
- 0x69cf6cc3, 0x7e8dc06a, 0x83dc4d73, 0x65812aa0, 0x67e85919, 0x1a0ccc4a,
- 0x938d77f0, 0x4f2cd7ef, 0xfdc6e3dd, 0x8fd42b10, 0x9a5b33fe, 0x77e4ca72,
- 0xe5995d7b, 0xd7e93a04, 0x7ab0c744, 0x1f91249f, 0x1f8454f2, 0x1fa994f2,
- 0x7da6cd89, 0x28bc488a, 0x281dfe36, 0xb3ff0985, 0x9dfe87c0, 0x3e6ea5a4,
- 0x8fc295ce, 0xaffa04fd, 0x363b022f, 0xc1f645d6, 0x7c2c0b92, 0xe853687d,
- 0x3c6b2bbe, 0xf1c5af2f, 0xff71d871, 0x59f5c643, 0xde276098, 0xd5d32610,
- 0xf1c2128b, 0xdc2123cc, 0xe0978587, 0x5c63a37a, 0xfcf803cb, 0xd7207b79,
- 0xa6ff7809, 0x0901f36f, 0x81fc33f7, 0x35cf118b, 0x03d33072, 0x772d7fe5,
- 0x74b96266, 0x8138fac8, 0x39e017a7, 0x9f618087, 0xdcd7df94, 0xe13dcb0d,
- 0x112be60b, 0x5fdf86fb, 0xc7b7cc6c, 0x1fb02af8, 0x4acbdf91, 0xfda242fc,
- 0x074cfc41, 0x34fdff9f, 0xf2772f3f, 0x07f10575, 0x6e3ed7f2, 0x3c529d3f,
- 0x87efb871, 0xb4dd79d8, 0xbcf363ef, 0x114f686e, 0xe05ad8eb, 0x4fb0c557,
- 0xb3e2a177, 0x545d3f20, 0xfd8dcf0d, 0x2727628d, 0xf2dae838, 0xdebd76a8,
- 0x83af3c3f, 0x4f4f94f8, 0x92247b22, 0xed74762f, 0x69eff027, 0x9e33a1dd,
- 0xf1c388b2, 0xfad1ff4c, 0xfdae93ee, 0x761c45aa, 0x5efca873, 0x69fe3fbe,
- 0x99c51c6e, 0xa3b8fdea, 0xda336969, 0xf53477c5, 0xbcf8899d, 0x3fe2e0a3,
- 0xed43ba63, 0xfa8b13dc, 0xce897ee2, 0xc1f9dd97, 0xa42c6aeb, 0x475fdf5b,
- 0x2f3c1ff7, 0xeb3a71e4, 0x01fe9154, 0x7ef8d6e6, 0x47df8857, 0xae02bcc5,
- 0x715fd157, 0xdb743877, 0xf3dd000d, 0x3406e87a, 0xebefa6f7, 0x43d5037c,
- 0x893ddea0, 0xf7f494f6, 0x726fbd1a, 0x35d7bf98, 0xe346c57e, 0x8daf1ee9,
- 0x0f8fafc6, 0xeff84a7a, 0xf7b88fc2, 0xf8c7c74d, 0x77dc7c99, 0x1d75dec4,
- 0xe03acb3b, 0x3fb0db0e, 0xde3e78f3, 0x7cfc489f, 0x1fa05985, 0xf6fa745f,
- 0xe33e3f20, 0xbd45edf4, 0x4ceb6257, 0xbc920657, 0xcbcf85bc, 0xc905c0e4,
- 0x0313fe30, 0x21271702, 0x9cfb9a1e, 0xc07fbd97, 0x80fbf9ce, 0x81f7f39d,
- 0x5baf9d0c, 0xecd7c89c, 0x538d2274, 0x92c77eff, 0xbb1f87ad, 0xc4fbf81d,
- 0xbb3efcdb, 0xe373d952, 0x9697e443, 0x3e2e3199, 0xfc203d32, 0x7c5d2d0c,
- 0x433bc7c8, 0xa332f2e1, 0xc1ce9621, 0x9b2f98cc, 0x319fdbee, 0x32c3c79f,
- 0xadf879a5, 0x22c275a6, 0xb3d2d711, 0x4483f41e, 0xfe7333d6, 0x6517ba04,
- 0x471ee69b, 0x9c35917e, 0xf44e66cf, 0x608e78c9, 0xf68932cc, 0xf21f47f1,
- 0x3c00b634, 0x45ef1433, 0xe0f99d31, 0xfbc20d7f, 0xb99aca51, 0x9e45347f,
- 0x4853f993, 0xf3e1ed57, 0x1073c23d, 0xc79f0e4f, 0x69cfd861, 0xdd322b53,
- 0x38f7cfc8, 0x7207a87c, 0x827df56f, 0x22fdd574, 0x0afbbcfa, 0x171801d8,
- 0x27b77b9a, 0xb724f907, 0xd4a3eede, 0xd01894c6, 0xb30ab96b, 0x31a29a61,
- 0x0c698ec5, 0xbd9a61b3, 0x354fd850, 0xe0fd9137, 0x786bf1ca, 0xd36e79bf,
- 0xfbe35ff3, 0xb7784af9, 0xdcabe064, 0xa3bfb7a6, 0x3f3e7673, 0x565efdc5,
- 0x9fd699a7, 0xf0cdeac3, 0x38668de5, 0x47866c33, 0x65c333ee, 0x67683638,
- 0xe11ef88c, 0x86569d9e, 0xde2b2bdf, 0xf438a56c, 0xa0ae7157, 0xe93b5e78,
- 0x4dc509c5, 0x712718d9, 0x05a745fc, 0xfe3b95fd, 0x59c532fa, 0x658a6e74,
- 0xfbb86718, 0x831618d3, 0xed9bbc71, 0x18bf30eb, 0xd9fe8768, 0xb5f6cde2,
- 0xedb34f18, 0x434f9d52, 0xedb50f14, 0x4bbcfc6f, 0x086b06e7, 0x6f8e2ee3,
- 0xe445fe7f, 0xfa1be3cb, 0xaaf61d93, 0x7d60b414, 0xdd3847c1, 0x3ebd08c7,
- 0xe2f5e846, 0xfc7af33a, 0xaf6e970a, 0xfce287ba, 0xe3812637, 0x2fb2b5bb,
- 0x2577c587, 0x8c6dfb74, 0x40dd67b0, 0x7687cfcf, 0xd08879d3, 0x7ba179cf,
- 0x6bd11f35, 0xb3ea0c41, 0x0cdaa38e, 0x5c5d4bf4, 0xcea3c663, 0xcc8497df,
- 0x24ba27cf, 0xcf0ce7a1, 0xc55e3033, 0xe71524b3, 0xdfa367ef, 0x8bbd7f53,
- 0xbc2f19db, 0x20f2e9a0, 0x992a7b8b, 0xb2ae70c7, 0x79b3ef5b, 0x089e31fd,
- 0xfbb035e9, 0xbb447179, 0x2eb1fd7a, 0xda5fcf2e, 0x448279f8, 0x95638781,
- 0xe86ec8fb, 0x7d2b23b2, 0x380689be, 0x727766af, 0x776fe12e, 0xf986bdf2,
- 0xdec364aa, 0x4e30bbe4, 0x8f414eae, 0xe3b92b36, 0x498f9fb9, 0x3d72e7c4,
- 0x11f313f6, 0x6ff56d8f, 0xd81cb0b8, 0x718c23d9, 0x5735f967, 0xe41a26fb,
- 0xb9f287fe, 0x3712b74e, 0x392bcbc7, 0x9cf093cd, 0xff0d7148, 0xfd71618e,
- 0x80dcb76d, 0xcfcd5ef8, 0xcc2b67d3, 0x963c832f, 0xfaedb96c, 0xfcbcf061,
- 0xec5e5199, 0x2b71540f, 0x78de2f3e, 0x3d15ce92, 0x8efee16a, 0x0504fa48,
- 0x13fa3d9f, 0x39ea0147, 0xcb75efa8, 0x9f7f7a08, 0x239bec05, 0xdcef83e3,
- 0xb38e4505, 0xa06f0ffa, 0x9f3330f8, 0x684bdf02, 0x97ae75bf, 0xe9e8ebbc,
- 0xd19becc2, 0xa02df754, 0x8fc87978, 0x0c297eba, 0xa489eb99, 0x6fc16aef,
- 0xe4621bf0, 0x7d72c893, 0xdce904a6, 0xd07cc974, 0x43ff0693, 0x8a6aa1c9,
- 0x076c8dcf, 0xc1985823, 0xe181da0e, 0x9b972875, 0xfc169c78, 0x88b65b24,
- 0x61c41f63, 0xf915c7ba, 0xf8a21811, 0x83d13652, 0x4d99bd78, 0x37d754c6,
- 0xc3f5396d, 0x52abfcb1, 0xa2bf73cb, 0xe7249cfa, 0xdd30ee6d, 0x9c4fdb6f,
- 0x70f36f47, 0x8feeff58, 0x64d45f9e, 0xe3aeb8a7, 0xbfd23427, 0x149e300b,
- 0xb768bfcb, 0x3d68c058, 0x78cfa5be, 0xab6e538c, 0x1fa5f7e7, 0x5e33efab,
- 0x1ebccb3b, 0xf9f44fa9, 0x39fe20f6, 0xbe7afd1a, 0x83ce1726, 0x771c788b,
- 0xcc8a9f4a, 0xd274288a, 0x2ad44bdf, 0xd3fd7132, 0xbbc38f79, 0xcc14f08e,
- 0x9fefc850, 0x5c9a7e4a, 0xe83a9fe1, 0x02edbff6, 0xaca139ba, 0xec25fe0f,
- 0xdfa1d793, 0xfbd90bf3, 0xf7507b80, 0xacacfd3e, 0xa3df9d00, 0xfb40f40f,
- 0x56161533, 0xe266df80, 0x609c353c, 0xae674f9a, 0x719e2896, 0x78f372d6,
- 0xe36ebef0, 0xaac05afc, 0x5622dea9, 0x6ac1694f, 0xce217e73, 0x273c2e47,
- 0x8a76e3c7, 0xfaf9cd6a, 0x8d92c0b9, 0xf0d1ac67, 0xc7d335f6, 0xc702fbe7,
- 0xa36cdd27, 0x2ab7ddfe, 0x6977ef8e, 0x6df387cc, 0xe9272ae7, 0xa01662ff,
- 0xe629dc7e, 0x7307f2fd, 0xed20b37d, 0x37d33f98, 0xcb9e0fab, 0x2d23f3e7,
- 0xf99e4919, 0x13c57ebd, 0xbf007859, 0xbce187cf, 0x8524dc5b, 0x036c2187,
- 0x9fc11d51, 0x3826bde3, 0x3679e37e, 0x6e38fc7d, 0x3ef673e3, 0x9e116fa7,
- 0xb8f9929b, 0x0225f98d, 0xad1b251f, 0x98d17f26, 0x79d0528d, 0x6aaf9e39,
- 0x1acaf7a1, 0xf54d58ce, 0xec1d798a, 0xba076601, 0x2b58298d, 0x755660e3,
- 0x25d0f1e9, 0x1ccbced1, 0x755c7810, 0x945f5e5b, 0xbed1c7db, 0x9d1027ed,
- 0xf84a7a43, 0x06d858a3, 0xec8cc5ed, 0x7b3f2982, 0xe2938721, 0x26a6bd1e,
- 0x4a2fbe8d, 0x653361fb, 0x0e789bff, 0xd03e32b3, 0x99da0e37, 0x2ba5f169,
- 0xc1bebf24, 0xcf9d6fe4, 0x88e4f0f1, 0xa22a4b8a, 0x3a75b7ac, 0x53d5213f,
- 0x3b70409c, 0x599da79f, 0x20c06a9d, 0xb8e32317, 0xd3db8cbe, 0x3a8fe742,
- 0xfe744ab7, 0x20e929f9, 0xea7e0f9d, 0xff430f5a, 0x09d02a40, 0x1253eff5,
- 0xfcf7845b, 0x34dc3565, 0x73a40de7, 0xe3178c56, 0xc61b4a0f, 0x1a0ea5c9,
- 0x62e3b73f, 0xbee2d62b, 0x218cca54, 0x61df9023, 0x866e33dc, 0x3ce3a3e7,
- 0x075f5ed4, 0xc2ea7ba7, 0xa1dcc660, 0xce7fbed8, 0xc38f281b, 0x7cbce862,
- 0x99cae00a, 0xb432e940, 0xe65952cf, 0x5333b46e, 0xa04678a7, 0x8b957f4f,
- 0x916493b7, 0xf684dc67, 0x270e08e3, 0xd6f92c3c, 0xa0ae1311, 0xfcac5276,
- 0x1cf87a93, 0xfa1b4ded, 0x7a061c27, 0xc4c8a84f, 0xf10653f6, 0xa70b5134,
- 0xbbfb3d61, 0x75a01ee8, 0x23373cc8, 0xbbef3d7d, 0x2eb82971, 0x0b06dfdc,
- 0xfb63d075, 0x97fdf4d3, 0xfbec83b0, 0xf2f0870b, 0x97994ec2, 0x24e7cfc9,
- 0x15f6eba6, 0xfaa1d72f, 0x5ea246e2, 0xf9db8f7d, 0xe47c395f, 0xeb42bf07,
- 0xa0803ce5, 0x58e9f953, 0x0bcc3216, 0x21bed3e5, 0xb4fcb3fb, 0xef1cf4cb,
- 0x95c63509, 0xa1ec1497, 0xb2943bef, 0x509f3a66, 0x838e6f5a, 0x7a2622bf,
- 0x979f3abb, 0x3059969f, 0xf99abb6a, 0x2c3ee9f9, 0xb95a27d8, 0xd3f3f364,
- 0xfc6e1992, 0xe8539456, 0x7169cb39, 0x0a71fae1, 0x67a847ce, 0x7aa09642,
- 0xda5d3779, 0x79a62ddd, 0xe1c3dda8, 0xa8bfb10e, 0xb7f5ebe7, 0x39c4d34f,
- 0x7bcf7e3d, 0x2028255b, 0x4dd3cfc0, 0x5ddfc927, 0xf09bb4d2, 0x3745f3a3,
- 0xd059629e, 0xaae4a780, 0x6405b0e6, 0xfdb8e9fc, 0x025e874b, 0xcba3d924,
- 0x7d4b3bf3, 0xbf1f2163, 0xef90616b, 0x792eacd8, 0xcab37527, 0xf0fd0b22,
- 0x6389d2ee, 0xdf2f308d, 0x35f37efd, 0xb2b78113, 0x6bf7f286, 0x6b7bdee3,
- 0x7506c621, 0x4ce83b9d, 0xb00d3bf7, 0x0076022d, 0xbb00cc3c, 0x2313f223,
- 0xe02353f2, 0xcdbe5e34, 0xbd974e19, 0xfb8e6d8c, 0xf4051ae0, 0xf0df5b5c,
- 0x6479bc74, 0xd747d579, 0x4b8ef7e0, 0x7bf7f8b3, 0xaf249acb, 0x65a3d064,
- 0xe4871e5e, 0x3368b6f0, 0x9a1e2287, 0x507d44df, 0x71b928d2, 0xdfa8e0fd,
- 0xdf182612, 0xabde18f3, 0x92d3ebe7, 0x5ef483fa, 0xb10ff5af, 0x3a3f3c90,
- 0x772a73e4, 0x362dfdae, 0xaf3dfcc5, 0x52bbf6de, 0x50b7812d, 0xc7f7eadf,
- 0xa8f96db7, 0x20aa7bfb, 0x7d7ded7f, 0x469f497b, 0xc72f5b9c, 0xe5ba38fe,
- 0xa3e3c745, 0x7dd14e43, 0xd6187fba, 0x079a01f4, 0x2e4ef3b1, 0xff75abc0,
- 0x14787a54, 0x27785fda, 0x4f1fce2f, 0x704ba148, 0x059a7a5e, 0xef76c12e,
- 0x3768bd29, 0x80ec6a7e, 0x5e0cf2da, 0xdc4df309, 0x01ffc249, 0xfc00cb67,
- 0xc7e9dd64, 0xa4e1c2ff, 0xe609ba16, 0xafefeab6, 0x1ecdefc1, 0xc032d018,
- 0x8ff7f002, 0xe0993a5f, 0x419e5a8b, 0x04eac2f8, 0x196b0f0e, 0x03fbc320,
- 0x23267d83, 0xa3bbd6fd, 0xa109fdcb, 0xc5fef46f, 0x891df60e, 0x84aafb43,
- 0x2c783bcf, 0x757a06da, 0x4db1d17a, 0xd31f01eb, 0xf49623ff, 0x5bb6fadd,
- 0x1e13f3ae, 0x6f8c7e82, 0xa6f8114c, 0xbbf49179, 0x5f44f642, 0xba130b9c,
- 0x6f4ce9e9, 0x71bcd0f6, 0xb416c569, 0x0fa6521f, 0x55e379a5, 0xee27ef97,
- 0xe9e9dd51, 0xc4fe9e24, 0x5bfae6ed, 0x46bc50b6, 0xb24e43ca, 0xdf171eab,
- 0x23b90067, 0xba0870fe, 0x3c7cdc58, 0x73190dff, 0x80001bd1, 0x00008000,
- 0x00088b1f, 0x00000000, 0x7dddff00, 0xc594780d, 0xbbbcf0b5, 0x26effeef,
- 0xb24d9bbb, 0xf379f909, 0x71100843, 0xa9189313, 0x18884dd6, 0x220bb531,
- 0x49716b62, 0xc93049f8, 0x2d16ad46, 0x544859bd, 0x46d10882, 0xe1b80a04,
- 0xfd2b6202, 0x1a8c4582, 0xf68882e8, 0x72dfbd2b, 0xbd3fadeb, 0x8a7e1bd7,
- 0xb4564288, 0xeb6dea5c, 0x2666739d, 0x5c9377d9, 0x9f7b7aa8, 0xbe8f8be7,
- 0xcef33bce, 0xfe73399c, 0xb3339ce6, 0x9086bb1a, 0x258e4264, 0x4ec730dc,
- 0xe631df9f, 0x224c9d15, 0xf433bba4, 0xc84b499c, 0xc421127b, 0x09f04845,
- 0x0e7b6853, 0xd1eddf21, 0xb4897504, 0x734de1de, 0x44b2d116, 0xc345bd7c,
- 0xd57fbde5, 0xd2b3e5de, 0xd32d3172, 0x9912abe7, 0xbd33f58b, 0xfe5a0e69,
- 0xa7aefe02, 0x9f561ee5, 0x58ad25ae, 0x7fbec39f, 0xe5dc84aa, 0x76d4cfa3,
- 0x7d296e3a, 0xb5b89dae, 0x916b8e9d, 0x0bca1789, 0x5d6c16e7, 0x736a614e,
- 0x897842cc, 0x51269bd7, 0xe6364ef8, 0x76d1566a, 0xc8afa7bf, 0x515c8435,
- 0x97b0cde0, 0xff40f9d1, 0x44d21c74, 0x3c369527, 0x37981cfe, 0x7ad7afad,
- 0xcf3a64b3, 0x39fe1ddb, 0xe35ebed0, 0xd0b4429d, 0x77c0b789, 0x8823b405,
- 0x3b76399f, 0x40f227b6, 0xffffbc19, 0xb8954f08, 0x4f115fee, 0x7534ef77,
- 0xf8242c9d, 0xb7fd05f7, 0x2aa1d7b9, 0xbad2fa07, 0xcb871a4e, 0xd0ffc377,
- 0x24ad4871, 0x2c3a1493, 0x8d6e22ab, 0xbfe836ff, 0x7a07e979, 0x513781a2,
- 0xf02ff43d, 0xeb0a4ebe, 0x82fce952, 0x76cf24fb, 0xb2cfdec2, 0xe8959211,
- 0x21e613bf, 0xc3f79ee0, 0xd17f34e6, 0x3f2c7cf0, 0x76e6a978, 0xe4b79c5a,
- 0xf4edaecc, 0x590f79fb, 0xdb865108, 0x9d711ed3, 0xb8cf7fdf, 0x9f495c9a,
- 0x86b0defa, 0x19fdebe2, 0xb69cb3c4, 0x1a435f7b, 0x73efff00, 0x743f95bc,
- 0x853211f7, 0xb5d95f90, 0xd0499df8, 0xbddbe483, 0x53b7e288, 0xd0234122,
- 0xd23d4cc3, 0xd28860c3, 0xfeb095c3, 0xfbe87d74, 0x872707ee, 0x067d7482,
- 0x619100c9, 0xbec4153e, 0xbfa9895d, 0x29eb00a3, 0xb44d049d, 0x0e68da3e,
- 0x5e80956d, 0x50a5a028, 0x5feb093f, 0x07fad895, 0x38e230ef, 0x1d1933dd,
- 0x433a3776, 0xb6001cc1, 0xc6de008b, 0x7694a3a2, 0x64487482, 0xb69994ef,
- 0xe36c7c61, 0x3a52c172, 0xb4dbe2f0, 0xe4dab23f, 0xb01f4f19, 0xbb943284,
- 0x4a3c7152, 0xbe91ab0f, 0xfd470664, 0xab42d38f, 0x394f5c70, 0x36a3cbac,
- 0x1f787cef, 0x014591fd, 0xc89937f8, 0x7d09634a, 0xe8c3a44a, 0xe1c0eba4,
- 0x134f5d21, 0x60bb83a0, 0x7f878a00, 0x536f386f, 0xd89ffbe8, 0x08038425,
- 0x484e58cd, 0x75f5611d, 0xa4c72ccb, 0x86d4f029, 0xddf4090d, 0x03bc1bca,
- 0xd972be82, 0xf3fb48d3, 0xeb22ba73, 0x83c036a3, 0x804bbe1f, 0x29b73ffe,
- 0xefd32856, 0xd3f2c0a7, 0xbf870bef, 0x7df039ff, 0xe0c7c019, 0x65166d27,
- 0x1f8c34bb, 0x80b9fcf1, 0x6f69ebaf, 0x9c6278ec, 0xd98f7ef8, 0xf007ffbd,
- 0x4e1ef145, 0xb45e0174, 0xf0f1aeb8, 0xc7d1f4ba, 0x5e7eb44d, 0x82b1d69b,
- 0xd4bfd3e2, 0xf015f386, 0xbd1a95de, 0xec8de48e, 0xa5a594ff, 0x2ff9865c,
- 0x964f7465, 0x62e22819, 0x2e1fa2f1, 0x485dd253, 0xd23587a2, 0xf0e5ef28,
- 0x517f8001, 0xf8f7cc77, 0x621abfdf, 0x21be09db, 0x3f07148a, 0x92452ba7,
- 0x12fcdd61, 0x3ebd375b, 0x56e40f3a, 0x9f02dc3c, 0x8de5c6ff, 0x7c788ba0,
- 0xbbe01bff, 0x5dbe246c, 0xe84c81fa, 0x80d4bfd7, 0x9fef8a78, 0xf77e1090,
- 0x4d0489b4, 0x4bd6ee94, 0xfaebd212, 0x90212d07, 0xe8a6839b, 0x6067c00e,
- 0xdeb88dff, 0x0acd1ae7, 0xea364da1, 0xf705bf19, 0x171f18db, 0xdc80140c,
- 0xece7473b, 0xee73eba5, 0xa09eda37, 0xa4208024, 0xadda37e5, 0x5ee7ff40,
- 0xb3f589be, 0x5a10a2dc, 0xe986000e, 0x7fe081b8, 0x578a11b6, 0xc7119669,
- 0x0a57b13f, 0x8fbea019, 0x5e4639e2, 0x36ffa39e, 0x8dcb0c94, 0x3800a841,
- 0x07082cfa, 0x8e23699d, 0x59335df7, 0xd16fc745, 0xad0d5e48, 0x2932596f,
- 0x31e0ced4, 0x16d5cac6, 0x4a90e90d, 0x45bff986, 0xdee0bc73, 0xa7275622,
- 0x60ac7970, 0x851243bb, 0x3ab8c9b3, 0x05fa05a2, 0x4bf5a03e, 0x78673ea0,
- 0x7f565a1d, 0x479817f4, 0x7d351ecb, 0x9eaf3d34, 0xba5892c7, 0x17a619ca,
- 0x17c3294b, 0xf1a126a9, 0x2f1b5e14, 0x21226a5b, 0xe963e02d, 0x2ae27234,
- 0xc0e0f4da, 0x5b23a074, 0xa3a92f69, 0xe269c0cf, 0xa7b8510d, 0x36bcf7f6,
- 0xd477b68e, 0xba613244, 0xcdbfa581, 0xf0d5793b, 0xaf380b3a, 0x4b427fe9,
- 0x7e1e38ac, 0xeef14147, 0x89bb62b6, 0x7d88aeb3, 0x92efc0ae, 0x0f2f4c35,
- 0x1fe02bc0, 0x75cde999, 0xfd526f5c, 0x617af28a, 0xafd404d7, 0xce40ffa0,
- 0xf4c0953d, 0x903dc831, 0xaa8e6d33, 0x9e741cab, 0x14d56766, 0xc71b1947,
- 0x27e98367, 0xa788fea1, 0x243d78eb, 0xb5e6a5da, 0xc75ab716, 0x0cf9476e,
- 0x90dd16f1, 0x2c88e4c8, 0xafd17961, 0x10ab3d75, 0xe6e9193e, 0x2839cdde,
- 0x97481b97, 0x89bce81e, 0xc740f484, 0x98248c8b, 0x1162e940, 0x9f48966d,
- 0x881bd78b, 0x8d7eb312, 0x89b97521, 0x49bb85cb, 0x7bbfbf04, 0x357d5c67,
- 0x7d68db09, 0x2d8491b3, 0xd755ecf0, 0x8e7d50b7, 0x85f7d67c, 0xe93df621,
- 0x8bbdf366, 0x3aa3bbaf, 0x79d3f5a4, 0xdd51306f, 0x5d0684ea, 0x97533eb8,
- 0x267ae0f5, 0x1e737896, 0x2bf2bd06, 0xa52b679d, 0xf5f03fdb, 0x6639f812,
- 0xbc00aaaf, 0x9c1ab59b, 0x0361f47f, 0xd524e7e2, 0x6bfeb0e3, 0x59aee41d,
- 0x8dae79f4, 0x8075f378, 0x2cd67b26, 0xaf3c48db, 0x00d4c57a, 0xd0e0d374,
- 0xd32ae8a8, 0xf972c3a1, 0xe5ff8e0a, 0x1cd6d096, 0xa014f744, 0xa15cf2a7,
- 0x9994c957, 0x474c7cb4, 0x6e5a3bed, 0x43f56399, 0x4f60037f, 0x0efdf2d0,
- 0x77eecf26, 0x453d71e8, 0xd057cc59, 0xfb071d0d, 0x9ec55f33, 0x43658e02,
- 0x74609fed, 0xbaf0f5c3, 0xea0f7346, 0xd5fa21e1, 0x22dfa410, 0xfaf01e9f,
- 0xf32b970a, 0xf8a16ec1, 0x1412857e, 0x2f608fc8, 0x3e295fb3, 0xe5a52de6,
- 0x79174e57, 0x67402956, 0xf2bcde4c, 0x4159331d, 0xccf37c87, 0x27fb1f4f,
- 0xb4fe7f5a, 0xfad0315e, 0x746b4005, 0x88915efd, 0xbe0bc617, 0xbe810868,
- 0x7b33d26c, 0x15ff69b4, 0xfbd19ecc, 0x71842c37, 0xc079d05e, 0x084a69de,
- 0xeb03b73d, 0xa2943cd3, 0x863aabc9, 0x16cbe0cf, 0xf439bdf6, 0xa0bb9fb3,
- 0xa413d53e, 0xff26a3ed, 0x74d75846, 0x7a889283, 0xc25ad7f9, 0x381709c6,
- 0x878f5e28, 0x9c7ddd98, 0x4e304956, 0xa1fb0dbf, 0x90b69a7c, 0x33a273f6,
- 0xe543e715, 0x2759da2f, 0x82b618d6, 0x34375dfc, 0x8fed84ae, 0xd3d37ceb,
- 0x8bf8f968, 0xb4e59ec5, 0x0fa7d06a, 0x073d29eb, 0xafbb32d6, 0x016ca35e,
- 0x16fd90fc, 0x8f58879c, 0xb5c59ac0, 0xb2581f50, 0x8f9016ec, 0xc839f163,
- 0x3723127b, 0x166891cf, 0x86c6d3f0, 0xe830dedc, 0x1e89fe95, 0x4dc4af54,
- 0x8dd29f17, 0xa93db59d, 0xee8df863, 0x5f3d21d3, 0x1740ff6e, 0x43d33972,
- 0xca804e30, 0x0ff82265, 0x594c72e5, 0xad995a3b, 0x5495e063, 0xeba9df6e,
- 0x47fc1253, 0x9e5a5d60, 0x97f78ffc, 0x145e302a, 0x4ae922e5, 0xa93cbe46,
- 0xba03cef3, 0xf5875475, 0xfd7a3175, 0x99d983a4, 0x076e06f5, 0x963eb092,
- 0x797d450f, 0xc5ee9a95, 0x7fa704f3, 0xf7c9845b, 0xce1af591, 0x401ab71f,
- 0x20654d8f, 0x23d06c93, 0xc15fe856, 0x0e9ea7fe, 0x3969ebeb, 0xbf58597b,
- 0x4f813f88, 0x46c3be28, 0x1b93ef3a, 0x29bf8c6c, 0x459fa01a, 0xe5f50415,
- 0x63b52d22, 0xd2bde04b, 0xe5d74037, 0xa40e8bd4, 0x8a67f22f, 0xf9ef8a15,
- 0x5033b784, 0xb1ca97bb, 0x30a43a97, 0xafe60bec, 0xe5356c37, 0xb57b5f00,
- 0xcdcf5836, 0xf9b1ca12, 0x1b05951d, 0x9ec97968, 0x13fd702b, 0x2e5d182a,
- 0x2f503909, 0xb1f2e54e, 0xa3d210de, 0x8933fe1d, 0xf6883ec0, 0x1374f68f,
- 0x64ad28fd, 0xae401e24, 0x1421e8ab, 0xd1f6a653, 0x57265ed4, 0x24e79509,
- 0xf2126ec6, 0x8938e41e, 0xf4d503b3, 0x88fa1411, 0xa4a23dc9, 0x7213dc82,
- 0x97dd98f9, 0x3e3b44e8, 0x97d6153f, 0x9b9327ae, 0x6bc425bb, 0x7d456933,
- 0xd0c0f422, 0x9c8f5cb8, 0xbe9906d2, 0xcf813c32, 0xae0e677c, 0x8bd212eb,
- 0x95e844fa, 0xdf20e8b1, 0x88fbe1a9, 0xbc60e9d1, 0x9afec153, 0x75f0934e,
- 0x65a6bc74, 0x853cdc24, 0x50536d3d, 0x693d323f, 0x9e127a64, 0x97d0cbe6,
- 0x5e31faf1, 0xc1ebc61f, 0x77d33d54, 0x3d859d62, 0xd98d3a93, 0x85975301,
- 0xfc08a4b4, 0x94eade35, 0x26bb61e4, 0xa8d18ef0, 0x1f65095c, 0x9ef905c9,
- 0x2a62f950, 0xc4c80fad, 0xa1657c0b, 0xefa1e978, 0xb7fb7337, 0xd7cd9527,
- 0xabf467ad, 0xd8a47d93, 0xc112eb0a, 0x99346f7d, 0x051e81d8, 0xe8db373e,
- 0x1df02577, 0xefa1b7e3, 0x1cc3a48d, 0x2bd57df3, 0x173fd426, 0x0c85b65e,
- 0xb3f88f68, 0x94bfb41d, 0x4ed01bdf, 0x0d8af73d, 0xae39e9f5, 0xefc25d0f,
- 0x7e611e40, 0x41aebe16, 0x008e3552, 0xc6334bed, 0xf6140881, 0xd983b359,
- 0x21ed2359, 0x99139f5e, 0x80cae8c3, 0x8e0bcdfb, 0x4ca00781, 0x7fa021e1,
- 0x7e32716e, 0x5699ec0f, 0x3efa43fc, 0x187ab3e0, 0x40c5fdf6, 0xf7ed06af,
- 0x7d2918e7, 0x8b2ed74d, 0xd1e7483e, 0x83b5699c, 0xfeceab7e, 0x41dddfd7,
- 0xd1ee1fcb, 0xf3ac0311, 0x497369f6, 0xb7f2d8ee, 0x3e3ba431, 0x772fc310,
- 0x9b9754ef, 0x40e5d57b, 0xbf7cba9f, 0x653ae6d3, 0xf9e1d941, 0xc1b5d282,
- 0x87ba7ad0, 0xd5786bc2, 0x8668fa80, 0x1390ffd3, 0x7a26ade4, 0xc86cf018,
- 0xf80a78fe, 0x9ffd023b, 0x5034f048, 0x31148a36, 0x5f5f03fc, 0xb6cfcd30,
- 0x61b7828f, 0x06a311fc, 0x75ad4cf1, 0x173944f6, 0xd2e27ce0, 0x403c3f7b,
- 0x9668bfe7, 0xdf02bed9, 0xcacb6b78, 0x18449ec1, 0x4dfd6049, 0x8bbec21f,
- 0xf5846bb6, 0xb693353f, 0xac3570a3, 0x89b0fa67, 0x6f801244, 0x69dda85b,
- 0x1bfc4ba4, 0x77776fce, 0xf4c3cb44, 0x359dbb7f, 0xf94e0113, 0xe80fb22f,
- 0x37e851e3, 0xeade4ec6, 0x4bfc7264, 0x463299fb, 0x02b699f8, 0x038d9afe,
- 0xfe3a4afa, 0x0cf97ff5, 0xa5e2fde5, 0x823ee1af, 0xb33e63ce, 0xc80a4dab,
- 0x1e0fc5a7, 0xdf62f7c0, 0x8ad32a76, 0x36d7b6fb, 0xa1d95818, 0xcda9f2c7,
- 0xb8b95f6c, 0x3cc10a57, 0x931759a5, 0x6c2f412a, 0x640dd9d6, 0xf1e35e24,
- 0xb7a6c1f8, 0xf5efc013, 0xf61d2201, 0xc7b3127b, 0xb809adec, 0x135a507f,
- 0xac0cbec0, 0x9043f1bf, 0x6b378b8f, 0x902f603d, 0xcff4367d, 0xc37cde2c,
- 0xe85685c4, 0x4aa4d3e7, 0xb96d13f0, 0xd0543c01, 0x7e6217ce, 0xf4f5c89e,
- 0x6ae5bcbd, 0xd0f1f805, 0x62ff0666, 0xd0077187, 0xd17ff5d1, 0x1ac97f22,
- 0xb93b07e2, 0x089def5b, 0xda6cad7c, 0xe7d61d3e, 0x1ae99983, 0x224bbf6c,
- 0x638bc076, 0x5fbc0a69, 0xe03ec92c, 0x8df586e3, 0x4f76b1b5, 0xc7f9939d,
- 0xa597b32a, 0xaf91580c, 0x6d3e80e6, 0x08f94cde, 0xdef59fc6, 0x0d70eeef,
- 0x6b3495f3, 0xa1532dfd, 0x1e7567ff, 0x7b21bbe0, 0x90b7d366, 0x4c2fe0be,
- 0xe398b5f1, 0x99f2abeb, 0xa4f822c1, 0xeae400b5, 0x05ad15e2, 0x8cec51f6,
- 0x44d93e21, 0x213272f9, 0xf9129da7, 0x1993fc02, 0x63bed54e, 0xb59a7dac,
- 0xc67a8350, 0xedde21e8, 0xb74a99f4, 0xb71fb0c9, 0x6f58c925, 0x7d23d24b,
- 0x77ba7fcb, 0xbce86fe7, 0x2ffa749e, 0x26ccbe80, 0x6bd062de, 0x455ed44a,
- 0x35405acd, 0x136461da, 0xcc89afb3, 0x92eb85fc, 0x31558ec9, 0x125373fb,
- 0x39504fdb, 0x73f405f1, 0x1f3fddee, 0x64b6fc06, 0xec053c7d, 0xcfc5c085,
- 0xb35fe0f4, 0xdf284bf6, 0x011f1ead, 0xcff409ba, 0x868a0b24, 0xc3c072e5,
- 0xbcfc46f4, 0x98e924e6, 0xb145751c, 0x82974a9f, 0x41076ee5, 0xd4b8da7a,
- 0x46fef68c, 0x4004c857, 0x2b7cadff, 0xee46a7ec, 0xfb6e340f, 0x740b5785,
- 0xe3ec921e, 0xfe30aca1, 0x17986c18, 0x3e71d2d2, 0xc41796dc, 0x8f4a9ef2,
- 0xb759d696, 0x5ccae3fd, 0xce9f53c0, 0x9eaded03, 0xdf980481, 0x244edb87,
- 0xb61afcc0, 0x0dde7169, 0x16524fa1, 0x09cb0d16, 0x905fc69d, 0x5d827604,
- 0x42f8c2b2, 0xedb87c5e, 0x560594d3, 0x7d403fe6, 0x5e3a3a5a, 0xc9cacecc,
- 0xdff5fdf0, 0x6672eb64, 0x72042197, 0xf9898cf0, 0x33bb45f7, 0xaeffa636,
- 0xcdfe124b, 0x3fd02cde, 0xa2796543, 0xf7c4e406, 0x2efe6ced, 0xf0166f7d,
- 0xba9247e5, 0xb52b259f, 0x52e54424, 0x84894ae3, 0xf33fcca8, 0x20594bdc,
- 0xfedc3fff, 0x0c5d5652, 0x89dff17c, 0x6a498de7, 0xaff09a7f, 0x0ce1f4ba,
- 0x63ceaf18, 0x31cc7e60, 0x3da2abfc, 0xa4fccf59, 0x816b9483, 0x8377c50e,
- 0xd82f660d, 0x18c483bb, 0x5d5b9702, 0x7ad7f73f, 0xd82ef9bd, 0xe3ef88d7,
- 0xf40d5ffa, 0xfa92e144, 0x5827f424, 0x9f28a28a, 0x77fcb4bf, 0x918cf5d1,
- 0x8d9d74ff, 0xc6cd4eb0, 0x0471e1e8, 0x780f43e9, 0x6558b7d3, 0xed2957d0,
- 0xf7a2be8c, 0xe59f706b, 0x814c2732, 0xdd3e80b8, 0x76f9056d, 0x43b9817d,
- 0xb3ef0893, 0x333ed042, 0x0bbf10bd, 0x0ffa3156, 0xc3f410a6, 0x095691a5,
- 0xe676b4fd, 0x20a8cfe7, 0xf8b455f6, 0xe76624b3, 0xbd6789b8, 0x5fd70f36,
- 0xc70738c2, 0x400fd08b, 0xcf2f2047, 0x23a44648, 0x7b425fa9, 0x9de9ab54,
- 0x458efd07, 0xbac52b57, 0x2a1aba72, 0xeae89dff, 0x23c74149, 0x20afcae8,
- 0xa38db95d, 0x23f715d3, 0x127b765f, 0x36bec1f4, 0x2d6be395, 0xfbd13f97,
- 0x2eafc28d, 0x796b7cc1, 0x6b46b57f, 0xc47a0b58, 0xd638fba3, 0xda89bc3f,
- 0x4a7fb0c5, 0x3e9ebb03, 0x57cfb5c7, 0x6448dd70, 0x9608fc00, 0x2fa88dab,
- 0x7244d31f, 0x9d498ec0, 0xe81bbad4, 0x515e7523, 0x0bee3b49, 0x17a01c33,
- 0x7fa2d740, 0x1f34e974, 0x1c5823b3, 0x8f533a28, 0x07969cfb, 0x8ecc7d2b,
- 0x097e41a8, 0xa02936ac, 0xe7f5a707, 0x08fa072c, 0x031e232c, 0x86cf71d2,
- 0x9dcfe045, 0xac80f56d, 0xb225f113, 0x9d77cd52, 0x05538b12, 0x0f18226f,
- 0x0d338e1b, 0xe821f96c, 0xf422c6ff, 0x8ff90c9b, 0x8dea09f3, 0xd6438dcb,
- 0xde2136ad, 0xd068fc45, 0x25741146, 0x3fb191fa, 0x7a646892, 0x407ca468,
- 0x054a73ff, 0xa1eb7f11, 0x3cca2e9c, 0x5ff823de, 0x456ca3c4, 0xc8b01cbe,
- 0xbf399c2b, 0x049c4332, 0xb36c77fc, 0x00fd8416, 0x19598dfa, 0x694fcadd,
- 0x50e92028, 0xaaab9ffb, 0xbcca6233, 0xc1f7d0fd, 0x5f573755, 0xa877fa8b,
- 0x7aa6c01e, 0x26bd9459, 0xc355e205, 0x83b532f5, 0xff127d8d, 0x1be6e2be,
- 0x941eaaa8, 0xee7ff8c4, 0xd11f82f4, 0xc5e35444, 0xf5c727c2, 0x5bfda3af,
- 0x383ede15, 0xefe826ee, 0x7e5112a9, 0xe14bd3a0, 0xf753ab5b, 0xdfe52887,
- 0xf78c4143, 0xaf0e537f, 0x6c319d5a, 0xe17b501f, 0xc36549cf, 0xefa3c276,
- 0x495d76d5, 0x3fd8b2c7, 0x15fe83d5, 0x92e03efa, 0xe7890ed0, 0xf49704d7,
- 0x656becd5, 0xe09d7d84, 0x74f5f662, 0x2fba4960, 0x581df941, 0xdf6023e6,
- 0xe9c4bb52, 0xe3e4bb42, 0xfd680753, 0x1f9f59b9, 0xbb40a71e, 0xbec1e67b,
- 0x4651702a, 0xa9d81bf9, 0x6f94490d, 0xaeccfd8c, 0xe31cfaa6, 0x967e8205,
- 0x38fd39d8, 0x97fc0482, 0x32a4fbdd, 0x5a4277a0, 0x6ba36eb3, 0x379703f9,
- 0xfbe1c713, 0x9779f8cd, 0x205f98bb, 0xa1b55850, 0x26dffa00, 0x5617b011,
- 0x594f1e15, 0x63a9fb80, 0xbe630b29, 0x0a7bec6b, 0x53b8d9f1, 0xcb1e2a37,
- 0x7804e1a9, 0x45f9796c, 0x338dc82f, 0x42650921, 0x04ea1c83, 0x41a1b6bb,
- 0x29211603, 0x03bfcd0d, 0xf5731fe3, 0x5f9d3c64, 0x8177d706, 0xa706b79d,
- 0xbfe9bcc2, 0xd1b57d12, 0xc4e508b7, 0x2b46b9c6, 0xeb0a91c6, 0xd83c41ee,
- 0xc3c05ecd, 0x34aac2aa, 0xe665a718, 0x4dc63b74, 0xf5073da8, 0x077e0f2d,
- 0xae0245fd, 0x1aba7d55, 0xa9ca77b0, 0x0a0bf75d, 0x4673a677, 0xf5f2878d,
- 0xe2eeed38, 0x5710acfb, 0xff8e5d1f, 0x174664bf, 0xf82f921d, 0x8ff452ed,
- 0x677f5892, 0x1fb31f76, 0x55e9716f, 0x5c5bf1fe, 0x36bdaecc, 0xe4069918,
- 0xb01e5fb2, 0x201d5d80, 0x5f604fde, 0x65567c4d, 0x9313ae3b, 0x0536ae5f,
- 0xd74666fd, 0x425763c0, 0xee32b5fd, 0xf03c8867, 0x5cf71863, 0x8ab3cba7,
- 0xf2803e70, 0x90214583, 0xfe5cfbc7, 0x96fac2ef, 0xdcf57b73, 0x831637cb,
- 0x5fd8517f, 0x5099cf9d, 0x94da766f, 0x4e406b27, 0x796649fe, 0x6468c603,
- 0xc967ed1a, 0xb71c4ee7, 0x84ea14d3, 0x68f60ff5, 0xeac9beb1, 0xdbf4045f,
- 0x29faeb78, 0x0d608798, 0xd51e8015, 0xd008bab9, 0xa0bedd31, 0xf2e8c51f,
- 0x4f238811, 0x2597ce0b, 0x767117d0, 0x63f034cd, 0x85c5bee1, 0xce2adc7e,
- 0x1529e31f, 0x2b22329c, 0x34917c74, 0xf9bce76c, 0xbc32d9e7, 0xc68ff614,
- 0xd5eefcc8, 0xec04cd73, 0xf448f25c, 0xf8fc06b0, 0x7b0108ae, 0xc257b9b8,
- 0x5f0b9a71, 0xe5fec3d0, 0xdfc65eee, 0xa0dfbe01, 0x78c2cbf8, 0xedc2cb94,
- 0x67460e81, 0x1c787224, 0xb679f9e0, 0x76d0849e, 0x42577e31, 0xc0793396,
- 0xf8f3d3fb, 0x37f73343, 0xf5884d51, 0xcec25cab, 0x5b8ea158, 0x49d771f0,
- 0xf016af11, 0xfca92c5a, 0xc3d9e2e4, 0x183c4fbf, 0x1bfc0e9d, 0x7e05f4a5,
- 0xccd20da7, 0xf3a75e7b, 0xc93650db, 0x9b98a603, 0x04b69392, 0xa45253de,
- 0xfbed2f78, 0x0dd03a64, 0xafc821a9, 0xda957d2d, 0xeb8b2b66, 0xa58c5e60,
- 0x53ea07b5, 0xfd442aef, 0x5993710c, 0x1cb3fdf4, 0xe65669af, 0x08af73c7,
- 0x341c40e6, 0x9eefa0f1, 0x2bfc61d7, 0x4d87e8cc, 0x73636ba5, 0xf82573e2,
- 0xf8a4dcbd, 0x7767e800, 0xf00252ad, 0xc41f7888, 0x0d16670b, 0x3d38e3e7,
- 0x7d2b7792, 0x983976ee, 0x6a40cedf, 0x1f785e00, 0x1fc70eb2, 0xe3079fc1,
- 0x9e0f7c42, 0x32c2d2e7, 0xc0c9fffa, 0xefb8ed96, 0x483e6037, 0xef1bdf6d,
- 0x35adfe80, 0xc78c5e92, 0xd52dd9c6, 0x02beb789, 0xf6783ff4, 0x018796d4,
- 0x7af6dbae, 0xce25ef30, 0x9bfeb91e, 0xb33f3ecc, 0x3f00a2dd, 0x9b72e56c,
- 0x27c88fda, 0x3f6c5dc1, 0x1e476f19, 0x27f7a975, 0xddafe543, 0x05f0648e,
- 0x0b3cb3b7, 0x7c03df21, 0x70d837ff, 0xd7f4013e, 0x13c10dbf, 0x8db20f97,
- 0x8ff483e7, 0xe6f20f9e, 0xe8104b0e, 0x09af7ce1, 0x8f3292fd, 0x45b59d7b,
- 0x7524001f, 0x01cf0e38, 0x72581b79, 0xca1ae7e6, 0x8b0f727f, 0x8f12c923,
- 0x4b4afd33, 0x6bcc5c58, 0x808bff07, 0x774c765b, 0x3e408b7b, 0x713779b2,
- 0xb39351bf, 0x2ef16140, 0x94d43796, 0x7b002e10, 0x87ae55ea, 0x5e2ccc9a,
- 0x87d0e835, 0x26a35d61, 0x185d1fff, 0x93df62d7, 0xd8941a5f, 0x884f56b8,
- 0x0a2775d9, 0x9d3d6135, 0x07d80f67, 0x59ab6eb0, 0x9f286b7c, 0xc7a1bf60,
- 0x5890e2c0, 0x41ccec1e, 0xe22f5939, 0x3f99fb56, 0xa7c79eae, 0xf45acc4e,
- 0x745ca40c, 0xb035ad48, 0xaab0bb3f, 0x0fe8fd12, 0x9f13393c, 0x7ed52bf5,
- 0xa7e045ff, 0x238e1bcf, 0x1d7bff0b, 0xbd99e8f1, 0xd447ec3c, 0x5945fb50,
- 0xbe815729, 0x15f621cc, 0x2095ff20, 0xe9abad5d, 0xc13e83b3, 0x12349768,
- 0xa77239d8, 0xfbeb0ccb, 0xf5068768, 0xe343b054, 0xcf027685, 0x8fccc939,
- 0xf3324d74, 0x0aa5d06b, 0xd9e238c1, 0x0771e3a1, 0xa272dfde, 0x2353c309,
- 0x76a3e7b1, 0x7d3466b9, 0xd0ebfa2d, 0x4fc11ab5, 0xa0d4cd17, 0xde82fbdf,
- 0xc6fd173b, 0x790202ce, 0xd6b61d54, 0x1eac3595, 0x2982e779, 0xebfac3ea,
- 0x12486664, 0x33f209c5, 0xcbe79935, 0x616de1c5, 0x1f1cba97, 0xa90c698f,
- 0x3fc4f5cb, 0xc58f2d21, 0xa7df620f, 0x75f93326, 0xc70e5561, 0xe3f307b7,
- 0x6797fcc4, 0x3269bc30, 0xb33733d9, 0x41d02e6a, 0x7397c42e, 0xabfcc9e0,
- 0x7f082674, 0x092e75ee, 0xde0e23e9, 0x80da300e, 0x3c593abe, 0x3f856ff4,
- 0xe4caee1e, 0xbc1fae14, 0xd65f886e, 0x8f18f5db, 0x493f5cbe, 0x0e5ab25d,
- 0xfebf950d, 0x27db2cfd, 0x9e796a75, 0x50e51d8d, 0xe5cd9d9d, 0x11d9e484,
- 0x6a56f786, 0x3a3cc02f, 0x3f6025b5, 0x8ad5bb4c, 0x6fd968f3, 0xf3703f42,
- 0xd02c81b2, 0x03552de3, 0x89b71005, 0x2b402fc7, 0xdb45f90b, 0xfee8b9d5,
- 0xd884ec03, 0x4b5f3c76, 0xfef5671d, 0xf60cb920, 0xbf762739, 0xb76afa01,
- 0xfd15f509, 0xf00603bf, 0x839cbcb3, 0x3687ccf6, 0x0bb41b7f, 0x9e5bc398,
- 0x85bb01cd, 0xfdcd4dd9, 0x0bb01e86, 0xe2623aeb, 0xd59ff07c, 0x591fb8ea,
- 0x3bff44e9, 0x6fbf56e9, 0xddf714d8, 0x17603888, 0xbd3af3ae, 0x3bf0227f,
- 0x7f983bd5, 0x8351b670, 0x5af50379, 0xb79022cf, 0x7b6a4d67, 0xad8dacfc,
- 0x75a196d7, 0xb5bda0f6, 0xf675cc65, 0xd73ac014, 0xb63f886b, 0x6758669f,
- 0x7c4dbeba, 0x78becf9d, 0xf3ac0175, 0x2eafbbc7, 0xa75e7580, 0xdf02f2eb,
- 0x5bfc39b4, 0x27bf6993, 0x3da1f06f, 0x2f58f225, 0x24f71e97, 0x432bfdab,
- 0xff21ffe5, 0x30fa58ca, 0x5a87043c, 0x4af4ba1f, 0x3a83c806, 0xd5bfe1a3,
- 0xaa37f08b, 0x4068cf1f, 0x3ffec77f, 0x0766ba7f, 0x2d7e81c8, 0xbfa223da,
- 0x0f3fb2fd, 0xeffda1ec, 0x69413db8, 0xb91bfeec, 0x246dd85f, 0x88abf041,
- 0x27b0807d, 0x5bf1e5e3, 0x251f3e7c, 0xbb006f7b, 0x8dfacbe6, 0x633bf81b,
- 0xe76653e8, 0xcc3c936e, 0x7e8bdc6f, 0xf37d96e4, 0x3e27e0ed, 0xe37e621d,
- 0xd18b1796, 0x7a18dc6f, 0x65790c2d, 0xc3b25fa4, 0xdb71a3fe, 0x07c804b1,
- 0xba5cfb10, 0x8c933daf, 0xefdea8f4, 0x489d0e9e, 0x0a01fc80, 0x71e82577,
- 0x07aa2b8b, 0xfba16fba, 0x6c23c83d, 0xa187a391, 0xc11716df, 0x3ed2973c,
- 0xc44ffef5, 0xf4fa3779, 0xf6377728, 0xd790214b, 0x4e7f7a29, 0x9235e806,
- 0x2078c761, 0xc98bb3e7, 0xb294d4de, 0xf7baf8d8, 0xe1e4e4f3, 0x0d81b07c,
- 0x03bf4889, 0x83b5e23a, 0xe360db3c, 0xf9464cf2, 0x8e4dc7f6, 0x630fcb10,
- 0x6218ffed, 0xc8a34276, 0x5849930b, 0x68b5eba6, 0x585df7b6, 0xe1f7906f,
- 0x5b1f7938, 0xbbfb7116, 0x52f51849, 0xca181933, 0x176d8b0f, 0x7887d71f,
- 0xd21faab8, 0x1f80ac5a, 0x07ab4eec, 0xb8f881e0, 0xf6c83eba, 0x961f94eb,
- 0xafd30c96, 0xbf410758, 0x1d0fdc2d, 0x08fe3868, 0x4fa06fd0, 0xd77d83b2,
- 0xdbf461e4, 0x905bf744, 0xefcf1b47, 0x379d57a4, 0x97ff163a, 0xd1f5a8a6,
- 0xe4eff950, 0x453ebd5f, 0xfe62f7cd, 0x343f6fc2, 0xf1897ecf, 0xe2bcdc65,
- 0xfef1a9f7, 0xbccfb176, 0x2738795c, 0x870f2d45, 0x79677fca, 0x2eb43758,
- 0x1d50f2f1, 0xe59bf8cf, 0x5c70ffe1, 0x4f7d99e3, 0x03bec027, 0xa7d878ec,
- 0x63aedcac, 0xfd1413f9, 0xe9e2f1b1, 0xc597ab5a, 0x5ea2b54f, 0xa657871d,
- 0xe33c38f3, 0xd45ed7eb, 0xf335bae2, 0x3ef37138, 0x369a079b, 0x9c631758,
- 0xba7e3e36, 0x0e9eec84, 0x471f154b, 0xce7e026d, 0x753c74bb, 0x8f8b0a75,
- 0x20725852, 0x6f3e216f, 0xa7eb35eb, 0x7598fe49, 0x1ba22aaf, 0xdbe85182,
- 0x33890728, 0x14c6fde6, 0xc6bf5766, 0x7adc8bf3, 0xad608e76, 0xfd85e2cd,
- 0xf2c35b8c, 0xf2e07e9f, 0x18bc826d, 0xfaf1c2a3, 0x4344edf2, 0xae8cf2f1,
- 0xb04ae517, 0x3901ead9, 0xa237fc28, 0x5e3c8bff, 0x3ffad971, 0xfcf7de8e,
- 0x3c7bd30f, 0xf18bf67e, 0xddb8d6fe, 0x151b8a7a, 0xe3a4105f, 0xca5f1023,
- 0x63bf4919, 0x1d1633f5, 0x1df14d1f, 0xfe766149, 0xb857cc14, 0x2963394c,
- 0x3f009e8d, 0x5063d911, 0x7e09afc0, 0xab8fd412, 0xaa3e78d3, 0xe6267ca7,
- 0x2573b369, 0x58ce1ce2, 0x4307e476, 0xc8ecc3eb, 0x9f5cc60f, 0xde47672f,
- 0x087df0ee, 0xd2b27674, 0x1e01e78b, 0x61f851b5, 0x619cf87f, 0xe22e73d4,
- 0xfca5c63c, 0xd1c45f2d, 0x4bff17d5, 0x3a92d472, 0x75f95d96, 0x13cfd1cb,
- 0x763a7fc0, 0xff9e413f, 0x45bc4119, 0x6b6449f7, 0x103b5f8c, 0x197bf961,
- 0xfef15e1c, 0xa1bef83f, 0x999bd521, 0xfc7fdf4a, 0x1248d1ae, 0x652e9ea9,
- 0x67c5b172, 0x4b42b8c5, 0x697fcb2f, 0x8e504659, 0xb4df80b7, 0x3389fc08,
- 0x4f7dd809, 0x2013fd3a, 0xf7d1ee8f, 0x226d41ac, 0x1167dbf8, 0xbdcef3b0,
- 0x9c33cacb, 0x6798c9fe, 0xe3006cb7, 0xceb3dd18, 0xf9561e60, 0x523e9f17,
- 0xa2f08a53, 0x5065c13f, 0x3db9679f, 0xf133c995, 0x6f843d9c, 0x3ff3fa2f,
- 0xdaf9606e, 0x0ed79701, 0x0fe1097e, 0x8c1128b7, 0x61ecb42b, 0x96b95bc6,
- 0x30fc87cd, 0x65a9e903, 0xf831654f, 0xa9af494d, 0xf2ddec18, 0xdf715bdf,
- 0xe983f1f7, 0xcfb12798, 0x7c02afe5, 0x37434ad8, 0x4d9a7d81, 0xf7bb01c7,
- 0x1537dde3, 0xfe42dc03, 0x39bf03ad, 0x4d9d7f1d, 0x462717ed, 0x64bf7796,
- 0x33ee2647, 0x5afeac9b, 0x133aff98, 0x9db82383, 0xfee14f9f, 0x17fe78f2,
- 0xd5aa9f7c, 0xdfa938e0, 0x5c9c6235, 0x3a7585c8, 0x0de637e2, 0x9e1293cb,
- 0xf1701867, 0x99fec73c, 0x97854f2c, 0xbe752ead, 0x37c947e7, 0x253c0094,
- 0x8b57f2a9, 0xe4475967, 0xb2a4940b, 0x5cea9678, 0xb322e5a2, 0x7aed73a7,
- 0x4adb27a4, 0x9454e2c2, 0xbfaec09e, 0x06991a36, 0xbbf2bce7, 0x9e02d7c3,
- 0x20d45ff7, 0x4799e49e, 0x28933e30, 0x56f2f1b1, 0x004e740f, 0xadfd8c7f,
- 0x954960eb, 0xa0157b2e, 0xefa749f4, 0xffe45481, 0xaf1842d6, 0x2c745fea,
- 0x059f72bf, 0x59dd0cfd, 0x795f984d, 0xea833dee, 0x33fc4e7c, 0x3e605648,
- 0x6fdf6e65, 0xdb604e31, 0x279a8d23, 0x15aa44fb, 0x1825a6f9, 0x36398e99,
- 0xce50bad7, 0x1f7efbca, 0xee43bb04, 0x91024194, 0x03579d0e, 0xcb82d3e7,
- 0xc7f5fa09, 0xb035db77, 0x3f3cd95e, 0x7fff7066, 0xbee3f14e, 0x4205c445,
- 0x3749bf2c, 0xc7ec08f0, 0xdf03e5e4, 0xec7ac20c, 0xc05a6871, 0xb68baa7f,
- 0x9f65dfa0, 0xd9acfd05, 0xbe2b797d, 0x2bd9cb41, 0x1b0718ed, 0x6ceee57c,
- 0xf3a7e7cc, 0x3cca3f1c, 0xf9654a1f, 0x8b3ef248, 0xfc99f406, 0xa8c0f104,
- 0x0aa523b2, 0x968a7ee1, 0x07df3f69, 0x8e1e4a7a, 0x0a3f829b, 0xaa4354f4,
- 0xcdd0077f, 0xa5a4b9d0, 0x892e7666, 0x2db5a79f, 0x9c176f7d, 0xfdc2d9f7,
- 0x4ff707b9, 0xbffe859e, 0x7582594e, 0xf960e0b8, 0xb2a42f95, 0xfc48e278,
- 0xd63cc41f, 0x65bf7ddc, 0x02e28d7a, 0x8c7597fa, 0x574ee45e, 0x5f19f80f,
- 0xde63f049, 0x611d75ee, 0xeccdc62d, 0xa35c7f27, 0xd677ecc4, 0xb2d33d33,
- 0xe3cfed93, 0xd29737f7, 0x921ebf2f, 0x0cbf4c33, 0x764eff95, 0xf4e2efcb,
- 0x6fbcdfca, 0x5efdea21, 0xbf12fdbc, 0x8f611bbf, 0x9637f5c7, 0x50f2231d,
- 0x61c786aa, 0xd84db4f6, 0x9e554149, 0x9f95954e, 0xfbaa343b, 0x47649f5f,
- 0x3b79107a, 0x72caed29, 0xfe8fdbc8, 0x4edfa088, 0x3c8915e4, 0xcb1560a2,
- 0x8c6a09f7, 0x4dd12e78, 0x687f30ba, 0x124b091c, 0xf006d7fa, 0xe42a6dfc,
- 0x4fefd111, 0xff62e6a4, 0xa567899b, 0x22a6e516, 0xc826fc01, 0xb802493f,
- 0xc1161b43, 0x7159b778, 0x9fe4133c, 0x033ee124, 0xc7dd39f9, 0x35a756f2,
- 0x3a43b8b0, 0x4e50cfd5, 0x697467cf, 0x3cc7ab9a, 0x22579156, 0x5e044ff2,
- 0xd3be38aa, 0x01ca2c27, 0x54f228b9, 0xe53d99d6, 0x39c11760, 0x1cbf3868,
- 0xbcf3346c, 0x776fd613, 0x4f9e2e63, 0x2979b2fe, 0xf91678f1, 0x7f44fa29,
- 0xe46cbba6, 0x37416739, 0x7089eb31, 0xecc7dc6d, 0x3d06aafc, 0x71b063ce,
- 0x072bfa06, 0xec04351b, 0x037eaa81, 0xf1b8c3a3, 0x93d5ce36, 0x872bf430,
- 0x054f204c, 0xceca5c3d, 0x085beba5, 0x6d83e0fe, 0x524ef33b, 0xd6d43fde,
- 0x9341cf8b, 0x12bdabd4, 0x03cea1cf, 0xb48df5c9, 0x1af95afc, 0x6689b7c8,
- 0x6a849449, 0x96faafd3, 0x60c4f54c, 0x287df472, 0x7be1bedf, 0xba3e3cac,
- 0x9beda245, 0xed623ed3, 0xa9d33681, 0xefff5ed8, 0x57eb41b5, 0x267f7fd0,
- 0x351cf9f1, 0xebf464ee, 0x3f41123c, 0xa57fd712, 0xadba3e4c, 0xdc9fb47a,
- 0x54951f3c, 0x8854fcf3, 0x7b72d0f8, 0xefc6315a, 0x13d944ad, 0x030cfa81,
- 0xe30827b3, 0xccf1f687, 0xf4e46d6f, 0xbf843240, 0xf208206a, 0x81c73dae,
- 0xe7c90fdf, 0xf310863d, 0x8ff1b19b, 0x9e0578be, 0xb679124b, 0x6733d884,
- 0x36f9815f, 0x135af2aa, 0xdb29a73f, 0x7bbce133, 0xc1db8ebb, 0xe6c47cbc,
- 0x04f3885f, 0xddf6a4be, 0x507e1bd1, 0x7674fc04, 0x41f30fef, 0xa7a8ddce,
- 0xe45184fb, 0x933a595a, 0xeb3a836b, 0xb77e894a, 0x016fe6c6, 0x32c77c3a,
- 0x311c3a6f, 0xa9549b9a, 0xc1bc0077, 0xd780b4e7, 0x8e274e64, 0x473e0cd9,
- 0x3c824fb5, 0x1b1376d4, 0x7b2fd937, 0x7f845cf1, 0x851b74b6, 0xf2625dbb,
- 0x88947e9b, 0x92a15576, 0x26c87108, 0xcb55ee7e, 0xcb9688e5, 0x1b6e7f91,
- 0xc1a997c8, 0x13ef4d78, 0x7fe7b05a, 0xbfe2e3cb, 0x9f9f51cd, 0xb83371e8,
- 0x569673c5, 0xcfe802b9, 0x523aaba5, 0xab40e94b, 0xfd7084f7, 0x37186d32,
- 0x772b603e, 0xa5efd00f, 0x42951fec, 0xe67b773e, 0xbe214a8f, 0xdc7a75a7,
- 0x8f7298be, 0x357fd19b, 0x59bc03b4, 0xefc14b5a, 0x97f5b5fb, 0xfa2bfb48,
- 0xf50dfdf2, 0x35706063, 0x7059a319, 0x9359fe6e, 0xffac3b7f, 0x30c7f985,
- 0xfa40fc2e, 0xaf21f7d1, 0xd18ea8e3, 0xe793305d, 0x69ee93e3, 0x0eee9409,
- 0x5e7839e7, 0x1ebf8b0a, 0xa8fcc09e, 0xfcb17e54, 0xe61289d1, 0x66ced621,
- 0x266f62e7, 0xfa018e91, 0x68593a3d, 0x1c8af4fd, 0x796b7fb4, 0x77f4c89e,
- 0x7eb0097c, 0xca8f6fd3, 0xb2c7f720, 0xeb746ee7, 0x3e188194, 0x975149be,
- 0x97542e6f, 0x9751e5bf, 0x97f15dbf, 0x9365b109, 0xe8107bd9, 0xdf8955f5,
- 0xb10d7147, 0xa4ba7f23, 0x935dd820, 0xe7e74a5f, 0xe53e5989, 0xf17ef94f,
- 0xf5820aa5, 0x5b8d3b29, 0xfdcf508d, 0x3f5e5aef, 0xd98c4dd9, 0xea07c44e,
- 0xf3c4a8e9, 0x93185d32, 0xb1ef7b22, 0x6d343f33, 0xecfda7ab, 0x1f20af9d,
- 0xe43558a7, 0xa5ebc09b, 0x04c3b446, 0x289bb45f, 0x963c537d, 0x819a338f,
- 0x9e75dbde, 0xd697d0f5, 0x2f40506c, 0xb1182657, 0xc83fed6f, 0x9b96d7a8,
- 0xcb4ec40c, 0x63371f07, 0x3e265cb9, 0x20a123c8, 0x51e786ce, 0x0ad4279d,
- 0x60eda5f3, 0x160eedbe, 0xeb96d757, 0x7ed3cf51, 0x3e0f5d71, 0x9c1109a1,
- 0xf98ca57f, 0xc1661ca6, 0x7c247477, 0x6be734ff, 0x518486ad, 0x7bb3a58e,
- 0xfed10e39, 0xbf83dfa1, 0xdfa0f6d2, 0x13b950ae, 0x271bcfea, 0xc0a8b9e0,
- 0x592f79d0, 0xda15c003, 0x67e87cb9, 0x3f04f2e7, 0xa542f90b, 0x852bbe5e,
- 0xf8149030, 0x053b050f, 0xfb8204ec, 0xccb71100, 0xd97a8a34, 0x0da6fd0b,
- 0xe0e767b5, 0x56997852, 0x60253585, 0x27f1bca7, 0xe4b1c3a0, 0x931a6145,
- 0xe429e213, 0xc3c316c5, 0x19af6a47, 0xef0a3d6d, 0x9b0cf2c7, 0x84c7ad9d,
- 0xad4be00c, 0xe8064279, 0x478776cd, 0x0b94c5f1, 0xae6a76e9, 0xdb45f013,
- 0x35adf2d1, 0x18e5f2c7, 0xc69854fd, 0xe76d00e4, 0x1ef0a24d, 0xc0192934,
- 0xdb8ca3bf, 0x7cb5c6cc, 0xe9bae3bd, 0x41ddb4b8, 0xb6971d1b, 0x843266db,
- 0x8da30935, 0x78c0a15f, 0xa2971a97, 0x833f911d, 0x93a503af, 0x0ec1f820,
- 0xaf4834da, 0xf2be7833, 0x1e3664c1, 0xffe75429, 0xf8e99be4, 0xcea65f98,
- 0xda51b9f7, 0xfa7a01d4, 0x56c25369, 0x3837cfa0, 0xfcb61cdd, 0x69d83e43,
- 0x382bcc6f, 0x71267284, 0xd1100779, 0xf28bd20c, 0x0bc1c846, 0xa1cac769,
- 0x8de1e54c, 0x0fde7469, 0x079d1ee4, 0x3c721f9d, 0xa5f68f9d, 0x56935bd9,
- 0x417e1236, 0xa06e029f, 0x218be053, 0x5f838d3a, 0xa5b91bd0, 0x37251317,
- 0x9e173b53, 0xa425eec2, 0x2bc5e595, 0xa3f3c399, 0xd8dd3e44, 0x18d1e6ca,
- 0x746fb844, 0xe6f318fc, 0xffe718ee, 0xf735c01e, 0xbef04fca, 0x3f9ee222,
- 0x1477f601, 0xc96979de, 0xc6f07bff, 0xca97f9db, 0xcf8b1f0f, 0xacd2f8c5,
- 0x1e1f989d, 0x7cc56d98, 0x3f3c69f1, 0xc1a0d036, 0x0fdd00b8, 0x85a23ee2,
- 0x97204318, 0x5cbb72a7, 0x45785b9c, 0xe0d6fe62, 0x7d45068b, 0xde7c513f,
- 0xe97982b8, 0xbf2c65c1, 0x6f7ec87c, 0x1f7ed056, 0x9cfc73d2, 0x93317744,
- 0x28f7dded, 0xe689fbea, 0x44fdf513, 0x7121ed0b, 0x32948a6f, 0xdddfbf9c,
- 0xbbfe9043, 0x9f58b96d, 0x88fa65ae, 0xa3e9837c, 0xbaa21cee, 0x399d691f,
- 0x94f31134, 0x46c15e78, 0x6ff83fc8, 0x9a7e0bf2, 0xc2fca926, 0xc9afe543,
- 0xf0e6dc2f, 0x5b3a02ef, 0x92cde458, 0xebd63d28, 0xd2987f99, 0x8108a6eb,
- 0x7cd6c574, 0x44dda7d8, 0xe4d2df5a, 0x02febd21, 0xa53275e9, 0xbd153cd7,
- 0x15fc61ee, 0xe82d2144, 0x0b4e8875, 0xfd00f3e3, 0x6edc60fb, 0x5befef47,
- 0x6fd35f60, 0x683cb0f0, 0x2f19d796, 0x59e0621f, 0x5c783320, 0xf3c22d5a,
- 0x0f13f43a, 0x4df0e5cf, 0x12a69d2c, 0xf1631fc6, 0x824caa4f, 0xfe6192b6,
- 0x6ffd9931, 0x7c43b8c1, 0xcfdb08f4, 0x6b5b808e, 0x739a7a45, 0x057f8b07,
- 0x802ecc2c, 0x1d1a5838, 0x7f1f267f, 0xdaafa74e, 0x4a66ed01, 0xfa610f0c,
- 0x167f850f, 0xdfd99faf, 0xb370798c, 0x63c775aa, 0x2f2120ed, 0x2e6ddc45,
- 0x7dab7f6f, 0xd2f20ea6, 0xe3aad767, 0x64ef735d, 0xb339b6f1, 0x25ccfdd5,
- 0x7cc13fab, 0x03aad24d, 0x53bdcdfc, 0xda49ff5d, 0x026c9c50, 0x710ec9c4,
- 0xe520d03f, 0xd7a3e013, 0xba6f1793, 0x84f9d287, 0x8095149f, 0x9486f0df,
- 0xd04f6dc6, 0x271bb3f2, 0x94f5f961, 0x28ff7eef, 0xc0296fd4, 0xe25c3572,
- 0xe056fb04, 0x8567ca43, 0xc8cc77e5, 0xc27d0049, 0xe087bdfb, 0xdfd9b77b,
- 0x73b6933d, 0x3cc5c94f, 0xd7ee6ad6, 0xeac85c18, 0xc6d2be6f, 0x52ef9552,
- 0x6d5c5fd0, 0x1d35f766, 0x04bb7e29, 0x73abaaf2, 0xd5e4b979, 0x243e5049,
- 0x3af7827d, 0xcab66b9c, 0xe92d0eb0, 0xb93ecfcc, 0xa44f0a50, 0xf276a978,
- 0xbcd99bfe, 0x4b9e4b6a, 0xaea93e07, 0xf64cfd62, 0x41e67654, 0x2c79cd3b,
- 0x26374b9f, 0xbf05fe00, 0x957df0e5, 0x5c7d2bb0, 0x3de4bc4e, 0xfb4491d6,
- 0x0f2519f5, 0x7157d14c, 0x664bdd8c, 0x7d03e765, 0xfc191cde, 0x2cbcd3f4,
- 0xb8cab6ef, 0xe1e40d3c, 0x297d7e2d, 0x2c6ecbcc, 0x1179043e, 0x65951589,
- 0x246da798, 0xfe94beb8, 0x3f03a7c7, 0x5649fd5e, 0x559d1002, 0xbe82ff4d,
- 0xafba0a66, 0xe537d356, 0x65e9c9db, 0x2adf9697, 0xd30d36fa, 0x3ef658f7,
- 0xe102ab85, 0xaf5a86fa, 0xc7138d0d, 0x8ee3f19f, 0x2fe03725, 0xc30efe56,
- 0x987c8bd7, 0x798dd901, 0x825da7c0, 0x38026f4f, 0x9e089af4, 0x3c96ca8f,
- 0x7180f093, 0x7a88c785, 0x055f8e2f, 0x33e0997c, 0x1709192f, 0x6ec2c9fc,
- 0xf02e7f65, 0x7af064a3, 0x38979dfa, 0xe3a2e187, 0x7a0e91df, 0xcf0611fc,
- 0xc995a966, 0x112fbe19, 0x311697fe, 0x7cf53edf, 0x1eeccdcb, 0xcbf83703,
- 0x3c527630, 0xcbee0869, 0x9f310758, 0xb3e7d700, 0x9e9b3e8d, 0x4736edce,
- 0xedcfd23d, 0x283aa354, 0xff74c25e, 0xd41e700f, 0x7ec1f704, 0x62f1216f,
- 0x47d29cfc, 0x6ec63d20, 0xe3c6f012, 0xb90c65a9, 0x789f3f1a, 0x5baf0cfc,
- 0xe29e0d24, 0x7cd0e1fc, 0xf19e732f, 0xaf4b8af6, 0xb93a5bf6, 0xec39d17f,
- 0xfa842c4f, 0xa0f6625a, 0xe123d13f, 0xda96af7e, 0x6ba7201f, 0x71fa086b,
- 0xfa0d569c, 0x321d8513, 0xff5c9f16, 0x6ab7264d, 0xf73f089b, 0x4f17e6c8,
- 0xe064a98f, 0x1ad6787e, 0x800b0d95, 0xaaac1bff, 0x56b50673, 0x4e788f16,
- 0x503211c8, 0xa87f7a06, 0x0fef423c, 0x8a1c8194, 0xf6ae7fbf, 0x3b7bf322,
- 0xacf84a2f, 0x032b1cf5, 0x19acefbd, 0x56790328, 0x14fef767, 0x13dc55d6,
- 0xbdcf8f19, 0x97911ae9, 0x1a745972, 0x0e2247cf, 0x7fe6c47a, 0x3fc63d39,
- 0xa08a5675, 0xcbb5759f, 0xcfe7e7ce, 0xd8767a01, 0xefc12a73, 0xaad8db34,
- 0xd138bb03, 0xce903fe1, 0x5f17e8e4, 0x9a17e6c0, 0x56de3c52, 0x66587fed,
- 0xee1e22c3, 0x81b878e5, 0x9bf3d9eb, 0xa90fb8b4, 0x0d3e16f6, 0x9bc0a0a1,
- 0xbe42123a, 0x147ea2f5, 0xa79dc6f7, 0xda185506, 0x7d436f3f, 0xf557f8bb,
- 0xb09b2718, 0x1894435e, 0x6431397d, 0x327fdd56, 0x5553a779, 0x5d37a2be,
- 0xbecafed5, 0x717d555c, 0xfeaa9278, 0x544b37aa, 0x54c8b2e5, 0xdfabfb55,
- 0xaf9552a9, 0x6aa19819, 0x3df403bf, 0x4e37e3c5, 0xffbd52cf, 0x37f4e368,
- 0x5d7d3e21, 0xefaa3bf4, 0x043f704f, 0x85237a09, 0x040bfe74, 0x53ac5ebd,
- 0x9acd4f7d, 0x7c0e54b0, 0xac16fecf, 0x95f77966, 0xfdb16314, 0xdb52ec2d,
- 0x28903713, 0x84b62be6, 0x40984f24, 0xbeba9dde, 0xf107afb1, 0x0f7ba97a,
- 0x6be6b826, 0xc69754c0, 0x22633b51, 0x0d5c8220, 0xf1638379, 0xbfd6a5fb,
- 0xa97fe480, 0xd5b837f5, 0xd4526feb, 0x54296feb, 0xa3cdbfaf, 0x0ac4ff5e,
- 0xbc3bfaf5, 0xaa4ff5ea, 0xb27faf51, 0xa9febd4f, 0x9febd573, 0xffaf57e6,
- 0xbaf506b8, 0xd7aab667, 0x7aa97b3b, 0x4b82735d, 0x74f1f554, 0xc849e820,
- 0xf795bccf, 0xa453dbaa, 0x42e86268, 0x5f02d9d0, 0x8d63e603, 0x35487aef,
- 0x4c7d3c5e, 0xf48f3c20, 0xe547d22b, 0x727f6e38, 0xa97aa0ba, 0xda325c6a,
- 0x73c03719, 0xff6e04ee, 0x33b746fb, 0xd58afc84, 0xe6fbb1eb, 0x08dae4b1,
- 0xd1f7c57d, 0xd82bea63, 0xf7869b47, 0xefd163d1, 0x59ea84bb, 0xfa357c1c,
- 0x33b0eecf, 0x999a0e38, 0x5429ff3d, 0xd1db435d, 0xde141536, 0x743e6177,
- 0x93cd77fc, 0x1df20fd1, 0x7183abd2, 0x7c1124ef, 0x7c5123ce, 0x755d89fa,
- 0xf10165be, 0x645fb9e9, 0xc9a9e009, 0x7a0e5038, 0xa3fcc2ff, 0xee7c63ef,
- 0xdd65d248, 0xe21c7207, 0x3909e33f, 0x49c9e5c5, 0xf2d10388, 0x27f71339,
- 0x8ae2897a, 0xee29e7c1, 0x269bacf7, 0x5a259ea1, 0xd5b1e633, 0x9ea12edd,
- 0xf60ffbaa, 0xf4c71f6c, 0x52e788da, 0x6e2ed781, 0xa13b301f, 0x62dd0e0f,
- 0xadf890fc, 0xec7a8f68, 0x3fb4deb0, 0x47f98716, 0xdbb17f76, 0x25dce0c8,
- 0x89c2b911, 0xdd7106c7, 0x7ce1fd61, 0xe0c8db9b, 0x4623a5db, 0xe264efc0,
- 0x31f0fb47, 0xd63c8a99, 0xefd624ef, 0x17f05cd1, 0x7e6fcd9a, 0xa9f21aab,
- 0xf472e0e5, 0xa88f7fdf, 0xb677f7fd, 0xffbfe84a, 0x3e9b851e, 0x1b8f76dd,
- 0xef28b2f4, 0x1e21b802, 0xfbe8ed00, 0x04ab7754, 0xadafb1fe, 0xb10f3dbf,
- 0xbfb25f76, 0x83087ea1, 0x3d60fe0b, 0x83367f85, 0xd281b7d2, 0x11efb6cb,
- 0xfbc61ff4, 0xa969c76b, 0x31fc8106, 0xc097bb1d, 0xfb67af2d, 0xbb1ec3e2,
- 0x7444cfca, 0x7a47380e, 0xf20e7b29, 0x9cc54fbe, 0x3474a0d3, 0x1fbafdea,
- 0xa47cb065, 0x44c8b6f6, 0xe39e4b88, 0xdb87d771, 0x56b2c4de, 0x265e60f6,
- 0x88e5f7dc, 0xa2ef5ef9, 0x4e7231f5, 0x63efd2b6, 0xeace8de4, 0x1e6bcbc3,
- 0xbc608b69, 0x25efc753, 0x5ee3347b, 0xbfc63fbb, 0x6e38cef2, 0xc4831927,
- 0x69b8429e, 0x4f4eff4f, 0x5a3f4023, 0x762a7cbb, 0xd3706d1f, 0xeef562fe,
- 0x1b1264c5, 0xf6d9587f, 0x88fdc20e, 0x6743f7e4, 0x36127c86, 0x641b7c51,
- 0xdf4d0338, 0xe511b86f, 0xaf76deaf, 0x1aa1ee07, 0xb7067f0b, 0x7e56217c,
- 0xdf8e387e, 0xe7e5c5cf, 0xc9d16d93, 0xdb7b4e30, 0x5d6f0a80, 0xfdf1176d,
- 0xc452369a, 0x7ac43fea, 0xf4828d4d, 0x42d28a73, 0xf27ae204, 0xc1fc0d80,
- 0x10263ed4, 0x8db9d67f, 0xb8306f18, 0xa2e4bc18, 0x9e63e90b, 0x3e00c19d,
- 0x1f4a4cbf, 0xe1d52fef, 0x4cbefafe, 0xefbfb62b, 0x780fe337, 0x29eadf29,
- 0xc37fb41a, 0x61c7867c, 0xf973d3f8, 0x0fbf6449, 0x5d3e80e4, 0xd38538c6,
- 0xf1d70b3e, 0xf027f6cb, 0xcc1137ae, 0x5a67d647, 0x5cb85ed1, 0x6a19dd38,
- 0x8fe3c7bc, 0xffe509e2, 0xf74f1c7d, 0x93fcc83d, 0xf04fddf7, 0x4a59053c,
- 0xe987caff, 0x87971c6a, 0xcf87c4a9, 0x082a36ae, 0x465eb00d, 0xed409fe2,
- 0x8d8bd211, 0x82a7e04d, 0x80ecaf7a, 0xaa2788d4, 0xb9e1335d, 0x1764e2a6,
- 0x6bdae3b0, 0x13c08b3f, 0x2f801162, 0xc109037b, 0xab98bc55, 0xf877c740,
- 0xd7813959, 0xe565cc27, 0xe89f5e44, 0xef4ce563, 0x0035520b, 0xcb471716,
- 0xca6f3ab4, 0x80bc7907, 0xfcf173b0, 0x84cd8d7e, 0x73ab0bcb, 0xdfd43566,
- 0x8b9cf049, 0xaf09ffa8, 0x5f1eb34f, 0x637a0799, 0x0dfbfab6, 0xd6a90f1c,
- 0x30d35de3, 0x17aea6de, 0xeb64acf1, 0xfbf137f9, 0x53fd7522, 0xf59b7bfc,
- 0xd41a647c, 0x7fc7abe7, 0xac5bd79c, 0xca8def2c, 0x037f767e, 0xd78c7faf,
- 0xc61ea09b, 0x5af5642f, 0x6f09df71, 0x18e1c9d7, 0x431e33e2, 0xbf33260c,
- 0x233696f2, 0xbf3c57f2, 0x73f707dd, 0x9bf30d95, 0xf519297d, 0x32fb86de,
- 0x5049dc98, 0x51debc06, 0x77a8a2e4, 0x37cc65da, 0x48f5bad0, 0x972b064f,
- 0x871f9c27, 0xead489e4, 0xe4c64461, 0x9ae8a5f4, 0x9005f012, 0x0ff4596b,
- 0xfbe33ae8, 0x918fe21a, 0x664de973, 0x83e58fe2, 0x39554e05, 0x5574cee5,
- 0x5cecd77b, 0x74b5bd55, 0xcc9eaa92, 0xdc9f2276, 0x5ccbe9cb, 0x17aaa254,
- 0x6d9065f7, 0xb59d9dbc, 0x554fe5d3, 0xa85f3bb5, 0x9f8d0224, 0xa3dc49ba,
- 0x7c8231e6, 0x9b96d7b8, 0xb3f8fc0a, 0x4e440ab6, 0xf627e53b, 0x1ba7f3b4,
- 0x54fa598c, 0xcb10b978, 0x7e583bcf, 0x879b7b7f, 0x9e087395, 0xab6f6faf,
- 0xca2ef2c1, 0x69fcf09f, 0xdb9f179b, 0xcfa15969, 0x2bfda47f, 0xda1e9fb4,
- 0xa19f943f, 0x3373c3fd, 0x3f9e1fed, 0xfd43fda1, 0x942fda06, 0xc170a69f,
- 0x0fda29f3, 0xed31ffbc, 0xb44fca1f, 0xb6bcb0f9, 0x1f962e6d, 0xf3e3f36f,
- 0x7c06b6b1, 0x8ad6d9df, 0x96db47e5, 0xb6e1f3e2, 0xdbdb3e20, 0x2f7d6256,
- 0xf9e793a7, 0x2be7dc79, 0xf103bdd9, 0x219fdfeb, 0x9d2fbb61, 0x154a539f,
- 0x3f2ab97a, 0xfc033fa7, 0xfceabd02, 0xc21fc054, 0x8c786261, 0x0668e387,
- 0x91270fb3, 0x930b72c8, 0x1f07181f, 0x6159e7df, 0xae35fca1, 0x4e7bad95,
- 0xd3eb145f, 0x4778d81a, 0x5c409db9, 0xce519241, 0xbb439b8e, 0xcaa45273,
- 0xd007f2c2, 0x14dc430f, 0x5aece53f, 0x21e64672, 0x5725c00d, 0x331e3d50,
- 0x397c21af, 0xb7809c18, 0x57fde0d1, 0x696d378e, 0xa75fbb2f, 0x6c0c2ba6,
- 0xe2b6f666, 0xb9c63afd, 0x9f4cb0be, 0xef1f9f2e, 0x717498e9, 0x5224dd3a,
- 0x9bf176f9, 0x8ccfa144, 0x31fef526, 0x6a89417d, 0xb8bda67f, 0xd1572886,
- 0xfbd48b7e, 0xbdfe733c, 0x198cefaa, 0xf5eaa90f, 0xfaaa15ae, 0x1e73bbba,
- 0xc73e0371, 0x6199b8b1, 0x210272f5, 0x4fdd85e4, 0x4ce65c20, 0x92738f36,
- 0x605f7ec2, 0x133dff37, 0xd6797fbe, 0x5c65f1ce, 0x09f2fb8d, 0x482c560e,
- 0x0f406a0c, 0x448bfc7d, 0x9e3b7f94, 0x7e9fa0d1, 0x40690922, 0xe6a64cde,
- 0x015fd424, 0xf16b8c37, 0x942d26aa, 0x85a2898b, 0x8a2455f2, 0x7fba3afb,
- 0xf5d264d1, 0x9ffad16b, 0xd9f2d131, 0x2cb3ff4c, 0xfa8c30bf, 0x67af80ba,
- 0xadc7d881, 0xdcfde397, 0x37f44cc6, 0x7625cfa9, 0x874bfdf0, 0x970df989,
- 0xc153ca3b, 0x46373e0e, 0x7dcda83e, 0x14058de2, 0x63b4b6df, 0x1fef14f8,
- 0x9ea33457, 0x94cbcfd7, 0xf75e5abe, 0xd44faa7a, 0xf307937c, 0xcffa5b38,
- 0x6b76e029, 0xff228fc9, 0x3c84e874, 0x9e411253, 0x893d970d, 0x3b1e6624,
- 0x93c9deda, 0x11fa2151, 0x375f326f, 0x4ff95f31, 0x4bc87695, 0xd179e02c,
- 0xf2d2db3b, 0x7f0fc7ab, 0x5074e3ef, 0xa0352248, 0x348b0b5f, 0xe074109e,
- 0x31fcabb5, 0x2f2efca6, 0x4b930b9c, 0xf2c40788, 0xf785d244, 0xd57fc829,
- 0x7c9a3e62, 0x50a21af0, 0x0d6ad8fb, 0x70d16093, 0x75fb84bf, 0xfce5cfbe,
- 0x9c6af667, 0xec259c8f, 0x74e80f26, 0x1bd599f2, 0xacfc3a01, 0xf4d8c75b,
- 0xd0bebab8, 0x2def504a, 0x1487d42a, 0xebcbee09, 0xe5407bc2, 0xc8c9122d,
- 0xb9a63801, 0xdf7e83e7, 0xb63a416b, 0x9fc72fac, 0xe359b830, 0x0efc40af,
- 0xc2357b28, 0x9aeda2e8, 0x82b7eb27, 0xf001393d, 0xdcbc0562, 0x430d5f91,
- 0x1e2217e7, 0x2f79f217, 0xc8e8f3e4, 0x833fc21c, 0x70bc7887, 0x6ea2ef1f,
- 0xcf528fe1, 0xaad2f1f3, 0xa2bdc36f, 0xff2d11ed, 0x3e352299, 0x5322e957,
- 0x70c34be6, 0x66173851, 0xb8015c82, 0xd80f82af, 0x919f9afc, 0x941cc6c8,
- 0x6f68356b, 0x3f306994, 0x9b2e9e3d, 0x8fdc9932, 0x7dd9d866, 0x4853eee4,
- 0x93e5c3cf, 0xc2482c6f, 0x5bb333fd, 0x8fcb326c, 0x58957af4, 0xe12af7bf,
- 0x72e7e45f, 0xa1de1ccc, 0xb127057b, 0x892b60bc, 0xb4bc87ac, 0x2bf5f6b1,
- 0xdc707332, 0xb53d7de1, 0xa53f205d, 0x5c7988cc, 0xa13e44ab, 0x69995472,
- 0x57384f63, 0xfa74e465, 0xf79d4da8, 0x6fcf9db3, 0x418f5f3b, 0xf27bc8a3,
- 0x9cc716d6, 0xafeba9f3, 0x88963f47, 0xff720ed3, 0x1d59a0e1, 0xa4e46d57,
- 0xaba87830, 0xc1f10cca, 0x6da7162e, 0xdd99bfec, 0xc7efbb6b, 0xed302f78,
- 0xa87a0153, 0x57ebede7, 0x0b58fdaa, 0x5f91fa77, 0xf164fde3, 0x398a317e,
- 0xe31fec3d, 0x335b62fd, 0x43c27ef9, 0x7b0e218a, 0x61de7562, 0x7277ec33,
- 0x1f0f9e08, 0xef017da7, 0x81bba6dd, 0x974fb82e, 0xa3fbb114, 0x54ffd7e2,
- 0xb2f11e96, 0x78efac53, 0x3ba5da2b, 0xd81c98cb, 0x2dfce079, 0x2b3f69e3,
- 0xf9d52473, 0x3a399580, 0x29b7a75c, 0x97b3c37d, 0xeed19a90, 0xa9943b29,
- 0xef726af9, 0xc1eff55a, 0x1c0df734, 0xff2828b6, 0x1fba035e, 0x4279fc3c,
- 0x1451f211, 0x08c4bf7f, 0xc19930c2, 0x76b3e70d, 0x17993e6b, 0x676f0f4b,
- 0x36ff58ca, 0x0d2f8ba7, 0xae1ab557, 0xa56f45b3, 0xfd7060cc, 0xb9c6e40e,
- 0x5894f1f0, 0xb5c0467b, 0x03df8c7b, 0xe2abf0f8, 0x1fad42a9, 0xfa74f062,
- 0x6ed3c3bf, 0xfcf0e8fd, 0xb3f3c395, 0x9b5eec43, 0x515ff591, 0xe1ab759f,
- 0x647cfb3d, 0x0a49880e, 0x7f115fef, 0x182993ee, 0xebf8e613, 0x59f4e52d,
- 0x078fe5ca, 0xc09150cf, 0x1e63577b, 0x924caf66, 0xbe5ca16a, 0x2cf77f00,
- 0x02c3ef93, 0xbf9e3f1a, 0x4619ef21, 0x64d77f95, 0x9ddeba31, 0x878a8d2e,
- 0xcf362cd2, 0xb2ea4703, 0xd8f1bfc1, 0x7202063b, 0xbfcf3361, 0x6bdecc7e,
- 0x05a67b84, 0x425ca11e, 0x747d019f, 0xc7bc2811, 0x2a333f4a, 0xd3c651d6,
- 0xc6d6f1b0, 0x4f188df1, 0x1564a73c, 0x3a557b32, 0x387385a4, 0x0b7daf6b,
- 0x5b5b7fef, 0xfdeca32a, 0x1d5ff8d2, 0x5bf0ff87, 0x7a30b729, 0xe1459299,
- 0x90fe916b, 0x0e5a6df0, 0x2a7fd148, 0xbd157c82, 0xa01fe71f, 0x4691ec78,
- 0x8b2d29e2, 0x9f988bd1, 0xdb80bf98, 0x5c02dd76, 0x06bbdb07, 0xbca51a54,
- 0x8917d0bd, 0xbcc1ff5c, 0x2b5c5f50, 0x654c73b3, 0xdafbae32, 0xee78a98a,
- 0x17cf376c, 0x1fa35e89, 0x164477f5, 0x763dbc70, 0xb811b7f1, 0xafd83947,
- 0x883ffbc3, 0x15bee03c, 0x8dff1fee, 0x5389f78c, 0xfb81aa7a, 0x391c0ecc,
- 0xebfb009f, 0x843a59f9, 0x87973e7b, 0x35b51783, 0xc8ec1e78, 0x0c6d7667,
- 0x6965d7fd, 0x89127db9, 0x35af39c0, 0x8b3cec25, 0xd603db95, 0x001b2723,
- 0x43c56b7e, 0xde862906, 0x10196566, 0x68fa35ae, 0x17f6878a, 0x6125a7d8,
- 0x7bc1ffe6, 0xb3ce8719, 0x5a1e19da, 0xbda10f4a, 0xf767ed60, 0x2965d635,
- 0xb852ce4c, 0xe6f7d2f7, 0xebd99f89, 0x8e94bea1, 0xbdfc3b97, 0xd3d6cecd,
- 0x4beec65c, 0x3fed7b5a, 0xc83ee1db, 0x471df844, 0x79f2efd8, 0x7292b80a,
- 0x48dfbc35, 0xcbf81724, 0x5abe632e, 0x235ef86f, 0x2f82fbd8, 0x62d5cade,
- 0x39f947bb, 0x0a2b4789, 0x4cae7043, 0xdb35b1d0, 0xcc1640ff, 0x0bc5f28f,
- 0x7c44ef68, 0xf63f10d3, 0xdf33c862, 0x32e64525, 0x076f443b, 0x68d42c3e,
- 0xe116fc54, 0x549e26eb, 0x73dda3fd, 0xa15da73f, 0x46423bf7, 0xfe4de702,
- 0x22667178, 0x191da7d8, 0x1af3dec2, 0x259b5f01, 0x8c0e625f, 0xdc5a2ff3,
- 0x72381e0f, 0xedc601bc, 0xbe02f3a0, 0xeb75f87d, 0x3a53b06a, 0x53e45eec,
- 0xd0ecbe31, 0xfd60f5f0, 0xdf7bd6ec, 0xd4647f04, 0x3acdeec1, 0x11867538,
- 0xd3b69fe8, 0xa07f3f40, 0x04f0f7fb, 0xfd1aa7e8, 0xb3ed0b06, 0x8b77c3a6,
- 0xb011ff88, 0x6b75176f, 0x3c83f755, 0xc2c5e5cc, 0x8e12168b, 0xac2c2fd9,
- 0x6b9e0ef8, 0x0131785c, 0xcfcc3fdf, 0xcfcc3fed, 0xf8e2edbd, 0x5f3f9978,
- 0xfb8afacf, 0xde9c4f6f, 0x8eddfe4a, 0xbbf7c63a, 0xa59afd60, 0xfaa83d01,
- 0xc73f5335, 0x687f64f3, 0x21b093b3, 0xf311de06, 0x98e1224c, 0x5dda8771,
- 0x52709134, 0xfa32faec, 0x15af9e1d, 0xe6d0ffeb, 0xdd8e3c46, 0x1e1538ff,
- 0x53cffb87, 0xff6471e1, 0x87ff5805, 0xf44bc2b6, 0xfe8c793f, 0x0ff05473,
- 0xef8f9bf7, 0x7bac1dcf, 0xeef942d6, 0xc6c57860, 0xf7e14b57, 0x7bf80cf7,
- 0xb7afa41b, 0xeeb9cf0a, 0xfa0e7822, 0x7a7ffd81, 0x1f52f21f, 0xc0f7aad8,
- 0xe8ba8318, 0x7a28cf3c, 0x83d89f26, 0x789cef70, 0x87959dbe, 0xdeff1ceb,
- 0x90ec8728, 0x942c6a67, 0x8ce7a0ed, 0x015a1224, 0x235297fb, 0xdf1139ca,
- 0x34fefd12, 0xb392ab53, 0x46a17ee2, 0x68d87f9e, 0x26aff161, 0xac2cffab,
- 0x574d12ff, 0x1f68cfcb, 0xf03b0ba7, 0x0e213b7c, 0xf888d7dc, 0xc5fb0c8e,
- 0xf97d703c, 0x9b0b9c08, 0x0cffe397, 0x1509fbbe, 0xd1ef102b, 0x0fcdb15e,
- 0xf38f79f9, 0xa6e3e47d, 0x2313db88, 0xf2d9753f, 0xba1bb357, 0xecb7e8e2,
- 0x8cc23b77, 0x40d9757e, 0xcfc8dabf, 0x7ce072eb, 0x67bf00e3, 0xb9fb414e,
- 0xde30f4ae, 0xfc275947, 0xf3e32b02, 0x601d3256, 0x54788b4f, 0x8217e402,
- 0xdd86b0dd, 0x616f5853, 0x275ffae5, 0xba17b9e1, 0x8114b21f, 0x65add99c,
- 0x071e22fe, 0x1e61cf3b, 0x02c9ae34, 0x7cf20efc, 0xaffdf397, 0xe7a7bde1,
- 0x3a478e57, 0x0fe5ffa8, 0xddc31ef1, 0x0d9f4ce9, 0x3ea1b3ee, 0xca7837ab,
- 0xddcd5ee1, 0xed6ecce9, 0x2509c395, 0xa3ec7631, 0xa7285519, 0x5e395e3f,
- 0x19271b13, 0xc2e4cd9f, 0x94ffe11a, 0xce70e5a3, 0xf0d2e3ea, 0xdd3ea13f,
- 0x1bdfc263, 0x53fdecd3, 0xbabfde39, 0x63bf80c6, 0xe277b551, 0x5fb0b9ba,
- 0x1f31904c, 0x84d7b35b, 0xc55d9cf0, 0x6f8383ee, 0xef35ee41, 0xcbbf871d,
- 0x62896f56, 0xd9b364de, 0xc1f10053, 0xc0dfbdfa, 0xf1389fdf, 0x902cc4f8,
- 0x9593c783, 0xfb6fbc2c, 0x3a748a71, 0x26fbe3ef, 0x579df7b0, 0xdb6ab9e3,
- 0x347f8b1a, 0x4bd088ff, 0xedcdf7f1, 0xd73e2f4e, 0x6899f807, 0x5e1c80f4,
- 0x675fe438, 0xbfd607f7, 0x24a59d19, 0xf306ffa0, 0xa7edea17, 0xeb1df7f0,
- 0x49dd8fbb, 0x42e93e30, 0xbcfb15fa, 0xb9eb71f8, 0x8faddafe, 0xd5df83ce,
- 0xf8e76fab, 0x59f7bfe7, 0xdfc629af, 0x5ff8149b, 0xf31f7713, 0xc5de38f7,
- 0x1911c4f3, 0x76a4b9ef, 0x8ff81645, 0x2037ec4e, 0x33589dbd, 0x1057ef19,
- 0x5853d5e3, 0x8f4f94ed, 0xb029953b, 0x15b20bbe, 0xb676ff36, 0xe9ef157f,
- 0xbdf811f8, 0x2d3ee8ce, 0xda0dafe6, 0xc71009a3, 0x7944ed14, 0x5afd3e68,
- 0xddb7bdfc, 0xdd7007e9, 0xa0115d29, 0x6d2fcd2b, 0xbf03b7a8, 0xf71bbf64,
- 0x82092971, 0x8ef8349f, 0x077bf701, 0x9ed019f7, 0x9d977c1e, 0xef711fcf,
- 0x059a359f, 0x7e06dcf7, 0xdae50e39, 0x0b746660, 0x784dbfb3, 0x51e0e4cf,
- 0x5e3cd5ff, 0xd1efc69c, 0xefbb034c, 0x18533ec2, 0xc4fa3eec, 0x6c9043b8,
- 0xfdfbe373, 0x882fbc16, 0x24f9d93e, 0x7f1b8f69, 0xf1748937, 0xfdf823ef,
- 0x09fe5903, 0xc81fa720, 0xe15bfda3, 0xeed893fb, 0x4affae42, 0x9211598c,
- 0xc74bc7ce, 0xd9fd337e, 0xccfa5ef8, 0xa80f7ecd, 0xb047d78b, 0x5ff0603e,
- 0xbdf8f38d, 0x328cf48d, 0x5f7aafcf, 0x49d97de4, 0x6e028eb8, 0x23b4678a,
- 0x93d2f1e3, 0x029ff6cd, 0x3974f11f, 0x80979eb4, 0x7832fc0f, 0xb63ec0bf,
- 0xea26ab8e, 0x9ce93c99, 0xde32f68c, 0x27931430, 0x07df7cb8, 0x3a839748,
- 0x97a0d3ef, 0x847547a2, 0x2d48c3dd, 0x5457f003, 0x16f576b0, 0x7010f7e6,
- 0x07e7e19c, 0x1e593b1a, 0x3ee799e1, 0x856f9ac8, 0xa81ff3f3, 0xff0bcfce,
- 0x0124ed21, 0x8f5633fc, 0xc4575092, 0xc22d76ec, 0x6e8f7ec5, 0xdfc14e8d,
- 0x3e3e0c0b, 0x2712fd11, 0xbc5ecaf4, 0x15d57607, 0x6d27a01a, 0x4fbf9731,
- 0xfb8979b0, 0x6d3dc4dd, 0xc81978f1, 0x99b2fa66, 0x3b82eff8, 0x25138ffe,
- 0xf14b0785, 0xff744abe, 0x52cd206b, 0x7e589af6, 0x9185ea3b, 0x2fea42f7,
- 0xff827bf1, 0xb053e5bb, 0x9f806556, 0xd5e80260, 0x7fb676d3, 0x40225bc4,
- 0x3cd96bbf, 0xb803e03b, 0x4ef882ff, 0x5bc45e83, 0x4e1e2825, 0x9e3eac4b,
- 0x1bbc84ce, 0x1ba00f81, 0xa3be17e8, 0x9d9e7f7d, 0x763ff6c3, 0x17943f27,
- 0xaa5e43d4, 0x490157d0, 0x0f7dc0d6, 0x024a1d27, 0xcec9e5d0, 0xc872e73c,
- 0x292871f7, 0xe076f6b1, 0x0e7bc110, 0x73ff3814, 0x922efc35, 0x05f80a77,
- 0xfed53b77, 0x5e787888, 0xfd401ca8, 0xc6985ff3, 0x800053c5, 0x00008000,
- 0x00088b1f, 0x00000000, 0x7db5ff00, 0xd554780b, 0x733effb5, 0x79332666,
- 0x84841e4e, 0xe4249840, 0x09308401, 0x0741410f, 0x68151048, 0x85280978,
- 0x42100793, 0x17b6881e, 0x240cdb5b, 0x41b45a20, 0x768bd151, 0xb4544140,
- 0x03414141, 0x58a50077, 0x56d56351, 0x880dcb6d, 0xa8311fbc, 0xadadff97,
- 0xfb5bf5ff, 0x90ce649c, 0xf9b7b5a8, 0x67d9d83e, 0x7b5ad7bf, 0x3bdaf5ed,
- 0x3f437cdf, 0x756109d7, 0x10f4422b, 0x116dce22, 0xa3109862, 0x42f382dc,
- 0x11c885d8, 0xca8df3fc, 0x5c3adb89, 0x8df88588, 0xdaf9aaaa, 0x2bc89eb5,
- 0x1f5c2deb, 0x774675e3, 0xb5f1bdf1, 0x28f250ff, 0x084c21b3, 0x5d3dfe87,
- 0x1e310f88, 0x90ea7b8d, 0x460ca7dd, 0x09ac2e1a, 0x75ac5442, 0xa51a45fa,
- 0xbacc4e6f, 0x4285e653, 0x5c6cc775, 0xe34ad899, 0xca2a6f96, 0x1fb29112,
- 0xd0aaf341, 0xea9e55e7, 0x0a8752cd, 0xeaa8f6d1, 0xebf684da, 0x6a8f9e55,
- 0xa51eb8f3, 0xdbd627ef, 0x9fa9cb5c, 0x273e7d0a, 0xc5d16b7a, 0x0ab794b9,
- 0xf280bdab, 0x45da2d56, 0x54782efd, 0xb177f62d, 0x81f7aa3e, 0xf80ba0b5,
- 0x3a894d60, 0x1ea8327c, 0xe39469d6, 0x7268f7bf, 0xc2fcd157, 0x63cc77e9,
- 0xd1f7e2a3, 0xd1f44efc, 0xfc7f21e6, 0x82b13093, 0x45daeaf2, 0x2bdceed1,
- 0xa1c27de1, 0x01727b45, 0x031eb95f, 0x18e3a19e, 0x7808bcf0, 0xbabd20c6,
- 0xabf04bc5, 0xa0f5487d, 0x4be6bece, 0x98df80d1, 0xae47453d, 0x61b5f7c1,
- 0xecda8c22, 0xcefe9c3b, 0x8b8f34ad, 0x3d4155ab, 0x193dd28a, 0xdbc68289,
- 0x2e7cf96e, 0x4dbf73e0, 0xd2917acc, 0x47a7b7d2, 0x46fd285b, 0x21f51fa7,
- 0x6a352709, 0xae7cf47a, 0x98b93edf, 0x9edcc7f2, 0x7aa082c4, 0x2ce9d63f,
- 0x6b655f14, 0x718d16ff, 0x78d8d62a, 0x2e5e065d, 0xbf341d62, 0xfe118d8b,
- 0x8b9704e5, 0x5fb8dbbd, 0xbf464f03, 0x4183c015, 0xa56f544f, 0xe38fa5db,
- 0x114717b3, 0xe1b4d35c, 0x64e82e9e, 0x2e3483c1, 0xe51f5bfa, 0xff7de675,
- 0x74780d71, 0x25969be0, 0x8f03fc0c, 0xbc6da44f, 0xde59be97, 0x93d10ab3,
- 0x7d78d0e0, 0xcbdf42aa, 0x850984f6, 0xda532bfa, 0x9c09288e, 0xac14fb77,
- 0x8c3cf17f, 0x9871f657, 0xf7c7e505, 0xf3c79f5e, 0xc12bc10a, 0x7a2bb529,
- 0x96d698bf, 0xdf8209ea, 0x736d3ec5, 0x7d06be79, 0xe79bce74, 0x4c37bb51,
- 0x4c5c5f60, 0x76467c23, 0xf801b1c2, 0x5df5c619, 0x6f6fa676, 0xb1d7e01e,
- 0x7ac8575e, 0xfdeb215d, 0x0b7d3040, 0x29ebc68f, 0x82cc24ff, 0xdc0fe5ef,
- 0x71a6e594, 0x8e3bdf8e, 0xce3c75d7, 0x75fd879b, 0xcffa953c, 0xe59d72bd,
- 0x733ad00f, 0x8d9d65bf, 0xb757c64e, 0x7b6b8ceb, 0x3acb7c42, 0x6874ea37,
- 0xab33f3ac, 0xfa8ada3b, 0x9cb155bb, 0x14fb6a8a, 0xcc8d7fdf, 0xd0d056bb,
- 0x0f4936b5, 0xfc236bb5, 0x6685d7c0, 0x6e7f04db, 0xf1a01f27, 0x583d27be,
- 0x8f8e1e98, 0x023c3f75, 0xea9f75f4, 0x9701b9f2, 0x9cfcef21, 0x57efc7f2,
- 0xb1f9025d, 0x0fc47e12, 0xc70fe02c, 0x73278b53, 0xb5cdaf7e, 0xb4f9fa82,
- 0x047f6ff1, 0x63dc5cfd, 0x5f5e0b73, 0x90b3fdf1, 0xaf82f9a7, 0xc66e5c11,
- 0xebce54b8, 0xd619ef57, 0xe8f17288, 0xbba65760, 0x0214be0b, 0xaa358ae7,
- 0x01d21f69, 0x3ed5e3c1, 0x3ac6e290, 0x8713380c, 0xa83a9acd, 0x4fc81e13,
- 0x9709d41f, 0x9ad0bb5a, 0xfb12fbf8, 0xfc414194, 0x9749f00c, 0x3cff44e7,
- 0xa2d2c7c9, 0xc873f683, 0x8ff942fc, 0xff48cf51, 0xcc57c1d2, 0x705178fc,
- 0x1950e09e, 0xc21c5f92, 0xca42aa37, 0xb7ca43ab, 0xf99cfaf7, 0x13f8e840,
- 0x31bee4d3, 0xc3aa58e0, 0x9145bb71, 0xc53ee47c, 0x2d7e89bf, 0x4bedbab5,
- 0x8e2ffe69, 0x4fd0f311, 0xae385599, 0xced97de5, 0x8ab52beb, 0x7c02b086,
- 0x633d70f7, 0x435fd4dd, 0xc3e51c58, 0x7aa21f25, 0x7941ec13, 0xf31adf83,
- 0xf0934f09, 0x5bc5d230, 0x83c78d9d, 0x14dd59e0, 0xeed7ca6b, 0xee3c6e4a,
- 0xc62fcce8, 0x6ff4c92f, 0x387ead22, 0xaa7f22e0, 0x8c1eb577, 0xb249fa20,
- 0xd469e168, 0xff83c5ef, 0x66eb9d1b, 0x262f0fbc, 0xe9a816fc, 0xf5a61d2f,
- 0x3d56edb6, 0x9befd09b, 0x5f11fcf2, 0x1b787a5f, 0x9bd9af7d, 0x7775ee21,
- 0x8e143fae, 0x8a5d7717, 0x17efa74e, 0x05c3d90e, 0xcda501c9, 0xd1ed63f1,
- 0x84babfbc, 0xbb875bbb, 0x6b05dfd1, 0xa094f46b, 0x6b44177a, 0x7a20d4f4,
- 0xa975dd29, 0xfc31e44e, 0x1f106a7c, 0x8f4f74ff, 0x2f7d2ab1, 0xb1af7dfb,
- 0xe9c74a16, 0x736fdefd, 0xe686b93f, 0xe61ddbed, 0xbef34cd9, 0x0b2ce6f0,
- 0xb3785fda, 0xea7f4f42, 0x4fb3f4e5, 0xb47e3153, 0x31bbd245, 0x293488de,
- 0x8e59954f, 0xfc1a313e, 0x699ed5ff, 0xe59d69f5, 0x2c829665, 0xad9b79e0,
- 0x7de62e6d, 0x95ab1141, 0xc67eceb8, 0xfdb9b9a5, 0x9f27dd85, 0xf4f87f00,
- 0x60053efe, 0x6776172b, 0x7e5469e7, 0x5921e3e1, 0xc2f7ea2e, 0xf01ec97d,
- 0xf7366d85, 0xeede994f, 0xdf60f289, 0x9c61fd1b, 0xf77fe825, 0xa435c355,
- 0x52f9cb1f, 0xe3934f3e, 0xce8294fa, 0xee2da37e, 0xbf028f5f, 0xb3cdbdf8,
- 0x7fa59299, 0x8b19e8cf, 0x773f61f5, 0xd5b28781, 0xe26dc261, 0xde782b27,
- 0x8763c2a5, 0x1172841c, 0xa2e55f44, 0x6fcfbf98, 0x405f7f34, 0x17df027c,
- 0xaf7f37ae, 0x5aab8d10, 0xfc8b7d69, 0xf682efe6, 0xfb112f8f, 0xe269f8da,
- 0xd6f17ef3, 0xf54cc26f, 0x0fe74f84, 0xa5c7e60e, 0xc7c11fb4, 0xfefc579e,
- 0x3defc015, 0x7433af2a, 0xd2d3cb5d, 0x448f1d78, 0x6b6e63fc, 0x598f5e10,
- 0xe0893584, 0x1c2ecc7a, 0x47e80549, 0xbeab9c08, 0xcdfe613d, 0xfedee4d4,
- 0x3296a55f, 0xe0b24bdf, 0x05c3b83c, 0xedfd47ce, 0x7e8a9939, 0x791756ca,
- 0x77e6835b, 0xe47de6d1, 0xdf5790e7, 0xf54d7e23, 0x37f58d8e, 0x1d79a58e,
- 0xd4f557bb, 0x33af3177, 0xe3f99f24, 0x28f71e09, 0xf2843fc2, 0x2d4c9ccf,
- 0xde9cbc21, 0x34b5327c, 0x3115fe98, 0x8d1e982b, 0xebc26694, 0xf489ac82,
- 0xeb05ad18, 0x89d7ad09, 0x0d7cf35f, 0xb1553a78, 0x787a2ba4, 0xe54f7414,
- 0x05577f39, 0x3d9acee4, 0x33e83f36, 0x0f17e362, 0x6cfa0adf, 0xda40b9b6,
- 0x2f547bb5, 0x5bb174e4, 0x1ce267f5, 0xba34fe6b, 0xeecce712, 0x68352e21,
- 0x170e74dd, 0xb0b97ce3, 0x596252eb, 0x1933f72e, 0x9eed44f2, 0xdfa03c87,
- 0x5cf1e6ee, 0xf1affa9a, 0xff99af3f, 0x20fdcf9d, 0x81f046f1, 0xc0b2278d,
- 0x3e0f89df, 0x99fd8697, 0x791db5f5, 0x83875a21, 0x2c7e68fe, 0x7ff45fbf,
- 0xa3a5f2c5, 0xbbfaf559, 0x349ec3c0, 0x07ffc33b, 0xcd026fcf, 0x7e73b12f,
- 0xe03d9f34, 0x6b3cc6cb, 0x9c766ddc, 0xd11d17b3, 0xb4a7e079, 0x89f989a0,
- 0x06e4f9fa, 0x289b2d7f, 0xee16bf88, 0x09c2bf9e, 0xf151a179, 0x6f280f40,
- 0x2adcf956, 0xddfaa0df, 0xecc29784, 0x213bf6bb, 0xe5443e9f, 0x3abc74d4,
- 0xa8b38fea, 0x54fbc2fe, 0xf8dbefce, 0x80da3fd3, 0x11360dd7, 0x47863c06,
- 0x63c7d26f, 0x3e916879, 0x37cd45bf, 0xb7a0569d, 0x013d51ec, 0xe51cdfb4,
- 0xd5b2f7c1, 0xf4c163b6, 0x50bf1f35, 0x2bd7f37f, 0xf81a40fe, 0xc2fcb984,
- 0x27ce9f30, 0x5c6fbe42, 0x027f7535, 0x89eb2b52, 0x72e6fc8b, 0xf34ebcfc,
- 0xdf7fd5a9, 0x17a6b99a, 0x29c173f0, 0xabf60b44, 0x1df595b5, 0x054d6811,
- 0xfeec2f1e, 0xac78152c, 0xb27ff57d, 0xebf81744, 0x51cd4fd8, 0x84222709,
- 0xc6e74b38, 0xfdd01637, 0x5dc5c9a5, 0x8fb17fd4, 0x6d5b17dc, 0x63905ebe,
- 0x8afc6ff7, 0xddc5c1f9, 0x17575f5a, 0x5fb9dbf4, 0x124b4e7d, 0x205380d2,
- 0xbae4da1d, 0xe484fb11, 0x1f417bc1, 0xdd4d569b, 0x6be77944, 0xa2424836,
- 0xf7923336, 0xfcc7f60b, 0x7d8d7ea0, 0x017c15b2, 0x1fc930e9, 0xe523ec5e,
- 0xbcbad584, 0xfb5f75b0, 0xe62ecce4, 0x26cd3ab3, 0x923edbcf, 0x2b4dcc6f,
- 0x9c874f0e, 0x0345f161, 0x75ebc21f, 0x157c1027, 0x97eabe9d, 0x3df0512d,
- 0xda723449, 0xfa71345b, 0x245a10b8, 0x0b8f0bea, 0x4fa21670, 0x7bc7e02c,
- 0x31abd79e, 0x8e89fcdf, 0xd06af03b, 0xf8562f83, 0xeaefd337, 0x63508746,
- 0x46b5ed20, 0xa0d451a3, 0x4beebfa9, 0x540fb6e5, 0x3ed49fd6, 0x2e3d3e06,
- 0xc8cbf7e0, 0xf8c131e9, 0x74b877db, 0xdeabfa02, 0xf52e7a49, 0x4d877e77,
- 0x5957a004, 0x3d50bf69, 0xec2fe1db, 0xcd4be069, 0x5cbc808a, 0xaf7c794b,
- 0xfaf5651d, 0x9792e083, 0x9a91e12e, 0xbb70c59e, 0x9a1ef560, 0x9573fa08,
- 0xdbd721da, 0xc04f970e, 0x2a4b6379, 0xfb5e63b5, 0xa4758f0e, 0x56b16f01,
- 0x9aab37de, 0x5c5b718d, 0xf62a3fe8, 0x436f9e03, 0x534445ae, 0xc28f86bb,
- 0x874c0cfc, 0x3a6143e4, 0x85021b5c, 0xf817770e, 0x14c289f1, 0x77ca8231,
- 0xcf3013a8, 0x1752aef3, 0x958b68f0, 0x9b308776, 0x9af40277, 0x78b8d8b0,
- 0x7a446fcc, 0xabffcf06, 0xcf3c25d8, 0x80bc48af, 0x7af241be, 0xbd0df231,
- 0x7d8655cb, 0x8fbc23e3, 0xfc721d6b, 0x9f2a3da8, 0x43a462a3, 0xbbefdbe7,
- 0xc89c68ca, 0xd024dabe, 0xa89f3183, 0xf00baf61, 0x858b1ce7, 0x3786b3e5,
- 0x2f80d722, 0xd21be518, 0xf819bd25, 0x75609958, 0xae3c7f81, 0x574ae7d3,
- 0x6820a3b1, 0x161eb69d, 0x0ec55e1d, 0xbdbb69c0, 0x97ce10f8, 0x738efa36,
- 0x54d27f73, 0xaa14f407, 0x273f4167, 0x64c768ea, 0x0ee9dfa3, 0x424177c0,
- 0x5bb478e9, 0xc2ac9628, 0x5eb85b7e, 0x3e208115, 0xe39360db, 0x211cb82e,
- 0xc73a4302, 0xe3f8405d, 0xf9a397f6, 0xd653837b, 0xfb92886b, 0x2974cee7,
- 0xd3d4ae2f, 0x83fa7ab5, 0xccc7baf9, 0xfec7cfd7, 0xe4a94b71, 0x53a677ef,
- 0xeb4ad5bf, 0xab268878, 0x80edda92, 0x973a89ef, 0xcd058408, 0xc6758af7,
- 0x38d0408b, 0x3b2ef51d, 0x183e2045, 0x47c66e1f, 0xb9237ae7, 0x125d44fc,
- 0xfefbb1c3, 0xec704c53, 0x04c33fec, 0xcffb2bc7, 0x7513f2e2, 0xffd1df39,
- 0x4ffa6ec0, 0xb3bfcd33, 0x5dfc7edf, 0x82fad2ec, 0x22eddcbf, 0xd374c07e,
- 0xbb2676ca, 0x7606fda2, 0x9871f12f, 0x95f7dc80, 0x0576cb53, 0xe96d87f1,
- 0x0b9f5d76, 0xfadf80a4, 0x6b4e3ac4, 0x8f1a5d77, 0x0be26ef6, 0xcbd0e76c,
- 0xcf1b456b, 0xfa02fc13, 0xbab648bd, 0x96977cb9, 0x98c8bd0d, 0xf33c8747,
- 0x859f48bb, 0x9ed841f6, 0x1f6347bf, 0x4db6b45f, 0xa9aa7d86, 0xde088d59,
- 0xfdf407d7, 0x17cfb631, 0xd5d7b079, 0xbdf11da0, 0x9c5dee9f, 0x84d4f80d,
- 0xde61e5b5, 0x2dfef7fb, 0x57c8e70f, 0xc5f7167b, 0x9f54adf7, 0x5b7b0fe5,
- 0xbfa8278d, 0xb3e5c27e, 0x9b4ce88c, 0xfa1ffdf5, 0xfa9eeb7d, 0x36c7985e,
- 0x2e483dd8, 0x56f659ac, 0xb078f1c6, 0xe083ef21, 0x16f8825f, 0xa6bb43eb,
- 0xdf2063a9, 0x0f32487d, 0x96ee87e5, 0x3ed0c372, 0x83496fc2, 0x2ce1f7dc,
- 0x619a89f0, 0xe1541776, 0x9616fcf0, 0x3987c3b7, 0x9f9f385c, 0xebc193ed,
- 0xc84e43b3, 0x78a2fb40, 0xf154e7a6, 0x1b6dc9af, 0xe04ff642, 0x68db350f,
- 0x75b56abc, 0xf78538f2, 0xa9f031d1, 0x78bfb79a, 0x135fd747, 0x8c5a9f81,
- 0x5f78f04b, 0x432127ef, 0x9a7a893b, 0xabbef5a3, 0x9b8cdea8, 0x1fa15393,
- 0x99fae895, 0x19404898, 0x1068fcc9, 0x9e5720ec, 0x7a0f52db, 0xc034d14d,
- 0xf0ec97c1, 0x981afce0, 0x71c91c22, 0xf4fed0d8, 0x57ee34a9, 0x2ec316e9,
- 0x03de60aa, 0xdf3d35f4, 0x2c6969ab, 0x38fe939f, 0x3b3fd1d0, 0xfbc325ae,
- 0xa30bf077, 0xdf3787fe, 0xe2eb483a, 0x79e430dc, 0x36e9bdbb, 0x3aadb3cc,
- 0x9847f592, 0xc9eed0f3, 0x2a02c39b, 0xc8b68aec, 0x3fe7d0d5, 0xb07b988a,
- 0xfee3c107, 0x83222d28, 0x799acdda, 0x95e42ac3, 0xa5eef1fd, 0xd692e7a0,
- 0xd3e7c0e1, 0x83262d4e, 0x6872afc6, 0x8969137d, 0xd968fbe7, 0x8be43831,
- 0x449e25e3, 0x2ee2a0f1, 0x53e72fe7, 0x0ff1c8a2, 0xe8496947, 0xf2d2c4a7,
- 0x66f855c4, 0x837b616d, 0xfdc1e868, 0x8a8bb79c, 0x037fe4ae, 0x75f4470e,
- 0x6b89b3ec, 0xf6fad32f, 0xd4f18dad, 0xefcb7cd3, 0x96b7399e, 0xe296f9d2,
- 0x9a6a80c4, 0x55d61677, 0x9be92be5, 0x79f3f24c, 0x65ef3e9b, 0xaeadbcfa,
- 0x1cfde0ac, 0x437aef3a, 0xc285f95e, 0x50ff20fa, 0xac5f15fe, 0x87ca5eff,
- 0x307d2e59, 0x20d6e70d, 0x3649db0b, 0x22ded384, 0x7d5df23d, 0xbed38f9e,
- 0xf7f1c473, 0x149ef8d5, 0x3d27db2e, 0x7ec3f16c, 0x37763c50, 0x9ac9e9e3,
- 0x634a8f48, 0x1db70895, 0xf0995072, 0xd9fc5cb2, 0x69edbf98, 0x661575a5,
- 0x6e01d768, 0xa92de2f3, 0xb43cf01f, 0x6f205381, 0xf8eb928d, 0xd7937916,
- 0x6cb85531, 0x3589942c, 0x531fc816, 0xf329725d, 0xa63fb915, 0xe30daf09,
- 0xd71a10cd, 0xbb05c3fb, 0x1fc4fa17, 0xbcd10ba0, 0x7f1f0a67, 0x9cfc2d9f,
- 0x5c022ade, 0x95a2c7ff, 0x89bc06f3, 0x4825e63e, 0x53d938fa, 0x8cdff865,
- 0x9117bf79, 0xad1967d7, 0xd923ca63, 0xad5fac99, 0xf9f0c1eb, 0xd14f79ae,
- 0xeff686e9, 0xfd83f43c, 0x99fa9d3b, 0xfec8637a, 0xe061ec2d, 0xf6dbf333,
- 0x877b4b51, 0x4c9914fe, 0x475eb870, 0xc5def5e9, 0xa9153fac, 0xf847c291,
- 0xfaa51969, 0xf21c7721, 0xa0484f2e, 0xb9fddc75, 0xb77e83d4, 0x843dbc5c,
- 0x46377fca, 0xd2dcf515, 0x64d4f2cb, 0xbdc99fbd, 0x9d869fc7, 0x2408b0f5,
- 0x17b9a50c, 0x8f5ed65d, 0x564ef9a1, 0x52c435b7, 0xa4de84f9, 0xbdf104c7,
- 0x5bb6121b, 0xd8ddd7a1, 0x627dfccf, 0x99df59ae, 0xc0551a24, 0x7350f279,
- 0x0f807dbd, 0x0c8ad7d1, 0x0188b7a9, 0xdfee8062, 0x47fbb963, 0x13ed1f7a,
- 0x0be1d92f, 0xbb433579, 0x3a5c7007, 0x18b9b3e9, 0x7ae55857, 0xd951de6a,
- 0xe48c779e, 0xdf9d2f2c, 0x84e8ebc7, 0x08f29308, 0x6e48a7f2, 0xcea67a40,
- 0x3a39e9cd, 0xa17e51e7, 0x67eb23ce, 0x7d803f14, 0x73faba56, 0xb772f02b,
- 0x6ef9c253, 0x761faa67, 0xc6a68ab5, 0xe55e98f1, 0x4883a6ae, 0xe3c503cb,
- 0x382ecc71, 0xd220e4b4, 0xb6f43bbb, 0x5fdd0e25, 0x5dbff3c0, 0xa3dbd3a7,
- 0x8834dea6, 0xbbedc9f6, 0xf6ebdfa5, 0x4da7533e, 0xc6de404a, 0xa8e8eef9,
- 0x3422b2fa, 0xa8cf22da, 0xb758cdde, 0xc1e8f9b7, 0xc9e75a78, 0xff3c11ba,
- 0x9e5e75d3, 0x09bad9ff, 0xa33dfe9c, 0x27ae39f8, 0x6c79673e, 0xd6a3b6d2,
- 0xe45faa14, 0xb7d8bc55, 0xdf857ad7, 0xdeb1744f, 0xf581cf26, 0x1f600e74,
- 0xf534198f, 0xe9303bf1, 0xda276d0c, 0x5171b8cf, 0x3c99c611, 0x7a8ac4a2,
- 0x2216bf33, 0x4e93ad3e, 0x8dee8bbf, 0xf8eb57f5, 0x6157bf3b, 0x1bdf9e78,
- 0xdf6cf0cb, 0xf9031191, 0x8ccee960, 0x6f89489e, 0x046f7a1a, 0xd97ed7e0,
- 0xff6df3c2, 0x8ef59c28, 0x774bf6d0, 0x7a89ec0e, 0x22df0967, 0xfb3cde48,
- 0x83b87ffc, 0x71b395cf, 0x027d5f4d, 0xc957f6fe, 0x39b248df, 0x5ff818f1,
- 0xd01e5eef, 0xce5d05cb, 0x02233d26, 0x6e8d5fe7, 0x427f0457, 0xb4b86cfe,
- 0x217f0ee7, 0x17f62c65, 0x9c1373c6, 0xb9191cc3, 0x7f7087c7, 0xfd467e47,
- 0x9258fcbd, 0xb9effa07, 0x63a48fed, 0xf34dadfc, 0xfa8c793f, 0xf8b7ef3f,
- 0x9d4e746c, 0x5e174d17, 0x2a7e1f05, 0x777bed92, 0x9c2f342b, 0x717b9bc3,
- 0x86b1473e, 0x2c39c32f, 0x73cfbcfc, 0x1975b714, 0x17aaadf1, 0x7a05ed1f,
- 0x30608d7c, 0x5b5fca82, 0xed7cc11b, 0xc8e79b35, 0xb8f7f432, 0xfbe9efec,
- 0x0bb63cef, 0x05d57de9, 0x65fa5277, 0xa1e31c46, 0x034581fc, 0x79ce9ed0,
- 0x3dfd4c91, 0x80128af7, 0xbad06abf, 0x69922b7d, 0x1c37837e, 0x34a2f4b5,
- 0x1ea529ff, 0x373ec0e9, 0xf9fd821e, 0x6e6e196f, 0x9a5b643f, 0xd96d829a,
- 0x75c9ffcb, 0xe59bfe7c, 0x9f75dc82, 0x3a25ed8f, 0x4a0183e5, 0x348d99d3,
- 0x8fd4b0d7, 0x6386340a, 0x6767af23, 0x6ff7b4f3, 0x49075815, 0x8977981e,
- 0x91e7c3dd, 0x7811b7df, 0x78e5af3e, 0xf62bbf58, 0x3b7a0a3d, 0x707a25af,
- 0xfa4cbd3e, 0x7fa8d5fc, 0x7cebcac4, 0xa2f7a9e5, 0x2189df61, 0xbf09d93d,
- 0x78db7e48, 0xe3eeafd4, 0xf587f016, 0x09fae279, 0x8ecd4f80, 0x9fb91b9d,
- 0xfa07872a, 0x4bcec56e, 0x2f205307, 0x993c20de, 0x321dc7a0, 0xaf42abff,
- 0x56a5a547, 0xe652fc6c, 0x5f398a5b, 0xfc27da4c, 0xca4ca2fe, 0xe7e88f49,
- 0x63cd68a0, 0xee24c97e, 0xafd7c4ee, 0xebe518a8, 0xb0c97cd3, 0x27e71b6f,
- 0xfda97b9d, 0xb2ec65b0, 0x5bd8cb7d, 0xdf2e1953, 0xebb3dcf3, 0xdfd197e7,
- 0x73e17623, 0xdf303f52, 0xc1be9ec0, 0xcdebcf2e, 0x2f4067c4, 0xe34d79c6,
- 0xed93f5e6, 0x29afe0bd, 0x076832aa, 0x91e523c1, 0xbe379630, 0x62b3f8ef,
- 0x6df9f156, 0xe1b55bc8, 0xd9f22f92, 0x885fed41, 0x37eeaed2, 0x7932760c,
- 0x3bab0bde, 0xe3c8f217, 0xfa6bde51, 0x96d5bcb1, 0x39d0358a, 0x53e61d7a,
- 0x95fc92a3, 0x457f2411, 0x73af7dc6, 0x2de51034, 0x5beffb42, 0xcd046c7f,
- 0xf1290633, 0x86a468ef, 0x485a45de, 0x7d39fc97, 0xf3f8135b, 0x3f926143,
- 0xbe610d47, 0x7433ac64, 0x07c4039c, 0x6f3be234, 0x11a339d0, 0x3917183f,
- 0x7d78cac6, 0x907552dd, 0x3922e5ce, 0x1ada0802, 0xdef3943b, 0x61638228,
- 0x2eb42aa4, 0x252347f4, 0x3ac7cdbc, 0x984427c7, 0xc42515ea, 0xbf8fb1da,
- 0x1d55faef, 0x3cb86a4f, 0x8370d4bf, 0x7413babf, 0xfac87dbf, 0x776f7ae5,
- 0x3abe630e, 0xeb7ef956, 0xdf15b22e, 0x8b8f3c09, 0x7373e7cc, 0x2394e45c,
- 0xd475e09a, 0x7ae87be1, 0x1c25d743, 0xfa8e4fdf, 0x167c2289, 0xedcfc7ec,
- 0xb66b776c, 0x5bf73eb5, 0xa2f36b82, 0x47ec0f5c, 0x70bed32f, 0xb54e9f80,
- 0x0cdb9cb3, 0x37ea92d9, 0x5c7170f7, 0xdfba6bcb, 0x6f5b37dc, 0xbe7c14ef,
- 0xc5eecf34, 0x615ef47e, 0x48ec1034, 0xd26fd2f5, 0x16f25b6c, 0xe5e6ebce,
- 0x819a1e29, 0x69efc150, 0x97e47ccb, 0x095ebcfc, 0x817f0adc, 0x40bb73ef,
- 0xfeb175fd, 0x5f94e9d5, 0x9e0c8bf7, 0x8fa447cf, 0x8abc62d7, 0xeb5be670,
- 0x71c9bd62, 0xff979f04, 0xb279f2a1, 0x91f29f2e, 0x6ed9d7cc, 0x378a6eb3,
- 0x04ad7e19, 0x36eb6f1d, 0xb05ef2ca, 0x4d3ca293, 0x26c4ffb6, 0xd7a2dfeb,
- 0xfbf1d04b, 0xb4a74eb1, 0x683f99ff, 0xa0ac2393, 0x95fb77ff, 0x46fbc6be,
- 0x17e19378, 0x933cac7a, 0x54b7986d, 0xf4c690de, 0x66d3dba4, 0xe8dcfce9,
- 0xc31c0d17, 0x9fcb4f21, 0x3b37f3d9, 0x2a33df41, 0x1f21479c, 0x22b1547e,
- 0x0cfd7a0a, 0x21840d4d, 0x917a6abe, 0x4bae43b7, 0x395eb8c7, 0x1fa1b96e,
- 0xdf00ca06, 0x710e6dbd, 0x81ffcb2f, 0x96fac121, 0xfa45e781, 0x1a6eadbe,
- 0x7eb060f3, 0xfe27695d, 0x72e51833, 0x6a45573f, 0xd57d07bf, 0xc1e1baee,
- 0x54fbbd60, 0xbc7943f9, 0xcf71f4ef, 0x3c1f79d5, 0x6f39099e, 0xb8c6a702,
- 0xf011fa1d, 0xd5f6fd49, 0xefda73cf, 0xdaf00b3e, 0x92fa94e4, 0x85e3edb5,
- 0x359faf94, 0x09f7cf80, 0xd85e1d53, 0x8477daf5, 0xadaf61f9, 0xc5ee159f,
- 0x44f7eaba, 0x985761f9, 0xd21befa7, 0x6fbbf8bb, 0xade98dbb, 0x667feeca,
- 0xdaabb50b, 0x89e99fdb, 0x96ed95e8, 0x642357be, 0x6d37b479, 0xf79450e5,
- 0xcd79fa64, 0xf2e18ee6, 0xe5c15537, 0x58ac81e1, 0x539b7782, 0x1375853b,
- 0xbcfdb2bd, 0x1fbf2eca, 0xfa12e9d1, 0x96fffb25, 0x42bf7144, 0x8f3f6bcf,
- 0x584f7d67, 0x91f3c9bd, 0xaf207dbf, 0x7dcbb347, 0x7ea46a21, 0xe725c478,
- 0x9e39a475, 0x8f4185f7, 0xdcb78a47, 0xef809593, 0xfcd2af24, 0x0d4cb2fe,
- 0xd06e1fc0, 0xf2f5329f, 0xbb5157db, 0xd9555f4f, 0xd7e7336f, 0xfbe30f8b,
- 0x13d5159c, 0x6bbcad39, 0xf5cb9f32, 0xa2eea71f, 0xa7a984f2, 0xe06bbfd8,
- 0xd9954e7f, 0xe9989a9f, 0xdf813355, 0x83f6ff5c, 0xd9e1ff54, 0xaf001627,
- 0x473533c3, 0xf6dbec26, 0x4cff97d6, 0xfe5d6df3, 0x36a3d627, 0xf8116b44,
- 0xd3f7717e, 0xc566bf5c, 0x7e802cff, 0x74956350, 0xb5db9c63, 0x91bf3d3a,
- 0xffa2c5a9, 0x63bf15aa, 0xb722223d, 0xbbd7f245, 0x3a3f1fbe, 0x65f9bcd3,
- 0x0e2dda85, 0x54e1ae6f, 0xfce1e7f5, 0xa204ab3b, 0x2b860c95, 0x5ce775eb,
- 0x47e06881, 0x72b948b3, 0xbf10d6f1, 0xa8925031, 0xdda88bdb, 0x8f5526e2,
- 0x41dbf457, 0x17f5a1a7, 0xf7ae77d3, 0x8a57bf3d, 0x763df926, 0x30d7fdd7,
- 0xfe0045fe, 0x64cf33ae, 0x9c3d026e, 0x5674f9df, 0x34369fb0, 0x72be72bd,
- 0x7df4e7fd, 0xd8be8e73, 0xc2db6f40, 0x0b85f64c, 0xf4eb24cf, 0xc2e9e926,
- 0xe7ecd933, 0xd9f7d44e, 0x0967c505, 0x085fbb47, 0x9e10678e, 0x971ce1a6,
- 0x0e1a6de3, 0x9d61fbb9, 0x6f8e2e2f, 0x67be0e1a, 0x68e141f0, 0x41bb63ca,
- 0xf41e534e, 0x8a7f8364, 0xfe2ca6e2, 0x42ca6fee, 0xd22d97fb, 0xa7cc630e,
- 0x8e14b9f2, 0xf0b5a27b, 0x6e7caefe, 0x8de426e0, 0x929dea71, 0x253bd4ef,
- 0xb75d097f, 0xe8ed2996, 0x1ee64fa4, 0x3ea4b3a7, 0x5c82f496, 0xde6593e4,
- 0x370bf329, 0x6fe1d894, 0xbcc9b7af, 0xfd897d6b, 0x35f7e618, 0x4fc4b569,
- 0xc5bf7473, 0xdda97f02, 0xfafefb0b, 0x3f1ce1e5, 0xcf3edb31, 0x7af6694b,
- 0x035c69bb, 0xe6fdfd0f, 0xf9f48bef, 0x0b890df4, 0xedb6a5ea, 0xf639c30b,
- 0x8e32e8a4, 0xb4a64960, 0x6cfb3ee3, 0xaa917c47, 0x6dc2dbeb, 0xea5ba1d0,
- 0x8fd78c1b, 0xef5e06ed, 0x2ff9a148, 0x5ea5e3d6, 0xfab848b6, 0xe37c959e,
- 0x052d7ce5, 0xc005d5e7, 0x2c5ce71d, 0xef2173e5, 0x7919bc49, 0xf0a15f03,
- 0x82f1f15d, 0x9f95d814, 0xc7f694c8, 0x8f2c7c50, 0xe513de1a, 0xd4cf5c06,
- 0xdc00ca1d, 0xa89d758d, 0x68e97af3, 0xafbfb4eb, 0x8c6877cf, 0x30477c8f,
- 0x1d6fd77d, 0x20248872, 0xd5ab6e71, 0x5bd42583, 0xbf43f7fd, 0x36aadfa8,
- 0x3b9704f9, 0x91739780, 0xbd41dffb, 0x0b621b05, 0xed180fa0, 0xf22fae17,
- 0x7bcd0796, 0x5e3356e0, 0xf3993506, 0xf3997783, 0x0d06715b, 0xe5dbe7fb,
- 0x21f9cc07, 0x93f9cc87, 0x3371dc1f, 0xea854fb6, 0xbe855fbb, 0x87f1e7f3,
- 0x7a9f4e70, 0xe06895f9, 0xcb5ff16b, 0x0b8f420f, 0x3c21678d, 0x7c73d02a,
- 0x97a6145b, 0xba5ae22b, 0xdc4643e1, 0x30627606, 0xdf0a54dd, 0x95da6b41,
- 0xa68acff5, 0x6744bd9b, 0xcfdecb55, 0xecb37a90, 0x5ad36477, 0xd0cee43b,
- 0x3be3bb71, 0xc6ebd222, 0x21192a3e, 0x365eaecb, 0xfe8a7c4e, 0x1e37bcd6,
- 0x2bf258f4, 0x929be585, 0x075fb297, 0x3edd1cdd, 0x6f4e46fb, 0x30f0c09e,
- 0x9b0b92ec, 0xe5144095, 0x8744235d, 0x8bf11f7f, 0xf1210da5, 0xe2426b9f,
- 0xcb99d682, 0xf7daee17, 0x504710ff, 0xe38278e1, 0x678cae2e, 0x5e801ff4,
- 0xb04a7959, 0xa9f2aa7d, 0xe5ccc26f, 0xf5f35d72, 0xade71875, 0xf1cb5df0,
- 0xaacb577b, 0xa3fe38e2, 0x4ba8e973, 0xcb73853b, 0x5eaf7738, 0xf29551b7,
- 0xfd84b7bc, 0x8e7691c8, 0x8876ac8b, 0xebcd0440, 0xebdd9450, 0xd697efa2,
- 0xb2bcb147, 0xe85ce480, 0x270a948b, 0x627a4dc7, 0xbbc4eed0, 0xd565cb2a,
- 0xd51e12f1, 0xb0fc51bf, 0xa8c3571d, 0x3293fc8b, 0xd80448bf, 0xf23a0bbe,
- 0xf803ad06, 0x468bce0b, 0x59565fa9, 0x9f00fb03, 0xab68738e, 0xad155eb9,
- 0xc838a3f3, 0x35efe67b, 0xd7eb8da2, 0x2c26faee, 0x3d907bf8, 0x435ef59a,
- 0xf97556ff, 0x3865fd4a, 0x20744fcb, 0x6cbe8384, 0xeebedcba, 0x6823921e,
- 0x7b0d2b7d, 0xdf295af8, 0x9e51b2dd, 0x679f2463, 0xd6eb4e01, 0xef867c92,
- 0xce206fa4, 0xf70a2c44, 0xea5ef94b, 0x6766eb0b, 0xf2f45cb1, 0x400a5e3f,
- 0x487b691f, 0xbad2bb61, 0xbaefd97c, 0x3973fafb, 0xe3c2a7f8, 0xb61cb184,
- 0xde518a6e, 0x4f91f587, 0xc864c530, 0x1ef7faf9, 0x4bdefe6e, 0x3ec166f5,
- 0xb2741e22, 0xfb90c47d, 0x2ebeb90d, 0x1ac9cb56, 0x75feb9d6, 0xf0516db1,
- 0xf88a89bb, 0x6cb725ef, 0x36e3cfd6, 0x2afc3f5a, 0x83e295c7, 0xf5198ff0,
- 0x73c96646, 0xef58f865, 0xfb1ebd16, 0x532dca5f, 0xe68ebdee, 0xc5b0fe55,
- 0x81a17b0d, 0x66f5e107, 0xd7c70e01, 0x77400b3a, 0x7b4ac7c3, 0xc97c91d9,
- 0x0a8623e7, 0xab1a378e, 0xcb363bf7, 0xc2934a62, 0x9fa91e89, 0x1ed245e3,
- 0x98b4351f, 0x132496ed, 0x6e2aebcc, 0x4fdeb265, 0xf7f8bdb9, 0x4f98bba3,
- 0x4a145d07, 0x6df8fbf9, 0x2f3926ca, 0x0e27c72f, 0xf6c9c07f, 0x39fae3ce,
- 0xe881e064, 0x0fcb1868, 0x0d8b5f3a, 0xa0b59ba1, 0xa0879c07, 0x6e982507,
- 0x8b7174cc, 0xee2be122, 0xbaf7f293, 0xe8379958, 0xf13ff482, 0x229ba0bf,
- 0x4eeff0c1, 0xdbd6340f, 0x74481e9d, 0xd07408b0, 0x0e842f51, 0xec3fd584,
- 0xa542fcdb, 0x2b876223, 0xab148284, 0x17ce21f0, 0xebc32467, 0xb11fab1e,
- 0x12adbd78, 0x92ac7d2f, 0xf1b4e8ee, 0x7d701785, 0x4b7de22f, 0xbc285c1e,
- 0x4524bf54, 0x1fad7db0, 0x713155c9, 0x45204edc, 0xbb0a8e58, 0x5f68a513,
- 0x2ffb2312, 0xfe3829e9, 0x5af3fa8e, 0x36e674e2, 0xc15efe1c, 0x47da0572,
- 0x9f7b7017, 0x5af7b645, 0x219bed29, 0x95b698f5, 0x5cbf1c61, 0x2c9f7772,
- 0xb1c4c9d0, 0xa2393a66, 0xde9195d3, 0x8dd6ed94, 0xf0249e75, 0xfe86d283,
- 0x3bd4de7c, 0x0277ab8b, 0xb047cf9f, 0xeab259fc, 0x618693c7, 0x7bc42f7e,
- 0x9333c280, 0xa83fb3b7, 0x4ff661b4, 0xb4be843e, 0x2bdfc9d5, 0x59f5b5b2,
- 0xf715ff90, 0xa1f49ddc, 0x7b01c674, 0x9ad7b512, 0x957f9ca6, 0xedbec9d2,
- 0x989e40ef, 0xfae55d3c, 0x3fb48593, 0xce39068b, 0xd6e7df24, 0xd26fea24,
- 0x69c38528, 0xa95d3a8e, 0xa40fc1b7, 0x2ca9f7e3, 0xe47f9745, 0x5592813d,
- 0x73d2b27d, 0xc9213fe1, 0xfd390bb8, 0x18fea353, 0xa5e40365, 0xfee4e3be,
- 0x1fa3ea33, 0x4b3a7bf4, 0xd5bf55ca, 0x09e462e1, 0x7cbf5cae, 0x8cd1d875,
- 0x40b6a468, 0xfde9a536, 0x7584bec7, 0xe3174c4e, 0x77ee03d7, 0xcf1362aa,
- 0xf984adb7, 0x1b965442, 0x4291abf4, 0xd6e3facd, 0x8f27ccfe, 0x7a3b698e,
- 0x6e8fe537, 0x8ced241e, 0xbe617dba, 0x707cb04b, 0x77e48c74, 0x98239b6d,
- 0x5ab88ffe, 0x3da4e2a3, 0x650ded8e, 0xb67c493a, 0xf87efeac, 0xed22cbb9,
- 0xcc7e7147, 0xc71a687f, 0x53ad9427, 0x07b86103, 0x6f6cc6b0, 0xded48aa8,
- 0xb5087ec6, 0x07da841b, 0xa3a03340, 0xd30a35f2, 0x8f7adf61, 0x9cf9993d,
- 0xcafac2e2, 0x70fd0323, 0x9c7b940e, 0x857cc71c, 0x826be0fd, 0xb9d870fb,
- 0xb5890705, 0x009f6b67, 0x258d254e, 0xe446efac, 0xfabfcc6a, 0xec1704aa,
- 0x26fe9d17, 0xbe0b5ec2, 0xc64d6d64, 0x9655fcbe, 0x3130f19b, 0xc91595ce,
- 0xfbe4ed74, 0xae6d4711, 0xe8efcc2c, 0xe705a74a, 0x9215c4ed, 0x39df69be,
- 0x1ee18f70, 0x3f0708ab, 0xfb259ad8, 0x5adcb39d, 0xbdf291bc, 0x151ac21d,
- 0x67cafa07, 0x5fd85efa, 0x75e62dfb, 0x046217ea, 0x35b289e4, 0x74bce56b,
- 0x96d610fa, 0xe71a78c2, 0x02b4e6d4, 0xe43a01d8, 0xdb63fedb, 0xba0ec701,
- 0x3d30ae98, 0xc10e7ad0, 0xbfde9c8e, 0xe9ca32f4, 0xcbd03efb, 0x7e81b1c4,
- 0x522f1b88, 0xb6be38ab, 0xe078493d, 0x6d176c77, 0x93b48f2c, 0x67be023c,
- 0x9f8319f0, 0x1d785d10, 0xdef89d89, 0x22534752, 0xceb5be1e, 0x75b3e9c1,
- 0x7825612e, 0xe24bab6f, 0x6e750bfc, 0x72ea9b4e, 0x758bfbf8, 0xa8efce1e,
- 0x97f9c11b, 0xdf9cbceb, 0xd3813755, 0xf98aeb57, 0x08afc1bb, 0x0c97cc3e,
- 0x27f063be, 0x3e0cbe83, 0x73574a15, 0x17b8cc09, 0x1f99ed41, 0xeb107c1a,
- 0xf27414b0, 0xe9cf0327, 0x092fb14a, 0xceb450fc, 0x5228ff06, 0x0aff3dcf,
- 0x22bdb9c1, 0xed22ed92, 0xf6c1f242, 0x079f0748, 0x0bb176a9, 0xdbfa89f6,
- 0x0eef47bc, 0xad6f873a, 0x88358450, 0xc4bc7f8e, 0x7441ac29, 0xac596f3c,
- 0xd9673f29, 0xa4f46ffb, 0xd18ddffe, 0x1e69b372, 0xe2797e47, 0xf7d13ff1,
- 0x4cf2fcdf, 0xf34ef026, 0xc608fcd8, 0x9f5c2bbd, 0xd79cab47, 0x9796765d,
- 0x7d4b86fa, 0xd4b86fab, 0x08e3f0b7, 0xa23dcf8a, 0x2d24a3e3, 0xb1a79df6,
- 0x9baeec6f, 0xb44ec047, 0xfa4bde52, 0xf2a3f804, 0x2bf8e8bf, 0x70c6165d,
- 0xf7d06d2d, 0x36dc706b, 0xb258f5c1, 0xf14ef960, 0xd7bf010a, 0x03d85fb1,
- 0x63882b24, 0x40afc38a, 0x6be52276, 0xab98ec0e, 0xe411f77f, 0x21d96576,
- 0x4735b396, 0x087fc724, 0x705ced9f, 0x83b2ca7f, 0xf6b44f5c, 0x466fc536,
- 0xc1daf50c, 0xc0e34037, 0x7ece695f, 0x1a2efd81, 0x547fbe15, 0x5f2f7fae,
- 0xa2e298ad, 0xf2ab6467, 0x959645de, 0x4259f3d3, 0xf91a473f, 0x96e832bc,
- 0x61c708f8, 0xdbe63796, 0xe7f10417, 0x597bfd52, 0xa714c58e, 0x9d967f79,
- 0xcd8f39fb, 0x9bdefd49, 0xcf9f6e93, 0xf7cdcffc, 0xa5fa8c05, 0x60ab0539,
- 0x835d2e4f, 0xf6cea6a8, 0x7d56d925, 0x7fa92e5e, 0x8b5ce839, 0x2ea2f8e2,
- 0x9e4307cf, 0x475f8539, 0xef59fcf2, 0xb9e17caa, 0xac8fe017, 0x9f1873fc,
- 0x75839553, 0x7fae4afb, 0x839634f8, 0x70ca91bc, 0xff12e1c8, 0x35fdcf85,
- 0xb55d711a, 0x97bda43b, 0x6b48a3d2, 0xfb60aaee, 0xf6878d5e, 0xadf81c49,
- 0xfaffefd9, 0xfbe67f0b, 0x14b0849d, 0xe3986e3d, 0x7c766ad4, 0xb06bf1ca,
- 0x7286f9c7, 0x1d5f1c7f, 0xf956beda, 0x4257f59a, 0x68a7c32c, 0x3c8997cf,
- 0x12979d8f, 0xf76ae7c1, 0x2aec4cac, 0x1fb4288e, 0xb0c1ce23, 0x358ad5ff,
- 0x59cfc39f, 0x9384d77b, 0xff65de92, 0xca1eeda1, 0x31384a8e, 0xeec62050,
- 0x5893b62a, 0x2c9fc705, 0xed38edd5, 0x63f64cfe, 0xd7772777, 0x2446a7ae,
- 0xdd5bb592, 0xbeb38831, 0xae84c428, 0xb649f4f0, 0xd3cf6b94, 0xfb3f823e,
- 0xe59536e2, 0xa2db8bca, 0x6cd43f78, 0xe220f07b, 0x529e6b04, 0x2d58edd8,
- 0xafce385a, 0x1c2a8766, 0xec1de7c1, 0xcfddf147, 0x5173f173, 0x8b5f404b,
- 0x66ef149a, 0xc3bb4f9a, 0x6823d31d, 0xbe80af3e, 0x87173488, 0xff470d35,
- 0x079ffcc6, 0x37920b7f, 0xc83f3517, 0xef548df1, 0xbf37cb02, 0x3c38e08d,
- 0xc1dec93a, 0x186ecf3c, 0x45f5fec2, 0x586bdb4d, 0xe116d83e, 0x8ce9e982,
- 0xe40f7ccd, 0x81de3e80, 0x9c8f296c, 0x67d1edd5, 0x1f59505f, 0x2fb13cc2,
- 0xb871e8cf, 0xf537bb46, 0x4b666f76, 0x5b26a7f9, 0xfea34fee, 0xd1a3a6a2,
- 0xc9fea8fd, 0xfa73ef5d, 0x166fbebe, 0x3df0b645, 0x223b93cf, 0xc9e09ef8,
- 0xfe39ff1d, 0x7cef1a35, 0x250498d3, 0xc89d9f68, 0xba7dc9b6, 0xf32fc641,
- 0x13d61725, 0x673d789a, 0xac28a5b7, 0xa4de032f, 0xf1dd9fb7, 0x3643df12,
- 0x1c1febe4, 0xb14b382f, 0x18a3dc86, 0x8d72083d, 0xd7bf55a3, 0x63dba6d1,
- 0xaffa6ffe, 0x5927bfd1, 0xe471f58a, 0xc4610d3d, 0xbd64b86f, 0x27b73522,
- 0xc1dcddf6, 0x97b899ee, 0x7192de2d, 0xfbb7a297, 0x737fe811, 0xbb678ddf,
- 0xbb9b52cb, 0x1c5ff227, 0xe0958526, 0xce887733, 0x875a9257, 0x347bbec1,
- 0x8615ca4d, 0xb56aad3f, 0xbf04bc22, 0x3e67445e, 0xd0aafde4, 0x49c90760,
- 0x563d7c67, 0x71daf161, 0x99d9463e, 0x3bb7ea2e, 0x75bec137, 0xec7c2ec4,
- 0x29d17b7f, 0xd2e927fd, 0xf618f20f, 0x7155a517, 0xd878ac81, 0xa9ba74f1,
- 0x41e54a9a, 0x29b553f4, 0xea390590, 0x2bda5d9c, 0xa9fd0e51, 0xabd640aa,
- 0xfd14e9d7, 0x69a3dfa0, 0xf72c0bae, 0xd0128cee, 0x44af2c3f, 0xd3c8bb49,
- 0x41614dce, 0x1cbf76e7, 0xc777118b, 0x66df4afe, 0x0bcc3f39, 0x7b22fcf2,
- 0x5de41663, 0xd145dc63, 0x39de3c8d, 0xe145bc7d, 0xa39fd28d, 0x3ea211c7,
- 0xec136f8f, 0x267b6a77, 0x33e6e58c, 0x632f2dc9, 0xf4cf33fc, 0xa387b8e7,
- 0xbb05fe69, 0xf1c9dcb8, 0x86cf95e7, 0xd3df3005, 0x5db144cf, 0xca4db4eb,
- 0x12a3a763, 0x143b1e59, 0xf65cf0f5, 0xa6153d63, 0x5a742ec0, 0x9424f611,
- 0xf2c1ee6f, 0x32dd6540, 0x1254d7f6, 0x4b1c817b, 0x7fc804e9, 0x67f737a7,
- 0x37e9d17b, 0x415cbe55, 0xbbe357df, 0xfee71a26, 0x0880f58c, 0x799e23b6,
- 0x83fd6ff6, 0x5a463bfd, 0x3ed994f9, 0x5183d066, 0xf923945e, 0xd48e5160,
- 0x71c86e53, 0xd11d5a71, 0xaf3a70f4, 0xc207f253, 0xb481eb03, 0xef61131f,
- 0x3bb4d23f, 0x9c048951, 0x09ff5903, 0xfa956fb8, 0x366d99d6, 0xbe5553f6,
- 0x3b65e512, 0xf157ddd4, 0x554ac97d, 0x1695e3ca, 0xf950df79, 0xffb656e5,
- 0x2ce33fd4, 0xde083c00, 0x6db6dfac, 0xe471f556, 0xf4b7a7b8, 0x808d7e91,
- 0x10797f9e, 0xc62635fb, 0x59537989, 0x0790dace, 0x2a7a5eb8, 0x69fee382,
- 0x34e22f1c, 0x73f67f2a, 0x0598cf09, 0xc1d027ac, 0x4ab9fccd, 0x77d5cfe7,
- 0xfb83135f, 0x955de210, 0xb25c79ef, 0xff827a7a, 0xd1ebc286, 0xbf3f9d1c,
- 0x83f338fc, 0x8837da2a, 0xfbac5b0f, 0xab3f1713, 0x78b95cb0, 0x308f35d5,
- 0x26c77ddf, 0x5ce22f70, 0xc1d183d3, 0x91cfa8f8, 0xbdb3b0fc, 0xa62feb87,
- 0x5bfdb2fa, 0x2d9f3cd1, 0x13e60f36, 0xddefc78a, 0x07f559fe, 0x226cafb5,
- 0xcaef22f9, 0x2d125ff5, 0xf833fd3f, 0xfb2736cb, 0x7cff0951, 0xadacea3f,
- 0x7fd60169, 0xf32779f6, 0x72b1b39d, 0xf3a49fdf, 0xf98d97d4, 0xb66bf4dc,
- 0x9a61fccb, 0xd0b439c0, 0x98d7ee6f, 0x9b1cead7, 0x4f78b7a4, 0xd544fc0c,
- 0x47f40f84, 0xb711f9f8, 0xedc6d77f, 0x40b3d743, 0x4fb1d76f, 0xba608f9f,
- 0xe24bdb39, 0xd90bece5, 0x8d1d9e7c, 0xf34ef495, 0x74de854d, 0xb8a65636,
- 0xa87a0499, 0x387a4974, 0xed89a63b, 0xed956702, 0xc9b51e9c, 0x74cb9576,
- 0x5fd13b7f, 0xb407e812, 0x63aabb09, 0x19e40b4d, 0x05e1f9f0, 0x4f70069c,
- 0x0e8ed43b, 0xd7f9c53a, 0xe333efaa, 0xebf6051d, 0x89a79fb0, 0xba6bc7ef,
- 0xedb5593c, 0xf0257f4a, 0x614db554, 0x197fda7f, 0x13acd0fd, 0xd1003f0c,
- 0xc29f62e5, 0x6e2c22ef, 0xfb116db8, 0xbdac96d3, 0xac6f7415, 0x6f7eb163,
- 0xf2a2a8fc, 0x693a8e7c, 0x395ee4ff, 0xdfdf019e, 0xef1d28e7, 0xf38cb875,
- 0x3bf0f68b, 0x47496e39, 0xfea46d94, 0x35941aaa, 0xa19a4e3c, 0x19f5cae7,
- 0xd8b02270, 0xaa3be761, 0x6eeed3df, 0xbb3cc6fd, 0x9d31cf9b, 0x934d1fcf,
- 0xdedb93f7, 0x2fccf796, 0x26243d7d, 0x41e45bee, 0xf46061be, 0xd063b887,
- 0x22f3f520, 0x35f61cf8, 0xcf34ebec, 0xff660dac, 0xe653ce4e, 0xe66d80fc,
- 0x730eee7c, 0x9cd9af3e, 0xce6ebcf7, 0x0ee309ff, 0xf41384eb, 0x4235c46f,
- 0xfd0a46ff, 0xf5261ddb, 0x7fa1e46f, 0x8dfe8523, 0x91bfd0ef, 0x3c8dfe87,
- 0xa1e46ff4, 0xfe85237f, 0xfeeeef8d, 0xba554e12, 0xe07814bd, 0x4eddbab8,
- 0xf7813e23, 0x89d9c5cb, 0x558547cc, 0x1717a5ea, 0xd8fcb2e5, 0xe29a6f61,
- 0x11937b60, 0xad18958f, 0x1c47f785, 0x2ab2d280, 0xb1db8d39, 0x55f6ba1d,
- 0x2aae8769, 0xeec24670, 0xe4f2bad1, 0xa73d882a, 0xd418b4a3, 0xdb6b68bf,
- 0x2f56f802, 0xff7ec03b, 0x77eee5d6, 0x63f893af, 0x5f118bfb, 0x0f738255,
- 0x25f49b7c, 0x71ee7719, 0x4353db04, 0x4d6244fd, 0xd3f21e50, 0xd43e733a,
- 0xe6be042f, 0x46abed35, 0x6c6fc7c6, 0xfbe0c96d, 0xe0e33e9f, 0xea9f69fb,
- 0xcb313bf6, 0x2198f2c1, 0x1bce23cf, 0x9f7a5970, 0x95e709b2, 0xc31c7fa7,
- 0xa650fdb9, 0x68617ee9, 0x0879765a, 0xf91df3cb, 0xe3058a35, 0xbe5f4f94,
- 0xcd6af58f, 0xedd2e7cb, 0xd7b2dcfa, 0xeef34c5b, 0xd1370fef, 0x71adc0d1,
- 0x5ecc7e21, 0x7783faa6, 0x31f887a5, 0xa7ca9807, 0xbe6219ad, 0x8d7c5f8f,
- 0xbdafbca9, 0xa1cf6e23, 0xfce4b9fb, 0xa5ceb25c, 0x6f5e02c8, 0xc554bd68,
- 0x6ff827f3, 0x4e52dbc5, 0xc673a72d, 0x2bbfaf1b, 0x9d7f0052, 0x57e03277,
- 0x858b64d1, 0x3f4cad9d, 0xf332c487, 0x15615cb9, 0x275c573e, 0x84b855dd,
- 0x7fda9637, 0x654c6d69, 0x47e5fa3a, 0x68812aa9, 0x3c9680d1, 0xde8bafe8,
- 0xe838727c, 0x98dd5aaa, 0x3bf2a2ea, 0x5c16ff14, 0xb7133f20, 0x9524713d,
- 0x495aa927, 0xaa73c27f, 0x1cff702d, 0x19edd1f0, 0x7ca4ef02, 0x68a5e6ba,
- 0xe9d41f8e, 0x0ae6d52f, 0x6c6c1d07, 0x814f5954, 0xeb8d4cfd, 0x8d8d93a4,
- 0x6bd0e1f1, 0x3e28c62a, 0x5c06c7c8, 0x8508fa0c, 0xefefc907, 0x97bd69ba,
- 0x94f7c90e, 0x752e758c, 0x41a2fac9, 0x07de37b6, 0x5c7bd630, 0x372b47d7,
- 0x3b7591be, 0x7fd73f7d, 0x7e1b9e5f, 0xbc5dbadc, 0x6d96c5ee, 0x7d29925b,
- 0x85dda1c7, 0x7b7d2d75, 0x1a48f45c, 0x326dcbe7, 0x75b3fdae, 0x23e13e4f,
- 0xe3777a7e, 0x0fe87693, 0x9dbf5695, 0x6679cddf, 0x0ef11da3, 0xc8dd6fd7,
- 0x2d6c17df, 0x71807b61, 0x1194eecf, 0xa3c3ad97, 0xc1b2ac62, 0xde3ceb45,
- 0x1585ca5f, 0xa69e32e1, 0x46f51d48, 0x55b5d602, 0xa6bac7c9, 0xe3b76f17,
- 0xf58781fd, 0xa6fba17a, 0xa2b4f0fd, 0x357bb01e, 0xd4c71c29, 0x11993edd,
- 0x64fbcfe8, 0x4e34e5da, 0xc81e5fa7, 0x8287de7a, 0x239c2fb4, 0xf5fa21b9,
- 0xf5da5561, 0x4ef9559a, 0x30903d98, 0x5ec2f20d, 0x35456ef9, 0x0a23439d,
- 0x710bb7a0, 0xa3c5a535, 0xd79d1354, 0xf6984616, 0xb4112cc1, 0x9bbfa8af,
- 0x7e532f45, 0x530cc4fa, 0x07d399fd, 0x0b9df886, 0x7f99cb3a, 0x8f7a6d5d,
- 0x9f2efaa6, 0xc7bb615b, 0x4a77f358, 0xbb3a62ef, 0x5abed4d1, 0x47bd354c,
- 0xf7a9e8b3, 0x6544ce18, 0x54e1c476, 0x6658f7e8, 0xeff54769, 0x169dfcad,
- 0x7dafda62, 0x927f3c33, 0xfd8da5e7, 0x7d3d8609, 0xe8cf7e16, 0xef0cbcea,
- 0xbc451788, 0x9a1dec30, 0x61691e59, 0x3c48553d, 0xa8f6eb54, 0x8f691cea,
- 0xd8b5f6aa, 0xf04d8f11, 0x4810a6b7, 0xb6151a6a, 0x477d5237, 0xdfcc9c4a,
- 0xcc3bef85, 0xdfd052f7, 0x521f9465, 0x42bfb04b, 0xdd686bcb, 0x606a1738,
- 0xd83b6247, 0x076c9384, 0xfbd1c633, 0xf434e837, 0xfed0807d, 0x33700c06,
- 0xbadcaeff, 0x822f60fd, 0xd8e2b4cf, 0x549dc47c, 0x95b14d35, 0x6f495ee4,
- 0x54bfff06, 0x7ebf6161, 0x4c03e1fb, 0x5615ed6f, 0xff4b8c8f, 0x78d4b876,
- 0x9435dda5, 0xbad0170e, 0xb05e7fe0, 0x15f8f143, 0xe9f00f59, 0x810cfa05,
- 0x70174a4f, 0x01d5e033, 0x7e7290bf, 0xe2286e3f, 0x0a7be426, 0x1425c057,
- 0x0b38fa9e, 0x2772c134, 0xf3cfcbcd, 0x8c57e90a, 0xb78fdd08, 0xb0ffd9db,
- 0xe52e1141, 0xf531e1bb, 0xf4e3b4b2, 0x6feb90cd, 0x2078a9db, 0xd97cdfbf,
- 0xe83bdfca, 0xd9c658a7, 0xde689f4f, 0x54f41daf, 0x8ccff72c, 0xeedc89cb,
- 0xdf5745df, 0xff864f45, 0xdd7e3426, 0x19e647b8, 0x1ab7dfa0, 0xf37d8626,
- 0x1be1c44f, 0xe77741f2, 0xe439c74c, 0x9910f1d2, 0xbcf9e5de, 0xe39d2a34,
- 0xbedd35cc, 0x4d69f068, 0x5b8c676f, 0x78eee542, 0x7e6f7bd0, 0x43557167,
- 0xfbf06a46, 0x1b4ada37, 0x975381db, 0xe25a73c7, 0x7ce22574, 0xdf2e5929,
- 0x4f763969, 0x29f844cf, 0x25b4ad8e, 0x8faea44c, 0x553439dd, 0x88be420c,
- 0x86d74fd3, 0xcfb60acd, 0x032de91b, 0x9c61f9e4, 0x872de7ef, 0x3f6167a3,
- 0x8d19dcae, 0x2bc5a190, 0xa2ee1fdf, 0xa2d9be73, 0xfec01a2d, 0xce7c8de0,
- 0x3cc6d70b, 0x390ce7d8, 0x516572a3, 0x5503c84f, 0x04f038ff, 0xb96d01e4,
- 0xea72112d, 0x81540fe9, 0xe73a1ad0, 0xe538be58, 0x6a7df494, 0xabdf0473,
- 0x2f08a53c, 0xd48b51fc, 0xd32e797d, 0x337cdb79, 0xd2708fc6, 0xae30c3b8,
- 0xc6124b7f, 0x30b2f8f5, 0x333cb6ae, 0x8bbb2ba6, 0x97aed691, 0xc316dff2,
- 0xa3dbacce, 0x0f23f721, 0x4b645fb9, 0xc8791fb9, 0xf72148fd, 0xfc0d7be3,
- 0xd71bf00e, 0x6f43e5b7, 0x39158df5, 0x8e1cf84b, 0x7f5c81cc, 0x01ee12bb,
- 0xf15dba3f, 0x8478e4f4, 0xf9e5620f, 0x2357821b, 0xb246dd1d, 0x5edd1059,
- 0x8221d977, 0x88c6ebe3, 0x9c7e5358, 0xbf54d923, 0x2a6695c8, 0xbfa93ebf,
- 0x7706fca9, 0x537f29be, 0xfd5348ce, 0xa6319e49, 0xdc468ffc, 0xc53faa60,
- 0x9f94c53b, 0xa9b66136, 0x12e28cfe, 0x59ccf953, 0xb3e54c8b, 0xf94cdbb5,
- 0x34ee2b5b, 0x92f1ffd5, 0xaf72a6e5, 0x0e715970, 0x231f4336, 0x3e85efb8,
- 0x6fede946, 0xe3064667, 0x4b38d475, 0x350cef97, 0x56fa900d, 0x39f7ae74,
- 0x09ee25d0, 0xe8fb0e81, 0xe2f680f7, 0xbf06199c, 0xfa914065, 0xe8324b70,
- 0x685eb426, 0xfd88a8f9, 0x6594f097, 0x9f6ee7ff, 0x313e2561, 0x43fdaaea,
- 0xfb7f2832, 0x5619e6c0, 0xaea32fe2, 0x3a52ffd9, 0xdcf17fe5, 0xf07cb237,
- 0x57284bfe, 0xfccbf772, 0xc822c134, 0x9bce06af, 0x8c75a3e1, 0x8d7d2eba,
- 0xba53da47, 0x5235538c, 0x9d7101c0, 0x00d20380, 0xfdd227d1, 0x5f489f44,
- 0xb72cfa27, 0xe8907109, 0xd221e913, 0xf7fdf14b, 0x3d2297a4, 0xd2297a4c,
- 0x452f4877, 0x297a42da, 0xcdd43fd2, 0x3a83f4e2, 0xb1fddb8d, 0x8fd382ae,
- 0xf7f096ea, 0x7196ea4f, 0x1f3a97fa, 0x8064ff7f, 0xb0087f61, 0x8bf0c69d,
- 0x091fc0d5, 0xdb2ede7b, 0xb1bf60b9, 0xabe795e2, 0x5facc7e1, 0xb0235a22,
- 0xb1ad5b4f, 0xfe9d1c27, 0xadf9eec9, 0x92089c55, 0xdee19ccb, 0xf8f006cf,
- 0xb7cc5dbd, 0xc447eff5, 0x84053eb4, 0xb5d34fa7, 0x3307e0b3, 0xc656ca0a,
- 0xeeb8ff10, 0xd03625eb, 0xae9687cb, 0xd5efa3ef, 0x03a7dbf9, 0xf7e86dbd,
- 0xa65dfd5a, 0xae321d6b, 0x6b6b5af0, 0xbfdbdb3d, 0x03c46e14, 0xefec33ed,
- 0x5ef958f7, 0xe085f2b1, 0xc104e8fc, 0x5b2ffaf9, 0x5af10e38, 0xcf892797,
- 0xc46f3d1d, 0xfdf87505, 0xef1413f1, 0x8de1f863, 0x2fc29f78, 0x3e41c75a,
- 0x77691d18, 0x0dc48587, 0x2fbedfc0, 0xbcc68fea, 0xc3277df8, 0x97d4ffbf,
- 0xf2f78022, 0xb5fe3f0c, 0xd834968e, 0xe1df4615, 0x33c704f0, 0xe57afe19,
- 0xe715168b, 0x64af1189, 0x3bcc638c, 0x15fd4aca, 0x5d23c674, 0x47ca6aeb,
- 0x757d465c, 0x93d7f724, 0x49dde3be, 0xb955e7aa, 0xec3e535d, 0x22aba3c7,
- 0x8ce9423d, 0xafa9e813, 0x3af1ea9b, 0x38d0bf0b, 0x1eb4624e, 0x1c7e8127,
- 0x01df9cb2, 0x48109d1c, 0xa39ffbc6, 0xb03dd897, 0xb88e3e83, 0xb8ce82b3,
- 0x088fd405, 0x2798c7da, 0x15f7edfa, 0xbcf217cd, 0x9df0cbd7, 0x29f492e6,
- 0x3f5e7adc, 0x2c6385af, 0x3d54bbdb, 0xfae61c5f, 0xcfd1046b, 0x90da19ad,
- 0x1fdfd481, 0x7ccc8c94, 0x7a3217d6, 0x094fdf60, 0x0bb04779, 0xf03119fa,
- 0xbc7e84ff, 0x05bdef12, 0xe942e1db, 0x418fc0c8, 0xbbde064f, 0x0e832ba3,
- 0x18d0e282, 0x65711def, 0xf4a17f7a, 0x199d1dd6, 0x43ad75f4, 0x8cf001d2,
- 0xae8320f8, 0xf89a2f94, 0x2ae8eb1e, 0x067f9f07, 0xc5d2855d, 0xe9257495,
- 0x0e27feb4, 0xba4aefee, 0xc007a4ea, 0x55d387e5, 0xf8f38a8b, 0x79a7a59f,
- 0xee3c626d, 0x765c97ff, 0xabda441f, 0x7c17b69f, 0x198c4ca6, 0x2e13120f,
- 0x62ec1075, 0xba32f5a1, 0x7f4a17a9, 0xbc6eeda1, 0x6e465da2, 0xfa71bb70,
- 0xaeda1959, 0x047aed12, 0x71c21bb7, 0xf7e96f11, 0x1a72de08, 0x999e2d71,
- 0xb90e5390, 0x2f2df26d, 0x27cc8de1, 0xf3a719ba, 0x096243f3, 0xee24bf9f,
- 0x854f40fa, 0xcb8d693a, 0x42fac85d, 0x71d76461, 0xedea3705, 0xdc5d7fc7,
- 0x4f8cf980, 0x37e3cb30, 0xf5fcf2ea, 0x0ffb91a2, 0xc6e1477d, 0xce59ebdc,
- 0x61477d0f, 0xfe3d40f3, 0x81a44d20, 0x8f0a17df, 0x0efe9f9c, 0xcfbea146,
- 0xc9ba7453, 0x5462ab70, 0x6a9bee1c, 0xaf321c56, 0x3c8c1de3, 0xfce3eb8c,
- 0xe9cfc20d, 0xfdc0224d, 0x0903a24c, 0x61091ff9, 0xc85fef93, 0xaa35bafb,
- 0x5790dff6, 0x4fba7b8d, 0xb057b53b, 0x4c440fcf, 0x4a77839e, 0xd7190dc6,
- 0x17f6ed0f, 0xdbce59ba, 0xb960c8ef, 0x16d2fb13, 0xde27c9d7, 0x5fba73a4,
- 0x8a37bca6, 0xfb46f714, 0x3bfa79d1, 0xbf91c73a, 0x40b96731, 0x736ef1bb,
- 0xfed193bc, 0x6138d726, 0x9cfeef8d, 0x776f29bc, 0xdecdd86f, 0x042ecd8a,
- 0xbd8adf7e, 0x7deb10aa, 0x45a7b62b, 0x4e7661a6, 0xafd2bd07, 0xa0d8b92b,
- 0xc6f1cefb, 0xc1dd78f3, 0x286b80d9, 0xff380d3c, 0xeb1eb800, 0x077bae0a,
- 0xaa379608, 0xad5f2423, 0xd57c908e, 0x58757380, 0x9ede7dc7, 0x5527f1c1,
- 0xf9af090e, 0x5611aecb, 0x2c17f512, 0x93f9c91b, 0xb807c275, 0x6092c69f,
- 0xf7b10f10, 0xce58eb09, 0x9ddcef1b, 0xe8bdf87d, 0x2ae79a24, 0x983ff687,
- 0x4082b9df, 0xe2844916, 0xbe7a86e4, 0x05fe7f8f, 0xaa7d03d5, 0xf1af754a,
- 0x96facec0, 0x7d71ef2a, 0xfe15207d, 0xd754f158, 0x0e55e8f1, 0x9f435f09,
- 0x98afd21c, 0x5fb1adf7, 0x80befe85, 0x0ef55f21, 0xc6dcf193, 0xe4eef73d,
- 0x92e1e1ad, 0x930ef5af, 0xebc0d8fc, 0xee7ebb06, 0x89c33f53, 0x3afca68f,
- 0x98abf59c, 0x2e4c6f58, 0xc28583ec, 0x76189fa4, 0xf904f695, 0x22b5ca7e,
- 0x945191eb, 0x13643c2f, 0x076f2a7e, 0x92794043, 0x1fb6b3f4, 0xef82a4ba,
- 0xfc294517, 0x6f71863e, 0x22c92c29, 0xc27c41dc, 0xbd370ee9, 0x13911b4b,
- 0x7947ca67, 0xc7ea997a, 0x9537488c, 0x98077ac7, 0x1427e3ca, 0x8a3df298,
- 0xefd536af, 0x29ac6b39, 0x68ddac9f, 0x31529faa, 0xf83794d5, 0x24fc8a58,
- 0xc5b92cfa, 0xb2efbed4, 0x34fd5352, 0x5ca9a55f, 0x319b3bc5, 0x25b7ab40,
- 0x81cf1127, 0xd58c9fca, 0xe3de434b, 0xf0cb08b5, 0xfe6b77ce, 0xcbde5a33,
- 0x80b91099, 0x6cc9afdf, 0x9e7999fc, 0x2c6b44ea, 0xcdbbd7a5, 0xc928b17c,
- 0xb9171f9c, 0x71df814f, 0x9fcccb9c, 0x4d589653, 0xeae51ff9, 0xe44f34fc,
- 0xbbe3ddb1, 0x300daff0, 0x4e143fe1, 0x7efc0f44, 0xef9d3b68, 0xcdebcc3e,
- 0x070f7e32, 0x75e0937e, 0x0c126fc0, 0x824df807, 0x049bf0f3, 0x24df87d7,
- 0x937e1cb8, 0x8721f2e0, 0xd61ff8cc, 0x55ffc662, 0x6ff1991f, 0x787765d0,
- 0xa66ad91a, 0x9a29a10f, 0xba782df2, 0x7e9994e6, 0x1d73f142, 0x09b15b89,
- 0x09e287c0, 0xbe387fb8, 0x8be08656, 0x37f7c3f0, 0x31477bdb, 0xd7d71e7e,
- 0x20606d75, 0x3a2e97df, 0x6fbc0aa4, 0x71f3ac63, 0x6d3fdcfd, 0x89731ad5,
- 0x5dcefccf, 0x763e0490, 0xdb7e909d, 0x4f1655f1, 0x207fba80, 0x29d99c64,
- 0x3fa843da, 0xaa52fe2b, 0x26d2741d, 0x0e7bcfdf, 0x95d8797c, 0x123eb2f1,
- 0xf6bef84f, 0x27be54cf, 0xa8d2c475, 0x8eaf8f80, 0x9f009ed1, 0x84bb9799,
- 0x8a249bd7, 0x5c402fb7, 0xa5857fd4, 0xafb73f22, 0x722dc7bc, 0x89fef95b,
- 0xa6e727c1, 0x2da9b8c8, 0xdd7fbab9, 0x9ea7e323, 0x777295c9, 0x71c5c794,
- 0xf2b925de, 0x8ba90d7e, 0x010773a9, 0xd99d873e, 0x0b3acf80, 0x8ad9ebbf,
- 0x9d09e47b, 0x0f21c8f7, 0xa3ecfe43, 0x1ff57fcb, 0x47581c3b, 0x3a617af6,
- 0x1dfbfb7f, 0x81e2f8a6, 0xfca65d5b, 0x5324a6a0, 0xdcbbc1fd, 0x40fcf2a6,
- 0xc87ca98e, 0x3f298f21, 0xa98465ac, 0x791f55fe, 0xad91f94d, 0xaff54c13,
- 0xca6c5539, 0x47b688a7, 0x8abedf01, 0xcd1c53b4, 0xb9fa974d, 0xe4dc705b,
- 0xe563bbdc, 0x7edd5f7d, 0x46fbc861, 0xd3a6b9dc, 0xd11ea875, 0xe8e52ed7,
- 0xf52164fa, 0x1fae8746, 0xa13eb30a, 0x1de371e9, 0xe67c58f7, 0x5e2371b8,
- 0xd0ef43bc, 0x7b8e8af5, 0xe2f19d34, 0xf178e0de, 0xbf5d61b9, 0xc75e7d1f,
- 0xfbfce87b, 0xeb7ae5da, 0xbdf3b4ef, 0xa15e631d, 0x96c949f3, 0xd1d9bb74,
- 0xbfaabdf5, 0x46fb4ae5, 0x25f1666b, 0x3613fdd0, 0x6dff2b4f, 0xf3c62b84,
- 0xb75e22b4, 0xcf7617fe, 0x8f77f70a, 0x5cb07737, 0x658b1ccf, 0x8e5c94de,
- 0xddfd338b, 0x92418884, 0x7583adbe, 0x78c84afb, 0xdc646373, 0xbbb1889a,
- 0x8fddbf41, 0x6499e127, 0xff7c0d17, 0xf167bf4b, 0xf74d35e3, 0xbd8e68a1,
- 0xce3f7f51, 0x4c3d036f, 0x59f24b1c, 0x5b13c93e, 0x49143d7a, 0xcb13ca72,
- 0x8a9f6cac, 0x3757fe7b, 0xde75fafb, 0xfa4be99f, 0xb203e810, 0x07a8f40e,
- 0xb72954f2, 0x2beb920c, 0xb8eebf52, 0x187ec0e7, 0x43f3f421, 0x174fbc70,
- 0x6874c6f4, 0x75dfe3ac, 0xdba0c1ef, 0xfa193850, 0x3be3d0af, 0xd2f319fb,
- 0x07ec67e1, 0xfdc67e03, 0xb66df713, 0x7c914de2, 0xe202658f, 0x6dfc0ce5,
- 0xc6f693c9, 0x503c3a05, 0xbba8fc0f, 0x6e6a457a, 0xedf7ec0c, 0xeae31dc2,
- 0xea3b0e82, 0x62e09bff, 0xfbbbbfc0, 0x87f1dd6d, 0x5df0be50, 0xa3baddf7,
- 0xdef67fd3, 0x909f105b, 0x5e3a4bf1, 0x1c2cfdfc, 0x94777017, 0x323f3f79,
- 0x9189f248, 0xe4fdf483, 0xccd6fd23, 0x0ffc042f, 0x9d552bf5, 0xbcf3c85f,
- 0xdf98ad24, 0x8af9c6af, 0x37f35bfb, 0x8847f94a, 0x87abc4e2, 0xe36f8fc2,
- 0x7ad7cbfb, 0x4a6ddb05, 0xde3f151b, 0x75f12af9, 0x9fb30fad, 0x0772cdcf,
- 0x26c83bbf, 0x46576a4d, 0x5da5f6ed, 0xc2facef9, 0x60eef948, 0x0beafbe8,
- 0x2f19bd75, 0x86df606a, 0x19eebdfa, 0x3cb1fba4, 0x9cf2c3c2, 0xa150d71e,
- 0x37a0e9d7, 0x0e6f7cbf, 0x31f6327a, 0x671f1ca5, 0x3f0dcdc0, 0x3cce90d4,
- 0x073c37c1, 0xb58379e7, 0x0ec5f8cb, 0xab7e1af8, 0x61ecbf0e, 0x1a1127be,
- 0x77ce718f, 0x3f2bba20, 0xeb1fe198, 0xf8741f6e, 0xefc3bec7, 0x89691ed6,
- 0x69f1dfc6, 0x67df26df, 0xfd5bf4e9, 0x22cbb865, 0xf03153fd, 0xfdeab53f,
- 0x5d798d89, 0x96d50fdd, 0x9438e4ef, 0x73b68b66, 0x2cefad10, 0x7b778ff5,
- 0x9fdc89ef, 0x26117788, 0x2ba976ea, 0xcdcbadd7, 0x8fe914a3, 0xef8ca9f6,
- 0x5ef209f6, 0x8151f13d, 0x4fc4677d, 0x0481114c, 0x4a1f86a4, 0xe1923d5b,
- 0x4aa1f86f, 0x9e792302, 0xda17ea33, 0xeb68e4f0, 0x851577a3, 0x53fd3bbb,
- 0x5c647dad, 0xaa7e7754, 0xb9f39769, 0xaf97e9bf, 0x183e7ee1, 0xb6e52694,
- 0x036efb86, 0x2ad80d9d, 0xab67586c, 0x4bbfebad, 0xabf3a851, 0x3d9ae812,
- 0x96ade282, 0x962fbc2b, 0xbf88c22a, 0xe46f3e62, 0xf9ea352f, 0x7dbf9922,
- 0xeab7cca5, 0xd16da7ef, 0x275820ed, 0x7a07ac52, 0x4edd36f9, 0xc5207582,
- 0x7c1df03a, 0x35f0790d, 0x90d7c1e4, 0x0a435f07, 0xa5ef86be, 0x761538a2,
- 0x0ad3f85b, 0xfc07f683, 0x72418569, 0xc169fc13, 0x82d3f879, 0x169fc3eb,
- 0x5a7f0e5c, 0x69fc3970, 0xd3f879c1, 0x9fc3eb82, 0x3f879c16, 0xfc3eb82d,
- 0xf879c169, 0xc3eb82d3, 0x0e5c169f, 0x39705a7f, 0x79c169fc, 0xeb82d3f8,
- 0x5c169fc3, 0x62996f3e, 0xd3cdb7f2, 0x5b287fdf, 0x51f4cf1f, 0x9b1c5198,
- 0xeffdf847, 0xc4fc7f88, 0x373c0e96, 0x2edd022f, 0x48f70ead, 0x904e373c,
- 0x8908b778, 0x8cd9b6e7, 0x32ecbbe7, 0xb4e3245f, 0x7e07e943, 0xf49b42ab,
- 0xdf85215b, 0x56fc290a, 0x2ab7e148, 0x2b7e94cc, 0xe15bf0a4, 0x4856fc3b,
- 0x0a42b7e1, 0xf85215bf, 0x6fc290ad, 0x2b7e1485, 0x0adf83b4, 0xf856fc29,
- 0x5215bf0e, 0xfdf0adf8, 0xfe03cd08, 0x905e632b, 0xf499fbf3, 0x9343a252,
- 0xe532ea5e, 0xd707e721, 0x5c1f9c87, 0xb83f390e, 0x707e721c, 0x707e721e,
- 0xc1f9c87d, 0xdc8349f9, 0xef20bfbc, 0xbc83b707, 0xd41f9c1f, 0xb6037be8,
- 0x2e1b49ab, 0x35b48ebc, 0x7142794a, 0x2f353109, 0x8bfc2673, 0x35254ead,
- 0x6d8423d6, 0x859980f9, 0x38f4d794, 0x66d13cc7, 0xae39be01, 0x05a6f080,
- 0x0f65c704, 0x5cc97ffa, 0xf9b3f86e, 0xbf9ef087, 0x50deb043, 0x35afdfa3,
- 0x4b847bda, 0xefd46a45, 0x2f5d77cc, 0x1ea37c74, 0x79a0cbf3, 0x8f996290,
- 0xbbfc9378, 0xaf700b22, 0x91458b60, 0x642bb8f1, 0x5d28743c, 0xe793caad,
- 0xf6cb16fb, 0x5388e1fd, 0xb83c5129, 0x156591ef, 0x80056c87, 0x7e0292d3,
- 0x562f2af7, 0xab92d75f, 0xcc658711, 0x124bb0db, 0x867be09f, 0xbd84daa3,
- 0xfd19c69c, 0xefe3b085, 0x4bb44c73, 0xa0ed0279, 0x29f40e6f, 0xf4414dde,
- 0x9e4f2cbd, 0xb6ef9a7b, 0xfbe9cbab, 0xae4b6dc0, 0x89c5fdc6, 0xd3ddb2e1,
- 0x386689bf, 0xf8506e4e, 0x6da8ce9e, 0xc9fb8bc2, 0x3a7e75cb, 0x5ecb9b70,
- 0xf8bae3ce, 0x6fd1a3de, 0xbe5486c9, 0x5a2259a7, 0x450f710b, 0x3df8550c,
- 0xb46e037c, 0xbeb1d7be, 0xb02ada2c, 0xfbe0ff2f, 0x7e2e244f, 0xa34ffb9f,
- 0x2116c687, 0xcb3450ae, 0x0d2742f7, 0x83d9592d, 0xe5f9a5e6, 0xbfa3a17b,
- 0xe706f258, 0x85ef929f, 0xe70cf932, 0x9879f1f9, 0xfdf853ed, 0x8dbec995,
- 0xee370496, 0x25b72f65, 0xe136fea2, 0xf5055881, 0x8d8af708, 0x168ae575,
- 0xbd01538b, 0x41f10388, 0x639c47f4, 0xdf25e83a, 0x59f7e363, 0x365d58a6,
- 0xce431bf0, 0xb1c97129, 0x3151d48b, 0x4432cf7c, 0xd0d4b84e, 0x7e62e383,
- 0x3b4e9c78, 0xba5fe7df, 0x8572c9d3, 0xbe615eb6, 0xc65f3e79, 0xf6dd56bb,
- 0x7a4b70e1, 0x99ce9c67, 0xbc16ff34, 0x7d267b03, 0x8508f47b, 0x79bd88e5,
- 0x0da3d704, 0xcd3df12f, 0xf06f9592, 0x0d4b943d, 0xfbcb450f, 0x52ffd26c,
- 0xb0cdc3ae, 0xf1d7cd3b, 0x69c7ae53, 0xef93ab1d, 0xcc39d33a, 0x6a5caeef,
- 0x119cb1b0, 0xf21a2f2a, 0x911ef1a7, 0xc23fae10, 0x60d153ce, 0x0bc03be3,
- 0x4aac94d7, 0x91ca5712, 0x7339758b, 0xe38d8351, 0xf7f42ab2, 0x6eff42d4,
- 0x1e3d62cf, 0xf356f16b, 0x42f24ff7, 0x7de350e4, 0xc94ebd4d, 0xb06607db,
- 0xc6c4b43c, 0xcb39cdfe, 0xb6247ca5, 0x93ee3f0b, 0xce3e59cc, 0xe666f782,
- 0x947af4ec, 0x5de9e82e, 0xd89a4e5d, 0x4ff864ea, 0xfcc11cb9, 0x14e5ea65,
- 0x397cdfce, 0x9799d399, 0xee2adc65, 0x5a6e8122, 0x073be48b, 0xd1f2ebef,
- 0xc6b1c40c, 0xc9eb3e43, 0xf44eddf4, 0x74f2218d, 0xabc035be, 0x3878801c,
- 0x44ada6d1, 0x8dc4ec9c, 0x4d83ef82, 0xfd451c82, 0x155c82cf, 0x5691fd8f,
- 0x2661f7c4, 0x68bf7c28, 0xf4dbd0d2, 0x43fb40fd, 0xf7e13f30, 0x29c2b457,
- 0xcd39c47e, 0x805bb6d2, 0x685f637f, 0x5efca3be, 0x629f24ea, 0x9a923bc7,
- 0x741b6fae, 0xe63fba1f, 0xb276e846, 0xeb076948, 0xb26193b0, 0xb7c92478,
- 0xd3e4266a, 0xf66db0b9, 0x608109d2, 0xcb2b951f, 0xd576fc7b, 0x419206cc,
- 0xc9fb55ff, 0xde458b1c, 0x9039233f, 0x96880bef, 0x2f949ea2, 0x4014a359,
- 0xf5e6323f, 0x38ec67b9, 0x3a4eb0cf, 0xa7d8ed28, 0xd2e51ef2, 0x7e4d327b,
- 0x8cb4d09b, 0x34fd8de0, 0x27f5a637, 0xf468610a, 0x1c2de160, 0x85ebf781,
- 0x005428f1, 0xe8b798f1, 0x3bc1eaf9, 0x973ab4ff, 0x91f9c4e1, 0xa6687dbf,
- 0xe05ff22f, 0x6b147393, 0x4b1bdff0, 0x0d5768b2, 0x50f7c1ee, 0x11bf03c7,
- 0x9efc6db9, 0x4bb64a44, 0x7b10a9f2, 0x8960f54b, 0x4bbb50c7, 0x773cae59,
- 0x7a9dd584, 0xdc7bfb2b, 0xd634b76c, 0xbe66cc7d, 0xf3a46be7, 0x5ee7eb07,
- 0x9ee7bfdd, 0xf916c3ca, 0x1663c2fe, 0x8857f6ff, 0xd0f72f5e, 0x8fbd6066,
- 0xe79ede21, 0x8cfaf1af, 0xf83a4cf7, 0x896efe95, 0x96474f41, 0x2afbe25d,
- 0xb77691a5, 0xe54f441a, 0x0fbe15ab, 0xde4cba5a, 0x2b56d6e7, 0x6e845df2,
- 0x99bf58ec, 0x9efcbffd, 0x117e6fd5, 0xf8750b2e, 0xbcb7b1ce, 0x84eb48e1,
- 0x3d979fef, 0x347c9360, 0x0efb8990, 0xf2712cb7, 0x7b9fd9bb, 0x0f06ab8a,
- 0x8c3c9e03, 0xe5d871a7, 0x8c4b7f54, 0x4bdf04b6, 0xd841cb45, 0xfcfee71d,
- 0xba8f7e6d, 0xdf8d39b6, 0x95d92cbf, 0xd9ef0abf, 0x7ed1ee7c, 0x4497f582,
- 0x4790ecba, 0xf9621a6a, 0x53db9e7c, 0xda2bcfbf, 0xe067cfd8, 0xd2c1bee7,
- 0xbe7d778e, 0xaea2e71c, 0x6cc01157, 0xbaf54c53, 0xf61a63b6, 0x4b3b50d1,
- 0xdf21bbe8, 0xdd815765, 0x5f641ec4, 0xb632ec35, 0x71b3639c, 0x77b1cfae,
- 0xf73ef7fd, 0xf437f3ea, 0x7a1df9da, 0x9ef8ee6d, 0x2ad7ff90, 0xcbd3d82e,
- 0x7133dd23, 0x90fca1bf, 0x62b4910d, 0xbe5b9c62, 0x7c8f731f, 0x8ef4a63f,
- 0x7367e67c, 0xdc029380, 0xfbc9193b, 0xe94fdcb8, 0xfbf7ee90, 0xf40f6bad,
- 0x0a7a0dd9, 0x821df978, 0x1ed79772, 0x951f2417, 0x77a62a35, 0x0bfc8c24,
- 0x97c95583, 0xfc00dd48, 0x9a477c7e, 0xcd396f1d, 0xf1093121, 0x27417b99,
- 0x51db3ac3, 0x993f8e3d, 0xca0e2e98, 0xfe14bdf7, 0x2f18e4bb, 0x955beff8,
- 0xc3df9a36, 0xdf2cfaa0, 0xc51c1aed, 0x68b895fd, 0x5d4869dd, 0x03824f3c,
- 0x3eeda9c3, 0xe3cdcfea, 0x02ca3e30, 0x07ec1b7e, 0x42f71073, 0x7e5c5bf9,
- 0x6d29c61b, 0x68d4ef90, 0xda38e46b, 0x20fb58ea, 0x975607c8, 0x5cb04fbd,
- 0xbddf20d8, 0xddffa39e, 0xcb2f9a11, 0x2704e5cd, 0xee33b3dc, 0xabc286dd,
- 0x797f9f44, 0xce59ac63, 0x036b5c6c, 0xf377667e, 0xdd39c65e, 0x30da5d0e,
- 0x2837df86, 0xbef97ab7, 0xfbc3a68a, 0xf79cdbb3, 0x7b325fc2, 0x34b623dd,
- 0xb065ffca, 0xe9cf6b94, 0x7a6271fb, 0xa9df9320, 0xf1c9cdba, 0x8d5db3e3,
- 0x780edebc, 0x81f0443f, 0x662ae2dc, 0xf89d1378, 0xbe596f10, 0xcedf8cce,
- 0x77c944f9, 0xf095d7fc, 0xd5605bfe, 0x79e0aeec, 0x8997dfac, 0xb4d9a1f8,
- 0x970ef1ef, 0x1f7c6970, 0x3343c4f6, 0x6205eff9, 0xe6cf1c9e, 0xbbc78f71,
- 0x4c374453, 0x18fd06d7, 0xf18df3f7, 0xb4ab1eac, 0x6bbe7bc7, 0x420f7a9f,
- 0x7c27af4e, 0xddd00fc3, 0x02e3b53e, 0x2f6b8d26, 0x5e07ef97, 0xfdf4efc1,
- 0x6a01fffa, 0x00d36c91, 0x0000d36c, 0x00088b1f, 0x00000000, 0x7dedff00,
- 0x65555c7b, 0xd6bbf0ba, 0xc0d857da, 0x51b08b66, 0x62020dc0, 0x10106d11,
- 0x80a17515, 0x636a735b, 0x8dc42937, 0x910150b7, 0xf39fa8ac, 0xa96f0db1,
- 0x962a2695, 0x8da6b675, 0xb2707595, 0xd99b1b46, 0x0f5d9a6a, 0x39d38d3a,
- 0x32cdb653, 0x34d209bb, 0x99d37d9f, 0xde79e7be, 0x0daf60b5, 0xf9a675a4,
- 0x3efcefce, 0x7df5e3fc, 0xee7d7bd7, 0x765ef3cf, 0xb24c6322, 0x98783631,
- 0x8c81b183, 0x45931819, 0x77a13fc8, 0x6302edfb, 0xbeac7195, 0x28d2132d,
- 0x0b6bff56, 0xdfe3df63, 0xa2749ef8, 0x8f2c6453, 0x5da0dbb1, 0x10af7c1b,
- 0xd6ccabd9, 0x29d33df3, 0x148af7d0, 0xd41dd336, 0x7ec3fb1e, 0x13efd5e3,
- 0x338b69fc, 0xe3abea7b, 0xbb78d856, 0x9a7ed0a9, 0xdd8beb05, 0x3ea81bf5,
- 0x26e9b3cf, 0x3632c591, 0x87ff04db, 0x7b4894a5, 0x32e6c456, 0x7057b0d6,
- 0xe1a8a11a, 0x18b18941, 0xf08b9f48, 0xbec664b1, 0x3bcdf868, 0xcfbd40b7,
- 0x64af6f37, 0x35e67b43, 0x398a3fc7, 0xf7363046, 0x0c733652, 0xa5de6c60,
- 0x0f569431, 0x073864f3, 0xf8dbd506, 0xc607ba5c, 0xfb2dadbf, 0x5a307fdc,
- 0x30e59fb7, 0xbf73fef6, 0xe868e3fd, 0xde9f3197, 0x3acf4d7d, 0xa13ead66,
- 0xc304b2af, 0x4d73af8d, 0x83155746, 0x18b6ce79, 0xcd14121c, 0x64c55e5e,
- 0x33b32798, 0x13e41a67, 0x422bcc75, 0x16fd6cbf, 0xf3eb04d9, 0xb557fe30,
- 0x5da9905c, 0x824fbe63, 0x7a860cf5, 0xdf5e1cc6, 0x58f7f00c, 0x4884670c,
- 0x912de8a8, 0xcdbc1903, 0xf83d29f7, 0x21a90c1d, 0x89ef07a7, 0x5ecc1d0a,
- 0x7b6d0657, 0x330305f0, 0x65eb0f96, 0xfceaae1c, 0xbff32aa7, 0xfb20bd6d,
- 0x4e0ddea0, 0x2757cf07, 0x7ac1e61b, 0x364face7, 0x5cb486cc, 0x473e5ef9,
- 0x2f8dde5b, 0xccaf8aab, 0x4f587695, 0x57c71b57, 0xe13d3ad7, 0x2f4f6bab,
- 0xa931257c, 0x00771e67, 0x8e00d8be, 0xe382362f, 0x57c0530b, 0xa82f33a5,
- 0x7c70bfde, 0xedfe7ecd, 0xd0765e0f, 0xceffa8fa, 0x1dbe8d07, 0xb6acffd0,
- 0xf2b784bd, 0xc9f41bd5, 0x99ceaf50, 0xdb51704c, 0xb6cfaecf, 0x6de78032,
- 0x1debb7ab, 0xe8eefc16, 0x9521ee93, 0x413f1059, 0x6790099e, 0x3bbc40ba,
- 0x397ea7a2, 0x9c617ba4, 0x91cd8b25, 0x719edaec, 0x3cf428b6, 0x86da3ebb,
- 0xafaecde3, 0x7165887a, 0xf66777fa, 0x66b3bfe6, 0xa0b317ce, 0xb3cfe43f,
- 0xe424ce45, 0xd4510a8b, 0x3e9a9bf0, 0x79837884, 0x35e0063d, 0xdbc3fe23,
- 0x0c38469e, 0x6ce6145e, 0xa9a94f86, 0x8b8e1f01, 0x36f38cf4, 0x826bcc88,
- 0x8135a97a, 0x548f388b, 0x876c28a0, 0x528d8469, 0x1df90b16, 0x4802ed30,
- 0xee9e2453, 0xc3f5f273, 0x677e3f77, 0x5c3c8131, 0xa1cf4abf, 0x3b606af4,
- 0xfe00a757, 0xd9cc310d, 0x4fa1e8ec, 0x3e951fb5, 0x6fedfa55, 0x70ae7b7d,
- 0x3993677d, 0x3386593c, 0x56e304c9, 0xb9cc3c3e, 0x3afcb846, 0x0f00610d,
- 0x817ad05b, 0x7d6c0b58, 0x903537ac, 0x0fcd7657, 0x24a5b7ad, 0x86f58fb6,
- 0x93e553ae, 0xc3ce2639, 0x015127c0, 0xfad77798, 0xf10c51a1, 0xca2f302d,
- 0xcd8bb39d, 0x5d5bce22, 0x504d53d7, 0xbbb6e619, 0x33e944c9, 0xc368c04d,
- 0x764d3e00, 0xe4df3fca, 0x29adb4a0, 0x9ddbca83, 0x633f9a36, 0x80698881,
- 0x85308aa7, 0x8f3cfdff, 0xe54165e5, 0xee9c6d53, 0x11035b4e, 0xfd3920b6,
- 0x0d79bd71, 0x0efa428b, 0xccfc883c, 0x5db2871a, 0xf5e9d430, 0x4cc42367,
- 0x3f3e4fa4, 0x7d12ddb5, 0x163fc927, 0x02ec7061, 0x24b19b96, 0xe02374fb,
- 0x38f2ee6b, 0x9b129027, 0xe49438d1, 0xb46f0cc2, 0x7eb00093, 0xcc78430b,
- 0xf860e453, 0x2395aa92, 0xb26b7eb1, 0xe6718055, 0x5ae79c5a, 0xced5fda9,
- 0x4b7bf1fb, 0x93252199, 0x9026caaa, 0x72287763, 0xdcc0896c, 0xa07787c8,
- 0x12fe449c, 0xfea2a50f, 0xf055a3b9, 0x56cf291b, 0x21d7000b, 0x78d2eecd,
- 0x055b1394, 0xbb6c0ee7, 0xa9a9e40d, 0x0d769e47, 0x7a817f73, 0xf4077d81,
- 0x255ffd07, 0x5d710220, 0xca1c726d, 0x75824df1, 0xb979c317, 0x059f080d,
- 0x6e9c9d0a, 0xc8e11339, 0xa3eb81ec, 0x65105ff8, 0x288b23cc, 0x3d141b6f,
- 0x79406486, 0x310e4e45, 0xca41f870, 0x3a3f11da, 0xa0e909a7, 0xc51292cb,
- 0x886f28fa, 0xf2c38948, 0xc912ad39, 0xaa9e9545, 0x7c2835d5, 0xa3be1733,
- 0x2a912bde, 0x56be9162, 0x74a44cb6, 0xcd9286ce, 0x24e3a05e, 0x9a3b1dc1,
- 0xb867a3d6, 0x13b5399e, 0x55bc47af, 0x9b4630ef, 0x7a496f00, 0x104e526f,
- 0xbed9ce3f, 0xbb41892a, 0xd3cddbf3, 0x5b17fe51, 0xa1a38acb, 0xd16dbcfd,
- 0x1e9052d9, 0x7ae6ca49, 0xc4ed4164, 0xacf00638, 0x2791fbf9, 0xe78fa0ac,
- 0xe8569f42, 0x70b69bff, 0xd4aa179f, 0x924fed34, 0x31dee780, 0xa1b3e279,
- 0xe0f142fe, 0x1f50a32d, 0xe2a7be08, 0xce23bea9, 0x503c87da, 0x0fc073d3,
- 0xdaf7a00e, 0xf51ef5ff, 0xd6f895f3, 0xbed0e5f5, 0x4885f6a6, 0xa6e167ec,
- 0xa15be43f, 0x49e8a0fc, 0x173ffec3, 0x45653fb6, 0x9edd6c02, 0xee7c7a85,
- 0x4f28b4a6, 0xf917f21f, 0xbd51f100, 0xaaf8205f, 0x517c33e5, 0xc7bb8406,
- 0x4c560ccf, 0xf480ccad, 0x8d625e7e, 0xf6a80f68, 0x323e5a8c, 0xf3adcb9b,
- 0x9093eb51, 0xb53fe64e, 0xccf50925, 0x5f3c1167, 0x6fadd4f1, 0xecf2dca0,
- 0xaf101a34, 0x38331d1e, 0x41799f51, 0x551d22bf, 0x93c6ff03, 0x04ae61dd,
- 0x0eca2a7a, 0x6fceb827, 0x51fa411d, 0xa77c179d, 0xcc74cff2, 0xd218f385,
- 0x748d99dc, 0x7f9d67ff, 0xcff3e22e, 0x17a766f5, 0xf5cd99f1, 0x4bd79fdb,
- 0x05ee58a5, 0xe47b4186, 0x885febcf, 0xd8f4b548, 0xfbd2256f, 0xd67684b2,
- 0xea36428b, 0x76ccf0ed, 0x1bb22cc3, 0x9d59d118, 0xc359d395, 0xe0e97d01,
- 0xa8c7b218, 0x37e746a4, 0x05af85f4, 0x9dd5bd8a, 0x80d7b7df, 0x87b3527c,
- 0x6d3511db, 0x508ec867, 0x855a92ed, 0x39ee179f, 0xda857643, 0x871f6eae,
- 0x5e3eed4b, 0xc801955e, 0x80e5cd1d, 0x0aba4200, 0xfbf905f1, 0xd3d7f5fe,
- 0x7bf26997, 0xb5df7f29, 0x750f2e56, 0xb7a8499d, 0x349c64d6, 0x976bfe20,
- 0x5e42fd2b, 0xbcde341f, 0x2f0481ec, 0xc16a1f2c, 0xfd8d0ef6, 0x9a2fbb50,
- 0xc36bfbda, 0x97bea356, 0x4c3a2ceb, 0xa42d6b9b, 0x8bd5b7ff, 0x9c5cba19,
- 0xed13985c, 0x916183b9, 0x07472859, 0x06653c2e, 0x3b6a0248, 0xbe50888f,
- 0x2f73ca3a, 0x031c67d2, 0x6f5090ae, 0x5fb405f8, 0x74f95e3b, 0x6e3ff604,
- 0x066be048, 0xbf0bd753, 0xf20c5e9b, 0x2d981964, 0x06671f64, 0x0f1d2046,
- 0xf4e5cc3c, 0x1ab67ae3, 0xb9d31bf5, 0xf72834d9, 0x3c42dca3, 0xdbe61b7f,
- 0x1dffff05, 0xfec60ff3, 0x143fc999, 0xd0a4bddb, 0x5968dba7, 0xaebcc02d,
- 0x8359ea1e, 0xd041be4b, 0x222d935f, 0xac34a40e, 0xdfe7a1d7, 0x82757b55,
- 0xc113a722, 0xc8bb408e, 0x416ec830, 0xf3366e3a, 0xccb209f5, 0xf71e611a,
- 0x8d9e1e67, 0xa76d7a7a, 0x9d611989, 0xc8c33a13, 0xe41c4d7e, 0x6cd6bd22,
- 0x2dbd224e, 0x02ac7438, 0x14ce1fea, 0xcfac3afd, 0xcfac3e4c, 0xae76214c,
- 0x9db19668, 0x6fb5f070, 0x960fbe51, 0x82891e2e, 0x47be0df5, 0x9d433670,
- 0x8f73aeca, 0x15a41bff, 0xfdec7697, 0x2dff4857, 0xe113b3ca, 0x75cbba7a,
- 0x5ba803c6, 0x39336d6b, 0xc160deb9, 0xef7838eb, 0xb13691b7, 0x9d1d7e67,
- 0x4dfb9ee7, 0x2726a62e, 0x07099fea, 0xa11fd225, 0xc3b0e9f3, 0x3d5287c4,
- 0x2c3b3bb2, 0xb0104fa2, 0x70f791fe, 0x164c137e, 0xbaf684bf, 0xb065ff49,
- 0xc48e617e, 0x935773e8, 0x83df614a, 0x938b1091, 0xd1747d47, 0x38eb7642,
- 0x3a550f85, 0xdb9b2b7b, 0x72296f8f, 0x73338555, 0xaf582cc8, 0xd66cf0a8,
- 0x1022faab, 0xf87b32ce, 0xaf529176, 0x932892eb, 0xf46d5e1d, 0xebb2e831,
- 0x33d250e0, 0x3fd9c9fd, 0xf601dda0, 0xf954f2c4, 0x5327845d, 0x0acdeef4,
- 0x2dfd54fc, 0xacdffd29, 0x8b66f1c0, 0x5376e1c8, 0x7a14dc08, 0x1e97a50a,
- 0xdb41887a, 0xeccf1ba3, 0x51a3f6be, 0x6bdf84c9, 0xfd78e61e, 0xedfaf090,
- 0xcd802b5b, 0x4dbfa0d8, 0x0cfefc21, 0xb98bf578, 0xedaf023f, 0x9bf578a1,
- 0x375e2187, 0xa0676489, 0xa376881d, 0xb5c0e507, 0x60f6e794, 0x51392306,
- 0xd7398529, 0x8077e324, 0x87c91643, 0x541f28a3, 0x15c430b9, 0xe9f506b8,
- 0x71e57069, 0x8db1017e, 0x10a4e797, 0xf6b0245d, 0xbc072c78, 0x277da1e7,
- 0x7e668699, 0xe5b7720c, 0xdfdedf01, 0x82cd3f40, 0x983ceb6f, 0x8b66f78f,
- 0x0eb7ed13, 0xc3d5e89f, 0x59a25a3c, 0xbf187ed6, 0x4e55fe65, 0x4533962f,
- 0xf8374c6e, 0xef837ed0, 0xbdf88d49, 0xe97f7f9c, 0x441f67ef, 0x8d33acfb,
- 0xb25abad1, 0x67da3a59, 0xf419652d, 0xdcaab7fd, 0xb7823079, 0xddf4e32f,
- 0x43e6df32, 0xa3e8f43d, 0x27a8e1be, 0xf1cbb65a, 0x510d4836, 0x981cf89e,
- 0xd38920ff, 0x94324b7d, 0x7059ba43, 0x7ec5cf97, 0x0df3e1ae, 0xff3d8794,
- 0x4e657414, 0xe506d105, 0x76231ba7, 0xe9555ca0, 0x2e30f074, 0xcf7887df,
- 0x7938456c, 0x7a8cb027, 0x8543ffe8, 0x0bf854de, 0x008d36c0, 0x3c1098f7,
- 0xa31774a8, 0xca585fc0, 0x413bcfe9, 0xf31d4f59, 0x0091bfa1, 0x38070953,
- 0xf0c11a57, 0xd5967483, 0x6ff38d93, 0x91f80c5e, 0x0f1c1d70, 0xdd5645a7,
- 0x155f07d6, 0x0df128e6, 0xa6f90218, 0xa9be7192, 0x7a42ba44, 0x0aba046c,
- 0x481647a2, 0xae173e88, 0x83ca15d0, 0x1cb8f708, 0xc257e758, 0xf0b1f21f,
- 0xa694ffad, 0xa4ce35f7, 0x1e2f2e1c, 0x734a7b33, 0xd04def48, 0x656f9dd8,
- 0xfa889a7f, 0xafbdf4e5, 0x149a6025, 0xeb8c9ee5, 0xd7fe5cd8, 0x1fff1452,
- 0xb8f407c6, 0xffcb0f8e, 0x2dda224f, 0x235f4b95, 0x79d2bffa, 0x37989996,
- 0x5d1ee01c, 0x00fd382c, 0x462d79bf, 0x16f824e7, 0x0c755c57, 0x6ad659e1,
- 0x56911874, 0x1c8d62d8, 0x408f2b3b, 0xda1d8a37, 0x39ba246a, 0xf4894bf7,
- 0x8b92b9c1, 0x0f800eaf, 0x4e0856e7, 0x32d657ac, 0x3790256c, 0xa816292b,
- 0xa057995e, 0x1ca9657a, 0x051a275f, 0xaf4037a2, 0xde283b25, 0x8ef5a731,
- 0x13df88a9, 0xa40f5fc5, 0x187ac1f8, 0x2e63e547, 0x959e48de, 0x56abf529,
- 0xbb47911b, 0xacb597bf, 0x3ffc88ba, 0xde521bd3, 0xec53e93a, 0x5b51acb7,
- 0x8235c6ee, 0x4e57771d, 0x07ca0c44, 0xefce64e6, 0x40f24811, 0x93fa0ff2,
- 0x447140bb, 0xc20f30cf, 0x61bc89c3, 0x99eba47a, 0xdba05708, 0xdd7ca5e8,
- 0xbe0aa733, 0x99ceb049, 0x1f67ce16, 0xfbbe0996, 0x09ff3e05, 0x5065ef40,
- 0x5d740b1e, 0x38e4c316, 0xe626dd48, 0x2e79c70f, 0xca09f61d, 0xd438d3db,
- 0x8fefaa28, 0xf75ca1b4, 0xb78911e8, 0xe5a52f32, 0xede947cc, 0x98f34fcc,
- 0x74933ac1, 0xfc93af90, 0xf38e312b, 0x0367b32b, 0x8b5fd7d2, 0xe0169c4e,
- 0x4239ddfb, 0x439428de, 0xdd68038d, 0x701f5b97, 0x067680a5, 0x5fac41aa,
- 0x147ee396, 0x4ccab3fb, 0x74ab718f, 0x995a8e95, 0x17d61537, 0x9be2debb,
- 0x6b8beb04, 0xf5c21cf5, 0x38374fa6, 0x1383ef10, 0x74133af8, 0x543f9fdc,
- 0x81a3606e, 0x183f360e, 0xdb3a43e6, 0xda2035bc, 0x03e6fea1, 0x97cc0180,
- 0xf0bc14af, 0x4e61eadd, 0x7559d38c, 0xfeed111e, 0x188f56a2, 0xe1a7e208,
- 0x394441b2, 0x23d3be91, 0x5ab49ea2, 0x353d53d7, 0x4fd4ac5f, 0x59067937,
- 0x4e9e4ec9, 0xa15c33f4, 0xd49fb51f, 0x045f8356, 0x4ac917b8, 0x57b7997d,
- 0x9e8a61fb, 0x3961db56, 0xab7a67d2, 0x453f4fa3, 0x3f505b4d, 0x08f88f83,
- 0x7bd205c6, 0xfd711fca, 0x1bf084da, 0x36abf378, 0x2103374c, 0x9d1c71f8,
- 0x79e34cc7, 0x15d33cf8, 0xbfbf87da, 0x63e38f7f, 0xb9bbf01e, 0xe422fef5,
- 0x1f00cda3, 0x9de6f3c4, 0xcfd4ccb3, 0x799a59f4, 0xf286a931, 0x4b070825,
- 0xa23c75ef, 0xd53d2fcc, 0xbd695a23, 0xe76843ce, 0xe28ccba5, 0x763f6a01,
- 0xf405741d, 0x857a776a, 0x90cbcc7a, 0x47b8945a, 0x4eb38e3a, 0x5d31ff40,
- 0x6b4957c1, 0xf63361fd, 0x5f1466e3, 0xfe85cf4c, 0x8426fea1, 0xfc37a183,
- 0x5e99e742, 0x4273e7cc, 0xf18edfa9, 0xe76c7494, 0x74431158, 0xd5d7e7c5,
- 0x1c6214ea, 0xa08fb197, 0x7e90c9fd, 0x0cb8c29e, 0x7e4ecfa4, 0xb42e4a6d,
- 0x97d1fe7f, 0x52d0b476, 0x0fb33e0e, 0xf5ab56e5, 0x9c709be6, 0xff9f2283,
- 0x5de2724d, 0x206ddf98, 0x53be9a3d, 0x7944db4e, 0xebfd1393, 0x55df56ae,
- 0x2cbd422f, 0xeb64c618, 0x0a138f3d, 0x3a15da9c, 0xcb793938, 0x53ef5c20,
- 0x582c7745, 0x5f87ed02, 0x3b8d38f7, 0x94fcca7c, 0x9b0fc816, 0x30abcbf8,
- 0xc78e5f7f, 0xfee4023c, 0xde5fd2b0, 0x6ae50fb6, 0x821cfce9, 0x4576c597,
- 0xda39a9f2, 0xbf02f5e3, 0x52dc4737, 0xd2b8fc8e, 0x24487066, 0xfa19eb77,
- 0x7711cd59, 0xe5bfb1db, 0x4c26f9d1, 0x36bfd60d, 0x6e3c9ca1, 0x1e2131c9,
- 0x18132d9a, 0x0aaceb96, 0x4f1bbe9e, 0x885240fa, 0x73847772, 0xe5744cba,
- 0x0c272864, 0xbcad0609, 0x2f7971d6, 0xb43e1dd9, 0xf5acba9f, 0x60cc8148,
- 0x7ca05409, 0x69795493, 0x3c717a71, 0xa3b4e2c9, 0x9142b4bf, 0xaf862c37,
- 0xf73960d3, 0x5eaf389f, 0x962e63fd, 0x867f4b50, 0x4128ccb0, 0x9bda3ff9,
- 0x573e10c6, 0xbbc58353, 0x6844f518, 0x70205d7f, 0x4fa38e50, 0x7e337647,
- 0x5eddee48, 0x7a341bb2, 0x7a5e5ba4, 0xf221f5a2, 0x7a811e52, 0x792058a2,
- 0x0ceb61e9, 0x0c12feb8, 0x3c5c00b2, 0x545eb8db, 0xce267bf9, 0x49e5f005,
- 0x5e5c9165, 0x2673e4e9, 0xd1efc60e, 0x452a5cae, 0x5e021e22, 0xc3e9e0c9,
- 0x9378f79f, 0x9d1e507f, 0xa987fa41, 0x21fe9007, 0x0fe144fd, 0x6f078a8f,
- 0x50a3f5d9, 0xd912cb5f, 0x85cb9503, 0xe2cfb436, 0x6947d1bc, 0x2edcc5be,
- 0xa6bf9768, 0x892a1cf5, 0x7979444b, 0xc799d962, 0xbebd41ef, 0xfff49c29,
- 0x5667a5a4, 0xa66e3c60, 0x211a7057, 0x7d1a59ef, 0x6f987bf7, 0x905d3a34,
- 0x81f0ab3f, 0x914597fb, 0xb8084f68, 0x759e8cce, 0x83321656, 0xf139e29b,
- 0x3b409633, 0x34e0a34f, 0xa1e07a3b, 0xef527ac7, 0x37bc05f5, 0xfad0fe46,
- 0xa8d7bc3f, 0x3e7759c8, 0xc6a2d9ca, 0x700a87e4, 0x7cf5eb5d, 0xd7d18d9e,
- 0x3927de53, 0x1cb97639, 0x3fd8a99e, 0x57b3a59e, 0xc0f7c3c6, 0xcef9416a,
- 0xc8a956f1, 0x88e340e5, 0x0d3f1863, 0x3e48172c, 0xa252bc79, 0x5ccdda1f,
- 0xef784d9e, 0x5d900a28, 0xb43de5d8, 0x722b5a92, 0x3674a3de, 0x94588c17,
- 0xe3dfa76f, 0xfe479ffe, 0x9bb62563, 0x83b5a2d3, 0x0cfd0226, 0x67bcb840,
- 0xf1e9fd26, 0xefbad196, 0xea6945f0, 0xd38ead55, 0x8bab3de4, 0xe7b0c7ae,
- 0x52277bac, 0x3992af3c, 0x2ade9122, 0xc1376e65, 0xe61b259f, 0x4f9d5733,
- 0x2ac7b731, 0xa27ec18b, 0xb07b5aef, 0x3389fec7, 0x78a8df20, 0x3a13f154,
- 0x19765eef, 0xacd076e3, 0xdd7ada75, 0x16301076, 0xe5caba8a, 0x32bf76da,
- 0xb9459fbb, 0xe038dee8, 0xaeabf21b, 0x80821e50, 0x266e7f21, 0xa61f71e3,
- 0xced543e8, 0x517a592f, 0x6668728f, 0xc23d45e3, 0x1fd2e673, 0x385fa7e6,
- 0xa1bef3b5, 0x3ebb4a20, 0xbf934e39, 0x534435d1, 0x30f766ff, 0xa75bf7cd,
- 0x5ef9ab5f, 0xc9a919ee, 0x5e3d5edf, 0xfd467f53, 0x7a1cad24, 0xa3d69a37,
- 0x79bfa7e2, 0xa3e8a5bf, 0x12ec4277, 0xe23a9d35, 0xbf91133f, 0xe4672c3f,
- 0x33787cbf, 0x1d31f8d3, 0xe7822423, 0xf93d5c80, 0xc8e5f731, 0xbf208fef,
- 0xa1f44fc9, 0x7343f3c2, 0xa228c9a1, 0x7ee4627f, 0x725fa879, 0x5e503990,
- 0xfdb1d4ce, 0xff8f5442, 0x9cf30e67, 0xe3bafec7, 0xf10f4b0d, 0x1f884378,
- 0xff78a573, 0xbfcc0670, 0x4d79790f, 0x16c3f72e, 0xffaf36ee, 0xb58e0838,
- 0xfc9ad16d, 0xebf1fda2, 0x3bd60e3f, 0xae1d044b, 0x93e146b3, 0x7da0165a,
- 0xa0e8bb52, 0x40c4eafe, 0x583be62c, 0xf4b46c67, 0x0a8b838f, 0x258f800f,
- 0xa9de2837, 0x193fc3fa, 0x9e0a453e, 0x1a70b4cb, 0x90e3cb93, 0x29108f5f,
- 0xc7239cdd, 0xf103fee7, 0xf49eb41c, 0xdc7fbcdc, 0xc847227a, 0x9f9f0859,
- 0xe3dfaf1b, 0x17940f1e, 0x7f0b908e, 0xfe4cb826, 0x47a5c247, 0xd82f47cf,
- 0x72a3fa0d, 0xfdfb819d, 0xbf5c33de, 0xfefd7237, 0xf68fb47c, 0x44f39b87,
- 0xed070ee7, 0xe93ed297, 0x618d7ba1, 0x59df1819, 0x797d23a1, 0x8190997a,
- 0x2126c2fe, 0x0f36fc8c, 0xc81648ab, 0xc878b9be, 0xaa31fd48, 0x3afded07,
- 0x0551f390, 0xe4096b3e, 0x71e5ccdf, 0x716e35b1, 0xf5038a4a, 0x1eac1ff6,
- 0xe27a8b8a, 0xfd9e1e11, 0x696be130, 0x2bee45df, 0x6bd0127e, 0x8512d1e5,
- 0xd5cc5f8f, 0x2e1f3ad1, 0x949db914, 0x1f70ba2a, 0xa9d81563, 0x96065768,
- 0x915f28eb, 0x6d59e9c7, 0x9d0a1ff7, 0x14dd94c7, 0xda88f386, 0x7d7dba24,
- 0x2e51fb8c, 0x793d0f8f, 0xb3ed1857, 0x68742a01, 0xd6bddbef, 0xaf582e69,
- 0x8d96d0bd, 0xdcdadfb6, 0x4d6fea68, 0xcf159746, 0x748cfca1, 0xfe8eca78,
- 0x8cfac0a0, 0xe655cd33, 0x580feeab, 0xe936fe94, 0x9da2bf41, 0x1e289822,
- 0xf91af161, 0xb16715f9, 0x1ccade26, 0xa76e0b02, 0xf428f3d6, 0x1b42c76a,
- 0xeff697e1, 0x5db178d5, 0x1ba417a1, 0xcf4abbc4, 0x8983fda1, 0xe9cc8dec,
- 0x15d9f389, 0xe51a8e52, 0x8f748dd9, 0x1f90eafd, 0x07fe5cbc, 0xe3c4be6e,
- 0xded7de2c, 0xe18879c3, 0x0c9c525f, 0x5fce4aec, 0xbee2434b, 0x024f913f,
- 0x40cf0e66, 0xde1e5684, 0xdac9d0ab, 0x48de827f, 0x3ebc02ba, 0x8fe5cb9c,
- 0x36fdc0ab, 0xb2c73bca, 0xfba230d4, 0x96270b1f, 0x51384560, 0x3872ba5e,
- 0x1f3df379, 0xcc749e10, 0x7f71b46f, 0x72e1f90b, 0x31c2a47c, 0xbe9e6449,
- 0x3c88f2f4, 0xca1bfbe5, 0x6ab7ae7e, 0x61d90fc8, 0x02c57728, 0xcc2cd2c6,
- 0xffb6bc61, 0x8f9c0e7a, 0x396ae885, 0x96aee5d2, 0xcfe43094, 0xcabc6564,
- 0x0ca7d29b, 0x205fa077, 0x040ed018, 0xe3c0c3bf, 0x574edc3f, 0xb94f7ae5,
- 0x72c47ed6, 0x1f8f664f, 0xeaf7daa6, 0x82973c77, 0x59f3aae3, 0xfd61d8a5,
- 0x125577cd, 0xdca2724b, 0x808f765a, 0x5ab1dcf0, 0x717df8d4, 0x0325615e,
- 0x7fce3e3f, 0x8efd13af, 0xcdafb038, 0xf575cf28, 0x5e083382, 0x0a817b81,
- 0xf8871338, 0xe24fe02b, 0x8967bd3a, 0x57c7425e, 0x85abb1d7, 0x5de71b8f,
- 0x9f90c82c, 0xa02f5154, 0x9956b7df, 0xa3055c7f, 0x3e9969ef, 0x9e21e301,
- 0xe38a5616, 0x03335655, 0x332af5c6, 0xf2865399, 0x7443c6ca, 0x02b9edde,
- 0x206f2539, 0x4f3a4fc9, 0xa4f02ae3, 0x4d1d01e7, 0x7643284d, 0x864bb867,
- 0x167f89f1, 0x4cb5a71d, 0x59efa2f0, 0x843ce2d4, 0x11d001fe, 0x2d3c7dc5,
- 0xe75f1a01, 0x5d7271e5, 0x80e9c18b, 0x658d4875, 0x5521ffb4, 0xd4329c1b,
- 0xdf29b63b, 0x2d95f18f, 0x0ddfdc8d, 0xd67493f5, 0xd1c3d7fa, 0x9910ab5f,
- 0x790a0144, 0x5659fa2a, 0x30562e85, 0xf7ee3b77, 0x41fe1933, 0xdca548bb,
- 0x2a6f3d5a, 0xd0e52266, 0x13dc8378, 0x6b9e409f, 0xd3b240dc, 0x678daa94,
- 0xc92b2d48, 0x7d6233af, 0x890faca8, 0xa5d54877, 0xac971714, 0xf35bf2da,
- 0x8e086222, 0x9e1e3c59, 0x8d88ef73, 0x727cc2b7, 0x1fe3797f, 0x41873d30,
- 0xfe5b8033, 0x4c073bb2, 0xac16ff87, 0xa62378d8, 0xe8cebc4f, 0xe08fc19c,
- 0xfa8c6657, 0xe8fafcf1, 0xb2abf295, 0xb9d00f26, 0xd27dafc2, 0x094f1abf,
- 0xfe954fe5, 0x4d4ef943, 0x7f865ed7, 0x120526d7, 0xdf4f0f91, 0xdb03323b,
- 0x73de3657, 0x5f88c7c8, 0x77d00705, 0x117177a5, 0x5660ba23, 0x5e5bd097,
- 0x490b3784, 0x1f37bfec, 0x3b7c863f, 0x13e7effe, 0x95df087f, 0x63ce8c09,
- 0xf649fd81, 0xdfaa9a9c, 0x3eb9f223, 0x246790bd, 0xc1464ebc, 0x053bac0a,
- 0xc7bee0da, 0x2b4e6078, 0xf02e7fa4, 0x4de38b3c, 0xef9e3c81, 0x6b40fd7b,
- 0x4b37ae0c, 0xa78ef5c7, 0x76e68edb, 0xa8ffb748, 0x06590fd8, 0xdced0536,
- 0x771126c0, 0xc0e0596e, 0xe2d63be7, 0xc9b96bbe, 0xcaeb0699, 0xf448dfba,
- 0xf68a0484, 0xa7689651, 0xb6aee5b8, 0x9f69cb8f, 0xd2c0d1b1, 0x0ee06e28,
- 0x006473c3, 0x4caab0cf, 0xacc357b2, 0x857aaf68, 0x1e88aaa4, 0x22f5087b,
- 0xef2cb40a, 0x30ac53ad, 0xb042aefe, 0xec7b3347, 0x59fed51c, 0xeb4c9f9c,
- 0x6820ed57, 0x8fddb0c7, 0x0b4aa7e5, 0x19bb224b, 0xf7fb83e6, 0x90264cb6,
- 0xff5213ed, 0xd92332f4, 0x7baf76af, 0x5bb470ca, 0xa0e6a797, 0x9ae30add,
- 0xfd7f6e24, 0xbb67ca3b, 0x285ef94e, 0x49b9e0e6, 0x05801f75, 0x8718d174,
- 0xfeaaed53, 0xe763a5e7, 0x9505b954, 0x9f2f9b7f, 0x59ff7ec1, 0x5563dd72,
- 0x634d4de8, 0xe9e079f8, 0xcf8dbd0a, 0x9e9a5337, 0x73dbb3ff, 0xfe93aea7,
- 0x39feeb79, 0x9ffae1d7, 0xffd88eb1, 0x3cd8f821, 0x3ac67ff9, 0x4ff2996e,
- 0x5f37875c, 0x43cfc86e, 0xe746d679, 0x7e2eec88, 0xdee41c2e, 0xcb9cbc3d,
- 0x09938b39, 0x74ffc764, 0xfd84d779, 0x1c1f419d, 0x7778a1cf, 0x67183a08,
- 0x88a1a588, 0x8ca5cdec, 0x2c8681f6, 0x4340fbe5, 0x224d3a96, 0x6e1603da,
- 0xec520e27, 0xb94b41ce, 0x9ca719dd, 0x118b882b, 0x3fd4327d, 0xca5bcbf6,
- 0xbee0c6e7, 0xd5ec9190, 0xf5dd36e6, 0x5e53d416, 0x868fce89, 0xd2d289da,
- 0x5f9c4a95, 0xf6aa9f6b, 0x79e31a68, 0xb4b3b2fd, 0xa3daa74f, 0xb4f29443,
- 0x603f7ca5, 0x1ed68b48, 0xdad6ab8d, 0x1082fa8f, 0xbaa9733b, 0xeb49d07f,
- 0xe9d72dd3, 0xa87ffcf1, 0xb07b89dd, 0xab0714a8, 0xfeb4067a, 0xf630d74d,
- 0xf9f77e74, 0x1fdc1c8c, 0xd05ab99a, 0xcf5539e8, 0x7e282402, 0x43e3e2a4,
- 0x3f8873d4, 0x5fb534f7, 0xaf3e6fd2, 0x2e4c7048, 0x539cd74f, 0x1e7eec62,
- 0x3a73712f, 0x11eaf5fa, 0xddaed16b, 0x37c6eeb7, 0xfd697d31, 0x04e5e19d,
- 0x6f54f5af, 0xebc6cb7f, 0x7650ff30, 0xe6123dbb, 0x53a8d0f5, 0xefd009ef,
- 0x85e33c6a, 0x2978b3eb, 0x9e14b68f, 0x7ab3d08b, 0xa4dbdfda, 0x0d9f4c0f,
- 0x45122be5, 0x23be911c, 0x1832981d, 0x59309f9d, 0x35f57e78, 0x30e3ee8c,
- 0x1a9f5ce5, 0xd73d0987, 0xc7c3cab7, 0xc4f00559, 0x18963573, 0x39a91f7e,
- 0x08e9fee1, 0x818766ef, 0x8b3939e1, 0x624fee72, 0xa82aaed5, 0xbf7edc77,
- 0x0bee167d, 0x7e881867, 0x26ce98a4, 0x9ed993c4, 0x71c2af63, 0xcd35e242,
- 0x2037e929, 0xfbb5bc59, 0x20679ef0, 0xc9cf7b7d, 0x2a9d312f, 0xf3c3efb5,
- 0x88465225, 0xbf6bd29f, 0x9bdc1198, 0x4a5f3387, 0x6e3b9632, 0x754e9110,
- 0x869a6feb, 0x50c154fe, 0x4f581ae7, 0x1bf30258, 0xbd611e60, 0x7b7989f6,
- 0xce9c20a9, 0xf59648d5, 0xdfd80d15, 0x7fba08a8, 0xae03bec0, 0x4df3a7cb,
- 0x80f657f4, 0x0e3a47a8, 0xc38ff653, 0x1fed7b32, 0x30c2fcd3, 0x3b59e14d,
- 0x7a15c3e4, 0xca7b635f, 0x6b77fb87, 0x106e5213, 0x69f53d1d, 0xbbd6195f,
- 0xab1bbbf2, 0x26fd5f68, 0x9fcf1593, 0xcafb2985, 0xa574e3a1, 0x43675b3a,
- 0x6418b46a, 0x55f11673, 0xe0725f0f, 0xe68353d8, 0x9cfaf501, 0x736e3aa7,
- 0xda83c71e, 0x64c2d19f, 0xf74323b4, 0x81fb43ad, 0x56be7079, 0x31fda9ea,
- 0x01e746d6, 0x518b8874, 0xa7abb57d, 0xe9df0db9, 0xff1fbb24, 0xcc82e382,
- 0x35fc431a, 0xcedb55ac, 0x0dcfca9c, 0x2a18f4a8, 0xfdd0a52f, 0x6f7ad4f7,
- 0x9f81e138, 0x1fad0827, 0xf6d0d70a, 0x5833b7f0, 0xe160ddde, 0xa95d88fb,
- 0xac22b99d, 0x473da57b, 0xbf5a7f33, 0xef7fd3d0, 0xbe6d3cfd, 0xb9f6364c,
- 0x7d07943e, 0x4e8277cd, 0x6c596fbb, 0x8d2fb6d1, 0x25777ed1, 0x4592f368,
- 0x6d91dfe9, 0x8e1af3a2, 0xf79e137c, 0x18d8f953, 0x8af7efe2, 0x2efa2adf,
- 0x1e74c991, 0x79de9375, 0xe3c4e50e, 0x01d24033, 0xf82c3c7d, 0x552e58cc,
- 0x0f515bb4, 0x93d3adc6, 0xaefc7a9c, 0xbde0ce5b, 0x6ba016a0, 0xf771e584,
- 0xc56e9b47, 0xf148b17c, 0x70fb9b0d, 0xcb51d239, 0x37bf5f77, 0x3a9fcf1b,
- 0x5bce740d, 0x75b1b73d, 0x1e2b61ac, 0x94cb8a0b, 0xfdf069cd, 0x84e62aa1,
- 0x6323b099, 0xfc712363, 0x15a2d12d, 0xd1f3ddf5, 0x718efff5, 0x8c19e694,
- 0xe14219f6, 0x46d23757, 0x756e3672, 0x5bf780b6, 0x5f9b1e1e, 0x06317289,
- 0xaf9465fc, 0xc57dca90, 0xf015c717, 0xc5b6c0f8, 0xbe23c52f, 0xdb0f5837,
- 0xa2159e69, 0x52d8a713, 0x8b7fe5c1, 0x7b3ed185, 0x3752a8f3, 0x72ec4d1e,
- 0x8b3c0ec9, 0x41dee2d8, 0x2d595ef3, 0x9cacd972, 0xc8580197, 0xbe9c3951,
- 0xfd4a360c, 0xb3346e98, 0x972839f8, 0x7ce8c292, 0x81f67f50, 0x57cb84b4,
- 0xe9cc6f6c, 0x1143debf, 0x5cc8f18d, 0x9fe467cb, 0x6dfd0b9f, 0xf299b19d,
- 0x538d3caa, 0xdfbbbbe8, 0x1bba3d10, 0x36724bf0, 0x9e2ce41a, 0x878e63c7,
- 0xf575b789, 0x3a20b4c2, 0x7c8055d5, 0x2ee7e2cd, 0xbebb7e30, 0x87e334a8,
- 0x9b9d4cfc, 0x5518e5cb, 0x97ebbb1e, 0xda05dc61, 0x635f51fb, 0x0fce783f,
- 0xb7d71952, 0x443fa851, 0x830cf37e, 0xe839ef03, 0x430e402a, 0x56825d7b,
- 0xc9181c4f, 0xc1fb35f1, 0xa09eccbb, 0x728c4d38, 0xbea3661e, 0xeb069cde,
- 0x744338d9, 0x6c78076e, 0xfa1068a9, 0x55c4c78a, 0x0d997e70, 0xde6fd1f5,
- 0x1b139152, 0x8c669ebc, 0x36d0c073, 0xdb9f0fd7, 0xbfc885d3, 0xbc79235d,
- 0x1cdd67bd, 0x3f4071be, 0x479a87a8, 0x6ae6ae97, 0x557241da, 0x6d6de567,
- 0x073a7aae, 0xcfc155d9, 0xf813ad5d, 0xc4a4827e, 0xf28b9bcb, 0x4bf4bf49,
- 0x492b152f, 0x57e2849f, 0xe5fd3f9d, 0x9911e907, 0x8719f1f1, 0x4cceb49b,
- 0xda07e1fa, 0x4af9743b, 0x1e0bd47d, 0x62ba7f6d, 0xf8e33651, 0xaf105fa8,
- 0x7bc5e63a, 0x95fda193, 0x3a16fc2a, 0xe069c91f, 0x8d9db1ed, 0xdbf48bf8,
- 0xc8e00169, 0xa1ce82e9, 0x3c38f7b3, 0x7c3a24b7, 0x2e01f86b, 0xae7487d2,
- 0x78f7a52b, 0x658e098f, 0x7de8efb8, 0xe7f3a25d, 0xcd4f7aa1, 0xb13070ab,
- 0x3e9ce736, 0x0f9c4dec, 0xa76935ea, 0x01fa89d7, 0xed8a97d0, 0x094b2a36,
- 0x5cd4b3bb, 0xd7ade8e0, 0xab6d5cba, 0x937282af, 0x03f69983, 0x99534c3c,
- 0x79c0307f, 0x1ccf33ed, 0x3df58abf, 0xf803ae0e, 0xe6bce099, 0xe63347f9,
- 0xedf37b40, 0xb9b426ad, 0xf5a1cf43, 0x76a4ef6e, 0x4cab4b71, 0x23c519d3,
- 0x86b95465, 0xafd90b08, 0xe48674cc, 0xc6c934b3, 0x3d10a7ed, 0x50f80eb9,
- 0x644af08f, 0x38d0af04, 0x49f8e871, 0xdefcc905, 0x1a52e2e4, 0xa7454377,
- 0x5d90e31e, 0x4ec57aae, 0xefa9f4f2, 0x7bb1fb42, 0xff23a73a, 0xc81a1577,
- 0xc1f87e1e, 0xcf119349, 0xc51265de, 0x7bd17ad1, 0x233dbac8, 0x1cae9cf5,
- 0x7f28cd8b, 0xdbb9ccb7, 0xfec3e8ec, 0x8b3152d8, 0x965a2fce, 0xa5633b70,
- 0x88e481bd, 0xe7b942a5, 0x71cbd8a2, 0xa213bfaa, 0x3754b727, 0x9bdef198,
- 0x8590de7a, 0xed97dbd8, 0xbbbd1fbf, 0xf18bf961, 0x2aee4fa8, 0x79c78869,
- 0x4ff0896f, 0xd5df1377, 0xf2029f93, 0xf1e51e38, 0x920e91a2, 0x7ff2dd2f,
- 0x0e3b39c6, 0x5569181e, 0x43db8af8, 0x417fe25f, 0x928d66bf, 0x1c6014a7,
- 0x8e44b52d, 0x74bc6076, 0x00d3bbdf, 0x7abd93ae, 0xfb8d63f2, 0x2fc1f481,
- 0x49382632, 0x681e9e5f, 0xac9d22b0, 0x8f46fc6a, 0xe2ce6bf7, 0x7fe855e9,
- 0x87b70255, 0x9818c556, 0xa1f342df, 0x2e754f45, 0xf5a7a866, 0x0137dc09,
- 0x798fc5bf, 0xfd102316, 0xbaf18e4c, 0x298700ad, 0x30bbbe31, 0xd7ac4aad,
- 0x129c60d9, 0xf080b447, 0xc563a29d, 0x9daf1e06, 0x115cf385, 0x59c511f3,
- 0xd1c5a727, 0xc5a3547d, 0xc9fbc3ad, 0xf6d5677a, 0x8bce8cb5, 0xb015bc51,
- 0x8ce1f74a, 0xb6bdc718, 0xeeab8e27, 0xdcf1a913, 0x04290575, 0xffc1212f,
- 0xcb23e22d, 0x1ef1101a, 0x403e987e, 0x46aaf8f6, 0xcd41f913, 0x91da3b09,
- 0xf823323d, 0x3e7aa43e, 0xb163e017, 0x0c567c02, 0x95d69bbc, 0x17bb1494,
- 0x91faa5e7, 0x50af20f1, 0xcc2565de, 0x4beb8a9b, 0x4aedc37a, 0x0cc67a86,
- 0x1660365d, 0xa2b9eae0, 0xc61eac78, 0xd8583c21, 0xabfb4c38, 0x40d122bf,
- 0xf2d0d8f1, 0x5c780b27, 0x21050b32, 0x135eebae, 0x755dcfdd, 0xaaf7bee0,
- 0x301e7e50, 0x6767c939, 0xffbc1481, 0x66771dde, 0xaeddff7c, 0xdbb5bf9c,
- 0xa63f740d, 0xf8ccbe3b, 0xe71abcbe, 0xd9e51a88, 0x31f2788c, 0xc7f421c7,
- 0x8f71abfe, 0x4fca461b, 0x6dac7f60, 0x63c515c0, 0x68eac6c2, 0x8529279f,
- 0x05f78279, 0x5feb2956, 0x7a870dd5, 0x75f5ea3b, 0xf6079428, 0x378d870f,
- 0x2226bbe7, 0x88ec46dd, 0x47dafd47, 0x171343bc, 0x79287bc1, 0xfa6204b1,
- 0x9c79aa93, 0x3cea6624, 0x5348778a, 0x0ad93ef9, 0xdcfc6016, 0x7c84c0a0,
- 0xfd4beaba, 0xe887700d, 0x927accd7, 0x90ae9193, 0x7f2f48b8, 0x6576e645,
- 0xa2dbdc88, 0x02f1f9f0, 0xcf91ee25, 0x93e7bff2, 0x5228bb25, 0x1889f7d9,
- 0xe8724295, 0xd90a5711, 0x411cc443, 0x9d9cbef0, 0x87b15073, 0x8f9ca77e,
- 0x83e72bf7, 0x83e72b0f, 0x0b77c55f, 0x863f90c0, 0x7a4016ef, 0xe549c9bc,
- 0x2815346f, 0x6fe399ca, 0x4892ee45, 0xf9941fb2, 0xadf994e9, 0x25734eb0,
- 0x6d567e03, 0x5879d3d3, 0xe984c263, 0xaf32cf68, 0xdb119edc, 0x7587ef73,
- 0x9efcbfc2, 0x095da773, 0x3a4f3a1e, 0x3ff7cac7, 0x542d7c55, 0xb612afea,
- 0xc75f9019, 0x36e16a76, 0xc6a452fe, 0xda622cae, 0x4d1397f3, 0x4bf53443,
- 0x97f3daac, 0x6ad7ec93, 0x68764fbe, 0x975e5fcf, 0x1f643e31, 0x0b574b56,
- 0x806e8013, 0x7d33aa4e, 0xd685ff34, 0xcd7b8a52, 0x74c7b90d, 0x3f36ab47,
- 0x2fcda7df, 0xabcdaddc, 0x46c3c9e7, 0x9230f429, 0xf131fc8d, 0x0cf7e44e,
- 0x0107ef85, 0x3ab36fbf, 0xcfda1199, 0xf8bf7816, 0x1b00c61e, 0x76c94bed,
- 0xe3ac238c, 0x5cb09ff7, 0xc3bdcbc7, 0xbe7af695, 0xdb8ec56f, 0x4b1dbee8,
- 0x06ede1cc, 0xfc7eeff0, 0x72f1a48e, 0xfe87af0e, 0xa21bd612, 0xe5c353f4,
- 0xfe459c93, 0x33ec9b82, 0x62b36b23, 0xc2fe016a, 0xe9399a34, 0xab0c759e,
- 0x9075bf27, 0x51327f72, 0x43bca4e8, 0x3e6186b0, 0xf0a67045, 0xe48f85f8,
- 0xfe4950c3, 0x89f12a75, 0xf447745b, 0xb90d97e6, 0xaaf007ba, 0x910286f8,
- 0x5623e2e4, 0xd8f9ef46, 0xbf13f75c, 0xb016c36e, 0x8f6b336e, 0xf87a1549,
- 0x61bcede7, 0x5c135fc4, 0xb52fda0e, 0x780b2415, 0x8588a52e, 0x4536cb9c,
- 0xc4a3e869, 0x5f42171a, 0x4be84243, 0x9d7f7f4b, 0x3945d5ec, 0xe842ce90,
- 0xe5be2ff0, 0xaf182c51, 0x05fa8f4c, 0x7689d58f, 0xca9e054a, 0x754f9602,
- 0xee319b46, 0x73d18b67, 0x3fd8a579, 0xab9f4aa5, 0xb2eb59e4, 0x566bfbe1,
- 0xf6e649d1, 0xf13d2dba, 0x96df1825, 0xea35f600, 0x5c919963, 0x1fd3b07d,
- 0x7fd43576, 0x65fffc04, 0xeb1bfd0c, 0x65efbc64, 0x5f10e4b5, 0x7949623f,
- 0xd05ef300, 0x437f58e8, 0xe5aff731, 0xef826ce8, 0x05bea151, 0xc23da5ef,
- 0xc1a94cf2, 0xfebc2df5, 0x5164597a, 0x31189f90, 0x9dbfea82, 0xcef86667,
- 0xd9a07781, 0x63ec7187, 0xdd77acf2, 0x7b7feb41, 0xaf07d714, 0xa8f11c19,
- 0x7c991e0f, 0xd287a677, 0x685f8d74, 0xbee4104b, 0x8f8517ce, 0x92bd7236,
- 0x78c7e25b, 0x34c2747c, 0xfd039957, 0xe90bb71d, 0xf112e742, 0xfd375be8,
- 0xa87e2b44, 0x0fc106e4, 0x5d749b4b, 0xe3ff430e, 0x35770b11, 0xd59e291e,
- 0x02f98652, 0xd903ee91, 0xd9ebe25c, 0x7e02aeb8, 0xe54af0fe, 0x181ea871,
- 0xbfdb9a32, 0x3c448693, 0xdffa1430, 0xb15a2450, 0x2b7a0dff, 0x4ef1e7dd,
- 0x1757e466, 0xe097eabb, 0x11096dbc, 0xda6fcf0c, 0xbe781a0a, 0x00ccc0d8,
- 0xbd6b934f, 0x4a69f117, 0xf6c08cf5, 0x7a7e0747, 0x5b19ed1c, 0x703a4882,
- 0xaef9cba2, 0x2817eb1b, 0x79e29df1, 0x9b3c70eb, 0x599ab445, 0xb9541c0f,
- 0xcbc99ebe, 0x0ab2ffc9, 0x0accdef4, 0xce0d436b, 0x708491e7, 0xae6df3b2,
- 0x79e20b06, 0xd13d40c3, 0x7f224941, 0xc2556a57, 0xffcc0ab4, 0x7191a062,
- 0x1f2ff3be, 0x5381fe8a, 0x5b3575a0, 0xc75e681a, 0xc139892e, 0xa9a896ef,
- 0xcf85a1d9, 0xf8f146ef, 0xf1e30990, 0xf5b79f80, 0x8b9a9ccc, 0x78a7a3f4,
- 0x6b7c7f53, 0x7ece5d73, 0x2afe61fb, 0x110b0394, 0xc29785be, 0xfa404f98,
- 0xfe61293d, 0x5b017f77, 0x60d9d680, 0x6e41fec1, 0xbfa2fabb, 0x7e9cd188,
- 0x4b0e0b9b, 0xd7824ef8, 0x341f1021, 0x444e4e5b, 0xb528783e, 0xa1e8e88c,
- 0x899a8f82, 0xfcf3862f, 0xeef779db, 0x137a3c41, 0xe77f69c3, 0x315982a1,
- 0x60bef4c1, 0x32f44894, 0x4e616fee, 0x9463e23f, 0x91fbf881, 0x8c56c708,
- 0xccf3794f, 0x824bbf64, 0x986cd975, 0x2862c4e7, 0x5da2fe87, 0x7ef13e62,
- 0x0b8f0575, 0xd57e302b, 0xf8843b65, 0x31664a90, 0x3949ae7e, 0xef9114f7,
- 0xb435435c, 0x25956ffa, 0xd8cfde97, 0x4270d092, 0xbb20b6d9, 0x5722906a,
- 0x45889406, 0x5906df28, 0xeb655db8, 0xbb940594, 0xaa47fba1, 0xed29d7be,
- 0xa65b328c, 0x371b54a3, 0x7d7015d2, 0xe97f6a1b, 0xc35edc2c, 0xae8fbc3f,
- 0x893f35cf, 0x317438e7, 0x197f7ada, 0x0a739ca5, 0x3a54afb1, 0x7ae560df,
- 0xd1ae4362, 0xa1bd7487, 0x2a59db98, 0x47f2ab1f, 0x872abf85, 0xef7e7bd4,
- 0x5195f628, 0x87365e4e, 0xe599eae4, 0xd4076f78, 0xc317739e, 0xfa56897b,
- 0x1f72aefe, 0x6f6294f1, 0x5bd8a7bd, 0x5bd8a1ff, 0x05bda3ef, 0x835186f9,
- 0x1437bf08, 0x08dd762e, 0x20901af3, 0x3a14df11, 0xedc44c4e, 0x271971af,
- 0x61d97d2c, 0x0ea2d111, 0x348f05e3, 0x36497bf2, 0x1598ed97, 0x95cf59f1,
- 0x766b2cf9, 0xbcbb3469, 0x7ae3f27c, 0xe43ed1d2, 0xb9557beb, 0x994c794f,
- 0xfe6571ff, 0x57f3286f, 0x43498fed, 0xbca132be, 0xefaf10df, 0xfc297e47,
- 0xb9d0a729, 0xb57950a8, 0xe908c401, 0xfc9122eb, 0xe778209f, 0x25bde46a,
- 0x4ef5f720, 0x1e68c959, 0x7660dbbf, 0x7c462c57, 0xa714664e, 0x27aae89d,
- 0xb90365b9, 0xf8b37245, 0xca6ceb5c, 0xe5833847, 0x6381519e, 0x8e5acbb1,
- 0x4638be72, 0x24571f4f, 0x5bbdd0a4, 0x1d0efed5, 0x0cf072f7, 0x82a66795,
- 0xf3e25ef5, 0x6c7247ff, 0x8ee3e32c, 0xfd3a24bd, 0x4f1cde5c, 0x91237926,
- 0x5fed0a7c, 0x636f3795, 0xbe2064cc, 0xfba1644f, 0x610a7700, 0x9de7844e,
- 0x3f307c28, 0xff7dd197, 0x673d8ac1, 0x01d1de57, 0xceb8a14e, 0xf5b04ed8,
- 0xfc7af883, 0x1bf75325, 0x8f8edc6c, 0x9a27e4d6, 0x4bf535e2, 0xef9ac9ac,
- 0x35c3ec93, 0xb23b27df, 0x32ebf935, 0xffea6946, 0xc9a459c2, 0x593050df,
- 0x2e4cbf53, 0x6665e4d3, 0x0e4877a5, 0xfa1eed36, 0xa7fd1eb1, 0xa71fa1b6,
- 0xa14f86f5, 0x0e0bf0f1, 0xa3b5e160, 0x00e8678b, 0x87518546, 0xfc864cef,
- 0x6793d1c6, 0x0aef80e8, 0x3afe1f07, 0xd3685819, 0x7f3c29e8, 0x53afe1f5,
- 0xf465bf20, 0x863f3c75, 0x3adcf091, 0x2f0cea7a, 0xea1c59e0, 0xd0347479,
- 0xea972df1, 0xf83da28f, 0xe6d365c7, 0x4ef84b26, 0x06625940, 0x8a6ce7cc,
- 0x7efc61e7, 0x15acec73, 0xfc761178, 0x8f74f577, 0x79a337ed, 0xfc8b8ebb,
- 0x8b8e8d5d, 0xbb0d1dfc, 0x53f6f1c8, 0xcbbef553, 0x7e9a0e04, 0x64115fdf,
- 0xfd05af7e, 0xdc6939cd, 0xfd14c4df, 0xdfd14c4d, 0xcdfd14c4, 0x6fee7a39,
- 0x26fe8a62, 0x89bfa396, 0x324d5be9, 0xb934efa5, 0x726f6d28, 0xbf7dda53,
- 0x6ae729e0, 0xef380a3d, 0x985b8b4f, 0x1117e4c3, 0x4ae7a14e, 0x4f9df43a,
- 0x45ca7ed0, 0x12fbc0e6, 0x394e2287, 0x39acbf70, 0x2e7444cf, 0x4c3bb674,
- 0x9730bdf0, 0xb62f9be7, 0x617e503b, 0x8e9eed1e, 0x946cb6e8, 0x16b5cdbf,
- 0x35bbee27, 0x23c7f45f, 0x1bd6149f, 0x714cdee8, 0xe9c52767, 0xbdfc2d0a,
- 0xc7114384, 0x91e3288e, 0x9179da5c, 0x277c45f9, 0xb0eedcc7, 0x3f60e32a,
- 0xea326e30, 0x3025c2b7, 0xbf5bf52e, 0xb0a9fa98, 0x842b8f74, 0xe1fa6b8c,
- 0x410a2771, 0x3176a6e3, 0xc701177a, 0xf5c66875, 0xfc3f744b, 0x78c25fa2,
- 0xd3b44761, 0x354d718e, 0x21df8c5f, 0xdfcf45bf, 0xf8742c5f, 0xb893d425,
- 0x5bef89bd, 0x33d881c6, 0x1f0d79d3, 0x47a865c9, 0x5d9db971, 0x9a179d7c,
- 0x9f900bfc, 0x6077958a, 0x7ba58cc0, 0x730c4c9b, 0x9128bea2, 0x38363bbe,
- 0xe339df17, 0x1b15a0ef, 0x1f90dbdd, 0xde5c74eb, 0xdf3318b0, 0xcfb5d057,
- 0x3bd415ff, 0xec983b19, 0x4bfb0495, 0xb404752c, 0x44cae45f, 0x5b24e3bb,
- 0x7568724f, 0x8f7fe794, 0x31be7a06, 0xf4505eb3, 0x7763f527, 0xfdc0ef85,
- 0x86578e88, 0x4d1f21e5, 0x645e3a33, 0x1f7fbfc0, 0x3cfc44dd, 0x8791ca2d,
- 0x7dfdac2f, 0x8f9e0af4, 0x3788bc73, 0x69acad83, 0x8ffc7146, 0xf1452f3f,
- 0xa79a740d, 0x7fb43a0a, 0x765373d4, 0x063613d1, 0xfaeb54e0, 0xd7e7c0ca,
- 0x7078c069, 0xc10718d4, 0x4661e06f, 0x273a98e7, 0xe076f847, 0xfa80df7e,
- 0xb2878c6c, 0xd61e474c, 0xd277d24b, 0xef8ef27d, 0xa827fdf8, 0x50537919,
- 0x8389fefc, 0xf8afab92, 0xdc31c9e3, 0x6a945d4e, 0xa8788759, 0x944c9bb3,
- 0xe748bc1e, 0x9dce9982, 0xd96bf18a, 0xa97bf7d0, 0xfae18eaf, 0x41a57921,
- 0x74410231, 0x30e594c2, 0x0cbde6a6, 0xbbf6d0f4, 0x8bdfbac3, 0x43327003,
- 0xdef3c89a, 0xeb178f1d, 0xac65f534, 0xe31dfddf, 0xbda7acf4, 0x8fcddbfc,
- 0xc6554f2f, 0xc7997a43, 0xd50c7fc8, 0x6d0b6b3b, 0x843f3bea, 0xcc63c7e7,
- 0x523de9db, 0x14877949, 0x4e315aea, 0x3de8ce11, 0x37bfc1ae, 0x9e819afb,
- 0x3d399a76, 0xdd3c8aa7, 0xeafaf229, 0xbbeaa53b, 0x7a14cf6b, 0xa3cc2b6e,
- 0x8fd4fc7e, 0xdf1b37b4, 0x6d6788cb, 0x6efabe34, 0x012f5a94, 0x2b0920f4,
- 0xe23a675d, 0xfb1250ab, 0x63e7e784, 0x1d20e68a, 0xb2f2685c, 0xcdf4824f,
- 0xc6c8f085, 0x49d5fc60, 0x3f5af7da, 0xda81331f, 0x1b6beda9, 0x284fb227,
- 0x3a27e978, 0x69154daa, 0x624ebd1f, 0x9c3be2af, 0xa80d5920, 0xa776d597,
- 0x78e2de40, 0xc5fc82ef, 0xbb903df4, 0x3ed1e89f, 0xfbe94e9d, 0x3f2a1e4d,
- 0x694d54dd, 0xca9ea9a0, 0xa46a6a3f, 0x23db96f4, 0x167f9172, 0x3ec65fed,
- 0xdaf7a209, 0x1027bd36, 0xd4553f94, 0x51ad1d37, 0x7254e8e8, 0x1c9fdfdf,
- 0x53bbedc3, 0x3b3e38e3, 0xf7c0dec0, 0x972e80da, 0xdbfd6d5b, 0xfdca1d1d,
- 0xf9e3a3ae, 0x3c4765fe, 0xc31f2fcf, 0x64596efd, 0xe8fed8ad, 0x3fef0378,
- 0xefc6ac45, 0x7bf78db2, 0x77a45d2a, 0xb1357ea4, 0x5831fee8, 0x73ca163f,
- 0xaea7f27a, 0x41e5dfe2, 0xaf9d5cbc, 0x42b6fdfa, 0x61eefaab, 0x8fcf7f3a,
- 0x7a02f7df, 0xfad5fea7, 0x3e702663, 0x4befad0c, 0x43c9e7e5, 0xc2a9f1e1,
- 0x6817c4b7, 0x241f2367, 0x9d45f107, 0xa542f883, 0xd6fe9543, 0xa7387216,
- 0x0f3a151a, 0x07eee7e7, 0x76842ea3, 0xb4cce383, 0xbbe3208f, 0x9d9eb0cb,
- 0xa12fc282, 0x63bca0fc, 0xca83f2ac, 0x0fbd2a07, 0xefe33e06, 0x8c75f334,
- 0x5f79fa95, 0x7b475958, 0x845dc46c, 0x2b7a83d7, 0x12b1adea, 0xb0792f7f,
- 0xedcef5d8, 0x11b19fc8, 0x96918c0e, 0xf7d4b2ac, 0xfe3ec725, 0x9543c2af,
- 0xa3c0fd0b, 0xca0c1c17, 0x123fc3bb, 0x50e7240e, 0xf6fd238e, 0x8c4eb721,
- 0x177629b1, 0xc7cfdfa7, 0x1d226fc8, 0x1d660875, 0x30e87bde, 0xf05f7df7,
- 0x0ebe78e8, 0x16d68e95, 0xe3074a32, 0x96f6873a, 0xba7aea7b, 0x230779d7,
- 0xc61a97f9, 0xacf143cb, 0xfe482bae, 0xa979c19d, 0xec0c64f0, 0xa127e81f,
- 0xe8ef42c6, 0xe0e856dd, 0xd3f036fc, 0x67ac0dca, 0x3e8a35fd, 0xf8944c7b,
- 0x7e8ac87b, 0xa4172ee9, 0x1a996599, 0xcf4743bd, 0xefe15f3a, 0x5645fb8a,
- 0xa372ef8d, 0x171c1d6f, 0xe5c8521f, 0x3cf4d743, 0x2f13f711, 0xf742d5fc,
- 0xea0c2f8b, 0xcef68d3c, 0x533d5685, 0x2a9b23de, 0x8b9dde80, 0xf90c133e,
- 0xf39ef2a5, 0x0ef7e8e7, 0x176d7a83, 0xb5bda34f, 0x4cc4ab68, 0xeb609e78,
- 0x3d20b737, 0x4f457bcd, 0x5b9a99e7, 0x7a471e37, 0xc04fb73c, 0x85d96fe7,
- 0x31c5027d, 0x7c225b6b, 0x0a5fa866, 0xc77fac79, 0xe3c7c96e, 0x39c5328b,
- 0x3ef1946a, 0xa0a5d731, 0xeb713e5d, 0xfb843a5d, 0x8b02edbc, 0xb48f7e83,
- 0xdf0c79de, 0x8db7391d, 0x366b2fdf, 0xf9c0ee47, 0x0ceb4a97, 0xc17ca083,
- 0x635e5e76, 0xf70cfd29, 0xcd3c1743, 0x60b3fe28, 0x8ff9046f, 0x1ff45af3,
- 0x8eec8205, 0xfcda6dea, 0x4066d67c, 0x53b0583a, 0x07b35e5b, 0x79f241f2,
- 0x2f12a150, 0x29b2ce19, 0xe3c2d25e, 0xef7caa07, 0xb97b5f6d, 0xde506d1c,
- 0x897f66ff, 0x5f0ff7a5, 0x23e926f9, 0x2997cf0b, 0xff9033f9, 0x178e1bea,
- 0xca752e15, 0xb3c55fd8, 0x675836dc, 0x2b662bdd, 0x0775edfa, 0x79e246ce,
- 0x016145b0, 0xbd99177a, 0xded1592c, 0xe4bf607b, 0x1ed6f845, 0xfb893f34,
- 0x9e2f7598, 0xa13c6030, 0xb262df74, 0xef312657, 0xfd9bf44a, 0x89dac8a2,
- 0x7de9da8e, 0xce77265f, 0x1c2e7ec3, 0x0ed15b30, 0x4ff97ba8, 0xfcc76ec7,
- 0xa7dd028b, 0x201890bc, 0x55b7993a, 0x0c437ba2, 0x1efcb42d, 0xaf10913a,
- 0x28b6e788, 0x0ee58f7a, 0x19e23bc4, 0x4648eef0, 0xd071e13a, 0xf44b4f79,
- 0xd9b5b9bd, 0xf9cff580, 0xbc557e38, 0x094b4a97, 0xe71e0bcf, 0x75b89cf8,
- 0xa430e6d7, 0x64f5a783, 0x76811f8f, 0x0d3b7883, 0xe15e181d, 0xc5d85ffd,
- 0xd37791cf, 0x376301c1, 0x2f3ce01d, 0xa7c00747, 0x472ff7a4, 0x97e89d07,
- 0xddffbf92, 0x0ed0c7b9, 0x87e7e08f, 0xd51b77d5, 0x2e071a77, 0xdf14753c,
- 0xbfb34ae7, 0xa5777640, 0xc5da8bed, 0x9d09de8c, 0x4be78853, 0x02bdbf26,
- 0xca7277d1, 0x2f14d9b3, 0x6d7607d5, 0x744378c1, 0x3ac7c538, 0xe1b6cb92,
- 0xb6c598fb, 0xc2f6936f, 0xcefd163a, 0xeb11e748, 0x3fc67e15, 0xbea2073c,
- 0xa7780c4b, 0x07b519f3, 0xc65cfc8d, 0xe1fbed3e, 0xce9cf11d, 0x959d0c4b,
- 0x804fd18b, 0x411c70fe, 0xc2e9fee6, 0x451dfc83, 0xa85c9fd5, 0x47b8a7be,
- 0x60836efb, 0x3dea9b7d, 0x70429850, 0xd6371a18, 0x73797681, 0x0d84f339,
- 0xc17d21fd, 0x5c7ca9df, 0xb5fa8bf1, 0x1bd1fb27, 0xbcc91daa, 0x15daf721,
- 0x014775b9, 0xbbd1e39f, 0x7be1d0df, 0xf93b1d8c, 0x3fcc3bef, 0x062af208,
- 0x1af519f7, 0xd4a753b9, 0x0fe914ff, 0x5bde76e0, 0x052892ff, 0x8bf797cb,
- 0xa79a9fb1, 0x48753f79, 0xf5571457, 0xfe830e6f, 0x33d36cbe, 0x4c0597e4,
- 0x23fb3791, 0x4bd46e28, 0xbedcecbe, 0x50f7cd12, 0x76085aba, 0x94222e26,
- 0x69f6eabe, 0xa85d3deb, 0x670e7bec, 0xfff9e0d7, 0x90e031af, 0xba5f23d7,
- 0x8e67e9df, 0x6eefe428, 0xef68287d, 0x056b0fef, 0x77ea0f96, 0x63c4cfb8,
- 0xeafe4aa4, 0xfe4d56dd, 0xa6bb369a, 0x1dfbb5fe, 0xfed9ef9a, 0x11f7cd0c,
- 0x7c9a9dc7, 0xa6817b5e, 0x64f7c8fe, 0xc0547e4d, 0xe63fa9a5, 0xef935bbc,
- 0xf4f584ca, 0xe9a8cf61, 0xa9a0bb24, 0xd661d93f, 0x465d7ff4, 0x65df26b4,
- 0xd8a3e051, 0xfbfdaa99, 0xff6e42a7, 0x7c2aa686, 0x8ed4e17f, 0x37edfaa3,
- 0x2bc76814, 0x5de3b593, 0x1df05e29, 0xff9e9d41, 0xf8a6027e, 0x34ba09fb,
- 0x9809fbfe, 0xc04fdfc7, 0x013f7f14, 0xe4dd7fcb, 0xa6befca4, 0x04bfca02,
- 0xf7e6097e, 0xe9829f83, 0x609fe0cb, 0x77e0e5f9, 0xb8f7194c, 0xca1bee32,
- 0x4e153fb8, 0xbdfd296f, 0xef87f4a3, 0x3df4ea0d, 0x795d6bdf, 0xe3e025e2,
- 0x7467db22, 0x086e595f, 0xa31c6294, 0xe18975f3, 0xf1e667f9, 0x418a6f1d,
- 0xa18036fd, 0x9ddcc49d, 0x6e3ee26f, 0xad438bdd, 0x81efae78, 0x07787ffd,
- 0x27d85fbf, 0xf0e6bc51, 0xd891b3fe, 0xc29797cf, 0xe90a30e9, 0x7cd7c845,
- 0x0d7e502b, 0x6773c77c, 0xca4af793, 0xa46d67bb, 0x554cbeef, 0x2fba3ef3,
- 0xd7b3deed, 0xb85a7880, 0x7f7d2f7b, 0xf35af81d, 0xcd76f77d, 0x87d62b77,
- 0x47cea174, 0xf7cf8571, 0xa9f9fdab, 0x7f2a4d7e, 0xddf3fe3f, 0x418e5647,
- 0x6ab7bc7d, 0x17b5c600, 0x3b1139ee, 0xf1f007fb, 0x66cf4bd5, 0x3da81ea2,
- 0xd1e72920, 0x07b57f78, 0xcf9e4af4, 0x6f7526bf, 0x63379e29, 0xb3ba047b,
- 0x4f5b25f4, 0xee16c4e7, 0x728355df, 0xedc66176, 0xb57f8a7a, 0x83bc4a49,
- 0x6350d3bf, 0x6baedc65, 0xdf123afb, 0xdb7dffa9, 0x1ef1ebd1, 0x23c1c774,
- 0xc74c5ef4, 0x4fe3493e, 0xf1cb1d8d, 0xf72c763b, 0x77dcbeff, 0x09cf1224,
- 0x8476d03e, 0xa7e75dc3, 0xf2561ff5, 0xbc12901d, 0xfeb44bf7, 0xcd2497f9,
- 0xc0b801ef, 0xcdfba171, 0x7022d3fb, 0xf8db275d, 0x7d40d378, 0xd56a7950,
- 0x1bff9c1c, 0xe53cf2f6, 0xddfa327d, 0xaeab8ea1, 0x767285db, 0xe7d49b61,
- 0xd839f779, 0x98efcc2f, 0xebe9d39e, 0x1b1c2fa9, 0xc37f7004, 0x749b2035,
- 0x62af5284, 0xa59bd72c, 0xea2a4f06, 0x47169391, 0xfdf9d204, 0x8811a1ae,
- 0x6298c3df, 0xba49ebb9, 0x1f60be07, 0xb5a4ef1f, 0xeee9123d, 0x5211bee4,
- 0x2dcbfef0, 0xe9ba7aca, 0x5e6f1bbb, 0x6fb553c2, 0xe9fb05bb, 0x9f2f1fc1,
- 0xf54ad636, 0xb89df0df, 0x93aced05, 0xc0ddfc19, 0xfe460663, 0xdc3dc2f5,
- 0x70793e4e, 0xfbe0f6f0, 0x7c14d359, 0x7df06474, 0xf5fb0bf5, 0x77dbbd4a,
- 0x3d3d4d31, 0xed4ed7c7, 0x33beac7c, 0x5e7da10f, 0x6744b8f3, 0xf5f46a1d,
- 0x4ffeb8b1, 0x57e769b7, 0x46b9c0ad, 0x0d8d8fef, 0x039ad7a2, 0x21637cdd,
- 0xf2a03f3a, 0xa9f08389, 0x8664f1e2, 0xe765e7c4, 0xecd5f8ef, 0xdd7445dd,
- 0xe3c4be3b, 0x31ef83b7, 0x74be2939, 0xb55a7f19, 0x2dfc821b, 0xbd23bdfa,
- 0x989e686b, 0x9c1f63d2, 0x1a1f942e, 0x987e879b, 0x93ccfc9b, 0x185bec0c,
- 0xebed16b3, 0x891dfa28, 0xd76e38cd, 0xffbd3d3e, 0xb03a6b5f, 0xef23df00,
- 0xc0a30272, 0xe9b6bbbc, 0x4667dfbb, 0x629e773b, 0xf0ea7ee7, 0x7fa04be4,
- 0xb489976b, 0x923d9abe, 0x5c17cf0f, 0x57dee450, 0x406f937b, 0x2e39ad7a,
- 0x9a3fd159, 0x70fc96d8, 0x77e92e61, 0xdaeb57b2, 0xb75c9db8, 0x58bb205b,
- 0x156a43b5, 0x629ce43b, 0xd65b9f07, 0x57e3edc9, 0xea11b604, 0x7b030dad,
- 0x9b5de604, 0xdaec8539, 0xcadd695a, 0x473c0ec1, 0xe61bb5a5, 0xe7443c1f,
- 0xd1cec0ae, 0xaddc2f94, 0x69b6d7cd, 0xf8bfaaf3, 0x3b6ed8d2, 0x37fa3863,
- 0x1c615225, 0x0a9bc3f2, 0xe77f555e, 0xf49c6bce, 0xe80f27fb, 0xb8d4531c,
- 0xd16bc204, 0xc7cc2f2b, 0xc26afb79, 0x347fe49c, 0xdae096fe, 0xd7ee17f1,
- 0x1bdee074, 0xf0e333f2, 0xe9cfd8ed, 0xf05e917c, 0x2cbaefe1, 0xfd815d42,
- 0x32df0499, 0xbb7b3b8c, 0x293e4922, 0xca1a08e7, 0x632affb9, 0xb2a6180c,
- 0xe7f72c7e, 0x38eaf543, 0x0e8a405d, 0xb1811392, 0xd8af5429, 0xde57cfc0,
- 0xfd24e119, 0xedc4c436, 0x6e2621f5, 0x75d10faf, 0x85dfa32e, 0x7df02418,
- 0x6997ac8e, 0x9d6d60ff, 0x0417f685, 0xe10e957b, 0x955076b1, 0x887de90e,
- 0xfd032db5, 0x8c5f353a, 0xec7b33df, 0x478b5283, 0x8cece387, 0x047d9417,
- 0x74cb4fae, 0x90747d56, 0x996c657e, 0x3dea7e66, 0x7e7d9fcc, 0xa59f9856,
- 0xef807e67, 0x75ff6c28, 0x86ec93ae, 0xf7f532a4, 0x2e49ea1a, 0x12fcf0a8,
- 0x7018bde8, 0x816c7745, 0x1db66a6e, 0x96b2ff22, 0x76c4afb5, 0x1d7c91a5,
- 0xbefe06a5, 0x4f186951, 0xfcb8e375, 0xa5d2512a, 0xc3f6b4e3, 0x7eb27191,
- 0xc63ba41c, 0xf2e34db9, 0x79953f68, 0x6f0d7d61, 0x43d677f3, 0x13943ee5,
- 0x7c0d7d3d, 0x466ff288, 0xd54d60bd, 0xbf9c69d8, 0x6ea2f116, 0xf6f85a3e,
- 0xea27c493, 0xc66acc39, 0xa3667bf9, 0xc41a9ad9, 0xdf908b17, 0xc377ded0,
- 0x138c7cbf, 0xeb6abff0, 0xe9973a7c, 0xa2b58c69, 0xfa48b75f, 0x7e25f692,
- 0xda2ddf2c, 0xcdfbcdaf, 0x11fdfe9c, 0x1949f902, 0x0de3bae3, 0x0a498fc4,
- 0x08f76c7f, 0xfb600e74, 0xcf1e3a77, 0x7e2810ab, 0x36143377, 0x624994da,
- 0xba22eabd, 0xe333724f, 0x4b596347, 0x3dbbf28c, 0x796fb431, 0x9beeb293,
- 0x2843fe75, 0xdbea8e57, 0x749e3192, 0xc4e4d6b4, 0x1b59cbfe, 0xc15a6fbd,
- 0x153d29da, 0x9fa2f75e, 0x2226f73a, 0x63c9fddd, 0xf6d678a4, 0x50223be5,
- 0xe5b167be, 0x044fdc56, 0xb7c6ec50, 0x73b3fb01, 0xd51df742, 0x2f60c4fb,
- 0x027d21c7, 0x1d2127fe, 0xd8dc079c, 0x5fb77a73, 0x2317c7f8, 0x2c5f7f11,
- 0x5b96e179, 0x9d5ffa19, 0xa82d47e4, 0x5df7465f, 0x33da9c81, 0xaaf07bf2,
- 0x5bc55de2, 0xf01d5e37, 0xb0af182f, 0x938404a6, 0xc91965f4, 0xe8917fa5,
- 0xf0e5d69c, 0xbc7dc2aa, 0x0e3b9f82, 0x8a15f970, 0xb70f156f, 0x43f5bbe2,
- 0x236eef49, 0xc923313c, 0xb87a50cb, 0x3080be1c, 0xc4d93ce9, 0xa1f92318,
- 0x4f2e4583, 0x2813cf07, 0xf33b795e, 0xf48012bc, 0xf5f7f096, 0xc70adefc,
- 0xb782855b, 0x2fdf313f, 0x71ff9232, 0xce323b78, 0x606e34dd, 0xe50dbe6f,
- 0xb2f8fed3, 0x37fce1c6, 0x18fa5f55, 0x3f0863f2, 0x376bf087, 0x2ff09d1e,
- 0xc69e8f08, 0x6ecbe248, 0xae7b4b7c, 0x7fe22f4c, 0x5fb58e30, 0xaf93f9f0,
- 0x46055f80, 0xf8f8bfbf, 0x54dead38, 0xa5c2a6f1, 0x07e0b8bf, 0x2ad47fcc,
- 0xe70abed0, 0x748dbbe3, 0x57dd43ff, 0x5e4ff751, 0x5cf5c719, 0xd801fa68,
- 0xb55fb84b, 0x40e4e326, 0x194f33b4, 0xfef87ed4, 0xdacb07ef, 0xb6f7f113,
- 0xe9e2283e, 0xddff0329, 0x872f350f, 0x07e4b8f1, 0xc22f46f1, 0xf86103e9,
- 0x1f33d404, 0xcf5cf708, 0x070671f3, 0x26e3cbe6, 0x53903de0, 0x798e357a,
- 0xf07f12bf, 0x8f9479f1, 0x027aa62c, 0x074a5dff, 0xf61ddefe, 0x1736082b,
- 0xbb83e7cc, 0x9d7de8d2, 0x718d7dee, 0x467f0edc, 0xdc774759, 0xe2815eff,
- 0x355133fe, 0x84c4fee1, 0x877c2e2d, 0x437df4f3, 0xb4df69b3, 0xea3e3b41,
- 0x978a64fd, 0xfee7e06e, 0xabea752e, 0xb75bf482, 0xc8be2dbe, 0xd1e4e7cb,
- 0xbfa88cef, 0x86db2747, 0xc7dcff73, 0xd550df7f, 0x5fc75d67, 0x73c704b0,
- 0xdfe2533f, 0x0fe1f9dd, 0xc3eb0526, 0x4dad4f43, 0x0daa7ec7, 0x05a72cde,
- 0xb1ee877f, 0xaa5bb424, 0x4e955a9f, 0x0f53f4f6, 0x545fa3a4, 0xba6d63bd,
- 0x0f70f94c, 0xbe3a65f9, 0x1b9e2fee, 0xd4f3e745, 0xdccaf6fe, 0x1d30a8af,
- 0x3dbd412a, 0x56afeae5, 0xda41fee0, 0xffc5027d, 0x15f6b066, 0x332b67a8,
- 0x16b15f38, 0xe87fc913, 0x776bf68f, 0x4ec5ff0d, 0x646f0794, 0x81cfd59c,
- 0x203e127a, 0xd5df1035, 0xdfa3adf2, 0x7fcd5c09, 0x7ea7b027, 0x56ffed22,
- 0x9de8172d, 0xfcf519ab, 0xf1a4f377, 0x59c704d1, 0xd18fb3ab, 0x794b57fb,
- 0x6fa314f9, 0x67ec49df, 0x3fdf818b, 0xe094ee64, 0xb29270fb, 0x9d73385f,
- 0xca717bf2, 0x639b6938, 0x53af07b7, 0x591df652, 0xdf2477ea, 0x32f0506e,
- 0x5789e975, 0x54efd0ed, 0x1e3cc7bd, 0xe9b3bfbe, 0x619faa5c, 0x3a33f41c,
- 0xf066985f, 0xd71f3a3c, 0x7148c3bd, 0xc1acdcd2, 0xcfd41c52, 0x11b45259,
- 0xab4b99d3, 0x728f9d1e, 0xcd94d5b8, 0xf9f2358f, 0x114e0835, 0xed91f4e5,
- 0xb842ceb7, 0x7fc4df9d, 0xfb61abff, 0xc2ddfa30, 0xafdee4fe, 0xf9eff89a,
- 0xa264dd3d, 0x2b26d9f4, 0xcfeba3c3, 0xff29d935, 0x4a0e4daf, 0xcd3cf4d9,
- 0xd7f4d8ef, 0xe14b88df, 0xb973bbf4, 0x3bf4cdab, 0x39460d88, 0x2bc03c75,
- 0x1ddaaaed, 0xc2eb280f, 0xbdb2b8f7, 0x0e1113c9, 0x3e2c0fb9, 0x75b3a686,
- 0x7d97df3c, 0x24eae4f3, 0x2c77d614, 0x7cc4f33d, 0x78fb7ef8, 0x270835f7,
- 0x148bb6d3, 0x607238a7, 0xbbc22555, 0xaf91877a, 0xf9f7594f, 0x8f71e94d,
- 0x75f97c62, 0x160dc53d, 0xc4f33b6d, 0x877f0c03, 0x9821b177, 0xbd74afde,
- 0x7ee78f57, 0xaaf8e5e6, 0x78fc383f, 0x449b5abe, 0xf803b3fc, 0xf3a7f32a,
- 0xcba5a2d5, 0xc6cb7e08, 0xb8426fbb, 0x937bd79d, 0x0fce9f90, 0xee744b1f,
- 0xf820457d, 0xdbbc72ab, 0xbfe056af, 0x575b6c50, 0xc723dc98, 0x04b961bf,
- 0x3e0743df, 0xf9fb474d, 0x3fe5fd9b, 0x6097eeb8, 0x1861fedd, 0x1a5133af,
- 0xe0df3dfa, 0xf584ea19, 0x3ef3f7e5, 0x6af1d2e8, 0x539f9ffc, 0x36213fc0,
- 0xe6219df8, 0xd4f9828d, 0x61fc141c, 0x26cfa859, 0xbf43a67d, 0x8fcffc11,
- 0x198ce734, 0x9f4828fb, 0xcbdf37f7, 0x4fd875a5, 0x1ddc8f5a, 0xfcc89ef9,
- 0x547b7a41, 0x83f98c20, 0x73f6edc6, 0xfb40cca0, 0x1724f14e, 0x2e786f10,
- 0xe181c2ec, 0x99ff303b, 0xc2f1e381, 0xf14f604b, 0xf2931078, 0xd9f9d67b,
- 0x50b22f81, 0xb7ae86ce, 0x882fe5ee, 0xaff66a3e, 0xfad028ba, 0xcba67f27,
- 0x0ffafcba, 0x1645f53d, 0x7d33efe2, 0xb6fd1f20, 0x1640860b, 0xb7eea1e2,
- 0x58ff9e5c, 0xf3e5a838, 0xf7e81b57, 0x1304eb3a, 0xf48949d1, 0x2e1fc525,
- 0x87f1e71c, 0x924f03ba, 0xc83aed3c, 0xc48b40e3, 0x8c38d2f6, 0x399fd49b,
- 0xcbacf286, 0xe831fdce, 0x2b71de9f, 0x41e8aa1c, 0xde12675d, 0x4dd83bf7,
- 0x3c8fdc0f, 0x0c3bfc8f, 0xf3a369fb, 0x9c2b2cbd, 0x39f15da1, 0x7c30f3f2,
- 0x257930bf, 0xdf79f9d2, 0x8f941cc0, 0xadfd666f, 0xbf86e28e, 0xb27ba70f,
- 0xe6926db5, 0x3af7799c, 0x703f127c, 0x29fb54c4, 0xe7c1c99c, 0x1b8e0cb9,
- 0x837e6ec8, 0xba2e13ef, 0x7b13f38a, 0xed53f399, 0x7b0643f2, 0x15bb7f50,
- 0xc8ed527e, 0x1bffbf29, 0x85b3e5f1, 0xd504fd32, 0xffc7a54f, 0x4cf7fe9f,
- 0x33412fff, 0x800063ec, 0x00008000, 0x00088b1f, 0x00000000, 0x5aa5ff00,
- 0x5554700d, 0xbdef3e96, 0xdd2749fe, 0x12421349, 0x42068408, 0x03621a88,
- 0xc4d67281, 0x206efce9, 0x6b01bb33, 0x8d08c42d, 0x749d2422, 0x6aece882,
- 0x021a6eb9, 0x367564ac, 0x1d47598c, 0x809f9b47, 0x9476ec28, 0x0da0c040,
- 0x6ba2cb0a, 0x3a26aa45, 0xab545b55, 0xa6e00eac, 0xd63b8223, 0x3be7b8e2,
- 0x1dddb5ef, 0xa6ed4fe2, 0xee7dba8a, 0x9ee7b9cf, 0xce77ce7b, 0x52b48f3d,
- 0x6a22ca22, 0x2a08cdcf, 0x6ea6ff0a, 0x6d4445a2, 0xf67f2429, 0xaf1f4541,
- 0x7dbc64d3, 0x58c9a340, 0xce08eb93, 0x4754419e, 0x459a26dd, 0x654284b4,
- 0x29bf71a4, 0x795bcbf2, 0x6d0dfebc, 0x61931741, 0xb06aad1b, 0x7aa6d513,
- 0x1314360b, 0xaacaab0d, 0x0bcc6286, 0x4b9d2e95, 0x7efe0df4, 0x879b744a,
- 0x2a224f99, 0xf60f14d3, 0x169c9d1b, 0x8b5dc9dc, 0x491bfb97, 0xeaa7984d,
- 0x534f98f3, 0xa3827c08, 0xd81d4b25, 0x9964b468, 0x8eef3e23, 0x07d6d237,
- 0xd2a14e31, 0xf9f6123b, 0x68858f4b, 0xcb17d121, 0x650faa17, 0xdaae79f2,
- 0x51337403, 0x29ed768d, 0x70ddf785, 0x05564ccc, 0xafbc67fc, 0x670239f2,
- 0xfa65ea34, 0x790a4752, 0x4bceccac, 0x1bcf0f1e, 0xd8293b99, 0x3f6fe7c5,
- 0xe78990a0, 0xeeb11db5, 0x6d79e14c, 0x9bb648e6, 0xf036ddf7, 0xdb878b3b,
- 0x2cf7fef6, 0xcf58b9ae, 0x9e433647, 0x6dfa1514, 0x174ff277, 0xce607f91,
- 0x3f3177fb, 0xf44d69ff, 0x67bd37ed, 0x05d7d621, 0x5afd8f9e, 0x82d5f60e,
- 0x56f0a56e, 0x3cfdda27, 0x9bbf48af, 0xe5dff86f, 0xb386575c, 0xf8be7e38,
- 0xa7a25d39, 0x69f8bd18, 0xd602f73e, 0x43eb468b, 0x21ee5976, 0x6e717b96,
- 0x252e8ece, 0x5fae9d71, 0x4b69768f, 0x9d15cb0e, 0x6615b8a9, 0x6c0d4d15,
- 0x851f4276, 0x1797b38a, 0xb97f5f47, 0x9bf42d74, 0x9dbd2c12, 0x90b517cf,
- 0xc7e2c7dc, 0x04b49bb6, 0x6a0f1679, 0x3443dc1e, 0xc90e9a95, 0xe2a77bbd,
- 0x61bca83e, 0xd61267a9, 0x2b7bbe8d, 0x7955196f, 0x73fafdbd, 0x7975ca04,
- 0xc9a9b0ce, 0xd7721b7d, 0x80ede5e7, 0xc400d9fe, 0xfaa94e8e, 0xc7951efe,
- 0xbfd7c7e7, 0x46a79c68, 0xf089ce2b, 0x9dc506f8, 0x9f671ce3, 0xf587bb58,
- 0xe9ef86be, 0xb46fbe45, 0x6938752f, 0xfda26ccd, 0xff42b91d, 0xda4b8773,
- 0xf4914750, 0x16e1d2bf, 0x2dc760fa, 0xf0ea1f42, 0x51d03d08, 0x8ed1ed27,
- 0x033fe906, 0x708cff51, 0xe2ec20a0, 0x4a6d7c14, 0x1cce1e9c, 0x9e494f43,
- 0x24a99c3f, 0x991453d3, 0x3cb870ff, 0xa5fa6018, 0x939ca732, 0xc0d1ca8d,
- 0x4b4e68fa, 0xb40ca12f, 0x674a41f9, 0x037bb1bb, 0x3ffbb61e, 0x43daedd4,
- 0x4bcfc533, 0xf33aaf30, 0xdbf846ce, 0x692b2ce5, 0x1ec3cfac, 0xde63dfef,
- 0x0555d3e9, 0x683fd1db, 0xfef95b73, 0x94dc5787, 0xff47bd01, 0xb78d234d,
- 0xb05a28ae, 0x0ae994b9, 0xcc7622bb, 0xc86e6efc, 0x4fc6bb66, 0xb83553e6,
- 0xe3a4d4ba, 0x02b67384, 0xc1aeb7fd, 0xdb261b3e, 0xfc795816, 0x57f7b94a,
- 0xf7a627d8, 0x0aeb29da, 0xd98bd0bc, 0xf3cabef5, 0xa66eff02, 0x80f79e5e,
- 0xdf649dc3, 0x822bcb47, 0x45c59bb0, 0x07cf36b3, 0xd9ba767f, 0xf5bb3fbc,
- 0x51e7c87e, 0xc14e94d3, 0xb8099731, 0xf3fdc410, 0x452e953e, 0x716c30ec,
- 0x7f993299, 0x2b22b538, 0x194eebc0, 0xb8da7df7, 0x7dc633ef, 0xd5fdc3bf,
- 0xfdcbbedc, 0x1fb88768, 0x9e988aed, 0xd085a34d, 0x0da7f05f, 0xef44792f,
- 0xa3a0f9a3, 0x3b0e5a66, 0xd33f025c, 0x81bf27f1, 0x5ca278e5, 0x036ee397,
- 0x6b6e867f, 0x85d7d3e8, 0x858b4f84, 0x4bffb0bc, 0x9f609f58, 0xf5f175b1,
- 0x9bb2ed24, 0xe7c29029, 0x20b6c3a0, 0x895344f4, 0x0ecb5f80, 0x692e08e7,
- 0xcf8ab329, 0x017a644f, 0xabd29e09, 0xae5e7d56, 0x85fc216b, 0x8cfb2475,
- 0x9980d504, 0x399fc4ed, 0xf2c99854, 0x167e188e, 0x49fd0fa3, 0xcff6fc13,
- 0xd7db9a67, 0xfe7cfd14, 0x13854365, 0xa9b15eb0, 0x4eff33b0, 0xe1acfc7d,
- 0x0699fe87, 0x943ce33f, 0x7dc7ca12, 0xce1d8f44, 0x2ee987bf, 0x1ead787b,
- 0x8285c207, 0x5c2e14df, 0x42549c06, 0xd44dc8e7, 0xaf7dfc77, 0x47d027e9,
- 0xfdd079e8, 0xd3af7fc7, 0x6739df4a, 0x50a4f8e2, 0xfd04e2be, 0x3df74181,
- 0x409dc13f, 0x87395f9b, 0xdfa6cb71, 0x3327ab7b, 0xa783586e, 0xff37603b,
- 0xed97dba2, 0xd027ff40, 0x2b11cb5b, 0x0f2b2ec1, 0x0af67ff4, 0x3bf4b78f,
- 0xa8fb80dc, 0xbbe88667, 0xc7dec8f3, 0x7d236f61, 0xae87f166, 0xfe7bbffd,
- 0x25679911, 0x35bd5b98, 0xcfbc4a54, 0xe37fe3d1, 0xb49f6135, 0x6fd015d0,
- 0x39179c57, 0xfeea27ea, 0xa9f1543d, 0xf5bd0037, 0xc46bf81f, 0x0a0cfab5,
- 0x65e96ec0, 0xe46647be, 0x6a86f57b, 0xc771e12a, 0x6ff04ad0, 0x86eac97b,
- 0xcd5efa9d, 0x5f1f84a9, 0xfb14ccf3, 0x3bb1be6b, 0x3d57711f, 0x23cf6fba,
- 0x23679859, 0xc99edbc8, 0xf57ac476, 0xdd163b69, 0x6bb7f72f, 0xf7206fcf,
- 0x64ed1b3e, 0x03cccd3e, 0x99ef35fb, 0xd1f00c1d, 0xe3fafb5e, 0x1a87b895,
- 0xe83db9ed, 0xa6dbb2bf, 0x2d670f42, 0xf8728c9e, 0xbbb359e1, 0xba0ceb17,
- 0x2ea27879, 0x56a45a4f, 0x3bab2fee, 0x37d7711f, 0x80bfe1f1, 0xf75af5dc,
- 0x3ce2cff3, 0x3884ad7b, 0xeb1f6171, 0xe85dd78d, 0x2dc7cf35, 0x9873ec8f,
- 0x94972f60, 0x82cf95ee, 0xef3eaf7f, 0xf45bad92, 0x439de819, 0x11e78fd8,
- 0x6525f2e2, 0x85ff527b, 0x5e25bdde, 0x97c5dfd6, 0x09bd8bea, 0x17f31bf6,
- 0x526b6edf, 0x6024147c, 0xbf19f25c, 0x3b2019c9, 0x8366dfc7, 0x99e878bc,
- 0xbe296791, 0x737ee2fe, 0x6a3ac2d8, 0x94e6d2b6, 0xf83fb8cc, 0x0ebcfef2,
- 0x3ba9f3e7, 0x34c7910a, 0x84ac882f, 0x51b05c5f, 0x7bcf2e4a, 0xbe5f88db,
- 0x2a971b83, 0x4f2ddf25, 0xc7ee854d, 0x38f57357, 0x16c07576, 0x1ddf280c,
- 0x83a3fe8f, 0x8eccef9c, 0x67af77d3, 0x7e71297e, 0xad425b6f, 0x2db7de6e,
- 0x738fc753, 0xe33f7f3c, 0xcfb19558, 0xe79287aa, 0x299152df, 0x8966d3f6,
- 0xc60e2214, 0x88ac2ff8, 0x10a45ae1, 0x5d763578, 0xe013d23d, 0xe08acbc8,
- 0xf2a0ef88, 0xa86e96a1, 0x4fae3b34, 0xa8204a5f, 0x0f7f8c95, 0x7b8c8bb9,
- 0x55ef5e60, 0xdbe57ee8, 0x98d8f36f, 0x246a4b4f, 0xab53791d, 0x7c8e9223,
- 0x46a8e468, 0xcbeb8d3b, 0x199ff18a, 0x4649afdf, 0xf6643fb8, 0x8fdbc6d8,
- 0x6f3c438f, 0x2ab37e1d, 0xfdd0a93e, 0x4d2069a6, 0x646723f6, 0xe9b6ec11,
- 0x3875e4b9, 0x1fc133a7, 0x65760647, 0x8fe2137b, 0xaa3b90cf, 0x137e287c,
- 0x7ca3fafd, 0xa54f81d8, 0xf6ab0acd, 0x65b1af22, 0x3a294d0a, 0xe5b1b01d,
- 0xa7b4befb, 0x5e2e7ec2, 0x1e3f156d, 0x73822251, 0x0aae27b9, 0x23988c3e,
- 0xca8e7382, 0x18fc11ff, 0x09591099, 0xb4adcadc, 0xc9f196af, 0x1e2e9591,
- 0xa0c2b2ff, 0x03e491a7, 0x57322785, 0xb5ea4f03, 0x3711b7d1, 0x09d99769,
- 0x7be9893f, 0xa227a19d, 0x783b86c7, 0xb3410ffc, 0x4e61f10b, 0x0be462a5,
- 0xb5f9f896, 0x908d3fb8, 0xf841c0eb, 0xdddd9367, 0xfdc1a32b, 0xbc1f20af,
- 0xe5dddb33, 0x326f5eba, 0xcacae587, 0xee2d6afc, 0xfbdd3b29, 0xdfcc158f,
- 0x07c91c5f, 0x4bb5b1ce, 0xdd7b6a1c, 0x47fb13ba, 0x807ba3cd, 0xde1c175f,
- 0x9f582b27, 0xada196ad, 0x67d22ca5, 0xa429c8e6, 0x6f604bf8, 0xbdba2382,
- 0xb2ef148d, 0x561e9f08, 0x9767eb2a, 0x4b940f71, 0xa1f603b4, 0xe6fcf7e8,
- 0x00efabc0, 0x6686466f, 0xf58f4e09, 0x4f030ba7, 0x3e3703a6, 0x981ef8e0,
- 0x60ffef13, 0xfa0b5ef5, 0xc3b8bf97, 0x9ef6e112, 0xbbe7c9cd, 0x0cf6ed7c,
- 0x9e3d0bf8, 0xec7b0fd0, 0xeac7a649, 0x4e197605, 0xe88083f2, 0x29c79cfd,
- 0x0e54b7f2, 0xdf0f41b5, 0xd698cbd2, 0x6313e812, 0xa9f331e8, 0xce1fcf41,
- 0xb6f84879, 0x430f0b4e, 0xcc07236f, 0xe4ef7c04, 0x7f7426b8, 0x1aef105a,
- 0xadc700f5, 0x216e3d2c, 0x0fa4b45e, 0x8cbdc4ad, 0x989d5bf4, 0xa7c8e9bf,
- 0xdb3f38f9, 0xdbce3e63, 0x3670e472, 0xf78dcec1, 0x6cc7c704, 0x1ff4b78c,
- 0x24bbc6c9, 0x86aadfd6, 0x4717210a, 0x47e012b8, 0x85afdfac, 0x8b7f210b,
- 0xf1825432, 0xf996e428, 0x49a06b4c, 0xe8aad1ce, 0x34474f7e, 0xf7b1f9c1,
- 0x6e8551f6, 0x250f8caf, 0x1d3707c8, 0xb11254bd, 0xd9a0f1c7, 0xe81395c0,
- 0xdffdd62f, 0x09c0c8b9, 0xbf0cda5e, 0xbc27071f, 0xf5a3dc31, 0xae7dc816,
- 0xb63b9742, 0x3bcaf85e, 0x6de32023, 0x992a5daf, 0xc6758c59, 0xa3c04a3c,
- 0x017c7159, 0x0e0ae40e, 0xf367326c, 0x2bcf7cb9, 0xd25e4eee, 0x96b1b8dc,
- 0xd33ad3a7, 0x6bd0b5fd, 0x5de40513, 0xb1ae5637, 0x8570f476, 0x553ebf7e,
- 0xf6fb8f7f, 0x964ec128, 0x7d6322eb, 0x9bc17cee, 0x5d67f030, 0xf85ac6f5,
- 0x7e597ddf, 0xf9bbe24b, 0xedaff887, 0xadd7a649, 0x339b58df, 0x1efb9f8e,
- 0x126a7eda, 0xd9afcf5d, 0xdb36a3bb, 0x4c7f7d75, 0x98b68bee, 0x49e6959c,
- 0xbe58fa89, 0xb71276b1, 0xaffe52eb, 0x7dcfd0fa, 0x8c3588f1, 0xb5facbb8,
- 0xfdb7fce0, 0x0925bd71, 0x5f807fb7, 0x9d6b0533, 0xfe5bbe33, 0x12ab6db1,
- 0x4f80561e, 0xe2bd5fec, 0x0937ec67, 0x18aa6dfb, 0x5a68a753, 0x37791d3d,
- 0x4f4f5779, 0x6d8c53ac, 0xa8a72819, 0x49bd88b7, 0xd2b87ecb, 0x623e8e3d,
- 0xd4ae6ff3, 0x864d9f64, 0x6fa94f1d, 0x1e15e679, 0x53ccb97f, 0x557ec956,
- 0xbf92a9ae, 0xa6a7dd8f, 0x860fcf52, 0x80bf1db2, 0xcd07453d, 0xb949f84e,
- 0x4f33eba6, 0xfc2efcbd, 0xe1db2f31, 0x357e64ea, 0xbcfa6955, 0xea273663,
- 0x5f63d140, 0xffe07be5, 0xa5cbec5b, 0xd3b262ce, 0x953f1e64, 0x3df0573b,
- 0xc6c7cfb6, 0x7aa5693e, 0x645ed3be, 0x533afefe, 0x3adbe3b1, 0xc51be493,
- 0x12d9c169, 0xf890bf87, 0xe85c1d16, 0xf7c05cd4, 0xd6fe1da0, 0x677ff5fe,
- 0x0c8f0e23, 0x0bba67fe, 0xd3ed75b8, 0xb6cfd874, 0x81d38f81, 0x6606270f,
- 0x1d9ed039, 0x1fd03972, 0x16b8fbad, 0x368cbaf3, 0x8b30675e, 0xf636b19c,
- 0x13d58e7e, 0xcdd1de12, 0x73af6bd0, 0x614b2fdb, 0x82dda9ef, 0xce8efc63,
- 0xd788fc44, 0xe3395c19, 0xeb1265d5, 0xf5b3050c, 0xd45a033a, 0x7acc0a19,
- 0xea34019d, 0x6751680c, 0x0cea3f40, 0x006751a0, 0x68033a8d, 0xa2d019d4,
- 0x2bfe80ce, 0xbcb16ba8, 0x50de4e51, 0xecd1aadf, 0xf40fff82, 0xf5e4416a,
- 0x74d31c0f, 0xc412877a, 0xfbc67f7d, 0xaf460e23, 0x28b075e8, 0xe77953c7,
- 0xfbcb341f, 0x5eda1a20, 0xd6f71337, 0x5571b9af, 0xd9371117, 0xa3cddb14,
- 0x6a1f5127, 0x1bdc53ef, 0x2e5fe85d, 0x5c1b6c72, 0xfa237ef8, 0xd56ecd7b,
- 0x9abafb85, 0x6f97fa8d, 0x58ea57b0, 0x2cc739d5, 0x15fbcf72, 0xeffde1ca,
- 0x64efeab0, 0x2cbdc6bf, 0x9545b0f7, 0x1d6fda3c, 0xcb4bf792, 0x4d738a8b,
- 0x7eda1e42, 0x1382e7cb, 0x9df4b69d, 0xb21fd790, 0xc524d739, 0x7de48f57,
- 0xc174fc7e, 0x45433c8d, 0xa7d5af4c, 0x7b5edf90, 0xf9213801, 0xb47e4248,
- 0x33fcd9d6, 0x5da467e4, 0x7efce133, 0x644ee87e, 0x6d3dd6f9, 0xb09228fe,
- 0x9930737f, 0x6df60df6, 0x99c823cd, 0x034a8fdc, 0x943fb2e2, 0x74aa1fdc,
- 0xc6927d64, 0x3cd1e63f, 0xff755be4, 0x3f40e6b4, 0xdbb977ef, 0x61caf92a,
- 0x2570f78f, 0xb349f1fb, 0x272fea47, 0xbde4d98f, 0x9cfb7e75, 0x8d4bfaa4,
- 0x1fea5536, 0xc48acc1b, 0xdee52bf1, 0xaacbb063, 0xeea57bba, 0x10eb9552,
- 0xe1d98e7f, 0x3786f2d1, 0x5cc377c0, 0x6abfd497, 0xe10bf4ac, 0xf72f7ec7,
- 0x7f16683c, 0x8254e9ab, 0xc9abd32a, 0xad7f816d, 0x3d8a7562, 0x298fed99,
- 0x78ab0fec, 0xbb04c6af, 0x915db0da, 0x100a42bc, 0x8695e7ac, 0xfe0d573e,
- 0xfb0a57eb, 0x3d56bdcb, 0x5553ce0f, 0xc5d79fe1, 0xdfe78b71, 0xfc0b5e47,
- 0x55c71d66, 0x5f671cb4, 0x37bf708f, 0x9ebe6a6d, 0xc072bbe7, 0x3319f57f,
- 0x726a4f01, 0x95e85e7e, 0xfced5f78, 0x095bef84, 0x737da5df, 0xa8e1f7d3,
- 0xc8493e89, 0x759a4f6b, 0xca7d61fc, 0xec14eb7b, 0x5e3eea55, 0x3474cf69,
- 0x8ca2bb49, 0x340bffc4, 0xe02f6f3d, 0x4a6672bb, 0xeb0fa2dd, 0x6eedda6b,
- 0x0b863fe8, 0xbefc8dbb, 0xe796e540, 0x5bd54eed, 0xdc29d30b, 0xca5b8d3f,
- 0xe7617e14, 0x5c71d47c, 0x3d4f3fc2, 0x7d05c0bb, 0x4377697c, 0xc739351f,
- 0x31dde1e6, 0x72ffe0cb, 0xdc55c359, 0x029d2797, 0x438f9fd8, 0x5adfacdd,
- 0x5d41481c, 0x50d1e43d, 0x38a63f27, 0x1ebfaef1, 0x716fb74f, 0x140acfc2,
- 0xb5b7ea27, 0xd935dda9, 0xe676bfcc, 0x9cf0370c, 0x61ea55f1, 0x76eadc23,
- 0x53506b70, 0x6ca6b5f4, 0xff0df3d4, 0x54a6f729, 0xd7f78a4d, 0x1d147e1b,
- 0xf11d22fc, 0x6dd447f5, 0x807f8377, 0x835eee6c, 0xfea0ec3f, 0xbf5269a6,
- 0xe5d1d98d, 0x613b39fd, 0xf4ab5347, 0xef8d8d75, 0x0c4f9199, 0xc1cde6dd,
- 0x7cd72bfe, 0xce5b25be, 0x8cbd7e39, 0xb8033771, 0x165eb63b, 0x463df1c3,
- 0x6b781dfd, 0x26baea32, 0x326baea3, 0xa326baea, 0xea326bae, 0xaea326ba,
- 0xbaea326b, 0x6baea326, 0x26baea32, 0x97ae13a9, 0x878eddf6, 0x08ea1da4,
- 0xbc4278c8, 0xc7eab9b8, 0x55175dd5, 0xa577538d, 0xc4865714, 0xbd7bf65d,
- 0xcea63dde, 0x26aefeca, 0xe0d57bf8, 0x431e7b84, 0x7163d25e, 0x6b5438b3,
- 0x603c16f1, 0x54f07c17, 0x8d6f5b8d, 0xf52ecfe9, 0x9b64cbd9, 0x2ca87b8f,
- 0x5152659a, 0x23ee34c7, 0xdf84ef56, 0x1bf09ce0, 0xd31bf0b4, 0xfcdfb8ec,
- 0x5daec2d6, 0x0109e7aa, 0x726c13c9, 0x32375bbf, 0x2f7d30ae, 0xe5709339,
- 0xc2b831b3, 0x90159a0f, 0x95a0ed63, 0x233f74ba, 0x37254ff8, 0x0e3f9c7f,
- 0x9c7484ce, 0xda1a9699, 0xb5a67d87, 0x1791baa5, 0x9d8bbfb3, 0x88a6dc9d,
- 0x06a1afbf, 0xbc1c77d9, 0x7c9e4749, 0x73d1c4ef, 0xf7f9e1bf, 0xf25d83fe,
- 0xd793ad9d, 0xe0fffa2e, 0xae954d4d, 0x84775f8f, 0x9659e77d, 0x43b654ea,
- 0x16d5578e, 0xb8ba922a, 0x50fe2a9a, 0x58ae3da3, 0xd377a380, 0xb577dc3c,
- 0xc839e1b5, 0x2efec399, 0xa32cdfef, 0x6a1a6bbe, 0xd9f4cbde, 0xbe373cec,
- 0x3dcd4dab, 0x800b0544, 0xb0c57547, 0xadd4b3ab, 0x1963dd60, 0xbf83bfde,
- 0xa7cc5edc, 0x96fee356, 0xb3b69753, 0xce63ee4b, 0x32fbdc42, 0xf51fabab,
- 0x9e6f2d86, 0xb2c27a90, 0xd442d70c, 0x79bcb61b, 0x5c73a75a, 0xe51b8afd,
- 0xabab13b2, 0x66f8827f, 0x109f3eeb, 0x09a1fd67, 0xc0fb7449, 0x09f3eee4,
- 0x3f05ae71, 0x3f4e9df8, 0xafb84c53, 0x5c944356, 0xf21dbbd5, 0x4bfeebf9,
- 0xa8d3cf7f, 0xaaa7c9c4, 0x749c5c74, 0xe7b0c282, 0xf90ec5d1, 0x713397fe,
- 0xdbd43cfd, 0x10b5d8a8, 0xfdaf38f3, 0xe2f8ec35, 0xc1a79ead, 0x7738cf27,
- 0x3579f10e, 0x0d90c758, 0xbbe319ed, 0xdbd529e4, 0x3d36b688, 0x357e9260,
- 0x6df68a58, 0xfa20f435, 0x81762fd9, 0xf393ed4f, 0x3a622c6e, 0xb79a1acf,
- 0xe9788ede, 0x73fe8dd9, 0xec5e9e65, 0xdfeeb637, 0xe58f9c69, 0xc37987d9,
- 0xf9e4aa85, 0x6dea37c3, 0x55c22ecc, 0x371d0e3a, 0x93aca8fc, 0x58e7fbe4,
- 0xa55e39fb, 0xfdf9781a, 0x47bcb372, 0x7e4c4f20, 0x0a5d5eea, 0xa3de5879,
- 0x61afbc86, 0x5299ec9c, 0x7b6ef98f, 0xc77ec80d, 0x7c653b0d, 0xe3af396c,
- 0xa685b4a3, 0x0de404e0, 0x4e0d1e53, 0x7653bc80, 0xdc5cda8c, 0xb51810be,
- 0xe1787f21, 0xe86d476f, 0x7543c17f, 0x56bfe1e3, 0xc2df09ad, 0x3f5951b2,
- 0x921af79d, 0x04e8c277, 0x4d856fe4, 0x6c02596f, 0xe69e73b7, 0xb7f2937d,
- 0xd3638922, 0xfe9a5b0d, 0x87b04aa8, 0xe490cfe9, 0x259d54ab, 0xdd14bee3,
- 0x3e8f7dff, 0x6e8ec2a8, 0x09dcb208, 0x69e737f6, 0x1248e5d3, 0x6bacb0df,
- 0xf3837031, 0x3f71a4b5, 0x3cbe4733, 0xe423c0c5, 0x378c8d8f, 0xbeb7a6fe,
- 0x79c8be42, 0x8c7e18dc, 0x261c314d, 0xebef5dc4, 0x20fc1711, 0xbbdade79,
- 0xf78ad91e, 0x76e3536d, 0xd78fbc8b, 0xdb456df4, 0x259efada, 0x4cbf2487,
- 0x65f9cf9a, 0x9c9d7d12, 0x7b68e463, 0x39adf3f0, 0x76cbece3, 0x0ed12d70,
- 0x37439a4e, 0xd27abde0, 0x480eea9f, 0x0fdd091c, 0x6ad9d97c, 0xecae2377,
- 0xd8a555fa, 0xa9f5b7d7, 0xfaa98f32, 0xa751d947, 0x52540fcc, 0x87e6fc11,
- 0xe1e011da, 0x0c3c24ec, 0x8972dd48, 0xddae7043, 0xadb60778, 0x123e4a71,
- 0x5336ebf3, 0x98adc3e8, 0xef90e597, 0x45b70c11, 0x6f7c2ca6, 0x4aeee29a,
- 0x2ece2bc8, 0x9d041599, 0x830a19dd, 0x15cfe8ef, 0xd5c8ea37, 0xd6ae3a69,
- 0x7bad0da8, 0x352dfc79, 0x5bf1b82c, 0x6ff307e0, 0x7697acb7, 0xb14cd945,
- 0x290a5cdb, 0x7067fffa, 0x3d7bc42d, 0x67ad3df6, 0x20efb05b, 0xf04afbde,
- 0x8fa8b599, 0xe45d95fe, 0x80d50689, 0x33d3cf99, 0x7bb70481, 0xb8942cee,
- 0xc686a513, 0x2cff91fb, 0x6a3a954f, 0x13d704cf, 0xd3da6ef8, 0xf5e4a37c,
- 0xc7a4fe87, 0x29a5d1fb, 0x3d71e46e, 0x711b5cf3, 0x5d479eae, 0xa29afe32,
- 0xa13c0bf3, 0xa967a7eb, 0xe69ece7e, 0xc59f794c, 0x8767a1ee, 0xbfbe3267,
- 0xe5bc3259, 0x1803a8d5, 0x667b1fdf, 0x4fb73f70, 0xde770d29, 0x75733e07,
- 0xb9945779, 0xde4edee4, 0x7b13e379, 0xf1867d74, 0x897dac1d, 0xfefde923,
- 0xcb80febf, 0x002220b3, 0x00000000
-};
-
-#endif /*__BNX2X_INIT_VALUES_H__*/
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index ad5ef25add3..fbf1352e9c1 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -53,12 +53,19 @@
#include "bnx2x.h"
#include "bnx2x_init.h"
+#include "bnx2x_init_ops.h"
#include "bnx2x_dump.h"
-#define DRV_MODULE_VERSION "1.48.105"
-#define DRV_MODULE_RELDATE "2009/03/02"
+#define DRV_MODULE_VERSION "1.48.105-1"
+#define DRV_MODULE_RELDATE "2009/04/22"
#define BNX2X_BC_VER 0x040200
+#include <linux/firmware.h>
+#include "bnx2x_fw_file_hdr.h"
+/* FW files */
+#define FW_FILE_PREFIX_E1 "bnx2x-e1-"
+#define FW_FILE_PREFIX_E1H "bnx2x-e1h-"
+
/* Time in jiffies before concluding the transmitter is hung */
#define TX_TIMEOUT (5*HZ)
@@ -1539,7 +1546,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
len, cqe, comp_ring_cons);
#ifdef BNX2X_STOP_ON_ERROR
if (bp->panic)
- return -EINVAL;
+ return 0;
#endif
bnx2x_update_sge_prod(fp,
@@ -5232,13 +5239,15 @@ static void bnx2x_gunzip_end(struct bnx2x *bp)
}
}
-static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len)
+static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len)
{
int n, rc;
/* check gzip header */
- if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED))
+ if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED)) {
+ BNX2X_ERR("Bad gzip header\n");
return -EINVAL;
+ }
n = 10;
@@ -5247,7 +5256,7 @@ static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len)
if (zbuf[3] & FNAME)
while ((zbuf[n++] != 0) && (n < len));
- bp->strm->next_in = zbuf + n;
+ bp->strm->next_in = (typeof(bp->strm->next_in))zbuf + n;
bp->strm->avail_in = len - n;
bp->strm->next_out = bp->gunzip_buf;
bp->strm->avail_out = FW_BUF_SIZE;
@@ -5369,8 +5378,8 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
msleep(50);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
msleep(50);
- bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
- bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
+ bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
DP(NETIF_MSG_HW, "part2\n");
@@ -5434,8 +5443,8 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
msleep(50);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
msleep(50);
- bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
- bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
+ bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
#ifndef BCM_ISCSI
/* set NIC mode */
REG_WR(bp, PRS_REG_NIC_MODE, 1);
@@ -5510,7 +5519,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc);
- bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END);
+ bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE);
if (CHIP_IS_E1H(bp))
REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp));
@@ -5518,14 +5527,14 @@ static int bnx2x_init_common(struct bnx2x *bp)
msleep(30);
REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0);
- bnx2x_init_block(bp, PXP_COMMON_START, PXP_COMMON_END);
+ bnx2x_init_block(bp, PXP_BLOCK, COMMON_STAGE);
if (CHIP_IS_E1(bp)) {
/* enable HW interrupt from PXP on USDM overflow
bit 16 on INT_MASK_0 */
REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0);
}
- bnx2x_init_block(bp, PXP2_COMMON_START, PXP2_COMMON_END);
+ bnx2x_init_block(bp, PXP2_BLOCK, COMMON_STAGE);
bnx2x_init_pxp(bp);
#ifdef __BIG_ENDIAN
@@ -5571,60 +5580,60 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0);
REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0);
- bnx2x_init_block(bp, DMAE_COMMON_START, DMAE_COMMON_END);
+ bnx2x_init_block(bp, DMAE_BLOCK, COMMON_STAGE);
/* clean the DMAE memory */
bp->dmae_ready = 1;
bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8);
- bnx2x_init_block(bp, TCM_COMMON_START, TCM_COMMON_END);
- bnx2x_init_block(bp, UCM_COMMON_START, UCM_COMMON_END);
- bnx2x_init_block(bp, CCM_COMMON_START, CCM_COMMON_END);
- bnx2x_init_block(bp, XCM_COMMON_START, XCM_COMMON_END);
+ bnx2x_init_block(bp, TCM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, UCM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, CCM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, XCM_BLOCK, COMMON_STAGE);
bnx2x_read_dmae(bp, XSEM_REG_PASSIVE_BUFFER, 3);
bnx2x_read_dmae(bp, CSEM_REG_PASSIVE_BUFFER, 3);
bnx2x_read_dmae(bp, TSEM_REG_PASSIVE_BUFFER, 3);
bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3);
- bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END);
+ bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE);
/* soft reset pulse */
REG_WR(bp, QM_REG_SOFT_RESET, 1);
REG_WR(bp, QM_REG_SOFT_RESET, 0);
#ifdef BCM_ISCSI
- bnx2x_init_block(bp, TIMERS_COMMON_START, TIMERS_COMMON_END);
+ bnx2x_init_block(bp, TIMERS_BLOCK, COMMON_STAGE);
#endif
- bnx2x_init_block(bp, DQ_COMMON_START, DQ_COMMON_END);
+ bnx2x_init_block(bp, DQ_BLOCK, COMMON_STAGE);
REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT);
if (!CHIP_REV_IS_SLOW(bp)) {
/* enable hw interrupt from doorbell Q */
REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
}
- bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
- bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
+ bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
/* set NIC mode */
REG_WR(bp, PRS_REG_NIC_MODE, 1);
if (CHIP_IS_E1H(bp))
REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp));
- bnx2x_init_block(bp, TSDM_COMMON_START, TSDM_COMMON_END);
- bnx2x_init_block(bp, CSDM_COMMON_START, CSDM_COMMON_END);
- bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END);
- bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END);
+ bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, USDM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, XSDM_BLOCK, COMMON_STAGE);
bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
- bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END);
- bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END);
- bnx2x_init_block(bp, CSEM_COMMON_START, CSEM_COMMON_END);
- bnx2x_init_block(bp, XSEM_COMMON_START, XSEM_COMMON_END);
+ bnx2x_init_block(bp, TSEM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, USEM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, CSEM_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, XSEM_BLOCK, COMMON_STAGE);
/* sync semi rtc */
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
@@ -5632,16 +5641,16 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
0x80000000);
- bnx2x_init_block(bp, UPB_COMMON_START, UPB_COMMON_END);
- bnx2x_init_block(bp, XPB_COMMON_START, XPB_COMMON_END);
- bnx2x_init_block(bp, PBF_COMMON_START, PBF_COMMON_END);
+ bnx2x_init_block(bp, UPB_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, XPB_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE);
REG_WR(bp, SRC_REG_SOFT_RST, 1);
for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) {
REG_WR(bp, i, 0xc0cac01a);
/* TODO: replace with something meaningful */
}
- bnx2x_init_block(bp, SRCH_COMMON_START, SRCH_COMMON_END);
+ bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE);
REG_WR(bp, SRC_REG_SOFT_RST, 0);
if (sizeof(union cdu_context) != 1024)
@@ -5649,7 +5658,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
printk(KERN_ALERT PFX "please adjust the size of"
" cdu_context(%ld)\n", (long)sizeof(union cdu_context));
- bnx2x_init_block(bp, CDU_COMMON_START, CDU_COMMON_END);
+ bnx2x_init_block(bp, CDU_BLOCK, COMMON_STAGE);
val = (4 << 24) + (0 << 12) + 1024;
REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val);
if (CHIP_IS_E1(bp)) {
@@ -5658,7 +5667,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, CDU_REG_CDU_DEBUG, 0);
}
- bnx2x_init_block(bp, CFC_COMMON_START, CFC_COMMON_END);
+ bnx2x_init_block(bp, CFC_BLOCK, COMMON_STAGE);
REG_WR(bp, CFC_REG_INIT_REG, 0x7FF);
/* enable context validation interrupt from CFC */
REG_WR(bp, CFC_REG_CFC_INT_MASK, 0);
@@ -5666,20 +5675,25 @@ static int bnx2x_init_common(struct bnx2x *bp)
/* set the thresholds to prevent CFC/CDU race */
REG_WR(bp, CFC_REG_DEBUG0, 0x20020000);
- bnx2x_init_block(bp, HC_COMMON_START, HC_COMMON_END);
- bnx2x_init_block(bp, MISC_AEU_COMMON_START, MISC_AEU_COMMON_END);
+ bnx2x_init_block(bp, HC_BLOCK, COMMON_STAGE);
+ bnx2x_init_block(bp, MISC_AEU_BLOCK, COMMON_STAGE);
/* PXPCS COMMON comes here */
+ bnx2x_init_block(bp, PXPCS_BLOCK, COMMON_STAGE);
/* Reset PCIE errors for debug */
REG_WR(bp, 0x2814, 0xffffffff);
REG_WR(bp, 0x3820, 0xffffffff);
/* EMAC0 COMMON comes here */
+ bnx2x_init_block(bp, EMAC0_BLOCK, COMMON_STAGE);
/* EMAC1 COMMON comes here */
+ bnx2x_init_block(bp, EMAC1_BLOCK, COMMON_STAGE);
/* DBU COMMON comes here */
+ bnx2x_init_block(bp, DBU_BLOCK, COMMON_STAGE);
/* DBG COMMON comes here */
+ bnx2x_init_block(bp, DBG_BLOCK, COMMON_STAGE);
- bnx2x_init_block(bp, NIG_COMMON_START, NIG_COMMON_END);
+ bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE);
if (CHIP_IS_E1H(bp)) {
REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp));
REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp));
@@ -5763,6 +5777,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
static int bnx2x_init_port(struct bnx2x *bp)
{
int port = BP_PORT(bp);
+ int init_stage = port ? PORT1_STAGE : PORT0_STAGE;
u32 low, high;
u32 val;
@@ -5771,7 +5786,9 @@ static int bnx2x_init_port(struct bnx2x *bp)
REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0);
/* Port PXP comes here */
+ bnx2x_init_block(bp, PXP_BLOCK, init_stage);
/* Port PXP2 comes here */
+ bnx2x_init_block(bp, PXP2_BLOCK, init_stage);
#ifdef BCM_ISCSI
/* Port0 1
* Port1 385 */
@@ -5798,21 +5815,19 @@ static int bnx2x_init_port(struct bnx2x *bp)
REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
#endif
/* Port CMs come here */
- bnx2x_init_block(bp, (port ? XCM_PORT1_START : XCM_PORT0_START),
- (port ? XCM_PORT1_END : XCM_PORT0_END));
+ bnx2x_init_block(bp, XCM_BLOCK, init_stage);
/* Port QM comes here */
#ifdef BCM_ISCSI
REG_WR(bp, TM_REG_LIN0_SCAN_TIME + func*4, 1024/64*20);
REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + func*4, 31);
- bnx2x_init_block(bp, func ? TIMERS_PORT1_START : TIMERS_PORT0_START,
- func ? TIMERS_PORT1_END : TIMERS_PORT0_END);
+ bnx2x_init_block(bp, TIMERS_BLOCK, init_stage);
#endif
/* Port DQ comes here */
+ bnx2x_init_block(bp, DQ_BLOCK, init_stage);
- bnx2x_init_block(bp, (port ? BRB1_PORT1_START : BRB1_PORT0_START),
- (port ? BRB1_PORT1_END : BRB1_PORT0_END));
+ bnx2x_init_block(bp, BRB1_BLOCK, init_stage);
if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) {
/* no pause for emulation and FPGA */
low = 0;
@@ -5837,25 +5852,27 @@ static int bnx2x_init_port(struct bnx2x *bp)
/* Port PRS comes here */
+ bnx2x_init_block(bp, PRS_BLOCK, init_stage);
/* Port TSDM comes here */
+ bnx2x_init_block(bp, TSDM_BLOCK, init_stage);
/* Port CSDM comes here */
+ bnx2x_init_block(bp, CSDM_BLOCK, init_stage);
/* Port USDM comes here */
+ bnx2x_init_block(bp, USDM_BLOCK, init_stage);
/* Port XSDM comes here */
+ bnx2x_init_block(bp, XSDM_BLOCK, init_stage);
- bnx2x_init_block(bp, port ? TSEM_PORT1_START : TSEM_PORT0_START,
- port ? TSEM_PORT1_END : TSEM_PORT0_END);
- bnx2x_init_block(bp, port ? USEM_PORT1_START : USEM_PORT0_START,
- port ? USEM_PORT1_END : USEM_PORT0_END);
- bnx2x_init_block(bp, port ? CSEM_PORT1_START : CSEM_PORT0_START,
- port ? CSEM_PORT1_END : CSEM_PORT0_END);
- bnx2x_init_block(bp, port ? XSEM_PORT1_START : XSEM_PORT0_START,
- port ? XSEM_PORT1_END : XSEM_PORT0_END);
+ bnx2x_init_block(bp, TSEM_BLOCK, init_stage);
+ bnx2x_init_block(bp, USEM_BLOCK, init_stage);
+ bnx2x_init_block(bp, CSEM_BLOCK, init_stage);
+ bnx2x_init_block(bp, XSEM_BLOCK, init_stage);
/* Port UPB comes here */
+ bnx2x_init_block(bp, UPB_BLOCK, init_stage);
/* Port XPB comes here */
+ bnx2x_init_block(bp, XPB_BLOCK, init_stage);
- bnx2x_init_block(bp, port ? PBF_PORT1_START : PBF_PORT0_START,
- port ? PBF_PORT1_END : PBF_PORT0_END);
+ bnx2x_init_block(bp, PBF_BLOCK, init_stage);
/* configure PBF to work without PAUSE mtu 9000 */
REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
@@ -5885,18 +5902,17 @@ static int bnx2x_init_port(struct bnx2x *bp)
/* Port SRCH comes here */
#endif
/* Port CDU comes here */
+ bnx2x_init_block(bp, CDU_BLOCK, init_stage);
/* Port CFC comes here */
+ bnx2x_init_block(bp, CFC_BLOCK, init_stage);
if (CHIP_IS_E1(bp)) {
REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
}
- bnx2x_init_block(bp, port ? HC_PORT1_START : HC_PORT0_START,
- port ? HC_PORT1_END : HC_PORT0_END);
+ bnx2x_init_block(bp, HC_BLOCK, init_stage);
- bnx2x_init_block(bp, port ? MISC_AEU_PORT1_START :
- MISC_AEU_PORT0_START,
- port ? MISC_AEU_PORT1_END : MISC_AEU_PORT0_END);
+ bnx2x_init_block(bp, MISC_AEU_BLOCK, init_stage);
/* init aeu_mask_attn_func_0/1:
* - SF mode: bits 3-7 are masked. only bits 0-2 are in use
* - MF mode: bit 3 is masked. bits 0-2 are in use as in SF
@@ -5905,13 +5921,17 @@ static int bnx2x_init_port(struct bnx2x *bp)
(IS_E1HMF(bp) ? 0xF7 : 0x7));
/* Port PXPCS comes here */
+ bnx2x_init_block(bp, PXPCS_BLOCK, init_stage);
/* Port EMAC0 comes here */
+ bnx2x_init_block(bp, EMAC0_BLOCK, init_stage);
/* Port EMAC1 comes here */
+ bnx2x_init_block(bp, EMAC1_BLOCK, init_stage);
/* Port DBU comes here */
+ bnx2x_init_block(bp, DBU_BLOCK, init_stage);
/* Port DBG comes here */
+ bnx2x_init_block(bp, DBG_BLOCK, init_stage);
- bnx2x_init_block(bp, port ? NIG_PORT1_START : NIG_PORT0_START,
- port ? NIG_PORT1_END : NIG_PORT0_END);
+ bnx2x_init_block(bp, NIG_BLOCK, init_stage);
REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
@@ -5931,7 +5951,9 @@ static int bnx2x_init_port(struct bnx2x *bp)
}
/* Port MCP comes here */
+ bnx2x_init_block(bp, MCP_BLOCK, init_stage);
/* Port DMAE comes here */
+ bnx2x_init_block(bp, DMAE_BLOCK, init_stage);
switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
@@ -6036,7 +6058,7 @@ static int bnx2x_init_func(struct bnx2x *bp)
if (CHIP_IS_E1H(bp)) {
for (i = 0; i < 9; i++)
bnx2x_init_block(bp,
- cm_start[func][i], cm_end[func][i]);
+ cm_blocks[i], FUNC0_STAGE + func);
REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov);
@@ -6049,7 +6071,7 @@ static int bnx2x_init_func(struct bnx2x *bp)
REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
}
- bnx2x_init_block(bp, hc_limits[func][0], hc_limits[func][1]);
+ bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func);
/* Reset PCIE errors for debug */
REG_WR(bp, 0x2114, 0xffffffff);
@@ -10595,7 +10617,6 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
mmiowb();
fp->tx_bd_prod += nbd;
- dev->trans_start = jiffies;
if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
/* We want bnx2x_tx_int to "see" the updated tx_bd_prod
@@ -11082,6 +11103,190 @@ static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp)
val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
return val;
}
+static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
+{
+ struct bnx2x_fw_file_hdr *fw_hdr;
+ struct bnx2x_fw_file_section *sections;
+ u16 *ops_offsets;
+ u32 offset, len, num_ops;
+ int i;
+ const struct firmware *firmware = bp->firmware;
+ const u8 * fw_ver;
+
+ if (firmware->size < sizeof(struct bnx2x_fw_file_hdr))
+ return -EINVAL;
+
+ fw_hdr = (struct bnx2x_fw_file_hdr *)firmware->data;
+ sections = (struct bnx2x_fw_file_section *)fw_hdr;
+
+ /* Make sure none of the offsets and sizes make us read beyond
+ * the end of the firmware data */
+ for (i = 0; i < sizeof(*fw_hdr) / sizeof(*sections); i++) {
+ offset = be32_to_cpu(sections[i].offset);
+ len = be32_to_cpu(sections[i].len);
+ if (offset + len > firmware->size) {
+ printk(KERN_ERR PFX "Section %d length is out of bounds\n", i);
+ return -EINVAL;
+ }
+ }
+
+ /* Likewise for the init_ops offsets */
+ offset = be32_to_cpu(fw_hdr->init_ops_offsets.offset);
+ ops_offsets = (u16 *)(firmware->data + offset);
+ num_ops = be32_to_cpu(fw_hdr->init_ops.len) / sizeof(struct raw_op);
+
+ for (i = 0; i < be32_to_cpu(fw_hdr->init_ops_offsets.len) / 2; i++) {
+ if (be16_to_cpu(ops_offsets[i]) > num_ops) {
+ printk(KERN_ERR PFX "Section offset %d is out of bounds\n", i);
+ return -EINVAL;
+ }
+ }
+
+ /* Check FW version */
+ offset = be32_to_cpu(fw_hdr->fw_version.offset);
+ fw_ver = firmware->data + offset;
+ if ((fw_ver[0] != BCM_5710_FW_MAJOR_VERSION) ||
+ (fw_ver[1] != BCM_5710_FW_MINOR_VERSION) ||
+ (fw_ver[2] != BCM_5710_FW_REVISION_VERSION) ||
+ (fw_ver[3] != BCM_5710_FW_ENGINEERING_VERSION)) {
+ printk(KERN_ERR PFX "Bad FW version:%d.%d.%d.%d."
+ " Should be %d.%d.%d.%d\n",
+ fw_ver[0], fw_ver[1], fw_ver[2],
+ fw_ver[3], BCM_5710_FW_MAJOR_VERSION,
+ BCM_5710_FW_MINOR_VERSION,
+ BCM_5710_FW_REVISION_VERSION,
+ BCM_5710_FW_ENGINEERING_VERSION);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void inline be32_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
+{
+ u32 i;
+ const __be32 *source = (const __be32*)_source;
+ u32 *target = (u32*)_target;
+
+ for (i = 0; i < n/4; i++)
+ target[i] = be32_to_cpu(source[i]);
+}
+
+/*
+ Ops array is stored in the following format:
+ {op(8bit), offset(24bit, big endian), data(32bit, big endian)}
+ */
+static void inline bnx2x_prep_ops(const u8 *_source, u8 *_target, u32 n)
+{
+ u32 i, j, tmp;
+ const __be32 *source = (const __be32*)_source;
+ struct raw_op *target = (struct raw_op*)_target;
+
+ for (i = 0, j = 0; i < n/8; i++, j+=2) {
+ tmp = be32_to_cpu(source[j]);
+ target[i].op = (tmp >> 24) & 0xff;
+ target[i].offset = tmp & 0xffffff;
+ target[i].raw_data = be32_to_cpu(source[j+1]);
+ }
+}
+static void inline be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
+{
+ u32 i;
+ u16 *target = (u16*)_target;
+ const __be16 *source = (const __be16*)_source;
+
+ for (i = 0; i < n/2; i++)
+ target[i] = be16_to_cpu(source[i]);
+}
+
+#define BNX2X_ALLOC_AND_SET(arr, lbl, func) \
+ do { \
+ u32 len = be32_to_cpu(fw_hdr->arr.len); \
+ bp->arr = kmalloc(len, GFP_KERNEL); \
+ if (!bp->arr) { \
+ printk(KERN_ERR PFX "Failed to allocate %d bytes for "#arr"\n", len); \
+ goto lbl; \
+ } \
+ func(bp->firmware->data + \
+ be32_to_cpu(fw_hdr->arr.offset), \
+ (u8*)bp->arr, len); \
+ } while (0)
+
+
+static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
+{
+ char fw_file_name[40] = {0};
+ int rc, offset;
+ struct bnx2x_fw_file_hdr *fw_hdr;
+
+ /* Create a FW file name */
+ if (CHIP_IS_E1(bp))
+ offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1);
+ else
+ offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1H);
+
+ sprintf(fw_file_name + offset, "%d.%d.%d.%d.fw",
+ BCM_5710_FW_MAJOR_VERSION,
+ BCM_5710_FW_MINOR_VERSION,
+ BCM_5710_FW_REVISION_VERSION,
+ BCM_5710_FW_ENGINEERING_VERSION);
+
+ printk(KERN_INFO PFX "Loading %s\n", fw_file_name);
+
+ rc = request_firmware(&bp->firmware, fw_file_name, dev);
+ if (rc) {
+ printk(KERN_ERR PFX "Can't load firmware file %s\n", fw_file_name);
+ goto request_firmware_exit;
+ }
+
+ rc = bnx2x_check_firmware(bp);
+ if (rc) {
+ printk(KERN_ERR PFX "Corrupt firmware file %s\n", fw_file_name);
+ goto request_firmware_exit;
+ }
+
+ fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data;
+
+ /* Initialize the pointers to the init arrays */
+ /* Blob */
+ BNX2X_ALLOC_AND_SET(init_data, request_firmware_exit, be32_to_cpu_n);
+
+ /* Opcodes */
+ BNX2X_ALLOC_AND_SET(init_ops, init_ops_alloc_err, bnx2x_prep_ops);
+
+ /* Offsets */
+ BNX2X_ALLOC_AND_SET(init_ops_offsets, init_offsets_alloc_err, be16_to_cpu_n);
+
+ /* STORMs firmware */
+ bp->tsem_int_table_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->tsem_int_table_data.offset);
+ bp->tsem_pram_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->tsem_pram_data.offset);
+ bp->usem_int_table_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->usem_int_table_data.offset);
+ bp->usem_pram_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->usem_pram_data.offset);
+ bp->xsem_int_table_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->xsem_int_table_data.offset);
+ bp->xsem_pram_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->xsem_pram_data.offset);
+ bp->csem_int_table_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->csem_int_table_data.offset);
+ bp->csem_pram_data = bp->firmware->data +
+ be32_to_cpu(fw_hdr->csem_pram_data.offset);
+
+ return 0;
+init_offsets_alloc_err:
+ kfree(bp->init_ops);
+init_ops_alloc_err:
+ kfree(bp->init_data);
+request_firmware_exit:
+ release_firmware(bp->firmware);
+
+ return rc;
+}
+
+
static int __devinit bnx2x_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -11116,6 +11321,13 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
if (rc)
goto init_one_exit;
+ /* Set init arrays */
+ rc = bnx2x_init_firmware(bp, &pdev->dev);
+ if (rc) {
+ printk(KERN_ERR PFX "Error loading firmware\n");
+ goto init_one_exit;
+ }
+
rc = register_netdev(dev);
if (rc) {
dev_err(&pdev->dev, "Cannot register net device\n");
@@ -11163,6 +11375,11 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
unregister_netdev(dev);
+ kfree(bp->init_ops_offsets);
+ kfree(bp->init_ops);
+ kfree(bp->init_data);
+ release_firmware(bp->firmware);
+
if (bp->regview)
iounmap(bp->regview);
@@ -11412,13 +11629,20 @@ static struct pci_driver bnx2x_pci_driver = {
static int __init bnx2x_init(void)
{
+ int ret;
+
bnx2x_wq = create_singlethread_workqueue("bnx2x");
if (bnx2x_wq == NULL) {
printk(KERN_ERR PFX "Cannot create workqueue\n");
return -ENOMEM;
}
- return pci_register_driver(&bnx2x_pci_driver);
+ ret = pci_register_driver(&bnx2x_pci_driver);
+ if (ret) {
+ printk(KERN_ERR PFX "Cannot register driver\n");
+ destroy_workqueue(bnx2x_wq);
+ }
+ return ret;
}
static void __exit bnx2x_cleanup(void)
@@ -11431,3 +11655,4 @@ static void __exit bnx2x_cleanup(void)
module_init(bnx2x_init);
module_exit(bnx2x_cleanup);
+
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index faf094abef7..d4b570886c6 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -1850,9 +1850,10 @@ static u16 aggregator_identifier;
* Can be called only after the mac address of the bond is set.
*/
void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast)
-{
+{
// check that the bond is not initialized yet
- if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), &(bond->dev->dev_addr))) {
+ if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr),
+ bond->dev->dev_addr)) {
aggregator_identifier = 0;
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index a306230381c..2c46a154f2c 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -26,10 +26,10 @@
#include <asm/byteorder.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
+#include <linux/if_ether.h>
// General definitions
-#define BOND_ETH_P_LACPDU 0x8809
-#define PKT_TYPE_LACPDU cpu_to_be16(BOND_ETH_P_LACPDU)
+#define PKT_TYPE_LACPDU cpu_to_be16(ETH_P_SLOW)
#define AD_TIMER_INTERVAL 100 /*msec*/
#define MULTICAST_LACPDU_ADDR {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02}
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 74824028f85..d927f71af8a 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -51,10 +51,10 @@
#include <linux/ctype.h>
#include <linux/inet.h>
#include <linux/bitops.h>
+#include <linux/io.h>
#include <asm/system.h>
-#include <asm/io.h>
#include <asm/dma.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
@@ -89,19 +89,19 @@ static int max_bonds = BOND_DEFAULT_MAX_BONDS;
static int num_grat_arp = 1;
static int num_unsol_na = 1;
static int miimon = BOND_LINK_MON_INTERV;
-static int updelay = 0;
-static int downdelay = 0;
+static int updelay;
+static int downdelay;
static int use_carrier = 1;
-static char *mode = NULL;
-static char *primary = NULL;
-static char *lacp_rate = NULL;
-static char *ad_select = NULL;
-static char *xmit_hash_policy = NULL;
+static char *mode;
+static char *primary;
+static char *lacp_rate;
+static char *ad_select;
+static char *xmit_hash_policy;
static int arp_interval = BOND_LINK_ARP_INTERV;
-static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
-static char *arp_validate = NULL;
-static char *fail_over_mac = NULL;
-struct bond_params bonding_defaults;
+static char *arp_ip_target[BOND_MAX_ARP_TARGETS];
+static char *arp_validate;
+static char *fail_over_mac;
+static struct bond_params bonding_defaults;
module_param(max_bonds, int, 0);
MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
@@ -151,14 +151,14 @@ static const char * const version =
LIST_HEAD(bond_dev_list);
#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *bond_proc_dir = NULL;
+static struct proc_dir_entry *bond_proc_dir;
#endif
-static __be32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ;
-static int arp_ip_count = 0;
+static __be32 arp_target[BOND_MAX_ARP_TARGETS];
+static int arp_ip_count;
static int bond_mode = BOND_MODE_ROUNDROBIN;
-static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2;
-static int lacp_fast = 0;
+static int xmit_hashtype = BOND_XMIT_POLICY_LAYER2;
+static int lacp_fast;
const struct bond_parm_tbl bond_lacp_tbl[] = {
@@ -210,6 +210,7 @@ struct bond_parm_tbl ad_select_tbl[] = {
/*-------------------------- Forward declarations ---------------------------*/
static void bond_send_gratuitous_arp(struct bonding *bond);
+static int bond_init(struct net_device *bond_dev);
static void bond_deinit(struct net_device *bond_dev);
/*---------------------------- General routines -----------------------------*/
@@ -221,7 +222,7 @@ static const char *bond_mode_name(int mode)
[BOND_MODE_ACTIVEBACKUP] = "fault-tolerance (active-backup)",
[BOND_MODE_XOR] = "load balancing (xor)",
[BOND_MODE_BROADCAST] = "fault-tolerance (broadcast)",
- [BOND_MODE_8023AD]= "IEEE 802.3ad Dynamic link aggregation",
+ [BOND_MODE_8023AD] = "IEEE 802.3ad Dynamic link aggregation",
[BOND_MODE_TLB] = "transmit load balancing",
[BOND_MODE_ALB] = "adaptive load balancing",
};
@@ -246,12 +247,11 @@ static int bond_add_vlan(struct bonding *bond, unsigned short vlan_id)
struct vlan_entry *vlan;
pr_debug("bond: %s, vlan id %d\n",
- (bond ? bond->dev->name: "None"), vlan_id);
+ (bond ? bond->dev->name : "None"), vlan_id);
vlan = kzalloc(sizeof(struct vlan_entry), GFP_KERNEL);
- if (!vlan) {
+ if (!vlan)
return -ENOMEM;
- }
INIT_LIST_HEAD(&vlan->vlan_list);
vlan->vlan_id = vlan_id;
@@ -351,16 +351,15 @@ static int bond_has_challenged_slaves(struct bonding *bond)
*
* Returns %NULL if list is empty, bond->next_vlan if @curr is %NULL,
* or @curr->next otherwise (even if it is @curr itself again).
- *
+ *
* Caller must hold bond->lock
*/
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr)
{
struct vlan_entry *next, *last;
- if (list_empty(&bond->vlan_list)) {
+ if (list_empty(&bond->vlan_list))
return NULL;
- }
if (!curr) {
next = list_entry(bond->vlan_list.next,
@@ -382,11 +381,11 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr)
/**
* bond_dev_queue_xmit - Prepare skb for xmit.
- *
+ *
* @bond: bond device that got this skb for tx.
* @skb: hw accel VLAN tagged skb to transmit
* @slave_dev: slave that is supposed to xmit this skbuff
- *
+ *
* When the bond gets an skb to transmit that is
* already hardware accelerated VLAN tagged, and it
* needs to relay this skb to a slave that is not
@@ -394,7 +393,8 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr)
* i.e. strip the hwaccel tag and re-insert it as part
* of the payload.
*/
-int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev)
+int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
+ struct net_device *slave_dev)
{
unsigned short uninitialized_var(vlan_id);
@@ -428,7 +428,7 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_de
* b. The operation is protected by the RTNL semaphore in the 8021q code,
* c. Holding a lock with BH disabled while directly calling a base driver
* entry point is generally a BAD idea.
- *
+ *
* The design of synchronization/protection for this operation in the 8021q
* module is good for one or more VLAN devices over a single physical device
* and cannot be extended for a teaming solution like bonding, so there is a
@@ -443,7 +443,8 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_de
* @bond_dev: bonding net device that got called
* @grp: vlan group being registered
*/
-static void bond_vlan_rx_register(struct net_device *bond_dev, struct vlan_group *grp)
+static void bond_vlan_rx_register(struct net_device *bond_dev,
+ struct vlan_group *grp)
{
struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave;
@@ -485,7 +486,7 @@ static void bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid)
res = bond_add_vlan(bond, vid);
if (res) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Error: Failed to add vlan id %d\n",
bond_dev->name, vid);
}
@@ -520,7 +521,7 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid)
res = bond_del_vlan(bond, vid);
if (res) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Error: Failed to remove vlan id %d\n",
bond_dev->name, vid);
}
@@ -551,7 +552,8 @@ out:
write_unlock_bh(&bond->lock);
}
-static void bond_del_vlans_from_slave(struct bonding *bond, struct net_device *slave_dev)
+static void bond_del_vlans_from_slave(struct bonding *bond,
+ struct net_device *slave_dev)
{
const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
struct vlan_entry *vlan;
@@ -673,7 +675,7 @@ static int bond_update_speed_duplex(struct slave *slave)
* if <dev> supports MII link status reporting, check its link status.
*
* We either do MII/ETHTOOL ioctls, or check netif_carrier_ok(),
- * depening upon the setting of the use_carrier parameter.
+ * depending upon the setting of the use_carrier parameter.
*
* Return either BMSR_LSTATUS, meaning that the link is up (or we
* can't tell and just pretend it is), or 0, meaning that the link is
@@ -685,16 +687,29 @@ static int bond_update_speed_duplex(struct slave *slave)
* It'd be nice if there was a good way to tell if a driver supports
* netif_carrier, but there really isn't.
*/
-static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_dev, int reporting)
+static int bond_check_dev_link(struct bonding *bond,
+ struct net_device *slave_dev, int reporting)
{
const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
- static int (* ioctl)(struct net_device *, struct ifreq *, int);
+ static int (*ioctl)(struct net_device *, struct ifreq *, int);
struct ifreq ifr;
struct mii_ioctl_data *mii;
if (bond->params.use_carrier)
return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
+ /* Try to get link status using Ethtool first. */
+ if (slave_dev->ethtool_ops) {
+ if (slave_dev->ethtool_ops->get_link) {
+ u32 link;
+
+ link = slave_dev->ethtool_ops->get_link(slave_dev);
+
+ return link ? BMSR_LSTATUS : 0;
+ }
+ }
+
+ /* Ethtool can't be used, fallback to MII ioctls. */
ioctl = slave_ops->ndo_do_ioctl;
if (ioctl) {
/* TODO: set pointer to correct ioctl on a per team member */
@@ -714,23 +729,8 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
mii = if_mii(&ifr);
if (IOCTL(slave_dev, &ifr, SIOCGMIIPHY) == 0) {
mii->reg_num = MII_BMSR;
- if (IOCTL(slave_dev, &ifr, SIOCGMIIREG) == 0) {
- return (mii->val_out & BMSR_LSTATUS);
- }
- }
- }
-
- /*
- * Some drivers cache ETHTOOL_GLINK for a period of time so we only
- * attempt to get link status from it if the above MII ioctls fail.
- */
- if (slave_dev->ethtool_ops) {
- if (slave_dev->ethtool_ops->get_link) {
- u32 link;
-
- link = slave_dev->ethtool_ops->get_link(slave_dev);
-
- return link ? BMSR_LSTATUS : 0;
+ if (IOCTL(slave_dev, &ifr, SIOCGMIIREG) == 0)
+ return mii->val_out & BMSR_LSTATUS;
}
}
@@ -740,7 +740,7 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
* cannot report link status). If not reporting, pretend
* we're ok.
*/
- return (reporting ? -1 : BMSR_LSTATUS);
+ return reporting ? -1 : BMSR_LSTATUS;
}
/*----------------------------- Multicast list ------------------------------*/
@@ -748,7 +748,8 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
/*
* Returns 0 if dmi1 and dmi2 are the same, non-0 otherwise
*/
-static inline int bond_is_dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2)
+static inline int bond_is_dmi_same(const struct dev_mc_list *dmi1,
+ const struct dev_mc_list *dmi2)
{
return memcmp(dmi1->dmi_addr, dmi2->dmi_addr, dmi1->dmi_addrlen) == 0 &&
dmi1->dmi_addrlen == dmi2->dmi_addrlen;
@@ -757,14 +758,14 @@ static inline int bond_is_dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list
/*
* returns dmi entry if found, NULL otherwise
*/
-static struct dev_mc_list *bond_mc_list_find_dmi(struct dev_mc_list *dmi, struct dev_mc_list *mc_list)
+static struct dev_mc_list *bond_mc_list_find_dmi(struct dev_mc_list *dmi,
+ struct dev_mc_list *mc_list)
{
struct dev_mc_list *idmi;
for (idmi = mc_list; idmi; idmi = idmi->next) {
- if (bond_is_dmi_same(dmi, idmi)) {
+ if (bond_is_dmi_same(dmi, idmi))
return idmi;
- }
}
return NULL;
@@ -826,15 +827,14 @@ static void bond_mc_add(struct bonding *bond, void *addr, int alen)
{
if (USES_PRIMARY(bond->params.mode)) {
/* write lock already acquired */
- if (bond->curr_active_slave) {
+ if (bond->curr_active_slave)
dev_mc_add(bond->curr_active_slave->dev, addr, alen, 0);
- }
} else {
struct slave *slave;
int i;
- bond_for_each_slave(bond, slave, i) {
+
+ bond_for_each_slave(bond, slave, i)
dev_mc_add(slave->dev, addr, alen, 0);
- }
}
}
@@ -846,9 +846,9 @@ static void bond_mc_delete(struct bonding *bond, void *addr, int alen)
{
if (USES_PRIMARY(bond->params.mode)) {
/* write lock already acquired */
- if (bond->curr_active_slave) {
- dev_mc_delete(bond->curr_active_slave->dev, addr, alen, 0);
- }
+ if (bond->curr_active_slave)
+ dev_mc_delete(bond->curr_active_slave->dev, addr,
+ alen, 0);
} else {
struct slave *slave;
int i;
@@ -872,9 +872,8 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
rcu_read_lock();
in_dev = __in_dev_get_rcu(bond->dev);
if (in_dev) {
- for (im = in_dev->mc_list; im; im = im->next) {
+ for (im = in_dev->mc_list; im; im = im->next)
ip_mc_rejoin_group(im);
- }
}
rcu_read_unlock();
@@ -893,7 +892,8 @@ static void bond_mc_list_destroy(struct bonding *bond)
kfree(dmi);
dmi = bond->mc_list;
}
- bond->mc_list = NULL;
+
+ bond->mc_list = NULL;
}
/*
@@ -926,14 +926,14 @@ static int bond_mc_list_copy(struct dev_mc_list *mc_list, struct bonding *bond,
/*
* flush all members of flush->mc_list from device dev->mc_list
*/
-static void bond_mc_list_flush(struct net_device *bond_dev, struct net_device *slave_dev)
+static void bond_mc_list_flush(struct net_device *bond_dev,
+ struct net_device *slave_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
struct dev_mc_list *dmi;
- for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
+ for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next)
dev_mc_delete(slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
- }
if (bond->params.mode == BOND_MODE_8023AD) {
/* del lacpdu mc addr from mc list */
@@ -950,44 +950,40 @@ static void bond_mc_list_flush(struct net_device *bond_dev, struct net_device *s
* old active slaves (if any) according to the multicast mode, and
* promiscuous flags unconditionally.
*/
-static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct slave *old_active)
+static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
+ struct slave *old_active)
{
struct dev_mc_list *dmi;
- if (!USES_PRIMARY(bond->params.mode)) {
+ if (!USES_PRIMARY(bond->params.mode))
/* nothing to do - mc list is already up-to-date on
* all slaves
*/
return;
- }
if (old_active) {
- if (bond->dev->flags & IFF_PROMISC) {
+ if (bond->dev->flags & IFF_PROMISC)
dev_set_promiscuity(old_active->dev, -1);
- }
- if (bond->dev->flags & IFF_ALLMULTI) {
+ if (bond->dev->flags & IFF_ALLMULTI)
dev_set_allmulti(old_active->dev, -1);
- }
- for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next) {
- dev_mc_delete(old_active->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
- }
+ for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next)
+ dev_mc_delete(old_active->dev, dmi->dmi_addr,
+ dmi->dmi_addrlen, 0);
}
if (new_active) {
/* FIXME: Signal errors upstream. */
- if (bond->dev->flags & IFF_PROMISC) {
+ if (bond->dev->flags & IFF_PROMISC)
dev_set_promiscuity(new_active->dev, 1);
- }
- if (bond->dev->flags & IFF_ALLMULTI) {
+ if (bond->dev->flags & IFF_ALLMULTI)
dev_set_allmulti(new_active->dev, 1);
- }
- for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next) {
- dev_mc_add(new_active->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
- }
+ for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next)
+ dev_mc_add(new_active->dev, dmi->dmi_addr,
+ dmi->dmi_addrlen, 0);
bond_resend_igmp_join_requests(bond);
}
}
@@ -1041,7 +1037,7 @@ static void bond_do_fail_over_mac(struct bonding *bond,
rv = dev_set_mac_address(new_active->dev, &saddr);
if (rv) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Error %d setting MAC of slave %s\n",
bond->dev->name, -rv, new_active->dev->name);
goto out;
@@ -1055,7 +1051,7 @@ static void bond_do_fail_over_mac(struct bonding *bond,
rv = dev_set_mac_address(old_active->dev, &saddr);
if (rv)
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Error %d setting MAC of slave %s\n",
bond->dev->name, -rv, new_active->dev->name);
out:
@@ -1063,7 +1059,7 @@ out:
write_lock_bh(&bond->curr_slave_lock);
break;
default:
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: bond_do_fail_over_mac impossible: bad policy %d\n",
bond->dev->name, bond->params.fail_over_mac);
break;
@@ -1088,17 +1084,17 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
new_active = old_active = bond->curr_active_slave;
if (!new_active) { /* there were no active slaves left */
- if (bond->slave_cnt > 0) { /* found one slave */
+ if (bond->slave_cnt > 0) /* found one slave */
new_active = bond->first_slave;
- } else {
+ else
return NULL; /* still no slave, return NULL */
- }
}
- /* first try the primary link; if arping, a link must tx/rx traffic
- * before it can be considered the curr_active_slave - also, we would skip
- * slaves between the curr_active_slave and primary_slave that may be up
- * and able to arp
+ /*
+ * first try the primary link; if arping, a link must tx/rx
+ * traffic before it can be considered the curr_active_slave.
+ * also, we would skip slaves between the curr_active_slave
+ * and primary_slave that may be up and able to arp
*/
if ((bond->primary_slave) &&
(!bond->params.arp_interval) &&
@@ -1146,16 +1142,15 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
{
struct slave *old_active = bond->curr_active_slave;
- if (old_active == new_active) {
+ if (old_active == new_active)
return;
- }
if (new_active) {
new_active->jiffies = jiffies;
if (new_active->link == BOND_LINK_BACK) {
if (USES_PRIMARY(bond->params.mode)) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: making interface %s the new "
"active one %d ms earlier.\n",
bond->dev->name, new_active->dev->name,
@@ -1165,15 +1160,14 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
new_active->delay = 0;
new_active->link = BOND_LINK_UP;
- if (bond->params.mode == BOND_MODE_8023AD) {
+ if (bond->params.mode == BOND_MODE_8023AD)
bond_3ad_handle_link_change(new_active, BOND_LINK_UP);
- }
if (bond_is_lb(bond))
bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP);
} else {
if (USES_PRIMARY(bond->params.mode)) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: making interface %s the new "
"active one.\n",
bond->dev->name, new_active->dev->name);
@@ -1181,9 +1175,8 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
}
}
- if (USES_PRIMARY(bond->params.mode)) {
+ if (USES_PRIMARY(bond->params.mode))
bond_mc_swap(bond, new_active, old_active);
- }
if (bond_is_lb(bond)) {
bond_alb_handle_active_change(bond, new_active);
@@ -1196,9 +1189,8 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
}
if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
- if (old_active) {
+ if (old_active)
bond_set_slave_inactive_flags(old_active);
- }
if (new_active) {
bond_set_slave_active_flags(new_active);
@@ -1228,7 +1220,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
* bond_select_active_slave - select a new active slave, if needed
* @bond: our bonding struct
*
- * This functions shoud be called when one of the following occurs:
+ * This functions should be called when one of the following occurs:
* - The old curr_active_slave has been released or lost its link.
* - The primary_slave has got its link back.
* - A slave has got its link back and there's no old curr_active_slave.
@@ -1248,11 +1240,11 @@ void bond_select_active_slave(struct bonding *bond)
return;
if (netif_carrier_ok(bond->dev)) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: first active interface up!\n",
bond->dev->name);
} else {
- printk(KERN_INFO DRV_NAME ": %s: "
+ pr_info(DRV_NAME ": %s: "
"now running without any active interface !\n",
bond->dev->name);
}
@@ -1294,13 +1286,11 @@ static void bond_attach_slave(struct bonding *bond, struct slave *new_slave)
*/
static void bond_detach_slave(struct bonding *bond, struct slave *slave)
{
- if (slave->next) {
+ if (slave->next)
slave->next->prev = slave->prev;
- }
- if (slave->prev) {
+ if (slave->prev)
slave->prev->next = slave->next;
- }
if (bond->first_slave == slave) { /* slave is the first slave */
if (bond->slave_cnt > 1) { /* there are more slave */
@@ -1331,7 +1321,7 @@ static int bond_sethwaddr(struct net_device *bond_dev,
(NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | \
NETIF_F_HW_VLAN_FILTER)
-/*
+/*
* Compute the common dev->feature set available to all slaves. Some
* feature bits are managed elsewhere, so preserve those feature bits
* on the master device.
@@ -1399,14 +1389,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
slave_ops->ndo_do_ioctl == NULL) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": %s: Warning: no link monitoring support for %s\n",
bond_dev->name, slave_dev->name);
}
/* bond must be initialized by bond_open() before enslaving */
if (!(bond_dev->flags & IFF_UP)) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
" %s: master_dev is not up in bond_enslave\n",
bond_dev->name);
}
@@ -1422,14 +1412,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) {
pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
if (!list_empty(&bond->vlan_list)) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Error: cannot enslave VLAN "
"challenged slave %s on VLAN enabled "
"bond %s\n", bond_dev->name, slave_dev->name,
bond_dev->name);
return -EPERM;
} else {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": %s: Warning: enslaved VLAN challenged "
"slave %s. Adding VLANs will be blocked as "
"long as %s is part of bond %s\n",
@@ -1449,12 +1439,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
/*
* Old ifenslave binaries are no longer supported. These can
- * be identified with moderate accurary by the state of the slave:
+ * be identified with moderate accuracy by the state of the slave:
* the current ifenslave will set the interface down prior to
* enslaving it; the old ifenslave will not.
*/
if ((slave_dev->flags & IFF_UP)) {
- printk(KERN_ERR DRV_NAME ": %s is up. "
+ pr_err(DRV_NAME ": %s is up. "
"This may be due to an out of date ifenslave.\n",
slave_dev->name);
res = -EPERM;
@@ -1472,7 +1462,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
if (slave_dev->type != ARPHRD_ETHER)
bond_setup_by_slave(bond_dev, slave_dev);
} else if (bond_dev->type != slave_dev->type) {
- printk(KERN_ERR DRV_NAME ": %s ether type (%d) is different "
+ pr_err(DRV_NAME ": %s ether type (%d) is different "
"from other slaves (%d), can not enslave it.\n",
slave_dev->name,
slave_dev->type, bond_dev->type);
@@ -1482,14 +1472,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
if (slave_ops->ndo_set_mac_address == NULL) {
if (bond->slave_cnt == 0) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": %s: Warning: The first slave device "
"specified does not support setting the MAC "
"address. Setting fail_over_mac to active.",
bond_dev->name);
bond->params.fail_over_mac = BOND_FOM_ACTIVE;
} else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Error: The slave device specified "
"does not support setting the MAC address, "
"but fail_over_mac is not set to active.\n"
@@ -1539,7 +1529,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
/* open the slave since the application closed it */
res = dev_open(slave_dev);
if (res) {
- pr_debug("Openning slave %s failed\n", slave_dev->name);
+ pr_debug("Opening slave %s failed\n", slave_dev->name);
goto err_unset_master;
}
@@ -1551,9 +1541,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
* it might fail and we do not want to have to undo everything
*/
res = bond_alb_init_slave(bond, new_slave);
- if (res) {
+ if (res)
goto err_close;
- }
}
/* If the mode USES_PRIMARY, then the new slave gets the
@@ -1578,9 +1567,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
netif_addr_lock_bh(bond_dev);
/* upload master's mc_list to new slave */
- for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
- dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
- }
+ for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next)
+ dev_mc_add(slave_dev, dmi->dmi_addr,
+ dmi->dmi_addrlen, 0);
netif_addr_unlock_bh(bond_dev);
}
@@ -1621,7 +1610,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
* supported); thus, we don't need to change
* the messages for netif_carrier.
*/
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": %s: Warning: MII and ETHTOOL support not "
"available for interface %s, and "
"arp_interval/arp_ip_target module parameters "
@@ -1630,7 +1619,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
bond_dev->name, slave_dev->name);
} else if (link_reporting == -1) {
/* unable get link status using mii/ethtool */
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": %s: Warning: can't get link status from "
"interface %s; the network driver associated "
"with this interface does not support MII or "
@@ -1662,13 +1651,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
if (bond_update_speed_duplex(new_slave) &&
(new_slave->link != BOND_LINK_DOWN)) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": %s: Warning: failed to get speed and duplex from %s, "
"assumed to be 100Mb/sec and Full.\n",
bond_dev->name, new_slave->dev->name);
if (bond->params.mode == BOND_MODE_8023AD) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": %s: Warning: Operation of 802.3ad mode requires ETHTOOL "
"support in base driver for proper aggregator "
"selection.\n", bond_dev->name);
@@ -1677,9 +1666,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
/* if there is a primary slave, remember it */
- if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
+ if (strcmp(bond->params.primary, new_slave->dev->name) == 0)
bond->primary_slave = new_slave;
- }
}
write_lock_bh(&bond->curr_slave_lock);
@@ -1726,9 +1714,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
* anyway (it holds no special properties of the bond device),
* so we can change it without calling change_active_interface()
*/
- if (!bond->curr_active_slave) {
+ if (!bond->curr_active_slave)
bond->curr_active_slave = new_slave;
- }
+
break;
} /* switch(bond_mode) */
@@ -1742,7 +1730,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
if (res)
goto err_close;
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: enslaving %s as a%s interface with a%s link.\n",
bond_dev->name, slave_dev->name,
new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup",
@@ -1774,7 +1762,7 @@ err_free:
err_undo_flags:
bond_dev->features = old_features;
-
+
return res;
}
@@ -1799,7 +1787,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
/* slave is not a slave or master is not master of this slave */
if (!(slave_dev->flags & IFF_SLAVE) ||
(slave_dev->master != bond_dev)) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Error: cannot release %s.\n",
bond_dev->name, slave_dev->name);
return -EINVAL;
@@ -1810,7 +1798,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
slave = bond_get_slave_by_dev(bond, slave_dev);
if (!slave) {
/* not a slave of this bond */
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: %s not enslaved\n",
bond_dev->name, slave_dev->name);
write_unlock_bh(&bond->lock);
@@ -1821,7 +1809,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
mac_addr_differ = memcmp(bond_dev->dev_addr, slave->perm_hwaddr,
ETH_ALEN);
if (!mac_addr_differ && (bond->slave_cnt > 1))
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": %s: Warning: the permanent HWaddr of %s - "
"%pM - is still in use by %s. "
"Set the HWaddr of %s to a different address "
@@ -1839,7 +1827,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
bond_3ad_unbind_slave(slave);
}
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: releasing %s interface %s\n",
bond_dev->name,
(slave->state == BOND_STATE_ACTIVE)
@@ -1855,13 +1843,11 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
bond_compute_features(bond);
- if (bond->primary_slave == slave) {
+ if (bond->primary_slave == slave)
bond->primary_slave = NULL;
- }
- if (oldcurrent == slave) {
+ if (oldcurrent == slave)
bond_change_active_slave(bond, NULL);
- }
if (bond_is_lb(bond)) {
/* Must be called only after the slave has been
@@ -1903,18 +1889,18 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
if (list_empty(&bond->vlan_list)) {
bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
} else {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": %s: Warning: clearing HW address of %s while it "
"still has VLANs.\n",
bond_dev->name, bond_dev->name);
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": %s: When re-adding slaves, make sure the bond's "
"HW address matches its VLANs'.\n",
bond_dev->name);
}
} else if ((bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
!bond_has_challenged_slaves(bond)) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: last VLAN challenged slave %s "
"left bond %s. VLAN blocking is removed\n",
bond_dev->name, slave_dev->name, bond_dev->name);
@@ -1934,14 +1920,12 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
*/
if (!USES_PRIMARY(bond->params.mode)) {
/* unset promiscuity level from slave */
- if (bond_dev->flags & IFF_PROMISC) {
+ if (bond_dev->flags & IFF_PROMISC)
dev_set_promiscuity(slave_dev, -1);
- }
/* unset allmulti level from slave */
- if (bond_dev->flags & IFF_ALLMULTI) {
+ if (bond_dev->flags & IFF_ALLMULTI)
dev_set_allmulti(slave_dev, -1);
- }
/* flush master's mc_list from slave */
netif_addr_lock_bh(bond_dev);
@@ -1974,41 +1958,36 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
* Destroy a bonding device.
* Must be under rtnl_lock when this function is called.
*/
-void bond_destroy(struct bonding *bond)
-{
- bond_deinit(bond->dev);
- bond_destroy_sysfs_entry(bond);
- unregister_netdevice(bond->dev);
-}
-
-static void bond_destructor(struct net_device *bond_dev)
+static void bond_uninit(struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
+ bond_deinit(bond_dev);
+ bond_destroy_sysfs_entry(bond);
+
if (bond->wq)
destroy_workqueue(bond->wq);
netif_addr_lock_bh(bond_dev);
bond_mc_list_destroy(bond);
netif_addr_unlock_bh(bond_dev);
-
- free_netdev(bond_dev);
}
/*
-* First release a slave and than destroy the bond if no more slaves iare left.
+* First release a slave and than destroy the bond if no more slaves are left.
* Must be under rtnl_lock when this function is called.
*/
-int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev)
+int bond_release_and_destroy(struct net_device *bond_dev,
+ struct net_device *slave_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
int ret;
ret = bond_release(bond_dev, slave_dev);
if ((ret == 0) && (bond->slave_cnt == 0)) {
- printk(KERN_INFO DRV_NAME ": %s: destroying bond %s.\n",
+ pr_info(DRV_NAME ": %s: destroying bond %s.\n",
bond_dev->name, bond_dev->name);
- bond_destroy(bond);
+ unregister_netdevice(bond_dev);
}
return ret;
}
@@ -2027,9 +2006,8 @@ static int bond_release_all(struct net_device *bond_dev)
netif_carrier_off(bond_dev);
- if (bond->slave_cnt == 0) {
+ if (bond->slave_cnt == 0)
goto out;
- }
bond->current_arp_slave = NULL;
bond->primary_slave = NULL;
@@ -2039,9 +2017,8 @@ static int bond_release_all(struct net_device *bond_dev)
/* Inform AD package of unbinding of slave
* before slave is detached from the list.
*/
- if (bond->params.mode == BOND_MODE_8023AD) {
+ if (bond->params.mode == BOND_MODE_8023AD)
bond_3ad_unbind_slave(slave);
- }
slave_dev = slave->dev;
bond_detach_slave(bond, slave);
@@ -2070,14 +2047,12 @@ static int bond_release_all(struct net_device *bond_dev)
*/
if (!USES_PRIMARY(bond->params.mode)) {
/* unset promiscuity level from slave */
- if (bond_dev->flags & IFF_PROMISC) {
+ if (bond_dev->flags & IFF_PROMISC)
dev_set_promiscuity(slave_dev, -1);
- }
/* unset allmulti level from slave */
- if (bond_dev->flags & IFF_ALLMULTI) {
+ if (bond_dev->flags & IFF_ALLMULTI)
dev_set_allmulti(slave_dev, -1);
- }
/* flush master's mc_list from slave */
netif_addr_lock_bh(bond_dev);
@@ -2112,20 +2087,20 @@ static int bond_release_all(struct net_device *bond_dev)
*/
memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
- if (list_empty(&bond->vlan_list)) {
+ if (list_empty(&bond->vlan_list))
bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
- } else {
- printk(KERN_WARNING DRV_NAME
+ else {
+ pr_warning(DRV_NAME
": %s: Warning: clearing HW address of %s while it "
"still has VLANs.\n",
bond_dev->name, bond_dev->name);
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": %s: When re-adding slaves, make sure the bond's "
"HW address matches its VLANs'.\n",
bond_dev->name);
}
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: released all slaves\n",
bond_dev->name);
@@ -2143,8 +2118,8 @@ out:
* - <slave_dev> is already active.
* - The link state of <slave_dev> is not BOND_LINK_UP.
* - <slave_dev> is not running.
- * In these cases, this fuction does nothing.
- * In the other cases, currnt_slave pointer is changed and 0 is returned.
+ * In these cases, this function does nothing.
+ * In the other cases, current_slave pointer is changed and 0 is returned.
*/
static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_device *slave_dev)
{
@@ -2153,15 +2128,12 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
struct slave *new_active = NULL;
int res = 0;
- if (!USES_PRIMARY(bond->params.mode)) {
+ if (!USES_PRIMARY(bond->params.mode))
return -EINVAL;
- }
/* Verify that master_dev is indeed the master of slave_dev */
- if (!(slave_dev->flags & IFF_SLAVE) ||
- (slave_dev->master != bond_dev)) {
+ if (!(slave_dev->flags & IFF_SLAVE) || (slave_dev->master != bond_dev))
return -EINVAL;
- }
read_lock(&bond->lock);
@@ -2186,9 +2158,8 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
write_lock_bh(&bond->curr_slave_lock);
bond_change_active_slave(bond, new_active);
write_unlock_bh(&bond->curr_slave_lock);
- } else {
+ } else
res = -EINVAL;
- }
read_unlock(&bond->lock);
@@ -2240,6 +2211,9 @@ static int bond_miimon_inspect(struct bonding *bond)
{
struct slave *slave;
int i, link_state, commit = 0;
+ bool ignore_updelay;
+
+ ignore_updelay = !bond->curr_active_slave ? true : false;
bond_for_each_slave(bond, slave, i) {
slave->new_link = BOND_LINK_NOCHANGE;
@@ -2254,7 +2228,7 @@ static int bond_miimon_inspect(struct bonding *bond)
slave->link = BOND_LINK_FAIL;
slave->delay = bond->params.downdelay;
if (slave->delay) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: link status down for %s"
"interface %s, disabling it in %d ms.\n",
bond->dev->name,
@@ -2273,7 +2247,7 @@ static int bond_miimon_inspect(struct bonding *bond)
*/
slave->link = BOND_LINK_UP;
slave->jiffies = jiffies;
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: link status up again after %d "
"ms for interface %s.\n",
bond->dev->name,
@@ -2300,10 +2274,11 @@ static int bond_miimon_inspect(struct bonding *bond)
slave->delay = bond->params.updelay;
if (slave->delay) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: link status up for "
"interface %s, enabling it in %d ms.\n",
bond->dev->name, slave->dev->name,
+ ignore_updelay ? 0 :
bond->params.updelay *
bond->params.miimon);
}
@@ -2311,7 +2286,7 @@ static int bond_miimon_inspect(struct bonding *bond)
case BOND_LINK_BACK:
if (!link_state) {
slave->link = BOND_LINK_DOWN;
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: link status down again after %d "
"ms for interface %s.\n",
bond->dev->name,
@@ -2322,9 +2297,13 @@ static int bond_miimon_inspect(struct bonding *bond)
continue;
}
+ if (ignore_updelay)
+ slave->delay = 0;
+
if (slave->delay <= 0) {
slave->new_link = BOND_LINK_UP;
commit++;
+ ignore_updelay = false;
continue;
}
@@ -2361,7 +2340,7 @@ static void bond_miimon_commit(struct bonding *bond)
slave->state = BOND_STATE_BACKUP;
}
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: link status definitely "
"up for interface %s.\n",
bond->dev->name, slave->dev->name);
@@ -2390,7 +2369,7 @@ static void bond_miimon_commit(struct bonding *bond)
bond->params.mode == BOND_MODE_8023AD)
bond_set_slave_inactive_flags(slave);
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: link status definitely down for "
"interface %s, disabling it\n",
bond->dev->name, slave->dev->name);
@@ -2399,8 +2378,7 @@ static void bond_miimon_commit(struct bonding *bond)
bond_3ad_handle_link_change(slave,
BOND_LINK_DOWN);
- if (bond->params.mode == BOND_MODE_TLB ||
- bond->params.mode == BOND_MODE_ALB)
+ if (bond_is_lb(bond))
bond_alb_handle_link_change(bond, slave,
BOND_LINK_DOWN);
@@ -2410,7 +2388,7 @@ static void bond_miimon_commit(struct bonding *bond)
continue;
default:
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: invalid new link %d on slave %s\n",
bond->dev->name, slave->new_link,
slave->dev->name);
@@ -2531,18 +2509,18 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_
pr_debug("arp %d on slave %s: dst %x src %x vid %d\n", arp_op,
slave_dev->name, dest_ip, src_ip, vlan_id);
-
+
skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip,
NULL, slave_dev->dev_addr, NULL);
if (!skb) {
- printk(KERN_ERR DRV_NAME ": ARP packet allocation failed\n");
+ pr_err(DRV_NAME ": ARP packet allocation failed\n");
return;
}
if (vlan_id) {
skb = vlan_put_tag(skb, vlan_id);
if (!skb) {
- printk(KERN_ERR DRV_NAME ": failed to insert VLAN tag\n");
+ pr_err(DRV_NAME ": failed to insert VLAN tag\n");
return;
}
}
@@ -2582,7 +2560,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
rv = ip_route_output_key(&init_net, &rt, &fl);
if (rv) {
if (net_ratelimit()) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": %s: no route to arp_ip_target %pI4\n",
bond->dev->name, &fl.fl4_dst);
}
@@ -2619,7 +2597,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
}
if (net_ratelimit()) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": %s: no path to arp_ip_target %pI4 via rt.dev %s\n",
bond->dev->name, &fl.fl4_dst,
rt->u.dst.dev ? rt->u.dst.dev->name : "NULL");
@@ -2767,13 +2745,11 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval);
- if (bond->kill_timers) {
+ if (bond->kill_timers)
goto out;
- }
- if (bond->slave_cnt == 0) {
+ if (bond->slave_cnt == 0)
goto re_arm;
- }
read_lock(&bond->curr_slave_lock);
oldcurrent = bond->curr_active_slave;
@@ -2789,7 +2765,7 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
*/
bond_for_each_slave(bond, slave, i) {
if (slave->link != BOND_LINK_UP) {
- if (time_before_eq(jiffies, slave->dev->trans_start + delta_in_ticks) &&
+ if (time_before_eq(jiffies, dev_trans_start(slave->dev) + delta_in_ticks) &&
time_before_eq(jiffies, slave->dev->last_rx + delta_in_ticks)) {
slave->link = BOND_LINK_UP;
@@ -2801,14 +2777,14 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
* is closed.
*/
if (!oldcurrent) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: link status definitely "
"up for interface %s, ",
bond->dev->name,
slave->dev->name);
do_failover = 1;
} else {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: interface %s is now up\n",
bond->dev->name,
slave->dev->name);
@@ -2821,24 +2797,22 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
* when the source ip is 0, so don't take the link down
* if we don't know our ip yet
*/
- if (time_after_eq(jiffies, slave->dev->trans_start + 2*delta_in_ticks) ||
+ if (time_after_eq(jiffies, dev_trans_start(slave->dev) + 2*delta_in_ticks) ||
(time_after_eq(jiffies, slave->dev->last_rx + 2*delta_in_ticks))) {
slave->link = BOND_LINK_DOWN;
slave->state = BOND_STATE_BACKUP;
- if (slave->link_failure_count < UINT_MAX) {
+ if (slave->link_failure_count < UINT_MAX)
slave->link_failure_count++;
- }
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: interface %s is now down.\n",
bond->dev->name,
slave->dev->name);
- if (slave == oldcurrent) {
+ if (slave == oldcurrent)
do_failover = 1;
- }
}
}
@@ -2849,9 +2823,8 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
* do - all replies will be rx'ed on same link causing slaves
* to be unstable during low/no traffic periods
*/
- if (IS_UP(slave->dev)) {
+ if (IS_UP(slave->dev))
bond_arp_send_all(bond, slave);
- }
}
if (do_failover) {
@@ -2932,7 +2905,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
* the bond has an IP address)
*/
if ((slave->state == BOND_STATE_ACTIVE) &&
- (time_after_eq(jiffies, slave->dev->trans_start +
+ (time_after_eq(jiffies, dev_trans_start(slave->dev) +
2 * delta_in_ticks) ||
(time_after_eq(jiffies, slave_last_rx(bond, slave)
+ 2 * delta_in_ticks)))) {
@@ -2976,13 +2949,13 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
write_lock_bh(&bond->curr_slave_lock);
if (!bond->curr_active_slave &&
- time_before_eq(jiffies, slave->dev->trans_start +
+ time_before_eq(jiffies, dev_trans_start(slave->dev) +
delta_in_ticks)) {
slave->link = BOND_LINK_UP;
bond_change_active_slave(bond, slave);
bond->current_arp_slave = NULL;
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: %s is up and now the "
"active interface\n",
bond->dev->name, slave->dev->name);
@@ -2998,7 +2971,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
bond_set_slave_inactive_flags(slave);
bond->current_arp_slave = NULL;
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: backup interface %s is now up\n",
bond->dev->name, slave->dev->name);
}
@@ -3014,7 +2987,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
slave->link = BOND_LINK_DOWN;
if (slave == bond->curr_active_slave) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: link status down for active "
"interface %s, disabling it\n",
bond->dev->name, slave->dev->name);
@@ -3033,7 +3006,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
bond->current_arp_slave = NULL;
} else if (slave->state == BOND_STATE_BACKUP) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: backup interface %s is now down\n",
bond->dev->name, slave->dev->name);
@@ -3042,7 +3015,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
break;
default:
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: impossible: new_link %d on slave %s\n",
bond->dev->name, slave->new_link,
slave->dev->name);
@@ -3076,7 +3049,7 @@ static void bond_ab_arp_probe(struct bonding *bond)
read_lock(&bond->curr_slave_lock);
if (bond->current_arp_slave && bond->curr_active_slave)
- printk("PROBE: c_arp %s && cas %s BAD\n",
+ pr_info(DRV_NAME "PROBE: c_arp %s && cas %s BAD\n",
bond->current_arp_slave->dev->name,
bond->curr_active_slave->dev->name);
@@ -3126,7 +3099,7 @@ static void bond_ab_arp_probe(struct bonding *bond)
bond_set_slave_inactive_flags(slave);
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: backup interface %s is now down.\n",
bond->dev->name, slave->dev->name);
}
@@ -3176,9 +3149,8 @@ void bond_activebackup_arp_mon(struct work_struct *work)
bond_ab_arp_probe(bond);
re_arm:
- if (bond->params.arp_interval) {
+ if (bond->params.arp_interval)
queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
- }
out:
read_unlock(&bond->lock);
}
@@ -3200,14 +3172,12 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
read_lock(&dev_base_lock);
read_lock(&bond->lock);
- if (*pos == 0) {
+ if (*pos == 0)
return SEQ_START_TOKEN;
- }
bond_for_each_slave(bond, slave, i) {
- if (++off == *pos) {
+ if (++off == *pos)
return slave;
- }
}
return NULL;
@@ -3219,9 +3189,8 @@ static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
struct slave *slave = v;
++*pos;
- if (v == SEQ_START_TOKEN) {
+ if (v == SEQ_START_TOKEN)
return bond->first_slave;
- }
slave = slave->next;
@@ -3284,14 +3253,14 @@ static void bond_info_show_master(struct seq_file *seq)
/* ARP information */
- if(bond->params.arp_interval > 0) {
- int printed=0;
+ if (bond->params.arp_interval > 0) {
+ int printed = 0;
seq_printf(seq, "ARP Polling Interval (ms): %d\n",
bond->params.arp_interval);
seq_printf(seq, "ARP IP target/s (n.n.n.n form):");
- for(i = 0; (i < BOND_MAX_ARP_TARGETS) ;i++) {
+ for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
if (!bond->params.arp_targets[i])
break;
if (printed)
@@ -3331,7 +3300,8 @@ static void bond_info_show_master(struct seq_file *seq)
}
}
-static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave)
+static void bond_info_show_slave(struct seq_file *seq,
+ const struct slave *slave)
{
struct bonding *bond = seq->private;
@@ -3347,12 +3317,11 @@ static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave
const struct aggregator *agg
= SLAVE_AD_INFO(slave).port.aggregator;
- if (agg) {
+ if (agg)
seq_printf(seq, "Aggregator ID: %d\n",
agg->aggregator_identifier);
- } else {
+ else
seq_puts(seq, "Aggregator ID: N/A\n");
- }
}
}
@@ -3361,9 +3330,8 @@ static int bond_info_seq_show(struct seq_file *seq, void *v)
if (v == SEQ_START_TOKEN) {
seq_printf(seq, "%s\n", version);
bond_info_show_master(seq);
- } else {
+ } else
bond_info_show_slave(seq, v);
- }
return 0;
}
@@ -3408,13 +3376,12 @@ static int bond_create_proc_entry(struct bonding *bond)
bond->proc_entry = proc_create_data(bond_dev->name,
S_IRUGO, bond_proc_dir,
&bond_info_fops, bond);
- if (bond->proc_entry == NULL) {
- printk(KERN_WARNING DRV_NAME
+ if (bond->proc_entry == NULL)
+ pr_warning(DRV_NAME
": Warning: Cannot create /proc/net/%s/%s\n",
DRV_NAME, bond_dev->name);
- } else {
+ else
memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ);
- }
}
return 0;
@@ -3437,7 +3404,7 @@ static void bond_create_proc_dir(void)
if (!bond_proc_dir) {
bond_proc_dir = proc_mkdir(DRV_NAME, init_net.proc_net);
if (!bond_proc_dir)
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: cannot create /proc/net/%s\n",
DRV_NAME);
}
@@ -3453,8 +3420,28 @@ static void bond_destroy_proc_dir(void)
bond_proc_dir = NULL;
}
}
+
+#else /* !CONFIG_PROC_FS */
+
+static int bond_create_proc_entry(struct bonding *bond)
+{
+}
+
+static void bond_remove_proc_entry(struct bonding *bond)
+{
+}
+
+static void bond_create_proc_dir(void)
+{
+}
+
+static void bond_destroy_proc_dir(void)
+{
+}
+
#endif /* CONFIG_PROC_FS */
+
/*-------------------------- netdev event handling --------------------------*/
/*
@@ -3462,18 +3449,17 @@ static void bond_destroy_proc_dir(void)
*/
static int bond_event_changename(struct bonding *bond)
{
-#ifdef CONFIG_PROC_FS
bond_remove_proc_entry(bond);
bond_create_proc_entry(bond);
-#endif
- down_write(&(bonding_rwsem));
- bond_destroy_sysfs_entry(bond);
- bond_create_sysfs_entry(bond);
- up_write(&(bonding_rwsem));
+
+ bond_destroy_sysfs_entry(bond);
+ bond_create_sysfs_entry(bond);
+
return NOTIFY_DONE;
}
-static int bond_master_netdev_event(unsigned long event, struct net_device *bond_dev)
+static int bond_master_netdev_event(unsigned long event,
+ struct net_device *bond_dev)
{
struct bonding *event_bond = netdev_priv(bond_dev);
@@ -3490,7 +3476,8 @@ static int bond_master_netdev_event(unsigned long event, struct net_device *bond
return NOTIFY_DONE;
}
-static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev)
+static int bond_slave_netdev_event(unsigned long event,
+ struct net_device *slave_dev)
{
struct net_device *bond_dev = slave_dev->master;
struct bonding *bond = netdev_priv(bond_dev);
@@ -3568,7 +3555,8 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave
* locks for us to safely manipulate the slave devices (RTNL lock,
* dev_probe_lock).
*/
-static int bond_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
+static int bond_netdev_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
{
struct net_device *event_dev = (struct net_device *)ptr;
@@ -3923,9 +3911,9 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
switch (cmd) {
case SIOCGMIIPHY:
mii = if_mii(ifr);
- if (!mii) {
+ if (!mii)
return -EINVAL;
- }
+
mii->phy_id = 0;
/* Fall Through */
case SIOCGMIIREG:
@@ -3934,18 +3922,18 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
* instead of SIOCGMIIPHY.
*/
mii = if_mii(ifr);
- if (!mii) {
+ if (!mii)
return -EINVAL;
- }
+
if (mii->reg_num == 1) {
struct bonding *bond = netdev_priv(bond_dev);
mii->val_out = 0;
read_lock(&bond->lock);
read_lock(&bond->curr_slave_lock);
- if (netif_carrier_ok(bond->dev)) {
+ if (netif_carrier_ok(bond->dev))
mii->val_out = BMSR_LSTATUS;
- }
+
read_unlock(&bond->curr_slave_lock);
read_unlock(&bond->lock);
}
@@ -3955,32 +3943,26 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
case SIOCBONDINFOQUERY:
u_binfo = (struct ifbond __user *)ifr->ifr_data;
- if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond))) {
+ if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond)))
return -EFAULT;
- }
res = bond_info_query(bond_dev, &k_binfo);
- if (res == 0) {
- if (copy_to_user(u_binfo, &k_binfo, sizeof(ifbond))) {
- return -EFAULT;
- }
- }
+ if (res == 0 &&
+ copy_to_user(u_binfo, &k_binfo, sizeof(ifbond)))
+ return -EFAULT;
return res;
case BOND_SLAVE_INFO_QUERY_OLD:
case SIOCBONDSLAVEINFOQUERY:
u_sinfo = (struct ifslave __user *)ifr->ifr_data;
- if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave))) {
+ if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave)))
return -EFAULT;
- }
res = bond_slave_info_query(bond_dev, &k_sinfo);
- if (res == 0) {
- if (copy_to_user(u_sinfo, &k_sinfo, sizeof(ifslave))) {
- return -EFAULT;
- }
- }
+ if (res == 0 &&
+ copy_to_user(u_sinfo, &k_sinfo, sizeof(ifslave)))
+ return -EFAULT;
return res;
default:
@@ -3988,18 +3970,16 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
break;
}
- if (!capable(CAP_NET_ADMIN)) {
+ if (!capable(CAP_NET_ADMIN))
return -EPERM;
- }
- down_write(&(bonding_rwsem));
slave_dev = dev_get_by_name(&init_net, ifr->ifr_slave);
pr_debug("slave_dev=%p: \n", slave_dev);
- if (!slave_dev) {
+ if (!slave_dev)
res = -ENODEV;
- } else {
+ else {
pr_debug("slave_dev->name=%s: \n", slave_dev->name);
switch (cmd) {
case BOND_ENSLAVE_OLD:
@@ -4025,7 +4005,6 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
dev_put(slave_dev);
}
- up_write(&(bonding_rwsem));
return res;
}
@@ -4037,30 +4016,30 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
/*
* Do promisc before checking multicast_mode
*/
- if ((bond_dev->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC)) {
+ if ((bond_dev->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC))
/*
* FIXME: Need to handle the error when one of the multi-slaves
* encounters error.
*/
bond_set_promiscuity(bond, 1);
- }
- if (!(bond_dev->flags & IFF_PROMISC) && (bond->flags & IFF_PROMISC)) {
+
+ if (!(bond_dev->flags & IFF_PROMISC) && (bond->flags & IFF_PROMISC))
bond_set_promiscuity(bond, -1);
- }
+
/* set allmulti flag to slaves */
- if ((bond_dev->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI)) {
+ if ((bond_dev->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI))
/*
* FIXME: Need to handle the error when one of the multi-slaves
* encounters error.
*/
bond_set_allmulti(bond, 1);
- }
- if (!(bond_dev->flags & IFF_ALLMULTI) && (bond->flags & IFF_ALLMULTI)) {
+
+ if (!(bond_dev->flags & IFF_ALLMULTI) && (bond->flags & IFF_ALLMULTI))
bond_set_allmulti(bond, -1);
- }
+
read_lock(&bond->lock);
@@ -4068,16 +4047,14 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
/* looking for addresses to add to slaves' mc list */
for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
- if (!bond_mc_list_find_dmi(dmi, bond->mc_list)) {
+ if (!bond_mc_list_find_dmi(dmi, bond->mc_list))
bond_mc_add(bond, dmi->dmi_addr, dmi->dmi_addrlen);
- }
}
/* looking for addresses to delete from slaves' list */
for (dmi = bond->mc_list; dmi; dmi = dmi->next) {
- if (!bond_mc_list_find_dmi(dmi, bond_dev->mc_list)) {
+ if (!bond_mc_list_find_dmi(dmi, bond_dev->mc_list))
bond_mc_delete(bond, dmi->dmi_addr, dmi->dmi_addrlen);
- }
}
/* save master's multicast list */
@@ -4197,9 +4174,8 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
if (bond->params.fail_over_mac == BOND_FOM_ACTIVE)
return 0;
- if (!is_valid_ether_addr(sa->sa_data)) {
+ if (!is_valid_ether_addr(sa->sa_data))
return -EADDRNOTAVAIL;
- }
/* Can't hold bond->lock with bh disabled here since
* some base drivers panic. On the other hand we can't
@@ -4270,9 +4246,8 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
read_lock(&bond->lock);
- if (!BOND_IS_OK(bond)) {
+ if (!BOND_IS_OK(bond))
goto out;
- }
/*
* Concurrent TX may collide on rr_tx_counter; we accept that
@@ -4282,9 +4257,8 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
bond_for_each_slave(bond, slave, i) {
slave_no--;
- if (slave_no < 0) {
+ if (slave_no < 0)
break;
- }
}
start_at = slave;
@@ -4319,9 +4293,8 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
read_lock(&bond->lock);
read_lock(&bond->curr_slave_lock);
- if (!BOND_IS_OK(bond)) {
+ if (!BOND_IS_OK(bond))
goto out;
- }
if (!bond->curr_active_slave)
goto out;
@@ -4329,10 +4302,10 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
out:
- if (res) {
+ if (res)
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
- }
+
read_unlock(&bond->curr_slave_lock);
read_unlock(&bond->lock);
return 0;
@@ -4353,17 +4326,15 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
read_lock(&bond->lock);
- if (!BOND_IS_OK(bond)) {
+ if (!BOND_IS_OK(bond))
goto out;
- }
slave_no = bond->xmit_hash_policy(skb, bond_dev, bond->slave_cnt);
bond_for_each_slave(bond, slave, i) {
slave_no--;
- if (slave_no < 0) {
+ if (slave_no < 0)
break;
- }
}
start_at = slave;
@@ -4399,17 +4370,15 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
read_lock(&bond->lock);
- if (!BOND_IS_OK(bond)) {
+ if (!BOND_IS_OK(bond))
goto out;
- }
read_lock(&bond->curr_slave_lock);
start_at = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
- if (!start_at) {
+ if (!start_at)
goto out;
- }
bond_for_each_slave_from(bond, slave, i, start_at) {
if (IS_UP(slave->dev) &&
@@ -4418,7 +4387,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
if (tx_dev) {
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
if (!skb2) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Error: bond_xmit_broadcast(): "
"skb_clone() failed\n",
bond_dev->name);
@@ -4435,15 +4404,14 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
}
}
- if (tx_dev) {
+ if (tx_dev)
res = bond_dev_queue_xmit(bond, skb, tx_dev);
- }
out:
- if (res) {
+ if (res)
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
- }
+
/* frame sent to all suitable interfaces */
read_unlock(&bond->lock);
return 0;
@@ -4487,7 +4455,7 @@ static int bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
return bond_alb_xmit(skb, dev);
default:
/* Should never happen, mode already checked */
- printk(KERN_ERR DRV_NAME ": %s: Error: Unknown bonding mode %d\n",
+ pr_err(DRV_NAME ": %s: Error: Unknown bonding mode %d\n",
dev->name, bond->params.mode);
WARN_ON_ONCE(1);
dev_kfree_skb(skb);
@@ -4524,7 +4492,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
break;
default:
/* Should never happen, mode already checked */
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Error: Unknown bonding mode %d\n",
bond_dev->name,
mode);
@@ -4551,6 +4519,8 @@ static const struct ethtool_ops bond_ethtool_ops = {
};
static const struct net_device_ops bond_netdev_ops = {
+ .ndo_init = bond_init,
+ .ndo_uninit = bond_uninit,
.ndo_open = bond_open,
.ndo_stop = bond_close,
.ndo_start_xmit = bond_start_xmit,
@@ -4565,48 +4535,34 @@ static const struct net_device_ops bond_netdev_ops = {
.ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid,
};
-/*
- * Does not allocate but creates a /proc entry.
- * Allowed to fail.
- */
-static int bond_init(struct net_device *bond_dev, struct bond_params *params)
+static void bond_setup(struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
- pr_debug("Begin bond_init for %s\n", bond_dev->name);
-
/* initialize rwlocks */
rwlock_init(&bond->lock);
rwlock_init(&bond->curr_slave_lock);
- bond->params = *params; /* copy params struct */
-
- bond->wq = create_singlethread_workqueue(bond_dev->name);
- if (!bond->wq)
- return -ENOMEM;
+ bond->params = bonding_defaults;
/* Initialize pointers */
- bond->first_slave = NULL;
- bond->curr_active_slave = NULL;
- bond->current_arp_slave = NULL;
- bond->primary_slave = NULL;
bond->dev = bond_dev;
- bond->send_grat_arp = 0;
- bond->send_unsol_na = 0;
- bond->setup_by_slave = 0;
INIT_LIST_HEAD(&bond->vlan_list);
/* Initialize the device entry points */
+ ether_setup(bond_dev);
bond_dev->netdev_ops = &bond_netdev_ops;
bond_dev->ethtool_ops = &bond_ethtool_ops;
bond_set_mode_ops(bond, bond->params.mode);
- bond_dev->destructor = bond_destructor;
+ bond_dev->destructor = free_netdev;
/* Initialize the device options */
bond_dev->tx_queue_len = 0;
bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
bond_dev->priv_flags |= IFF_BONDING;
+ bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
+
if (bond->params.arp_interval)
bond_dev->priv_flags |= IFF_MASTER_ARPMON;
@@ -4631,12 +4587,6 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER);
-#ifdef CONFIG_PROC_FS
- bond_create_proc_entry(bond);
-#endif
- list_add_tail(&bond->bond_list, &bond_dev_list);
-
- return 0;
}
static void bond_work_cancel_all(struct bonding *bond)
@@ -4671,9 +4621,7 @@ static void bond_deinit(struct net_device *bond_dev)
bond_work_cancel_all(bond);
-#ifdef CONFIG_PROC_FS
bond_remove_proc_entry(bond);
-#endif
}
/* Unregister and free all bond devices.
@@ -4689,12 +4637,10 @@ static void bond_free_all(void)
bond_work_cancel_all(bond);
/* Release the bonded slaves */
bond_release_all(bond_dev);
- bond_destroy(bond);
+ unregister_netdevice(bond_dev);
}
-#ifdef CONFIG_PROC_FS
bond_destroy_proc_dir();
-#endif
}
/*------------------------- Module initialization ---------------------------*/
@@ -4742,7 +4688,7 @@ static int bond_check_params(struct bond_params *params)
if (mode) {
bond_mode = bond_parse_parm(mode, bond_mode_tbl);
if (bond_mode == -1) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": Error: Invalid bonding mode \"%s\"\n",
mode == NULL ? "NULL" : mode);
return -EINVAL;
@@ -4752,16 +4698,16 @@ static int bond_check_params(struct bond_params *params)
if (xmit_hash_policy) {
if ((bond_mode != BOND_MODE_XOR) &&
(bond_mode != BOND_MODE_8023AD)) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": xor_mode param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
} else {
xmit_hashtype = bond_parse_parm(xmit_hash_policy,
xmit_hashtype_tbl);
if (xmit_hashtype == -1) {
- printk(KERN_ERR DRV_NAME
- ": Error: Invalid xmit_hash_policy \"%s\"\n",
- xmit_hash_policy == NULL ? "NULL" :
+ pr_err(DRV_NAME
+ ": Error: Invalid xmit_hash_policy \"%s\"\n",
+ xmit_hash_policy == NULL ? "NULL" :
xmit_hash_policy);
return -EINVAL;
}
@@ -4770,13 +4716,13 @@ static int bond_check_params(struct bond_params *params)
if (lacp_rate) {
if (bond_mode != BOND_MODE_8023AD) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": lacp_rate param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
} else {
lacp_fast = bond_parse_parm(lacp_rate, bond_lacp_tbl);
if (lacp_fast == -1) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": Error: Invalid lacp rate \"%s\"\n",
lacp_rate == NULL ? "NULL" : lacp_rate);
return -EINVAL;
@@ -4787,14 +4733,14 @@ static int bond_check_params(struct bond_params *params)
if (ad_select) {
params->ad_select = bond_parse_parm(ad_select, ad_select_tbl);
if (params->ad_select == -1) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": Error: Invalid ad_select \"%s\"\n",
ad_select == NULL ? "NULL" : ad_select);
return -EINVAL;
}
if (bond_mode != BOND_MODE_8023AD) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": ad_select param only affects 802.3ad mode\n");
}
} else {
@@ -4802,7 +4748,7 @@ static int bond_check_params(struct bond_params *params)
}
if (max_bonds < 0 || max_bonds > INT_MAX) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: max_bonds (%d) not in range %d-%d, so it "
"was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
max_bonds, 0, INT_MAX, BOND_DEFAULT_MAX_BONDS);
@@ -4810,7 +4756,7 @@ static int bond_check_params(struct bond_params *params)
}
if (miimon < 0) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: miimon module parameter (%d), "
"not in range 0-%d, so it was reset to %d\n",
miimon, INT_MAX, BOND_LINK_MON_INTERV);
@@ -4818,7 +4764,7 @@ static int bond_check_params(struct bond_params *params)
}
if (updelay < 0) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: updelay module parameter (%d), "
"not in range 0-%d, so it was reset to 0\n",
updelay, INT_MAX);
@@ -4826,7 +4772,7 @@ static int bond_check_params(struct bond_params *params)
}
if (downdelay < 0) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: downdelay module parameter (%d), "
"not in range 0-%d, so it was reset to 0\n",
downdelay, INT_MAX);
@@ -4834,7 +4780,7 @@ static int bond_check_params(struct bond_params *params)
}
if ((use_carrier != 0) && (use_carrier != 1)) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: use_carrier module parameter (%d), "
"not of valid value (0/1), so it was set to 1\n",
use_carrier);
@@ -4842,14 +4788,14 @@ static int bond_check_params(struct bond_params *params)
}
if (num_grat_arp < 0 || num_grat_arp > 255) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: num_grat_arp (%d) not in range 0-255 so it "
"was reset to 1 \n", num_grat_arp);
num_grat_arp = 1;
}
if (num_unsol_na < 0 || num_unsol_na > 255) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: num_unsol_na (%d) not in range 0-255 so it "
"was reset to 1 \n", num_unsol_na);
num_unsol_na = 1;
@@ -4858,12 +4804,12 @@ static int bond_check_params(struct bond_params *params)
/* reset values for 802.3ad */
if (bond_mode == BOND_MODE_8023AD) {
if (!miimon) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: miimon must be specified, "
"otherwise bonding will not detect link "
"failure, speed and duplex which are "
"essential for 802.3ad operation\n");
- printk(KERN_WARNING "Forcing miimon to 100msec\n");
+ pr_warning("Forcing miimon to 100msec\n");
miimon = 100;
}
}
@@ -4872,12 +4818,12 @@ static int bond_check_params(struct bond_params *params)
if ((bond_mode == BOND_MODE_TLB) ||
(bond_mode == BOND_MODE_ALB)) {
if (!miimon) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: miimon must be specified, "
"otherwise bonding will not detect link "
"failure and link speed which are essential "
"for TLB/ALB load balancing\n");
- printk(KERN_WARNING "Forcing miimon to 100msec\n");
+ pr_warning("Forcing miimon to 100msec\n");
miimon = 100;
}
}
@@ -4897,7 +4843,7 @@ static int bond_check_params(struct bond_params *params)
/* just warn the user the up/down delay will have
* no effect since miimon is zero...
*/
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: miimon module parameter not set "
"and updelay (%d) or downdelay (%d) module "
"parameter is set; updelay and downdelay have "
@@ -4907,7 +4853,7 @@ static int bond_check_params(struct bond_params *params)
} else {
/* don't allow arp monitoring */
if (arp_interval) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: miimon (%d) and arp_interval (%d) "
"can't be used simultaneously, disabling ARP "
"monitoring\n",
@@ -4916,7 +4862,7 @@ static int bond_check_params(struct bond_params *params)
}
if ((updelay % miimon) != 0) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: updelay (%d) is not a multiple "
"of miimon (%d), updelay rounded to %d ms\n",
updelay, miimon, (updelay / miimon) * miimon);
@@ -4925,7 +4871,7 @@ static int bond_check_params(struct bond_params *params)
updelay /= miimon;
if ((downdelay % miimon) != 0) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: downdelay (%d) is not a multiple "
"of miimon (%d), downdelay rounded to %d ms\n",
downdelay, miimon,
@@ -4936,7 +4882,7 @@ static int bond_check_params(struct bond_params *params)
}
if (arp_interval < 0) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: arp_interval module parameter (%d) "
", not in range 0-%d, so it was reset to %d\n",
arp_interval, INT_MAX, BOND_LINK_ARP_INTERV);
@@ -4949,7 +4895,7 @@ static int bond_check_params(struct bond_params *params)
/* not complete check, but should be good enough to
catch mistakes */
if (!isdigit(arp_ip_target[arp_ip_count][0])) {
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: bad arp_ip_target module parameter "
"(%s), ARP monitoring will not be performed\n",
arp_ip_target[arp_ip_count]);
@@ -4962,7 +4908,7 @@ static int bond_check_params(struct bond_params *params)
if (arp_interval && !arp_ip_count) {
/* don't allow arping if no arp_ip_target given... */
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: arp_interval module parameter (%d) "
"specified without providing an arp_ip_target "
"parameter, arp_interval was reset to 0\n",
@@ -4972,12 +4918,12 @@ static int bond_check_params(struct bond_params *params)
if (arp_validate) {
if (bond_mode != BOND_MODE_ACTIVEBACKUP) {
- printk(KERN_ERR DRV_NAME
- ": arp_validate only supported in active-backup mode\n");
+ pr_err(DRV_NAME
+ ": arp_validate only supported in active-backup mode\n");
return -EINVAL;
}
if (!arp_interval) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": arp_validate requires arp_interval\n");
return -EINVAL;
}
@@ -4985,7 +4931,7 @@ static int bond_check_params(struct bond_params *params)
arp_validate_value = bond_parse_parm(arp_validate,
arp_validate_tbl);
if (arp_validate_value == -1) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": Error: invalid arp_validate \"%s\"\n",
arp_validate == NULL ? "NULL" : arp_validate);
return -EINVAL;
@@ -4994,20 +4940,20 @@ static int bond_check_params(struct bond_params *params)
arp_validate_value = 0;
if (miimon) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": MII link monitoring set to %d ms\n",
miimon);
} else if (arp_interval) {
int i;
- printk(KERN_INFO DRV_NAME
- ": ARP monitoring set to %d ms, validate %s, with %d target(s):",
+ pr_info(DRV_NAME ": ARP monitoring set to %d ms,"
+ " validate %s, with %d target(s):",
arp_interval,
arp_validate_tbl[arp_validate_value].modename,
arp_ip_count);
for (i = 0; i < arp_ip_count; i++)
- printk (" %s", arp_ip_target[i]);
+ printk(" %s", arp_ip_target[i]);
printk("\n");
@@ -5015,7 +4961,7 @@ static int bond_check_params(struct bond_params *params)
/* miimon and arp_interval not set, we need one so things
* work as expected, see bonding.txt for details
*/
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: either miimon or arp_interval and "
"arp_ip_target module parameters must be specified, "
"otherwise bonding will not detect link failures! see "
@@ -5026,7 +4972,7 @@ static int bond_check_params(struct bond_params *params)
/* currently, using a primary only makes sense
* in active backup, TLB or ALB modes
*/
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: %s primary device specified but has no "
"effect in %s mode\n",
primary, bond_mode_name(bond_mode));
@@ -5037,14 +4983,14 @@ static int bond_check_params(struct bond_params *params)
fail_over_mac_value = bond_parse_parm(fail_over_mac,
fail_over_mac_tbl);
if (fail_over_mac_value == -1) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": Error: invalid fail_over_mac \"%s\"\n",
arp_validate == NULL ? "NULL" : arp_validate);
return -EINVAL;
}
if (bond_mode != BOND_MODE_ACTIVEBACKUP)
- printk(KERN_WARNING DRV_NAME
+ pr_warning(DRV_NAME
": Warning: fail_over_mac only affects "
"active-backup mode.\n");
} else {
@@ -5094,37 +5040,53 @@ static void bond_set_lockdep_class(struct net_device *dev)
netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL);
}
+/*
+ * Called from registration process
+ */
+static int bond_init(struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+
+ pr_debug("Begin bond_init for %s\n", bond_dev->name);
+
+ bond->wq = create_singlethread_workqueue(bond_dev->name);
+ if (!bond->wq)
+ return -ENOMEM;
+
+ bond_set_lockdep_class(bond_dev);
+
+ netif_carrier_off(bond_dev);
+
+ bond_create_proc_entry(bond);
+ list_add_tail(&bond->bond_list, &bond_dev_list);
+
+ return 0;
+}
+
/* Create a new bond based on the specified name and bonding parameters.
* If name is NULL, obtain a suitable "bond%d" name for us.
* Caller must NOT hold rtnl_lock; we need to release it here before we
* set up our sysfs entries.
*/
-int bond_create(char *name, struct bond_params *params)
+int bond_create(const char *name)
{
struct net_device *bond_dev;
- struct bonding *bond;
int res;
rtnl_lock();
- down_write(&bonding_rwsem);
-
/* Check to see if the bond already exists. */
- if (name) {
- list_for_each_entry(bond, &bond_dev_list, bond_list)
- if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
- printk(KERN_ERR DRV_NAME
- ": cannot add bond %s; it already exists\n",
- name);
- res = -EPERM;
- goto out_rtnl;
- }
+ /* FIXME: pass netns from caller */
+ if (name && __dev_get_by_name(&init_net, name)) {
+ pr_err(DRV_NAME ": cannot add bond %s; already exists\n",
+ name);
+ res = -EEXIST;
+ goto out_rtnl;
}
bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
- ether_setup);
+ bond_setup);
if (!bond_dev) {
- printk(KERN_ERR DRV_NAME
- ": %s: eek! can't alloc netdev!\n",
+ pr_err(DRV_NAME ": %s: eek! can't alloc netdev!\n",
name);
res = -ENOMEM;
goto out_rtnl;
@@ -5136,43 +5098,24 @@ int bond_create(char *name, struct bond_params *params)
goto out_netdev;
}
- /* bond_init() must be called after dev_alloc_name() (for the
- * /proc files), but before register_netdevice(), because we
- * need to set function pointers.
- */
-
- res = bond_init(bond_dev, params);
- if (res < 0) {
- goto out_netdev;
- }
-
res = register_netdevice(bond_dev);
- if (res < 0) {
+ if (res < 0)
goto out_bond;
- }
-
- bond_set_lockdep_class(bond_dev);
-
- netif_carrier_off(bond_dev);
- up_write(&bonding_rwsem);
- rtnl_unlock(); /* allows sysfs registration of net device */
res = bond_create_sysfs_entry(netdev_priv(bond_dev));
if (res < 0)
goto out_unreg;
+ rtnl_unlock();
return 0;
out_unreg:
- rtnl_lock();
- down_write(&bonding_rwsem);
unregister_netdevice(bond_dev);
out_bond:
bond_deinit(bond_dev);
out_netdev:
free_netdev(bond_dev);
out_rtnl:
- up_write(&bonding_rwsem);
rtnl_unlock();
return res;
}
@@ -5182,21 +5125,16 @@ static int __init bonding_init(void)
int i;
int res;
- printk(KERN_INFO "%s", version);
+ pr_info("%s", version);
res = bond_check_params(&bonding_defaults);
- if (res) {
+ if (res)
goto out;
- }
-#ifdef CONFIG_PROC_FS
bond_create_proc_dir();
-#endif
-
- init_rwsem(&bonding_rwsem);
for (i = 0; i < max_bonds; i++) {
- res = bond_create(NULL, &bonding_defaults);
+ res = bond_create(NULL);
if (res)
goto err;
}
@@ -5238,13 +5176,3 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION);
MODULE_AUTHOR("Thomas Davis, tadavis@lbl.gov and many others");
-MODULE_SUPPORTED_DEVICE("most ethernet devices");
-
-/*
- * Local variables:
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
-
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index d2873153522..55bf34f59bb 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1,4 +1,3 @@
-
/*
* Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
*
@@ -34,33 +33,14 @@
#include <linux/ctype.h>
#include <linux/inet.h>
#include <linux/rtnetlink.h>
+#include <linux/etherdevice.h>
#include <net/net_namespace.h>
#include "bonding.h"
-#define to_dev(obj) container_of(obj,struct device,kobj)
+#define to_dev(obj) container_of(obj, struct device, kobj)
#define to_bond(cd) ((struct bonding *)(netdev_priv(to_net_dev(cd))))
-/*---------------------------- Declarations -------------------------------*/
-
-static int expected_refcount = -1;
-/*--------------------------- Data Structures -----------------------------*/
-
-/* Bonding sysfs lock. Why can't we just use the subsystem lock?
- * Because kobject_register tries to acquire the subsystem lock. If
- * we already hold the lock (which we would if the user was creating
- * a new bond through the sysfs interface), we deadlock.
- * This lock is only needed when deleting a bond - we need to make sure
- * that we don't collide with an ongoing ioctl.
- */
-
-struct rw_semaphore bonding_rwsem;
-
-
-
-
-/*------------------------------ Functions --------------------------------*/
-
/*
* "show" function for the bond_masters attribute.
* The class parameter is ignored.
@@ -70,7 +50,7 @@ static ssize_t bonding_show_bonds(struct class *cls, char *buf)
int res = 0;
struct bonding *bond;
- down_read(&(bonding_rwsem));
+ rtnl_lock();
list_for_each_entry(bond, &bond_dev_list, bond_list) {
if (res > (PAGE_SIZE - IFNAMSIZ)) {
@@ -84,10 +64,22 @@ static ssize_t bonding_show_bonds(struct class *cls, char *buf)
}
if (res)
buf[res-1] = '\n'; /* eat the leftover space */
- up_read(&(bonding_rwsem));
+
+ rtnl_unlock();
return res;
}
+static struct net_device *bond_get_by_name(const char *ifname)
+{
+ struct bonding *bond;
+
+ list_for_each_entry(bond, &bond_dev_list, bond_list) {
+ if (strncmp(bond->dev->name, ifname, IFNAMSIZ) == 0)
+ return bond->dev;
+ }
+ return NULL;
+}
+
/*
* "store" function for the bond_masters attribute. This is what
* creates and deletes entire bonds.
@@ -96,12 +88,12 @@ static ssize_t bonding_show_bonds(struct class *cls, char *buf)
*
*/
-static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t count)
+static ssize_t bonding_store_bonds(struct class *cls,
+ const char *buffer, size_t count)
{
char command[IFNAMSIZ + 1] = {0, };
char *ifname;
int rv, res = count;
- struct bonding *bond;
sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
ifname = command + 1;
@@ -110,67 +102,48 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
goto err_no_cmd;
if (command[0] == '+') {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s is being created...\n", ifname);
- rv = bond_create(ifname, &bonding_defaults);
+ rv = bond_create(ifname);
if (rv) {
- printk(KERN_INFO DRV_NAME ": Bond creation failed.\n");
+ pr_info(DRV_NAME ": Bond creation failed.\n");
res = rv;
}
- goto out;
- }
+ } else if (command[0] == '-') {
+ struct net_device *bond_dev;
- if (command[0] == '-') {
rtnl_lock();
- down_write(&bonding_rwsem);
-
- list_for_each_entry(bond, &bond_dev_list, bond_list)
- if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
- /* check the ref count on the bond's kobject.
- * If it's > expected, then there's a file open,
- * and we have to fail.
- */
- if (atomic_read(&bond->dev->dev.kobj.kref.refcount)
- > expected_refcount){
- printk(KERN_INFO DRV_NAME
- ": Unable remove bond %s due to open references.\n",
- ifname);
- res = -EPERM;
- goto out_unlock;
- }
- printk(KERN_INFO DRV_NAME
- ": %s is being deleted...\n",
- bond->dev->name);
- bond_destroy(bond);
- goto out_unlock;
- }
-
- printk(KERN_ERR DRV_NAME
- ": unable to delete non-existent bond %s\n", ifname);
- res = -ENODEV;
- goto out_unlock;
- }
-
-err_no_cmd:
- printk(KERN_ERR DRV_NAME
- ": no command found in bonding_masters. Use +ifname or -ifname.\n");
- return -EPERM;
-
-out_unlock:
- up_write(&bonding_rwsem);
- rtnl_unlock();
+ bond_dev = bond_get_by_name(ifname);
+ if (bond_dev) {
+ pr_info(DRV_NAME ": %s is being deleted...\n",
+ ifname);
+ unregister_netdevice(bond_dev);
+ } else {
+ pr_err(DRV_NAME ": unable to delete non-existent %s\n",
+ ifname);
+ res = -ENODEV;
+ }
+ rtnl_unlock();
+ } else
+ goto err_no_cmd;
/* Always return either count or an error. If you return 0, you'll
* get called forever, which is bad.
*/
-out:
return res;
+
+err_no_cmd:
+ pr_err(DRV_NAME ": no command found in bonding_masters."
+ " Use +ifname or -ifname.\n");
+ return -EPERM;
}
+
/* class attribute for bond_masters file. This ends up in /sys/class/net */
static CLASS_ATTR(bonding_masters, S_IWUSR | S_IRUGO,
bonding_show_bonds, bonding_store_bonds);
-int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave)
+int bond_create_slave_symlinks(struct net_device *master,
+ struct net_device *slave)
{
char linkname[IFNAMSIZ+7];
int ret = 0;
@@ -181,19 +154,20 @@ int bond_create_slave_symlinks(struct net_device *master, struct net_device *sla
if (ret)
return ret;
/* next, create a link from the master to the slave */
- sprintf(linkname,"slave_%s",slave->name);
+ sprintf(linkname, "slave_%s", slave->name);
ret = sysfs_create_link(&(master->dev.kobj), &(slave->dev.kobj),
linkname);
return ret;
}
-void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave)
+void bond_destroy_slave_symlinks(struct net_device *master,
+ struct net_device *slave)
{
char linkname[IFNAMSIZ+7];
sysfs_remove_link(&(slave->dev.kobj), "master");
- sprintf(linkname,"slave_%s",slave->name);
+ sprintf(linkname, "slave_%s", slave->name);
sysfs_remove_link(&(master->dev.kobj), linkname);
}
@@ -251,8 +225,8 @@ static ssize_t bonding_store_slaves(struct device *d,
/* Note: We can't hold bond->lock here, as bond_create grabs it. */
- rtnl_lock();
- down_write(&(bonding_rwsem));
+ if (!rtnl_trylock())
+ return restart_syscall();
sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
ifname = command + 1;
@@ -264,46 +238,47 @@ static ssize_t bonding_store_slaves(struct device *d,
/* Got a slave name in ifname. Is it already in the list? */
found = 0;
- read_lock(&bond->lock);
- bond_for_each_slave(bond, slave, i)
- if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
- printk(KERN_ERR DRV_NAME
- ": %s: Interface %s is already enslaved!\n",
- bond->dev->name, ifname);
- ret = -EPERM;
- read_unlock(&bond->lock);
- goto out;
- }
- read_unlock(&bond->lock);
- printk(KERN_INFO DRV_NAME ": %s: Adding slave %s.\n",
- bond->dev->name, ifname);
- dev = dev_get_by_name(&init_net, ifname);
+ /* FIXME: get netns from sysfs object */
+ dev = __dev_get_by_name(&init_net, ifname);
if (!dev) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: Interface %s does not exist!\n",
bond->dev->name, ifname);
- ret = -EPERM;
+ ret = -ENODEV;
goto out;
}
- else
- dev_put(dev);
if (dev->flags & IFF_UP) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Error: Unable to enslave %s "
"because it is already up.\n",
bond->dev->name, dev->name);
ret = -EPERM;
goto out;
}
+
+ read_lock(&bond->lock);
+ bond_for_each_slave(bond, slave, i)
+ if (slave->dev == dev) {
+ pr_err(DRV_NAME
+ ": %s: Interface %s is already enslaved!\n",
+ bond->dev->name, ifname);
+ ret = -EPERM;
+ read_unlock(&bond->lock);
+ goto out;
+ }
+ read_unlock(&bond->lock);
+
+ pr_info(DRV_NAME ": %s: Adding slave %s.\n",
+ bond->dev->name, ifname);
+
/* If this is the first slave, then we need to set
the master's hardware address to be the same as the
slave's. */
- if (!(*((u32 *) & (bond->dev->dev_addr[0])))) {
+ if (is_zero_ether_addr(bond->dev->dev_addr))
memcpy(bond->dev->dev_addr, dev->dev_addr,
dev->addr_len);
- }
/* Set the slave's MTU to match the bond */
original_mtu = dev->mtu;
@@ -317,9 +292,9 @@ static ssize_t bonding_store_slaves(struct device *d,
bond_for_each_slave(bond, slave, i)
if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0)
slave->original_mtu = original_mtu;
- if (res) {
+ if (res)
ret = res;
- }
+
goto out;
}
@@ -333,7 +308,7 @@ static ssize_t bonding_store_slaves(struct device *d,
break;
}
if (dev) {
- printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
+ pr_info(DRV_NAME ": %s: Removing slave %s\n",
bond->dev->name, dev->name);
res = bond_release(bond->dev, dev);
if (res) {
@@ -342,9 +317,9 @@ static ssize_t bonding_store_slaves(struct device *d,
}
/* set the slave MTU to the default */
dev_set_mtu(dev, original_mtu);
- }
- else {
- printk(KERN_ERR DRV_NAME ": unable to remove non-existent slave %s for bond %s.\n",
+ } else {
+ pr_err(DRV_NAME ": unable to remove non-existent"
+ " slave %s for bond %s.\n",
ifname, bond->dev->name);
ret = -ENODEV;
}
@@ -352,16 +327,16 @@ static ssize_t bonding_store_slaves(struct device *d,
}
err_no_cmd:
- printk(KERN_ERR DRV_NAME ": no command found in slaves file for bond %s. Use +ifname or -ifname.\n", bond->dev->name);
+ pr_err(DRV_NAME ": no command found in slaves file for bond %s. Use +ifname or -ifname.\n", bond->dev->name);
ret = -EPERM;
out:
- up_write(&(bonding_rwsem));
rtnl_unlock();
return ret;
}
-static DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves, bonding_store_slaves);
+static DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves,
+ bonding_store_slaves);
/*
* Show and set the bonding mode. The bond interface must be down to
@@ -385,16 +360,15 @@ static ssize_t bonding_store_mode(struct device *d,
struct bonding *bond = to_bond(d);
if (bond->dev->flags & IFF_UP) {
- printk(KERN_ERR DRV_NAME
- ": unable to update mode of %s because interface is up.\n",
- bond->dev->name);
+ pr_err(DRV_NAME ": unable to update mode of %s"
+ " because interface is up.\n", bond->dev->name);
ret = -EPERM;
goto out;
}
new_value = bond_parse_parm(buf, bond_mode_tbl);
if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Ignoring invalid mode value %.*s.\n",
bond->dev->name,
(int)strlen(buf) - 1, buf);
@@ -409,17 +383,19 @@ static ssize_t bonding_store_mode(struct device *d,
bond->params.mode = new_value;
bond_set_mode_ops(bond, bond->params.mode);
- printk(KERN_INFO DRV_NAME ": %s: setting mode to %s (%d).\n",
- bond->dev->name, bond_mode_tbl[new_value].modename, new_value);
+ pr_info(DRV_NAME ": %s: setting mode to %s (%d).\n",
+ bond->dev->name, bond_mode_tbl[new_value].modename,
+ new_value);
}
out:
return ret;
}
-static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, bonding_show_mode, bonding_store_mode);
+static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+ bonding_show_mode, bonding_store_mode);
/*
- * Show and set the bonding transmit hash method. The bond interface must be down to
- * change the xmit hash policy.
+ * Show and set the bonding transmit hash method.
+ * The bond interface must be down to change the xmit hash policy.
*/
static ssize_t bonding_show_xmit_hash(struct device *d,
struct device_attribute *attr,
@@ -440,7 +416,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
struct bonding *bond = to_bond(d);
if (bond->dev->flags & IFF_UP) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
"%s: Interface is up. Unable to update xmit policy.\n",
bond->dev->name);
ret = -EPERM;
@@ -449,7 +425,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
new_value = bond_parse_parm(buf, xmit_hashtype_tbl);
if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Ignoring invalid xmit hash policy value %.*s.\n",
bond->dev->name,
(int)strlen(buf) - 1, buf);
@@ -458,13 +434,15 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
} else {
bond->params.xmit_policy = new_value;
bond_set_mode_ops(bond, bond->params.mode);
- printk(KERN_INFO DRV_NAME ": %s: setting xmit hash policy to %s (%d).\n",
- bond->dev->name, xmit_hashtype_tbl[new_value].modename, new_value);
+ pr_info(DRV_NAME ": %s: setting xmit hash policy to %s (%d).\n",
+ bond->dev->name,
+ xmit_hashtype_tbl[new_value].modename, new_value);
}
out:
return ret;
}
-static DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);
+static DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR,
+ bonding_show_xmit_hash, bonding_store_xmit_hash);
/*
* Show and set arp_validate.
@@ -489,39 +467,41 @@ static ssize_t bonding_store_arp_validate(struct device *d,
new_value = bond_parse_parm(buf, arp_validate_tbl);
if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Ignoring invalid arp_validate value %s\n",
bond->dev->name, buf);
return -EINVAL;
}
if (new_value && (bond->params.mode != BOND_MODE_ACTIVEBACKUP)) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: arp_validate only supported in active-backup mode.\n",
bond->dev->name);
return -EINVAL;
}
- printk(KERN_INFO DRV_NAME ": %s: setting arp_validate to %s (%d).\n",
+ pr_info(DRV_NAME ": %s: setting arp_validate to %s (%d).\n",
bond->dev->name, arp_validate_tbl[new_value].modename,
new_value);
- if (!bond->params.arp_validate && new_value) {
+ if (!bond->params.arp_validate && new_value)
bond_register_arp(bond);
- } else if (bond->params.arp_validate && !new_value) {
+ else if (bond->params.arp_validate && !new_value)
bond_unregister_arp(bond);
- }
bond->params.arp_validate = new_value;
return count;
}
-static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate);
+static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate,
+ bonding_store_arp_validate);
/*
* Show and store fail_over_mac. User only allowed to change the
* value when there are no slaves.
*/
-static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attribute *attr, char *buf)
+static ssize_t bonding_show_fail_over_mac(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
{
struct bonding *bond = to_bond(d);
@@ -530,13 +510,15 @@ static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attrib
bond->params.fail_over_mac);
}
-static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t bonding_store_fail_over_mac(struct device *d,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
int new_value;
struct bonding *bond = to_bond(d);
if (bond->slave_cnt != 0) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Can't alter fail_over_mac with slaves in bond.\n",
bond->dev->name);
return -EPERM;
@@ -544,21 +526,22 @@ static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attri
new_value = bond_parse_parm(buf, fail_over_mac_tbl);
if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Ignoring invalid fail_over_mac value %s.\n",
bond->dev->name, buf);
return -EINVAL;
}
bond->params.fail_over_mac = new_value;
- printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %s (%d).\n",
+ pr_info(DRV_NAME ": %s: Setting fail_over_mac to %s (%d).\n",
bond->dev->name, fail_over_mac_tbl[new_value].modename,
new_value);
return count;
}
-static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac);
+static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR,
+ bonding_show_fail_over_mac, bonding_store_fail_over_mac);
/*
* Show and set the arp timer interval. There are two tricky bits
@@ -583,28 +566,28 @@ static ssize_t bonding_store_arp_interval(struct device *d,
struct bonding *bond = to_bond(d);
if (sscanf(buf, "%d", &new_value) != 1) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: no arp_interval value specified.\n",
bond->dev->name);
ret = -EINVAL;
goto out;
}
if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Invalid arp_interval value %d not in range 1-%d; rejected.\n",
bond->dev->name, new_value, INT_MAX);
ret = -EINVAL;
goto out;
}
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: Setting ARP monitoring interval to %d.\n",
bond->dev->name, new_value);
bond->params.arp_interval = new_value;
if (bond->params.arp_interval)
bond->dev->priv_flags |= IFF_MASTER_ARPMON;
if (bond->params.miimon) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: ARP monitoring cannot be used with MII monitoring. "
"%s Disabling MII monitoring.\n",
bond->dev->name, bond->dev->name);
@@ -615,7 +598,7 @@ static ssize_t bonding_store_arp_interval(struct device *d,
}
}
if (!bond->params.arp_targets[0]) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: ARP monitoring has been set up, "
"but no ARP targets have been specified.\n",
bond->dev->name);
@@ -641,7 +624,8 @@ static ssize_t bonding_store_arp_interval(struct device *d,
out:
return ret;
}
-static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR , bonding_show_arp_interval, bonding_store_arp_interval);
+static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR,
+ bonding_show_arp_interval, bonding_store_arp_interval);
/*
* Show and set the arp targets.
@@ -677,7 +661,7 @@ static ssize_t bonding_store_arp_targets(struct device *d,
/* look for adds */
if (buf[0] == '+') {
if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: invalid ARP target %pI4 specified for addition\n",
bond->dev->name, &newtarget);
ret = -EINVAL;
@@ -686,14 +670,14 @@ static ssize_t bonding_store_arp_targets(struct device *d,
/* look for an empty slot to put the target in, and check for dupes */
for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) {
if (targets[i] == newtarget) { /* duplicate */
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: ARP target %pI4 is already present\n",
bond->dev->name, &newtarget);
ret = -EINVAL;
goto out;
}
if (targets[i] == 0) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: adding ARP target %pI4.\n",
bond->dev->name, &newtarget);
done = 1;
@@ -701,17 +685,16 @@ static ssize_t bonding_store_arp_targets(struct device *d,
}
}
if (!done) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: ARP target table is full!\n",
bond->dev->name);
ret = -EINVAL;
goto out;
}
- }
- else if (buf[0] == '-') {
+ } else if (buf[0] == '-') {
if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: invalid ARP target %pI4 specified for removal\n",
bond->dev->name, &newtarget);
ret = -EINVAL;
@@ -721,7 +704,7 @@ static ssize_t bonding_store_arp_targets(struct device *d,
for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) {
if (targets[i] == newtarget) {
int j;
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: removing ARP target %pI4.\n",
bond->dev->name, &newtarget);
for (j = i; (j < (BOND_MAX_ARP_TARGETS-1)) && targets[j+1]; j++)
@@ -732,15 +715,15 @@ static ssize_t bonding_store_arp_targets(struct device *d,
}
}
if (!done) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: unable to remove nonexistent ARP target %pI4.\n",
bond->dev->name, &newtarget);
ret = -EINVAL;
goto out;
}
- }
- else {
- printk(KERN_ERR DRV_NAME ": no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",
+ } else {
+ pr_err(DRV_NAME ": no command found in arp_ip_targets file"
+ " for bond %s. Use +<addr> or -<addr>.\n",
bond->dev->name);
ret = -EPERM;
goto out;
@@ -773,7 +756,7 @@ static ssize_t bonding_store_downdelay(struct device *d,
struct bonding *bond = to_bond(d);
if (!(bond->params.miimon)) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Unable to set down delay as MII monitoring is disabled\n",
bond->dev->name);
ret = -EPERM;
@@ -781,14 +764,14 @@ static ssize_t bonding_store_downdelay(struct device *d,
}
if (sscanf(buf, "%d", &new_value) != 1) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: no down delay value specified.\n",
bond->dev->name);
ret = -EINVAL;
goto out;
}
if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
bond->dev->name, new_value, 1, INT_MAX);
ret = -EINVAL;
@@ -803,15 +786,17 @@ static ssize_t bonding_store_downdelay(struct device *d,
bond->params.miimon);
}
bond->params.downdelay = new_value / bond->params.miimon;
- printk(KERN_INFO DRV_NAME ": %s: Setting down delay to %d.\n",
- bond->dev->name, bond->params.downdelay * bond->params.miimon);
+ pr_info(DRV_NAME ": %s: Setting down delay to %d.\n",
+ bond->dev->name,
+ bond->params.downdelay * bond->params.miimon);
}
out:
return ret;
}
-static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR , bonding_show_downdelay, bonding_store_downdelay);
+static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR,
+ bonding_show_downdelay, bonding_store_downdelay);
static ssize_t bonding_show_updelay(struct device *d,
struct device_attribute *attr,
@@ -831,7 +816,7 @@ static ssize_t bonding_store_updelay(struct device *d,
struct bonding *bond = to_bond(d);
if (!(bond->params.miimon)) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Unable to set up delay as MII monitoring is disabled\n",
bond->dev->name);
ret = -EPERM;
@@ -839,14 +824,14 @@ static ssize_t bonding_store_updelay(struct device *d,
}
if (sscanf(buf, "%d", &new_value) != 1) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: no up delay value specified.\n",
bond->dev->name);
ret = -EINVAL;
goto out;
}
if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
bond->dev->name, new_value, 1, INT_MAX);
ret = -EINVAL;
@@ -861,7 +846,7 @@ static ssize_t bonding_store_updelay(struct device *d,
bond->params.miimon);
}
bond->params.updelay = new_value / bond->params.miimon;
- printk(KERN_INFO DRV_NAME ": %s: Setting up delay to %d.\n",
+ pr_info(DRV_NAME ": %s: Setting up delay to %d.\n",
bond->dev->name, bond->params.updelay * bond->params.miimon);
}
@@ -869,7 +854,8 @@ static ssize_t bonding_store_updelay(struct device *d,
out:
return ret;
}
-static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR , bonding_show_updelay, bonding_store_updelay);
+static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR,
+ bonding_show_updelay, bonding_store_updelay);
/*
* Show and set the LACP interval. Interface must be down, and the mode
@@ -894,7 +880,7 @@ static ssize_t bonding_store_lacp(struct device *d,
struct bonding *bond = to_bond(d);
if (bond->dev->flags & IFF_UP) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Unable to update LACP rate because interface is up.\n",
bond->dev->name);
ret = -EPERM;
@@ -902,7 +888,7 @@ static ssize_t bonding_store_lacp(struct device *d,
}
if (bond->params.mode != BOND_MODE_8023AD) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Unable to update LACP rate because bond is not in 802.3ad mode.\n",
bond->dev->name);
ret = -EPERM;
@@ -913,19 +899,20 @@ static ssize_t bonding_store_lacp(struct device *d,
if ((new_value == 1) || (new_value == 0)) {
bond->params.lacp_fast = new_value;
- printk(KERN_INFO DRV_NAME
- ": %s: Setting LACP rate to %s (%d).\n",
- bond->dev->name, bond_lacp_tbl[new_value].modename, new_value);
+ pr_info(DRV_NAME ": %s: Setting LACP rate to %s (%d).\n",
+ bond->dev->name, bond_lacp_tbl[new_value].modename,
+ new_value);
} else {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Ignoring invalid LACP rate value %.*s.\n",
- bond->dev->name, (int)strlen(buf) - 1, buf);
+ bond->dev->name, (int)strlen(buf) - 1, buf);
ret = -EINVAL;
}
out:
return ret;
}
-static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);
+static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR,
+ bonding_show_lacp, bonding_store_lacp);
static ssize_t bonding_show_ad_select(struct device *d,
struct device_attribute *attr,
@@ -947,7 +934,7 @@ static ssize_t bonding_store_ad_select(struct device *d,
struct bonding *bond = to_bond(d);
if (bond->dev->flags & IFF_UP) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Unable to update ad_select because interface "
"is up.\n", bond->dev->name);
ret = -EPERM;
@@ -958,12 +945,12 @@ static ssize_t bonding_store_ad_select(struct device *d,
if (new_value != -1) {
bond->params.ad_select = new_value;
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: Setting ad_select to %s (%d).\n",
bond->dev->name, ad_select_tbl[new_value].modename,
new_value);
} else {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Ignoring invalid ad_select value %.*s.\n",
bond->dev->name, (int)strlen(buf) - 1, buf);
ret = -EINVAL;
@@ -971,8 +958,8 @@ static ssize_t bonding_store_ad_select(struct device *d,
out:
return ret;
}
-
-static DEVICE_ATTR(ad_select, S_IRUGO | S_IWUSR, bonding_show_ad_select, bonding_store_ad_select);
+static DEVICE_ATTR(ad_select, S_IRUGO | S_IWUSR,
+ bonding_show_ad_select, bonding_store_ad_select);
/*
* Show and set the number of grat ARP to send after a failover event.
@@ -994,14 +981,14 @@ static ssize_t bonding_store_n_grat_arp(struct device *d,
struct bonding *bond = to_bond(d);
if (sscanf(buf, "%d", &new_value) != 1) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: no num_grat_arp value specified.\n",
bond->dev->name);
ret = -EINVAL;
goto out;
}
if (new_value < 0 || new_value > 255) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Invalid num_grat_arp value %d not in range 0-255; rejected.\n",
bond->dev->name, new_value);
ret = -EINVAL;
@@ -1012,10 +999,11 @@ static ssize_t bonding_store_n_grat_arp(struct device *d,
out:
return ret;
}
-static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR, bonding_show_n_grat_arp, bonding_store_n_grat_arp);
+static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR,
+ bonding_show_n_grat_arp, bonding_store_n_grat_arp);
/*
- * Show and set the number of unsolicted NA's to send after a failover event.
+ * Show and set the number of unsolicited NA's to send after a failover event.
*/
static ssize_t bonding_show_n_unsol_na(struct device *d,
struct device_attribute *attr,
@@ -1034,25 +1022,26 @@ static ssize_t bonding_store_n_unsol_na(struct device *d,
struct bonding *bond = to_bond(d);
if (sscanf(buf, "%d", &new_value) != 1) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: no num_unsol_na value specified.\n",
bond->dev->name);
ret = -EINVAL;
goto out;
}
+
if (new_value < 0 || new_value > 255) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Invalid num_unsol_na value %d not in range 0-255; rejected.\n",
bond->dev->name, new_value);
ret = -EINVAL;
goto out;
- } else {
+ } else
bond->params.num_unsol_na = new_value;
- }
out:
return ret;
}
-static DEVICE_ATTR(num_unsol_na, S_IRUGO | S_IWUSR, bonding_show_n_unsol_na, bonding_store_n_unsol_na);
+static DEVICE_ATTR(num_unsol_na, S_IRUGO | S_IWUSR,
+ bonding_show_n_unsol_na, bonding_store_n_unsol_na);
/*
* Show and set the MII monitor interval. There are two tricky bits
@@ -1077,37 +1066,37 @@ static ssize_t bonding_store_miimon(struct device *d,
struct bonding *bond = to_bond(d);
if (sscanf(buf, "%d", &new_value) != 1) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: no miimon value specified.\n",
bond->dev->name);
ret = -EINVAL;
goto out;
}
if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: Invalid miimon value %d not in range %d-%d; rejected.\n",
bond->dev->name, new_value, 1, INT_MAX);
ret = -EINVAL;
goto out;
} else {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: Setting MII monitoring interval to %d.\n",
bond->dev->name, new_value);
bond->params.miimon = new_value;
- if(bond->params.updelay)
- printk(KERN_INFO DRV_NAME
+ if (bond->params.updelay)
+ pr_info(DRV_NAME
": %s: Note: Updating updelay (to %d) "
"since it is a multiple of the miimon value.\n",
bond->dev->name,
bond->params.updelay * bond->params.miimon);
- if(bond->params.downdelay)
- printk(KERN_INFO DRV_NAME
+ if (bond->params.downdelay)
+ pr_info(DRV_NAME
": %s: Note: Updating downdelay (to %d) "
"since it is a multiple of the miimon value.\n",
bond->dev->name,
bond->params.downdelay * bond->params.miimon);
if (bond->params.arp_interval) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: MII monitoring cannot be used with "
"ARP monitoring. Disabling ARP monitoring...\n",
bond->dev->name);
@@ -1141,7 +1130,8 @@ static ssize_t bonding_store_miimon(struct device *d,
out:
return ret;
}
-static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store_miimon);
+static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR,
+ bonding_show_miimon, bonding_store_miimon);
/*
* Show and set the primary slave. The store function is much
@@ -1171,12 +1161,13 @@ static ssize_t bonding_store_primary(struct device *d,
struct slave *slave;
struct bonding *bond = to_bond(d);
- rtnl_lock();
+ if (!rtnl_trylock())
+ return restart_syscall();
read_lock(&bond->lock);
write_lock_bh(&bond->curr_slave_lock);
if (!USES_PRIMARY(bond->params.mode)) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: Unable to set primary slave; %s is in mode %d\n",
bond->dev->name, bond->dev->name, bond->params.mode);
} else {
@@ -1184,7 +1175,7 @@ static ssize_t bonding_store_primary(struct device *d,
if (strnicmp
(slave->dev->name, buf,
strlen(slave->dev->name)) == 0) {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: Setting %s as primary slave.\n",
bond->dev->name, slave->dev->name);
bond->primary_slave = slave;
@@ -1196,13 +1187,13 @@ static ssize_t bonding_store_primary(struct device *d,
/* if we got here, then we didn't match the name of any slave */
if (strlen(buf) == 0 || buf[0] == '\n') {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: Setting primary slave to None.\n",
bond->dev->name);
bond->primary_slave = NULL;
bond_select_active_slave(bond);
} else {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: Unable to set %.*s as primary slave as it is not a slave.\n",
bond->dev->name, (int)strlen(buf) - 1, buf);
}
@@ -1214,7 +1205,8 @@ out:
return count;
}
-static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary);
+static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR,
+ bonding_show_primary, bonding_store_primary);
/*
* Show and set the use_carrier flag.
@@ -1237,7 +1229,7 @@ static ssize_t bonding_store_carrier(struct device *d,
if (sscanf(buf, "%d", &new_value) != 1) {
- printk(KERN_ERR DRV_NAME
+ pr_err(DRV_NAME
": %s: no use_carrier value specified.\n",
bond->dev->name);
ret = -EINVAL;
@@ -1245,17 +1237,18 @@ static ssize_t bonding_store_carrier(struct device *d,
}
if ((new_value == 0) || (new_value == 1)) {
bond->params.use_carrier = new_value;
- printk(KERN_INFO DRV_NAME ": %s: Setting use_carrier to %d.\n",
+ pr_info(DRV_NAME ": %s: Setting use_carrier to %d.\n",
bond->dev->name, new_value);
} else {
- printk(KERN_INFO DRV_NAME
+ pr_info(DRV_NAME
": %s: Ignoring invalid use_carrier value %d.\n",
bond->dev->name, new_value);
}
out:
return count;
}
-static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier);
+static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR,
+ bonding_show_carrier, bonding_store_carrier);
/*
@@ -1284,19 +1277,20 @@ static ssize_t bonding_store_active_slave(struct device *d,
{
int i;
struct slave *slave;
- struct slave *old_active = NULL;
- struct slave *new_active = NULL;
+ struct slave *old_active = NULL;
+ struct slave *new_active = NULL;
struct bonding *bond = to_bond(d);
- rtnl_lock();
+ if (!rtnl_trylock())
+ return restart_syscall();
read_lock(&bond->lock);
write_lock_bh(&bond->curr_slave_lock);
- if (!USES_PRIMARY(bond->params.mode)) {
- printk(KERN_INFO DRV_NAME
- ": %s: Unable to change active slave; %s is in mode %d\n",
- bond->dev->name, bond->dev->name, bond->params.mode);
- } else {
+ if (!USES_PRIMARY(bond->params.mode))
+ pr_info(DRV_NAME ": %s: Unable to change active slave;"
+ " %s is in mode %d\n",
+ bond->dev->name, bond->dev->name, bond->params.mode);
+ else {
bond_for_each_slave(bond, slave, i) {
if (strnicmp
(slave->dev->name, buf,
@@ -1335,18 +1329,18 @@ static ssize_t bonding_store_active_slave(struct device *d,
/* if we got here, then we didn't match the name of any slave */
if (strlen(buf) == 0 || buf[0] == '\n') {
- printk(KERN_INFO DRV_NAME
- ": %s: Setting active slave to None.\n",
- bond->dev->name);
+ pr_info(DRV_NAME
+ ": %s: Setting active slave to None.\n",
+ bond->dev->name);
bond->primary_slave = NULL;
- bond_select_active_slave(bond);
+ bond_select_active_slave(bond);
} else {
- printk(KERN_INFO DRV_NAME
- ": %s: Unable to set %.*s as active slave as it is not a slave.\n",
- bond->dev->name, (int)strlen(buf) - 1, buf);
+ pr_info(DRV_NAME ": %s: Unable to set %.*s"
+ " as active slave as it is not a slave.\n",
+ bond->dev->name, (int)strlen(buf) - 1, buf);
}
}
-out:
+ out:
write_unlock_bh(&bond->curr_slave_lock);
read_unlock(&bond->lock);
rtnl_unlock();
@@ -1354,7 +1348,8 @@ out:
return count;
}
-static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, bonding_show_active_slave, bonding_store_active_slave);
+static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR,
+ bonding_show_active_slave, bonding_store_active_slave);
/*
@@ -1371,7 +1366,7 @@ static ssize_t bonding_show_mii_status(struct device *d,
curr = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
- return sprintf(buf, "%s\n", (curr) ? "up" : "down");
+ return sprintf(buf, "%s\n", curr ? "up" : "down");
}
static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
@@ -1388,7 +1383,9 @@ static ssize_t bonding_show_ad_aggregator(struct device *d,
if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info;
- count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.aggregator_id);
+ count = sprintf(buf, "%d\n",
+ (bond_3ad_get_active_agg_info(bond, &ad_info))
+ ? 0 : ad_info.aggregator_id);
}
return count;
@@ -1408,7 +1405,9 @@ static ssize_t bonding_show_ad_num_ports(struct device *d,
if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info;
- count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0: ad_info.ports);
+ count = sprintf(buf, "%d\n",
+ (bond_3ad_get_active_agg_info(bond, &ad_info))
+ ? 0 : ad_info.ports);
}
return count;
@@ -1428,7 +1427,9 @@ static ssize_t bonding_show_ad_actor_key(struct device *d,
if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info;
- count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.actor_key);
+ count = sprintf(buf, "%d\n",
+ (bond_3ad_get_active_agg_info(bond, &ad_info))
+ ? 0 : ad_info.actor_key);
}
return count;
@@ -1448,7 +1449,9 @@ static ssize_t bonding_show_ad_partner_key(struct device *d,
if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info;
- count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.partner_key);
+ count = sprintf(buf, "%d\n",
+ (bond_3ad_get_active_agg_info(bond, &ad_info))
+ ? 0 : ad_info.partner_key);
}
return count;
@@ -1468,9 +1471,8 @@ static ssize_t bonding_show_ad_partner_mac(struct device *d,
if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info;
- if (!bond_3ad_get_active_agg_info(bond, &ad_info)) {
+ if (!bond_3ad_get_active_agg_info(bond, &ad_info))
count = sprintf(buf, "%pM\n", ad_info.partner_system);
- }
}
return count;
@@ -1538,6 +1540,7 @@ int bond_create_sysfs(void)
printk(KERN_ERR
"network device named %s already exists in sysfs",
class_attr_bonding_masters.attr.name);
+ ret = 0;
}
return ret;
@@ -1562,12 +1565,8 @@ int bond_create_sysfs_entry(struct bonding *bond)
int err;
err = sysfs_create_group(&(dev->dev.kobj), &bonding_group);
- if (err) {
+ if (err)
printk(KERN_EMERG "eek! didn't create group!\n");
- }
-
- if (expected_refcount < 1)
- expected_refcount = atomic_read(&bond->dev->dev.kobj.kref.refcount);
return err;
}
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index ca849d2adf9..6290a502742 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -286,8 +286,7 @@ static inline unsigned long slave_last_rx(struct bonding *bond,
static inline void bond_set_slave_inactive_flags(struct slave *slave)
{
struct bonding *bond = netdev_priv(slave->dev->master);
- if (bond->params.mode != BOND_MODE_TLB &&
- bond->params.mode != BOND_MODE_ALB)
+ if (!bond_is_lb(bond))
slave->state = BOND_STATE_BACKUP;
slave->dev->priv_flags |= IFF_SLAVE_INACTIVE;
if (slave_do_arp_validate(bond, slave))
@@ -322,8 +321,7 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond)
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
-int bond_create(char *name, struct bond_params *params);
-void bond_destroy(struct bonding *bond);
+int bond_create(const char *name);
int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
int bond_create_sysfs(void);
void bond_destroy_sysfs(void);
@@ -350,12 +348,8 @@ extern const struct bond_parm_tbl bond_mode_tbl[];
extern const struct bond_parm_tbl xmit_hashtype_tbl[];
extern const struct bond_parm_tbl arp_validate_tbl[];
extern const struct bond_parm_tbl fail_over_mac_tbl[];
-extern struct bond_params bonding_defaults;
extern struct bond_parm_tbl ad_select_tbl[];
-/* exported from bond_sysfs.c */
-extern struct rw_semaphore bonding_rwsem;
-
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
void bond_send_unsolicited_na(struct bonding *bond);
void bond_register_ipv6_notifier(void);
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 57def0d5737..d5e18812bf4 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -12,6 +12,68 @@ config CAN_VCAN
This driver can also be built as a module. If so, the module
will be called vcan.
+config CAN_DEV
+ tristate "Platform CAN drivers with Netlink support"
+ depends on CAN
+ default Y
+ ---help---
+ Enables the common framework for platform CAN drivers with Netlink
+ support. This is the standard library for CAN drivers.
+ If unsure, say Y.
+
+config CAN_CALC_BITTIMING
+ bool "CAN bit-timing calculation"
+ depends on CAN_DEV
+ default Y
+ ---help---
+ If enabled, CAN bit-timing parameters will be calculated for the
+ bit-rate specified via Netlink argument "bitrate" when the device
+ get started. This works fine for the most common CAN controllers
+ with standard bit-rates but may fail for exotic bit-rates or CAN
+ source clock frequencies. Disabling saves some space, but then the
+ bit-timing parameters must be specified directly using the Netlink
+ arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw".
+ If unsure, say Y.
+
+config CAN_SJA1000
+ depends on CAN_DEV
+ tristate "Philips SJA1000"
+ ---help---
+ Driver for the SJA1000 CAN controllers from Philips or NXP
+
+config CAN_SJA1000_PLATFORM
+ depends on CAN_SJA1000
+ tristate "Generic Platform Bus based SJA1000 driver"
+ ---help---
+ This driver adds support for the SJA1000 chips connected to
+ the "platform bus" (Linux abstraction for directly to the
+ processor attached devices). Which can be found on various
+ boards from Phytec (http://www.phytec.de) like the PCM027,
+ PCM038.
+
+config CAN_SJA1000_OF_PLATFORM
+ depends on CAN_SJA1000 && PPC_OF
+ tristate "Generic OF Platform Bus based SJA1000 driver"
+ ---help---
+ This driver adds support for the SJA1000 chips connected to
+ the OpenFirmware "platform bus" found on embedded systems with
+ OpenFirmware bindings, e.g. if you have a PowerPC based system
+ you may want to enable this option.
+
+config CAN_EMS_PCI
+ tristate "EMS CPC-PCI and CPC-PCIe Card"
+ depends on PCI && CAN_SJA1000
+ ---help---
+ This driver is for the one or two channel CPC-PCI and CPC-PCIe
+ cards from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
+
+config CAN_KVASER_PCI
+ tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards"
+ depends on PCI && CAN_SJA1000
+ ---help---
+ This driver is for the the PCIcanx and PCIcan cards (1, 2 or
+ 4 channel) from Kvaser (http://www.kvaser.com).
+
config CAN_DEBUG_DEVICES
bool "CAN devices debugging messages"
depends on CAN
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index c4bead705cd..523a941b358 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -3,3 +3,10 @@
#
obj-$(CONFIG_CAN_VCAN) += vcan.o
+
+obj-$(CONFIG_CAN_DEV) += can-dev.o
+can-dev-y := dev.o
+
+obj-$(CONFIG_CAN_SJA1000) += sja1000/
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
new file mode 100644
index 00000000000..574daddc21b
--- /dev/null
+++ b/drivers/net/can/dev.c
@@ -0,0 +1,657 @@
+/*
+ * Copyright (C) 2005 Marc Kleine-Budde, Pengutronix
+ * Copyright (C) 2006 Andrey Volkov, Varma Electronics
+ * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/netlink.h>
+#include <net/rtnetlink.h>
+
+#define MOD_DESC "CAN device driver interface"
+
+MODULE_DESCRIPTION(MOD_DESC);
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+
+#ifdef CONFIG_CAN_CALC_BITTIMING
+#define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */
+
+/*
+ * Bit-timing calculation derived from:
+ *
+ * Code based on LinCAN sources and H8S2638 project
+ * Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz
+ * Copyright 2005 Stanislav Marek
+ * email: pisa@cmp.felk.cvut.cz
+ *
+ * Calculates proper bit-timing parameters for a specified bit-rate
+ * and sample-point, which can then be used to set the bit-timing
+ * registers of the CAN controller. You can find more information
+ * in the header file linux/can/netlink.h.
+ */
+static int can_update_spt(const struct can_bittiming_const *btc,
+ int sampl_pt, int tseg, int *tseg1, int *tseg2)
+{
+ *tseg2 = tseg + 1 - (sampl_pt * (tseg + 1)) / 1000;
+ if (*tseg2 < btc->tseg2_min)
+ *tseg2 = btc->tseg2_min;
+ if (*tseg2 > btc->tseg2_max)
+ *tseg2 = btc->tseg2_max;
+ *tseg1 = tseg - *tseg2;
+ if (*tseg1 > btc->tseg1_max) {
+ *tseg1 = btc->tseg1_max;
+ *tseg2 = tseg - *tseg1;
+ }
+ return 1000 * (tseg + 1 - *tseg2) / (tseg + 1);
+}
+
+static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt)
+{
+ struct can_priv *priv = netdev_priv(dev);
+ const struct can_bittiming_const *btc = priv->bittiming_const;
+ long rate, best_rate = 0;
+ long best_error = 1000000000, error = 0;
+ int best_tseg = 0, best_brp = 0, brp = 0;
+ int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0;
+ int spt_error = 1000, spt = 0, sampl_pt;
+ u64 v64;
+
+ if (!priv->bittiming_const)
+ return -ENOTSUPP;
+
+ /* Use CIA recommended sample points */
+ if (bt->sample_point) {
+ sampl_pt = bt->sample_point;
+ } else {
+ if (bt->bitrate > 800000)
+ sampl_pt = 750;
+ else if (bt->bitrate > 500000)
+ sampl_pt = 800;
+ else
+ sampl_pt = 875;
+ }
+
+ /* tseg even = round down, odd = round up */
+ for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1;
+ tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) {
+ tsegall = 1 + tseg / 2;
+ /* Compute all possible tseg choices (tseg=tseg1+tseg2) */
+ brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2;
+ /* chose brp step which is possible in system */
+ brp = (brp / btc->brp_inc) * btc->brp_inc;
+ if ((brp < btc->brp_min) || (brp > btc->brp_max))
+ continue;
+ rate = priv->clock.freq / (brp * tsegall);
+ error = bt->bitrate - rate;
+ /* tseg brp biterror */
+ if (error < 0)
+ error = -error;
+ if (error > best_error)
+ continue;
+ best_error = error;
+ if (error == 0) {
+ spt = can_update_spt(btc, sampl_pt, tseg / 2,
+ &tseg1, &tseg2);
+ error = sampl_pt - spt;
+ if (error < 0)
+ error = -error;
+ if (error > spt_error)
+ continue;
+ spt_error = error;
+ }
+ best_tseg = tseg / 2;
+ best_brp = brp;
+ best_rate = rate;
+ if (error == 0)
+ break;
+ }
+
+ if (best_error) {
+ /* Error in one-tenth of a percent */
+ error = (best_error * 1000) / bt->bitrate;
+ if (error > CAN_CALC_MAX_ERROR) {
+ dev_err(dev->dev.parent,
+ "bitrate error %ld.%ld%% too high\n",
+ error / 10, error % 10);
+ return -EDOM;
+ } else {
+ dev_warn(dev->dev.parent, "bitrate error %ld.%ld%%\n",
+ error / 10, error % 10);
+ }
+ }
+
+ /* real sample point */
+ bt->sample_point = can_update_spt(btc, sampl_pt, best_tseg,
+ &tseg1, &tseg2);
+
+ v64 = (u64)best_brp * 1000000000UL;
+ do_div(v64, priv->clock.freq);
+ bt->tq = (u32)v64;
+ bt->prop_seg = tseg1 / 2;
+ bt->phase_seg1 = tseg1 - bt->prop_seg;
+ bt->phase_seg2 = tseg2;
+ bt->sjw = 1;
+ bt->brp = best_brp;
+ /* real bit-rate */
+ bt->bitrate = priv->clock.freq / (bt->brp * (tseg1 + tseg2 + 1));
+
+ return 0;
+}
+#else /* !CONFIG_CAN_CALC_BITTIMING */
+static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt)
+{
+ dev_err(dev->dev.parent, "bit-timing calculation not available\n");
+ return -EINVAL;
+}
+#endif /* CONFIG_CAN_CALC_BITTIMING */
+
+/*
+ * Checks the validity of the specified bit-timing parameters prop_seg,
+ * phase_seg1, phase_seg2 and sjw and tries to determine the bitrate
+ * prescaler value brp. You can find more information in the header
+ * file linux/can/netlink.h.
+ */
+static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt)
+{
+ struct can_priv *priv = netdev_priv(dev);
+ const struct can_bittiming_const *btc = priv->bittiming_const;
+ int tseg1, alltseg;
+ u64 brp64;
+
+ if (!priv->bittiming_const)
+ return -ENOTSUPP;
+
+ tseg1 = bt->prop_seg + bt->phase_seg1;
+ if (!bt->sjw)
+ bt->sjw = 1;
+ if (bt->sjw > btc->sjw_max ||
+ tseg1 < btc->tseg1_min || tseg1 > btc->tseg1_max ||
+ bt->phase_seg2 < btc->tseg2_min || bt->phase_seg2 > btc->tseg2_max)
+ return -ERANGE;
+
+ brp64 = (u64)priv->clock.freq * (u64)bt->tq;
+ if (btc->brp_inc > 1)
+ do_div(brp64, btc->brp_inc);
+ brp64 += 500000000UL - 1;
+ do_div(brp64, 1000000000UL); /* the practicable BRP */
+ if (btc->brp_inc > 1)
+ brp64 *= btc->brp_inc;
+ bt->brp = (u32)brp64;
+
+ if (bt->brp < btc->brp_min || bt->brp > btc->brp_max)
+ return -EINVAL;
+
+ alltseg = bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1;
+ bt->bitrate = priv->clock.freq / (bt->brp * alltseg);
+ bt->sample_point = ((tseg1 + 1) * 1000) / alltseg;
+
+ return 0;
+}
+
+int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt)
+{
+ struct can_priv *priv = netdev_priv(dev);
+ int err;
+
+ /* Check if the CAN device has bit-timing parameters */
+ if (priv->bittiming_const) {
+
+ /* Non-expert mode? Check if the bitrate has been pre-defined */
+ if (!bt->tq)
+ /* Determine bit-timing parameters */
+ err = can_calc_bittiming(dev, bt);
+ else
+ /* Check bit-timing params and calculate proper brp */
+ err = can_fixup_bittiming(dev, bt);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+/*
+ * Local echo of CAN messages
+ *
+ * CAN network devices *should* support a local echo functionality
+ * (see Documentation/networking/can.txt). To test the handling of CAN
+ * interfaces that do not support the local echo both driver types are
+ * implemented. In the case that the driver does not support the echo
+ * the IFF_ECHO remains clear in dev->flags. This causes the PF_CAN core
+ * to perform the echo as a fallback solution.
+ */
+static void can_flush_echo_skb(struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ int i;
+
+ for (i = 0; i < CAN_ECHO_SKB_MAX; i++) {
+ if (priv->echo_skb[i]) {
+ kfree_skb(priv->echo_skb[i]);
+ priv->echo_skb[i] = NULL;
+ stats->tx_dropped++;
+ stats->tx_aborted_errors++;
+ }
+ }
+}
+
+/*
+ * Put the skb on the stack to be looped backed locally lateron
+ *
+ * The function is typically called in the start_xmit function
+ * of the device driver. The driver must protect access to
+ * priv->echo_skb, if necessary.
+ */
+void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ /* check flag whether this packet has to be looped back */
+ if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) {
+ kfree_skb(skb);
+ return;
+ }
+
+ if (!priv->echo_skb[idx]) {
+ struct sock *srcsk = skb->sk;
+
+ if (atomic_read(&skb->users) != 1) {
+ struct sk_buff *old_skb = skb;
+
+ skb = skb_clone(old_skb, GFP_ATOMIC);
+ kfree_skb(old_skb);
+ if (!skb)
+ return;
+ } else
+ skb_orphan(skb);
+
+ skb->sk = srcsk;
+
+ /* make settings for echo to reduce code in irq context */
+ skb->protocol = htons(ETH_P_CAN);
+ skb->pkt_type = PACKET_BROADCAST;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->dev = dev;
+
+ /* save this skb for tx interrupt echo handling */
+ priv->echo_skb[idx] = skb;
+ } else {
+ /* locking problem with netif_stop_queue() ?? */
+ dev_err(dev->dev.parent, "%s: BUG! echo_skb is occupied!\n",
+ __func__);
+ kfree_skb(skb);
+ }
+}
+EXPORT_SYMBOL_GPL(can_put_echo_skb);
+
+/*
+ * Get the skb from the stack and loop it back locally
+ *
+ * The function is typically called when the TX done interrupt
+ * is handled in the device driver. The driver must protect
+ * access to priv->echo_skb, if necessary.
+ */
+void can_get_echo_skb(struct net_device *dev, int idx)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ if ((dev->flags & IFF_ECHO) && priv->echo_skb[idx]) {
+ netif_rx(priv->echo_skb[idx]);
+ priv->echo_skb[idx] = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(can_get_echo_skb);
+
+/*
+ * CAN device restart for bus-off recovery
+ */
+void can_restart(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ struct can_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct sk_buff *skb;
+ struct can_frame *cf;
+ int err;
+
+ BUG_ON(netif_carrier_ok(dev));
+
+ /*
+ * No synchronization needed because the device is bus-off and
+ * no messages can come in or go out.
+ */
+ can_flush_echo_skb(dev);
+
+ /* send restart message upstream */
+ skb = dev_alloc_skb(sizeof(struct can_frame));
+ if (skb == NULL) {
+ err = -ENOMEM;
+ goto out;
+ }
+ skb->dev = dev;
+ skb->protocol = htons(ETH_P_CAN);
+ cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
+ memset(cf, 0, sizeof(struct can_frame));
+ cf->can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED;
+ cf->can_dlc = CAN_ERR_DLC;
+
+ netif_rx(skb);
+
+ dev->last_rx = jiffies;
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+
+ dev_dbg(dev->dev.parent, "restarted\n");
+ priv->can_stats.restarts++;
+
+ /* Now restart the device */
+ err = priv->do_set_mode(dev, CAN_MODE_START);
+
+out:
+ netif_carrier_on(dev);
+ if (err)
+ dev_err(dev->dev.parent, "Error %d during restart", err);
+}
+
+int can_restart_now(struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ /*
+ * A manual restart is only permitted if automatic restart is
+ * disabled and the device is in the bus-off state
+ */
+ if (priv->restart_ms)
+ return -EINVAL;
+ if (priv->state != CAN_STATE_BUS_OFF)
+ return -EBUSY;
+
+ /* Runs as soon as possible in the timer context */
+ mod_timer(&priv->restart_timer, jiffies);
+
+ return 0;
+}
+
+/*
+ * CAN bus-off
+ *
+ * This functions should be called when the device goes bus-off to
+ * tell the netif layer that no more packets can be sent or received.
+ * If enabled, a timer is started to trigger bus-off recovery.
+ */
+void can_bus_off(struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ dev_dbg(dev->dev.parent, "bus-off\n");
+
+ netif_carrier_off(dev);
+ priv->can_stats.bus_off++;
+
+ if (priv->restart_ms)
+ mod_timer(&priv->restart_timer,
+ jiffies + (priv->restart_ms * HZ) / 1000);
+}
+EXPORT_SYMBOL_GPL(can_bus_off);
+
+static void can_setup(struct net_device *dev)
+{
+ dev->type = ARPHRD_CAN;
+ dev->mtu = sizeof(struct can_frame);
+ dev->hard_header_len = 0;
+ dev->addr_len = 0;
+ dev->tx_queue_len = 10;
+
+ /* New-style flags. */
+ dev->flags = IFF_NOARP;
+ dev->features = NETIF_F_NO_CSUM;
+}
+
+/*
+ * Allocate and setup space for the CAN network device
+ */
+struct net_device *alloc_candev(int sizeof_priv)
+{
+ struct net_device *dev;
+ struct can_priv *priv;
+
+ dev = alloc_netdev(sizeof_priv, "can%d", can_setup);
+ if (!dev)
+ return NULL;
+
+ priv = netdev_priv(dev);
+
+ priv->state = CAN_STATE_STOPPED;
+
+ init_timer(&priv->restart_timer);
+
+ return dev;
+}
+EXPORT_SYMBOL_GPL(alloc_candev);
+
+/*
+ * Free space of the CAN network device
+ */
+void free_candev(struct net_device *dev)
+{
+ free_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(free_candev);
+
+/*
+ * Common open function when the device gets opened.
+ *
+ * This function should be called in the open function of the device
+ * driver.
+ */
+int open_candev(struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ if (!priv->bittiming.tq && !priv->bittiming.bitrate) {
+ dev_err(dev->dev.parent, "bit-timing not yet defined\n");
+ return -EINVAL;
+ }
+
+ setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(open_candev);
+
+/*
+ * Common close function for cleanup before the device gets closed.
+ *
+ * This function should be called in the close function of the device
+ * driver.
+ */
+void close_candev(struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ if (del_timer_sync(&priv->restart_timer))
+ dev_put(dev);
+ can_flush_echo_skb(dev);
+}
+EXPORT_SYMBOL_GPL(close_candev);
+
+/*
+ * CAN netlink interface
+ */
+static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
+ [IFLA_CAN_STATE] = { .type = NLA_U32 },
+ [IFLA_CAN_CTRLMODE] = { .len = sizeof(struct can_ctrlmode) },
+ [IFLA_CAN_RESTART_MS] = { .type = NLA_U32 },
+ [IFLA_CAN_RESTART] = { .type = NLA_U32 },
+ [IFLA_CAN_BITTIMING] = { .len = sizeof(struct can_bittiming) },
+ [IFLA_CAN_BITTIMING_CONST]
+ = { .len = sizeof(struct can_bittiming_const) },
+ [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) },
+};
+
+static int can_changelink(struct net_device *dev,
+ struct nlattr *tb[], struct nlattr *data[])
+{
+ struct can_priv *priv = netdev_priv(dev);
+ int err;
+
+ /* We need synchronization with dev->stop() */
+ ASSERT_RTNL();
+
+ if (data[IFLA_CAN_CTRLMODE]) {
+ struct can_ctrlmode *cm;
+
+ /* Do not allow changing controller mode while running */
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+ cm = nla_data(data[IFLA_CAN_CTRLMODE]);
+ priv->ctrlmode &= ~cm->mask;
+ priv->ctrlmode |= cm->flags;
+ }
+
+ if (data[IFLA_CAN_BITTIMING]) {
+ struct can_bittiming bt;
+
+ /* Do not allow changing bittiming while running */
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+ memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
+ if ((!bt.bitrate && !bt.tq) || (bt.bitrate && bt.tq))
+ return -EINVAL;
+ err = can_get_bittiming(dev, &bt);
+ if (err)
+ return err;
+ memcpy(&priv->bittiming, &bt, sizeof(bt));
+
+ if (priv->do_set_bittiming) {
+ /* Finally, set the bit-timing registers */
+ err = priv->do_set_bittiming(dev);
+ if (err)
+ return err;
+ }
+ }
+
+ if (data[IFLA_CAN_RESTART_MS]) {
+ /* Do not allow changing restart delay while running */
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+ priv->restart_ms = nla_get_u32(data[IFLA_CAN_RESTART_MS]);
+ }
+
+ if (data[IFLA_CAN_RESTART]) {
+ /* Do not allow a restart while not running */
+ if (!(dev->flags & IFF_UP))
+ return -EINVAL;
+ err = can_restart_now(dev);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+ struct can_ctrlmode cm = {.flags = priv->ctrlmode};
+ enum can_state state = priv->state;
+
+ if (priv->do_get_state)
+ priv->do_get_state(dev, &state);
+ NLA_PUT_U32(skb, IFLA_CAN_STATE, state);
+ NLA_PUT(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm);
+ NLA_PUT_U32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms);
+ NLA_PUT(skb, IFLA_CAN_BITTIMING,
+ sizeof(priv->bittiming), &priv->bittiming);
+ NLA_PUT(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock);
+ if (priv->bittiming_const)
+ NLA_PUT(skb, IFLA_CAN_BITTIMING_CONST,
+ sizeof(*priv->bittiming_const), priv->bittiming_const);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
+static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ NLA_PUT(skb, IFLA_INFO_XSTATS,
+ sizeof(priv->can_stats), &priv->can_stats);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
+static struct rtnl_link_ops can_link_ops __read_mostly = {
+ .kind = "can",
+ .maxtype = IFLA_CAN_MAX,
+ .policy = can_policy,
+ .setup = can_setup,
+ .changelink = can_changelink,
+ .fill_info = can_fill_info,
+ .fill_xstats = can_fill_xstats,
+};
+
+/*
+ * Register the CAN network device
+ */
+int register_candev(struct net_device *dev)
+{
+ dev->rtnl_link_ops = &can_link_ops;
+ return register_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(register_candev);
+
+/*
+ * Unregister the CAN network device
+ */
+void unregister_candev(struct net_device *dev)
+{
+ unregister_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(unregister_candev);
+
+static __init int can_dev_init(void)
+{
+ int err;
+
+ err = rtnl_link_register(&can_link_ops);
+ if (!err)
+ printk(KERN_INFO MOD_DESC "\n");
+
+ return err;
+}
+module_init(can_dev_init);
+
+static __exit void can_dev_exit(void)
+{
+ rtnl_link_unregister(&can_link_ops);
+}
+module_exit(can_dev_exit);
+
+MODULE_ALIAS_RTNL_LINK("can");
diff --git a/drivers/net/can/sja1000/Makefile b/drivers/net/can/sja1000/Makefile
new file mode 100644
index 00000000000..9d0c08da273
--- /dev/null
+++ b/drivers/net/can/sja1000/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the SJA1000 CAN controller drivers.
+#
+
+obj-$(CONFIG_CAN_SJA1000) += sja1000.o
+obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o
+obj-$(CONFIG_CAN_SJA1000_OF_PLATFORM) += sja1000_of_platform.o
+obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o
+obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/sja1000/ems_pci.c b/drivers/net/can/sja1000/ems_pci.c
new file mode 100644
index 00000000000..121b64101d7
--- /dev/null
+++ b/drivers/net/can/sja1000/ems_pci.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
+ * Copyright (C) 2008 Markus Plessing <plessing@ems-wuensche.com>
+ * Copyright (C) 2008 Sebastian Haas <haas@ems-wuensche.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/io.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "ems_pci"
+
+MODULE_AUTHOR("Sebastian Haas <haas@ems-wuenche.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for EMS CPC-PCI/PCIe CAN cards");
+MODULE_SUPPORTED_DEVICE("EMS CPC-PCI/PCIe CAN card");
+MODULE_LICENSE("GPL v2");
+
+#define EMS_PCI_MAX_CHAN 2
+
+struct ems_pci_card {
+ int channels;
+
+ struct pci_dev *pci_dev;
+ struct net_device *net_dev[EMS_PCI_MAX_CHAN];
+
+ void __iomem *conf_addr;
+ void __iomem *base_addr;
+};
+
+#define EMS_PCI_CAN_CLOCK (16000000 / 2)
+
+/*
+ * Register definitions and descriptions are from LinCAN 0.3.3.
+ *
+ * PSB4610 PITA-2 bridge control registers
+ */
+#define PITA2_ICR 0x00 /* Interrupt Control Register */
+#define PITA2_ICR_INT0 0x00000002 /* [RC] INT0 Active/Clear */
+#define PITA2_ICR_INT0_EN 0x00020000 /* [RW] Enable INT0 */
+
+#define PITA2_MISC 0x1c /* Miscellaneous Register */
+#define PITA2_MISC_CONFIG 0x04000000 /* Multiplexed parallel interface */
+
+/*
+ * The board configuration is probably following:
+ * RX1 is connected to ground.
+ * TX1 is not connected.
+ * CLKO is not connected.
+ * Setting the OCR register to 0xDA is a good idea.
+ * This means normal output mode , push-pull and the correct polarity.
+ */
+#define EMS_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
+
+/*
+ * In the CDR register, you should set CBP to 1.
+ * You will probably also want to set the clock divider value to 7
+ * (meaning direct oscillator output) because the second SJA1000 chip
+ * is driven by the first one CLKOUT output.
+ */
+#define EMS_PCI_CDR (CDR_CBP | CDR_CLKOUT_MASK)
+#define EMS_PCI_MEM_SIZE 4096 /* Size of the remapped io-memory */
+#define EMS_PCI_CAN_BASE_OFFSET 0x400 /* offset where the controllers starts */
+#define EMS_PCI_CAN_CTRL_SIZE 0x200 /* memory size for each controller */
+
+#define EMS_PCI_PORT_BYTES 0x4 /* Each register occupies 4 bytes */
+
+#define EMS_PCI_VENDOR_ID 0x110a /* PCI device and vendor ID */
+#define EMS_PCI_DEVICE_ID 0x2104
+
+static struct pci_device_id ems_pci_tbl[] = {
+ {EMS_PCI_VENDOR_ID, EMS_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+ {0,}
+};
+MODULE_DEVICE_TABLE(pci, ems_pci_tbl);
+
+/*
+ * Helper to read internal registers from card logic (not CAN)
+ */
+static u8 ems_pci_readb(struct ems_pci_card *card, unsigned int port)
+{
+ return readb(card->base_addr + (port * EMS_PCI_PORT_BYTES));
+}
+
+static u8 ems_pci_read_reg(const struct sja1000_priv *priv, int port)
+{
+ return readb(priv->reg_base + (port * EMS_PCI_PORT_BYTES));
+}
+
+static void ems_pci_write_reg(const struct sja1000_priv *priv, int port, u8 val)
+{
+ writeb(val, priv->reg_base + (port * EMS_PCI_PORT_BYTES));
+}
+
+static void ems_pci_post_irq(const struct sja1000_priv *priv)
+{
+ struct ems_pci_card *card = (struct ems_pci_card *)priv->priv;
+
+ /* reset int flag of pita */
+ writel(PITA2_ICR_INT0_EN | PITA2_ICR_INT0, card->conf_addr
+ + PITA2_ICR);
+}
+
+/*
+ * Check if a CAN controller is present at the specified location
+ * by trying to set 'em into the PeliCAN mode
+ */
+static inline int ems_pci_check_chan(const struct sja1000_priv *priv)
+{
+ unsigned char res;
+
+ /* Make sure SJA1000 is in reset mode */
+ ems_pci_write_reg(priv, REG_MOD, 1);
+
+ ems_pci_write_reg(priv, REG_CDR, CDR_PELICAN);
+
+ /* read reset-values */
+ res = ems_pci_read_reg(priv, REG_CDR);
+
+ if (res == CDR_PELICAN)
+ return 1;
+
+ return 0;
+}
+
+static void ems_pci_del_card(struct pci_dev *pdev)
+{
+ struct ems_pci_card *card = pci_get_drvdata(pdev);
+ struct net_device *dev;
+ int i = 0;
+
+ for (i = 0; i < card->channels; i++) {
+ dev = card->net_dev[i];
+
+ if (!dev)
+ continue;
+
+ dev_info(&pdev->dev, "Removing %s.\n", dev->name);
+ unregister_sja1000dev(dev);
+ free_sja1000dev(dev);
+ }
+
+ if (card->base_addr != NULL)
+ pci_iounmap(card->pci_dev, card->base_addr);
+
+ if (card->conf_addr != NULL)
+ pci_iounmap(card->pci_dev, card->conf_addr);
+
+ kfree(card);
+
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+}
+
+static void ems_pci_card_reset(struct ems_pci_card *card)
+{
+ /* Request board reset */
+ writeb(0, card->base_addr);
+}
+
+/*
+ * Probe PCI device for EMS CAN signature and register each available
+ * CAN channel to SJA1000 Socket-CAN subsystem.
+ */
+static int __devinit ems_pci_add_card(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct sja1000_priv *priv;
+ struct net_device *dev;
+ struct ems_pci_card *card;
+ int err, i;
+
+ /* Enabling PCI device */
+ if (pci_enable_device(pdev) < 0) {
+ dev_err(&pdev->dev, "Enabling PCI device failed\n");
+ return -ENODEV;
+ }
+
+ /* Allocating card structures to hold addresses, ... */
+ card = kzalloc(sizeof(struct ems_pci_card), GFP_KERNEL);
+ if (card == NULL) {
+ dev_err(&pdev->dev, "Unable to allocate memory\n");
+ pci_disable_device(pdev);
+ return -ENOMEM;
+ }
+
+ pci_set_drvdata(pdev, card);
+
+ card->pci_dev = pdev;
+
+ card->channels = 0;
+
+ /* Remap PITA configuration space, and controller memory area */
+ card->conf_addr = pci_iomap(pdev, 0, EMS_PCI_MEM_SIZE);
+ if (card->conf_addr == NULL) {
+ err = -ENOMEM;
+ goto failure_cleanup;
+ }
+
+ card->base_addr = pci_iomap(pdev, 1, EMS_PCI_MEM_SIZE);
+ if (card->base_addr == NULL) {
+ err = -ENOMEM;
+ goto failure_cleanup;
+ }
+
+ /* Configure PITA-2 parallel interface (enable MUX) */
+ writel(PITA2_MISC_CONFIG, card->conf_addr + PITA2_MISC);
+
+ /* Check for unique EMS CAN signature */
+ if (ems_pci_readb(card, 0) != 0x55 ||
+ ems_pci_readb(card, 1) != 0xAA ||
+ ems_pci_readb(card, 2) != 0x01 ||
+ ems_pci_readb(card, 3) != 0xCB ||
+ ems_pci_readb(card, 4) != 0x11) {
+ dev_err(&pdev->dev, "Not EMS Dr. Thomas Wuensche interface\n");
+ err = -ENODEV;
+ goto failure_cleanup;
+ }
+
+ ems_pci_card_reset(card);
+
+ /* Detect available channels */
+ for (i = 0; i < EMS_PCI_MAX_CHAN; i++) {
+ dev = alloc_sja1000dev(0);
+ if (dev == NULL) {
+ err = -ENOMEM;
+ goto failure_cleanup;
+ }
+
+ card->net_dev[i] = dev;
+ priv = netdev_priv(dev);
+ priv->priv = card;
+ priv->irq_flags = IRQF_SHARED;
+
+ dev->irq = pdev->irq;
+ priv->reg_base = card->base_addr + EMS_PCI_CAN_BASE_OFFSET
+ + (i * EMS_PCI_CAN_CTRL_SIZE);
+
+ /* Check if channel is present */
+ if (ems_pci_check_chan(priv)) {
+ priv->read_reg = ems_pci_read_reg;
+ priv->write_reg = ems_pci_write_reg;
+ priv->post_irq = ems_pci_post_irq;
+ priv->can.clock.freq = EMS_PCI_CAN_CLOCK;
+ priv->ocr = EMS_PCI_OCR;
+ priv->cdr = EMS_PCI_CDR;
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ /* Enable interrupts from card */
+ writel(PITA2_ICR_INT0_EN, card->conf_addr + PITA2_ICR);
+
+ /* Register SJA1000 device */
+ err = register_sja1000dev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "Registering device failed "
+ "(err=%d)\n", err);
+ free_sja1000dev(dev);
+ goto failure_cleanup;
+ }
+
+ card->channels++;
+
+ dev_info(&pdev->dev, "Channel #%d at 0x%p, irq %d\n",
+ i + 1, priv->reg_base, dev->irq);
+ } else {
+ free_sja1000dev(dev);
+ }
+ }
+
+ return 0;
+
+failure_cleanup:
+ dev_err(&pdev->dev, "Error: %d. Cleaning Up.\n", err);
+
+ ems_pci_del_card(pdev);
+
+ return err;
+}
+
+static struct pci_driver ems_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = ems_pci_tbl,
+ .probe = ems_pci_add_card,
+ .remove = ems_pci_del_card,
+};
+
+static int __init ems_pci_init(void)
+{
+ return pci_register_driver(&ems_pci_driver);
+}
+
+static void __exit ems_pci_exit(void)
+{
+ pci_unregister_driver(&ems_pci_driver);
+}
+
+module_init(ems_pci_init);
+module_exit(ems_pci_exit);
+
diff --git a/drivers/net/can/sja1000/kvaser_pci.c b/drivers/net/can/sja1000/kvaser_pci.c
new file mode 100644
index 00000000000..7dd7769b971
--- /dev/null
+++ b/drivers/net/can/sja1000/kvaser_pci.c
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 2008 Per Dalen <per.dalen@cnw.se>
+ *
+ * Parts of this software are based on (derived) the following:
+ *
+ * - Kvaser linux driver, version 4.72 BETA
+ * Copyright (C) 2002-2007 KVASER AB
+ *
+ * - Lincan driver, version 0.3.3, OCERA project
+ * Copyright (C) 2004 Pavel Pisa
+ * Copyright (C) 2001 Arnaud Westenberg
+ *
+ * - Socketcan SJA1000 drivers
+ * Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
+ * 38106 Braunschweig, GERMANY
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/io.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "kvaser_pci"
+
+MODULE_AUTHOR("Per Dalen <per.dalen@cnw.se>");
+MODULE_DESCRIPTION("Socket-CAN driver for KVASER PCAN PCI cards");
+MODULE_SUPPORTED_DEVICE("KVASER PCAN PCI CAN card");
+MODULE_LICENSE("GPL v2");
+
+#define MAX_NO_OF_CHANNELS 4 /* max no of channels on a single card */
+
+struct kvaser_pci {
+ int channel;
+ struct pci_dev *pci_dev;
+ struct net_device *slave_dev[MAX_NO_OF_CHANNELS-1];
+ void __iomem *conf_addr;
+ void __iomem *res_addr;
+ int no_channels;
+ u8 xilinx_ver;
+};
+
+#define KVASER_PCI_CAN_CLOCK (16000000 / 2)
+
+/*
+ * The board configuration is probably following:
+ * RX1 is connected to ground.
+ * TX1 is not connected.
+ * CLKO is not connected.
+ * Setting the OCR register to 0xDA is a good idea.
+ * This means normal output mode , push-pull and the correct polarity.
+ */
+#define KVASER_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
+
+/*
+ * In the CDR register, you should set CBP to 1.
+ * You will probably also want to set the clock divider value to 0
+ * (meaning divide-by-2), the Pelican bit, and the clock-off bit
+ * (you will have no need for CLKOUT anyway).
+ */
+#define KVASER_PCI_CDR (CDR_CBP | CDR_CLKOUT_MASK)
+
+/*
+ * These register values are valid for revision 14 of the Xilinx logic.
+ */
+#define XILINX_VERINT 7 /* Lower nibble simulate interrupts,
+ high nibble version number. */
+
+#define XILINX_PRESUMED_VERSION 14
+
+/*
+ * Important S5920 registers
+ */
+#define S5920_INTCSR 0x38
+#define S5920_PTCR 0x60
+#define INTCSR_ADDON_INTENABLE_M 0x2000
+
+
+#define KVASER_PCI_PORT_BYTES 0x20
+
+#define PCI_CONFIG_PORT_SIZE 0x80 /* size of the config io-memory */
+#define PCI_PORT_SIZE 0x80 /* size of a channel io-memory */
+#define PCI_PORT_XILINX_SIZE 0x08 /* size of a xilinx io-memory */
+
+#define KVASER_PCI_VENDOR_ID1 0x10e8 /* the PCI device and vendor IDs */
+#define KVASER_PCI_DEVICE_ID1 0x8406
+
+#define KVASER_PCI_VENDOR_ID2 0x1a07 /* the PCI device and vendor IDs */
+#define KVASER_PCI_DEVICE_ID2 0x0008
+
+static struct pci_device_id kvaser_pci_tbl[] = {
+ {KVASER_PCI_VENDOR_ID1, KVASER_PCI_DEVICE_ID1, PCI_ANY_ID, PCI_ANY_ID,},
+ {KVASER_PCI_VENDOR_ID2, KVASER_PCI_DEVICE_ID2, PCI_ANY_ID, PCI_ANY_ID,},
+ { 0,}
+};
+
+MODULE_DEVICE_TABLE(pci, kvaser_pci_tbl);
+
+static u8 kvaser_pci_read_reg(const struct sja1000_priv *priv, int port)
+{
+ return ioread8(priv->reg_base + port);
+}
+
+static void kvaser_pci_write_reg(const struct sja1000_priv *priv,
+ int port, u8 val)
+{
+ iowrite8(val, priv->reg_base + port);
+}
+
+static void kvaser_pci_disable_irq(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct kvaser_pci *board = priv->priv;
+ u32 intcsr;
+
+ /* Disable interrupts from card */
+ intcsr = ioread32(board->conf_addr + S5920_INTCSR);
+ intcsr &= ~INTCSR_ADDON_INTENABLE_M;
+ iowrite32(intcsr, board->conf_addr + S5920_INTCSR);
+}
+
+static void kvaser_pci_enable_irq(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct kvaser_pci *board = priv->priv;
+ u32 tmp_en_io;
+
+ /* Enable interrupts from card */
+ tmp_en_io = ioread32(board->conf_addr + S5920_INTCSR);
+ tmp_en_io |= INTCSR_ADDON_INTENABLE_M;
+ iowrite32(tmp_en_io, board->conf_addr + S5920_INTCSR);
+}
+
+static int number_of_sja1000_chip(void __iomem *base_addr)
+{
+ u8 status;
+ int i;
+
+ for (i = 0; i < MAX_NO_OF_CHANNELS; i++) {
+ /* reset chip */
+ iowrite8(MOD_RM, base_addr +
+ (i * KVASER_PCI_PORT_BYTES) + REG_MOD);
+ status = ioread8(base_addr +
+ (i * KVASER_PCI_PORT_BYTES) + REG_MOD);
+ /* check reset bit */
+ if (!(status & MOD_RM))
+ break;
+ }
+
+ return i;
+}
+
+static void kvaser_pci_del_chan(struct net_device *dev)
+{
+ struct sja1000_priv *priv;
+ struct kvaser_pci *board;
+ int i;
+
+ if (!dev)
+ return;
+ priv = netdev_priv(dev);
+ board = priv->priv;
+ if (!board)
+ return;
+
+ dev_info(&board->pci_dev->dev, "Removing device %s\n",
+ dev->name);
+
+ /* Disable PCI interrupts */
+ kvaser_pci_disable_irq(dev);
+
+ for (i = 0; i < board->no_channels - 1; i++) {
+ if (board->slave_dev[i]) {
+ dev_info(&board->pci_dev->dev, "Removing device %s\n",
+ board->slave_dev[i]->name);
+ unregister_sja1000dev(board->slave_dev[i]);
+ free_sja1000dev(board->slave_dev[i]);
+ }
+ }
+ unregister_sja1000dev(dev);
+
+ pci_iounmap(board->pci_dev, priv->reg_base);
+ pci_iounmap(board->pci_dev, board->conf_addr);
+ pci_iounmap(board->pci_dev, board->res_addr);
+
+ free_sja1000dev(dev);
+}
+
+static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel,
+ struct net_device **master_dev,
+ void __iomem *conf_addr,
+ void __iomem *res_addr,
+ void __iomem *base_addr)
+{
+ struct net_device *dev;
+ struct sja1000_priv *priv;
+ struct kvaser_pci *board;
+ int err, init_step;
+
+ dev = alloc_sja1000dev(sizeof(struct kvaser_pci));
+ if (dev == NULL)
+ return -ENOMEM;
+
+ priv = netdev_priv(dev);
+ board = priv->priv;
+
+ board->pci_dev = pdev;
+ board->channel = channel;
+
+ /* S5920 */
+ board->conf_addr = conf_addr;
+
+ /* XILINX board wide address */
+ board->res_addr = res_addr;
+
+ if (channel == 0) {
+ board->xilinx_ver =
+ ioread8(board->res_addr + XILINX_VERINT) >> 4;
+ init_step = 2;
+
+ /* Assert PTADR# - we're in passive mode so the other bits are
+ not important */
+ iowrite32(0x80808080UL, board->conf_addr + S5920_PTCR);
+
+ /* Enable interrupts from card */
+ kvaser_pci_enable_irq(dev);
+ } else {
+ struct sja1000_priv *master_priv = netdev_priv(*master_dev);
+ struct kvaser_pci *master_board = master_priv->priv;
+ master_board->slave_dev[channel - 1] = dev;
+ master_board->no_channels = channel + 1;
+ board->xilinx_ver = master_board->xilinx_ver;
+ }
+
+ priv->reg_base = base_addr + channel * KVASER_PCI_PORT_BYTES;
+
+ priv->read_reg = kvaser_pci_read_reg;
+ priv->write_reg = kvaser_pci_write_reg;
+
+ priv->can.clock.freq = KVASER_PCI_CAN_CLOCK;
+
+ priv->ocr = KVASER_PCI_OCR;
+ priv->cdr = KVASER_PCI_CDR;
+
+ priv->irq_flags = IRQF_SHARED;
+ dev->irq = pdev->irq;
+
+ init_step = 4;
+
+ dev_info(&pdev->dev, "reg_base=%p conf_addr=%p irq=%d\n",
+ priv->reg_base, board->conf_addr, dev->irq);
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ /* Register SJA1000 device */
+ err = register_sja1000dev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "Registering device failed (err=%d)\n",
+ err);
+ goto failure;
+ }
+
+ if (channel == 0)
+ *master_dev = dev;
+
+ return 0;
+
+failure:
+ kvaser_pci_del_chan(dev);
+ return err;
+}
+
+static int __devinit kvaser_pci_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ int err;
+ struct net_device *master_dev = NULL;
+ struct sja1000_priv *priv;
+ struct kvaser_pci *board;
+ int no_channels;
+ void __iomem *base_addr = NULL;
+ void __iomem *conf_addr = NULL;
+ void __iomem *res_addr = NULL;
+ int i;
+
+ dev_info(&pdev->dev, "initializing device %04x:%04x\n",
+ pdev->vendor, pdev->device);
+
+ err = pci_enable_device(pdev);
+ if (err)
+ goto failure;
+
+ err = pci_request_regions(pdev, DRV_NAME);
+ if (err)
+ goto failure_release_pci;
+
+ /* S5920 */
+ conf_addr = pci_iomap(pdev, 0, PCI_CONFIG_PORT_SIZE);
+ if (conf_addr == NULL) {
+ err = -ENODEV;
+ goto failure_release_regions;
+ }
+
+ /* XILINX board wide address */
+ res_addr = pci_iomap(pdev, 2, PCI_PORT_XILINX_SIZE);
+ if (res_addr == NULL) {
+ err = -ENOMEM;
+ goto failure_iounmap;
+ }
+
+ base_addr = pci_iomap(pdev, 1, PCI_PORT_SIZE);
+ if (base_addr == NULL) {
+ err = -ENOMEM;
+ goto failure_iounmap;
+ }
+
+ no_channels = number_of_sja1000_chip(base_addr);
+ if (no_channels == 0) {
+ err = -ENOMEM;
+ goto failure_iounmap;
+ }
+
+ for (i = 0; i < no_channels; i++) {
+ err = kvaser_pci_add_chan(pdev, i, &master_dev,
+ conf_addr, res_addr,
+ base_addr);
+ if (err)
+ goto failure_cleanup;
+ }
+
+ priv = netdev_priv(master_dev);
+ board = priv->priv;
+
+ dev_info(&pdev->dev, "xilinx version=%d number of channels=%d\n",
+ board->xilinx_ver, board->no_channels);
+
+ pci_set_drvdata(pdev, master_dev);
+ return 0;
+
+failure_cleanup:
+ kvaser_pci_del_chan(master_dev);
+
+failure_iounmap:
+ if (conf_addr != NULL)
+ pci_iounmap(pdev, conf_addr);
+ if (res_addr != NULL)
+ pci_iounmap(pdev, res_addr);
+ if (base_addr != NULL)
+ pci_iounmap(pdev, base_addr);
+
+failure_release_regions:
+ pci_release_regions(pdev);
+
+failure_release_pci:
+ pci_disable_device(pdev);
+
+failure:
+ return err;
+
+}
+
+static void __devexit kvaser_pci_remove_one(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+
+ kvaser_pci_del_chan(dev);
+
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+}
+
+static struct pci_driver kvaser_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = kvaser_pci_tbl,
+ .probe = kvaser_pci_init_one,
+ .remove = __devexit_p(kvaser_pci_remove_one),
+};
+
+static int __init kvaser_pci_init(void)
+{
+ return pci_register_driver(&kvaser_pci_driver);
+}
+
+static void __exit kvaser_pci_exit(void)
+{
+ pci_unregister_driver(&kvaser_pci_driver);
+}
+
+module_init(kvaser_pci_init);
+module_exit(kvaser_pci_exit);
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
new file mode 100644
index 00000000000..571f133a8fe
--- /dev/null
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -0,0 +1,637 @@
+/*
+ * sja1000.c - Philips SJA1000 network device driver
+ *
+ * Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
+ * 38106 Braunschweig, GERMANY
+ *
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Volkswagen nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * The provided data structures and external interfaces from this code
+ * are not restricted to be used by modules with a GPL compatible license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/can/dev.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "sja1000"
+
+MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION(DRV_NAME "CAN netdevice driver");
+
+static struct can_bittiming_const sja1000_bittiming_const = {
+ .name = DRV_NAME,
+ .tseg1_min = 1,
+ .tseg1_max = 16,
+ .tseg2_min = 1,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 64,
+ .brp_inc = 1,
+};
+
+static int sja1000_probe_chip(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+
+ if (priv->reg_base && (priv->read_reg(priv, 0) == 0xFF)) {
+ printk(KERN_INFO "%s: probing @0x%lX failed\n",
+ DRV_NAME, dev->base_addr);
+ return 0;
+ }
+ return -1;
+}
+
+static void set_reset_mode(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ unsigned char status = priv->read_reg(priv, REG_MOD);
+ int i;
+
+ /* disable interrupts */
+ priv->write_reg(priv, REG_IER, IRQ_OFF);
+
+ for (i = 0; i < 100; i++) {
+ /* check reset bit */
+ if (status & MOD_RM) {
+ priv->can.state = CAN_STATE_STOPPED;
+ return;
+ }
+
+ priv->write_reg(priv, REG_MOD, MOD_RM); /* reset chip */
+ udelay(10);
+ status = priv->read_reg(priv, REG_MOD);
+ }
+
+ dev_err(dev->dev.parent, "setting SJA1000 into reset mode failed!\n");
+}
+
+static void set_normal_mode(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ unsigned char status = priv->read_reg(priv, REG_MOD);
+ int i;
+
+ for (i = 0; i < 100; i++) {
+ /* check reset bit */
+ if ((status & MOD_RM) == 0) {
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ /* enable all interrupts */
+ priv->write_reg(priv, REG_IER, IRQ_ALL);
+ return;
+ }
+
+ /* set chip to normal mode */
+ priv->write_reg(priv, REG_MOD, 0x00);
+ udelay(10);
+ status = priv->read_reg(priv, REG_MOD);
+ }
+
+ dev_err(dev->dev.parent, "setting SJA1000 into normal mode failed!\n");
+}
+
+static void sja1000_start(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+
+ /* leave reset mode */
+ if (priv->can.state != CAN_STATE_STOPPED)
+ set_reset_mode(dev);
+
+ /* Clear error counters and error code capture */
+ priv->write_reg(priv, REG_TXERR, 0x0);
+ priv->write_reg(priv, REG_RXERR, 0x0);
+ priv->read_reg(priv, REG_ECC);
+
+ /* leave reset mode */
+ set_normal_mode(dev);
+}
+
+static int sja1000_set_mode(struct net_device *dev, enum can_mode mode)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+
+ if (!priv->open_time)
+ return -EINVAL;
+
+ switch (mode) {
+ case CAN_MODE_START:
+ sja1000_start(dev);
+ if (netif_queue_stopped(dev))
+ netif_wake_queue(dev);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int sja1000_set_bittiming(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct can_bittiming *bt = &priv->can.bittiming;
+ u8 btr0, btr1;
+
+ btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
+ btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
+ (((bt->phase_seg2 - 1) & 0x7) << 4);
+ if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+ btr1 |= 0x80;
+
+ dev_info(dev->dev.parent,
+ "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
+
+ priv->write_reg(priv, REG_BTR0, btr0);
+ priv->write_reg(priv, REG_BTR1, btr1);
+
+ return 0;
+}
+
+/*
+ * initialize SJA1000 chip:
+ * - reset chip
+ * - set output mode
+ * - set baudrate
+ * - enable interrupts
+ * - start operating mode
+ */
+static void chipset_init(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+
+ /* set clock divider and output control register */
+ priv->write_reg(priv, REG_CDR, priv->cdr | CDR_PELICAN);
+
+ /* set acceptance filter (accept all) */
+ priv->write_reg(priv, REG_ACCC0, 0x00);
+ priv->write_reg(priv, REG_ACCC1, 0x00);
+ priv->write_reg(priv, REG_ACCC2, 0x00);
+ priv->write_reg(priv, REG_ACCC3, 0x00);
+
+ priv->write_reg(priv, REG_ACCM0, 0xFF);
+ priv->write_reg(priv, REG_ACCM1, 0xFF);
+ priv->write_reg(priv, REG_ACCM2, 0xFF);
+ priv->write_reg(priv, REG_ACCM3, 0xFF);
+
+ priv->write_reg(priv, REG_OCR, priv->ocr | OCR_MODE_NORMAL);
+}
+
+/*
+ * transmit a CAN message
+ * message layout in the sk_buff should be like this:
+ * xx xx xx xx ff ll 00 11 22 33 44 55 66 77
+ * [ can-id ] [flags] [len] [can data (up to 8 bytes]
+ */
+static int sja1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ uint8_t fi;
+ uint8_t dlc;
+ canid_t id;
+ uint8_t dreg;
+ int i;
+
+ netif_stop_queue(dev);
+
+ fi = dlc = cf->can_dlc;
+ id = cf->can_id;
+
+ if (id & CAN_RTR_FLAG)
+ fi |= FI_RTR;
+
+ if (id & CAN_EFF_FLAG) {
+ fi |= FI_FF;
+ dreg = EFF_BUF;
+ priv->write_reg(priv, REG_FI, fi);
+ priv->write_reg(priv, REG_ID1, (id & 0x1fe00000) >> (5 + 16));
+ priv->write_reg(priv, REG_ID2, (id & 0x001fe000) >> (5 + 8));
+ priv->write_reg(priv, REG_ID3, (id & 0x00001fe0) >> 5);
+ priv->write_reg(priv, REG_ID4, (id & 0x0000001f) << 3);
+ } else {
+ dreg = SFF_BUF;
+ priv->write_reg(priv, REG_FI, fi);
+ priv->write_reg(priv, REG_ID1, (id & 0x000007f8) >> 3);
+ priv->write_reg(priv, REG_ID2, (id & 0x00000007) << 5);
+ }
+
+ for (i = 0; i < dlc; i++)
+ priv->write_reg(priv, dreg++, cf->data[i]);
+
+ stats->tx_bytes += dlc;
+ dev->trans_start = jiffies;
+
+ can_put_echo_skb(skb, dev, 0);
+
+ priv->write_reg(priv, REG_CMR, CMD_TR);
+
+ return 0;
+}
+
+static void sja1000_rx(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ uint8_t fi;
+ uint8_t dreg;
+ canid_t id;
+ uint8_t dlc;
+ int i;
+
+ skb = dev_alloc_skb(sizeof(struct can_frame));
+ if (skb == NULL)
+ return;
+ skb->dev = dev;
+ skb->protocol = htons(ETH_P_CAN);
+
+ fi = priv->read_reg(priv, REG_FI);
+ dlc = fi & 0x0F;
+
+ if (fi & FI_FF) {
+ /* extended frame format (EFF) */
+ dreg = EFF_BUF;
+ id = (priv->read_reg(priv, REG_ID1) << (5 + 16))
+ | (priv->read_reg(priv, REG_ID2) << (5 + 8))
+ | (priv->read_reg(priv, REG_ID3) << 5)
+ | (priv->read_reg(priv, REG_ID4) >> 3);
+ id |= CAN_EFF_FLAG;
+ } else {
+ /* standard frame format (SFF) */
+ dreg = SFF_BUF;
+ id = (priv->read_reg(priv, REG_ID1) << 3)
+ | (priv->read_reg(priv, REG_ID2) >> 5);
+ }
+
+ if (fi & FI_RTR)
+ id |= CAN_RTR_FLAG;
+
+ cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
+ memset(cf, 0, sizeof(struct can_frame));
+ cf->can_id = id;
+ cf->can_dlc = dlc;
+ for (i = 0; i < dlc; i++)
+ cf->data[i] = priv->read_reg(priv, dreg++);
+
+ while (i < 8)
+ cf->data[i++] = 0;
+
+ /* release receive buffer */
+ priv->write_reg(priv, REG_CMR, CMD_RRB);
+
+ netif_rx(skb);
+
+ dev->last_rx = jiffies;
+ stats->rx_packets++;
+ stats->rx_bytes += dlc;
+}
+
+static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ enum can_state state = priv->can.state;
+ uint8_t ecc, alc;
+
+ skb = dev_alloc_skb(sizeof(struct can_frame));
+ if (skb == NULL)
+ return -ENOMEM;
+ skb->dev = dev;
+ skb->protocol = htons(ETH_P_CAN);
+ cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
+ memset(cf, 0, sizeof(struct can_frame));
+ cf->can_id = CAN_ERR_FLAG;
+ cf->can_dlc = CAN_ERR_DLC;
+
+ if (isrc & IRQ_DOI) {
+ /* data overrun interrupt */
+ dev_dbg(dev->dev.parent, "data overrun interrupt\n");
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+ priv->write_reg(priv, REG_CMR, CMD_CDO); /* clear bit */
+ }
+
+ if (isrc & IRQ_EI) {
+ /* error warning interrupt */
+ dev_dbg(dev->dev.parent, "error warning interrupt\n");
+
+ if (status & SR_BS) {
+ state = CAN_STATE_BUS_OFF;
+ cf->can_id |= CAN_ERR_BUSOFF;
+ can_bus_off(dev);
+ } else if (status & SR_ES) {
+ state = CAN_STATE_ERROR_WARNING;
+ } else
+ state = CAN_STATE_ERROR_ACTIVE;
+ }
+ if (isrc & IRQ_BEI) {
+ /* bus error interrupt */
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+
+ ecc = priv->read_reg(priv, REG_ECC);
+
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+ switch (ecc & ECC_MASK) {
+ case ECC_BIT:
+ cf->data[2] |= CAN_ERR_PROT_BIT;
+ break;
+ case ECC_FORM:
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ break;
+ case ECC_STUFF:
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ break;
+ default:
+ cf->data[2] |= CAN_ERR_PROT_UNSPEC;
+ cf->data[3] = ecc & ECC_SEG;
+ break;
+ }
+ /* Error occured during transmission? */
+ if ((ecc & ECC_DIR) == 0)
+ cf->data[2] |= CAN_ERR_PROT_TX;
+ }
+ if (isrc & IRQ_EPI) {
+ /* error passive interrupt */
+ dev_dbg(dev->dev.parent, "error passive interrupt\n");
+ if (status & SR_ES)
+ state = CAN_STATE_ERROR_PASSIVE;
+ else
+ state = CAN_STATE_ERROR_ACTIVE;
+ }
+ if (isrc & IRQ_ALI) {
+ /* arbitration lost interrupt */
+ dev_dbg(dev->dev.parent, "arbitration lost interrupt\n");
+ alc = priv->read_reg(priv, REG_ALC);
+ priv->can.can_stats.arbitration_lost++;
+ stats->rx_errors++;
+ cf->can_id |= CAN_ERR_LOSTARB;
+ cf->data[0] = alc & 0x1f;
+ }
+
+ if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING ||
+ state == CAN_STATE_ERROR_PASSIVE)) {
+ uint8_t rxerr = priv->read_reg(priv, REG_RXERR);
+ uint8_t txerr = priv->read_reg(priv, REG_TXERR);
+ cf->can_id |= CAN_ERR_CRTL;
+ if (state == CAN_STATE_ERROR_WARNING) {
+ priv->can.can_stats.error_warning++;
+ cf->data[1] = (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_WARNING :
+ CAN_ERR_CRTL_RX_WARNING;
+ } else {
+ priv->can.can_stats.error_passive++;
+ cf->data[1] = (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_PASSIVE :
+ CAN_ERR_CRTL_RX_PASSIVE;
+ }
+ }
+
+ priv->can.state = state;
+
+ netif_rx(skb);
+
+ dev->last_rx = jiffies;
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+
+ return 0;
+}
+
+irqreturn_t sja1000_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ uint8_t isrc, status;
+ int n = 0;
+
+ /* Shared interrupts and IRQ off? */
+ if (priv->read_reg(priv, REG_IER) == IRQ_OFF)
+ return IRQ_NONE;
+
+ if (priv->pre_irq)
+ priv->pre_irq(priv);
+
+ while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) {
+ n++;
+ status = priv->read_reg(priv, REG_SR);
+
+ if (isrc & IRQ_WUI)
+ dev_warn(dev->dev.parent, "wakeup interrupt\n");
+
+ if (isrc & IRQ_TI) {
+ /* transmission complete interrupt */
+ stats->tx_packets++;
+ can_get_echo_skb(dev, 0);
+ netif_wake_queue(dev);
+ }
+ if (isrc & IRQ_RI) {
+ /* receive interrupt */
+ while (status & SR_RBS) {
+ sja1000_rx(dev);
+ status = priv->read_reg(priv, REG_SR);
+ }
+ }
+ if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
+ /* error interrupt */
+ if (sja1000_err(dev, isrc, status))
+ break;
+ }
+ }
+
+ if (priv->post_irq)
+ priv->post_irq(priv);
+
+ if (n >= SJA1000_MAX_IRQ)
+ dev_dbg(dev->dev.parent, "%d messages handled in ISR", n);
+
+ return (n) ? IRQ_HANDLED : IRQ_NONE;
+}
+EXPORT_SYMBOL_GPL(sja1000_interrupt);
+
+static int sja1000_open(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ int err;
+
+ /* set chip into reset mode */
+ set_reset_mode(dev);
+
+ /* common open */
+ err = open_candev(dev);
+ if (err)
+ return err;
+
+ /* register interrupt handler, if not done by the device driver */
+ if (!(priv->flags & SJA1000_CUSTOM_IRQ_HANDLER)) {
+ err = request_irq(dev->irq, &sja1000_interrupt, priv->irq_flags,
+ dev->name, (void *)dev);
+ if (err) {
+ close_candev(dev);
+ return -EAGAIN;
+ }
+ }
+
+ /* init and start chi */
+ sja1000_start(dev);
+ priv->open_time = jiffies;
+
+ netif_start_queue(dev);
+
+ return 0;
+}
+
+static int sja1000_close(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+
+ netif_stop_queue(dev);
+ set_reset_mode(dev);
+
+ if (!(priv->flags & SJA1000_CUSTOM_IRQ_HANDLER))
+ free_irq(dev->irq, (void *)dev);
+
+ close_candev(dev);
+
+ priv->open_time = 0;
+
+ return 0;
+}
+
+struct net_device *alloc_sja1000dev(int sizeof_priv)
+{
+ struct net_device *dev;
+ struct sja1000_priv *priv;
+
+ dev = alloc_candev(sizeof(struct sja1000_priv) + sizeof_priv);
+ if (!dev)
+ return NULL;
+
+ priv = netdev_priv(dev);
+
+ priv->dev = dev;
+ priv->can.bittiming_const = &sja1000_bittiming_const;
+ priv->can.do_set_bittiming = sja1000_set_bittiming;
+ priv->can.do_set_mode = sja1000_set_mode;
+
+ if (sizeof_priv)
+ priv->priv = (void *)priv + sizeof(struct sja1000_priv);
+
+ return dev;
+}
+EXPORT_SYMBOL_GPL(alloc_sja1000dev);
+
+void free_sja1000dev(struct net_device *dev)
+{
+ free_candev(dev);
+}
+EXPORT_SYMBOL_GPL(free_sja1000dev);
+
+static const struct net_device_ops sja1000_netdev_ops = {
+ .ndo_open = sja1000_open,
+ .ndo_stop = sja1000_close,
+ .ndo_start_xmit = sja1000_start_xmit,
+};
+
+int register_sja1000dev(struct net_device *dev)
+{
+ if (!sja1000_probe_chip(dev))
+ return -ENODEV;
+
+ dev->flags |= IFF_ECHO; /* we support local echo */
+ dev->netdev_ops = &sja1000_netdev_ops;
+
+ set_reset_mode(dev);
+ chipset_init(dev);
+
+ return register_candev(dev);
+}
+EXPORT_SYMBOL_GPL(register_sja1000dev);
+
+void unregister_sja1000dev(struct net_device *dev)
+{
+ set_reset_mode(dev);
+ unregister_candev(dev);
+}
+EXPORT_SYMBOL_GPL(unregister_sja1000dev);
+
+static __init int sja1000_init(void)
+{
+ printk(KERN_INFO "%s CAN netdevice driver\n", DRV_NAME);
+
+ return 0;
+}
+
+module_init(sja1000_init);
+
+static __exit void sja1000_exit(void)
+{
+ printk(KERN_INFO "%s: driver removed\n", DRV_NAME);
+}
+
+module_exit(sja1000_exit);
diff --git a/drivers/net/can/sja1000/sja1000.h b/drivers/net/can/sja1000/sja1000.h
new file mode 100644
index 00000000000..302d2c763ad
--- /dev/null
+++ b/drivers/net/can/sja1000/sja1000.h
@@ -0,0 +1,181 @@
+/*
+ * sja1000.h - Philips SJA1000 network device driver
+ *
+ * Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
+ * 38106 Braunschweig, GERMANY
+ *
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Volkswagen nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * The provided data structures and external interfaces from this code
+ * are not restricted to be used by modules with a GPL compatible license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ *
+ */
+
+#ifndef SJA1000_DEV_H
+#define SJA1000_DEV_H
+
+#include <linux/can/dev.h>
+#include <linux/can/platform/sja1000.h>
+
+#define SJA1000_MAX_IRQ 20 /* max. number of interrupts handled in ISR */
+
+/* SJA1000 registers - manual section 6.4 (Pelican Mode) */
+#define REG_MOD 0x00
+#define REG_CMR 0x01
+#define REG_SR 0x02
+#define REG_IR 0x03
+#define REG_IER 0x04
+#define REG_ALC 0x0B
+#define REG_ECC 0x0C
+#define REG_EWL 0x0D
+#define REG_RXERR 0x0E
+#define REG_TXERR 0x0F
+#define REG_ACCC0 0x10
+#define REG_ACCC1 0x11
+#define REG_ACCC2 0x12
+#define REG_ACCC3 0x13
+#define REG_ACCM0 0x14
+#define REG_ACCM1 0x15
+#define REG_ACCM2 0x16
+#define REG_ACCM3 0x17
+#define REG_RMC 0x1D
+#define REG_RBSA 0x1E
+
+/* Common registers - manual section 6.5 */
+#define REG_BTR0 0x06
+#define REG_BTR1 0x07
+#define REG_OCR 0x08
+#define REG_CDR 0x1F
+
+#define REG_FI 0x10
+#define SFF_BUF 0x13
+#define EFF_BUF 0x15
+
+#define FI_FF 0x80
+#define FI_RTR 0x40
+
+#define REG_ID1 0x11
+#define REG_ID2 0x12
+#define REG_ID3 0x13
+#define REG_ID4 0x14
+
+#define CAN_RAM 0x20
+
+/* mode register */
+#define MOD_RM 0x01
+#define MOD_LOM 0x02
+#define MOD_STM 0x04
+#define MOD_AFM 0x08
+#define MOD_SM 0x10
+
+/* commands */
+#define CMD_SRR 0x10
+#define CMD_CDO 0x08
+#define CMD_RRB 0x04
+#define CMD_AT 0x02
+#define CMD_TR 0x01
+
+/* interrupt sources */
+#define IRQ_BEI 0x80
+#define IRQ_ALI 0x40
+#define IRQ_EPI 0x20
+#define IRQ_WUI 0x10
+#define IRQ_DOI 0x08
+#define IRQ_EI 0x04
+#define IRQ_TI 0x02
+#define IRQ_RI 0x01
+#define IRQ_ALL 0xFF
+#define IRQ_OFF 0x00
+
+/* status register content */
+#define SR_BS 0x80
+#define SR_ES 0x40
+#define SR_TS 0x20
+#define SR_RS 0x10
+#define SR_TCS 0x08
+#define SR_TBS 0x04
+#define SR_DOS 0x02
+#define SR_RBS 0x01
+
+#define SR_CRIT (SR_BS|SR_ES)
+
+/* ECC register */
+#define ECC_SEG 0x1F
+#define ECC_DIR 0x20
+#define ECC_ERR 6
+#define ECC_BIT 0x00
+#define ECC_FORM 0x40
+#define ECC_STUFF 0x80
+#define ECC_MASK 0xc0
+
+/*
+ * Flags for sja1000priv.flags
+ */
+#define SJA1000_CUSTOM_IRQ_HANDLER 0x1
+
+/*
+ * SJA1000 private data structure
+ */
+struct sja1000_priv {
+ struct can_priv can; /* must be the first member */
+ int open_time;
+ struct sk_buff *echo_skb;
+
+ /* the lower-layer is responsible for appropriate locking */
+ u8 (*read_reg) (const struct sja1000_priv *priv, int reg);
+ void (*write_reg) (const struct sja1000_priv *priv, int reg, u8 val);
+ void (*pre_irq) (const struct sja1000_priv *priv);
+ void (*post_irq) (const struct sja1000_priv *priv);
+
+ void *priv; /* for board-specific data */
+ struct net_device *dev;
+
+ void __iomem *reg_base; /* ioremap'ed address to registers */
+ unsigned long irq_flags; /* for request_irq() */
+
+ u16 flags; /* custom mode flags */
+ u8 ocr; /* output control register */
+ u8 cdr; /* clock divider register */
+};
+
+struct net_device *alloc_sja1000dev(int sizeof_priv);
+void free_sja1000dev(struct net_device *dev);
+int register_sja1000dev(struct net_device *dev);
+void unregister_sja1000dev(struct net_device *dev);
+
+irqreturn_t sja1000_interrupt(int irq, void *dev_id);
+
+#endif /* SJA1000_DEV_H */
diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c
new file mode 100644
index 00000000000..3373560405b
--- /dev/null
+++ b/drivers/net/can/sja1000/sja1000_of_platform.c
@@ -0,0 +1,235 @@
+/*
+ * Driver for SJA1000 CAN controllers on the OpenFirmware platform bus
+ *
+ * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* This is a generic driver for SJA1000 chips on the OpenFirmware platform
+ * bus found on embedded PowerPC systems. You need a SJA1000 CAN node
+ * definition in your flattened device tree source (DTS) file similar to:
+ *
+ * can@3,100 {
+ * compatible = "nxp,sja1000";
+ * reg = <3 0x100 0x80>;
+ * interrupts = <2 0>;
+ * interrupt-parent = <&mpic>;
+ * nxp,external-clock-frequency = <16000000>;
+ * };
+ *
+ * See "Documentation/powerpc/dts-bindings/can/sja1000.txt" for further
+ * information.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "sja1000_of_platform"
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the OF platform bus");
+MODULE_LICENSE("GPL v2");
+
+#define SJA1000_OFP_CAN_CLOCK (16000000 / 2)
+
+#define SJA1000_OFP_OCR OCR_TX0_PULLDOWN
+#define SJA1000_OFP_CDR (CDR_CBP | CDR_CLK_OFF)
+
+static u8 sja1000_ofp_read_reg(const struct sja1000_priv *priv, int reg)
+{
+ return in_8(priv->reg_base + reg);
+}
+
+static void sja1000_ofp_write_reg(const struct sja1000_priv *priv,
+ int reg, u8 val)
+{
+ out_8(priv->reg_base + reg, val);
+}
+
+static int __devexit sja1000_ofp_remove(struct of_device *ofdev)
+{
+ struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct device_node *np = ofdev->node;
+ struct resource res;
+
+ dev_set_drvdata(&ofdev->dev, NULL);
+
+ unregister_sja1000dev(dev);
+ free_sja1000dev(dev);
+ iounmap(priv->reg_base);
+ irq_dispose_mapping(dev->irq);
+
+ of_address_to_resource(np, 0, &res);
+ release_mem_region(res.start, resource_size(&res));
+
+ return 0;
+}
+
+static int __devinit sja1000_ofp_probe(struct of_device *ofdev,
+ const struct of_device_id *id)
+{
+ struct device_node *np = ofdev->node;
+ struct net_device *dev;
+ struct sja1000_priv *priv;
+ struct resource res;
+ const u32 *prop;
+ int err, irq, res_size, prop_size;
+ void __iomem *base;
+
+ err = of_address_to_resource(np, 0, &res);
+ if (err) {
+ dev_err(&ofdev->dev, "invalid address\n");
+ return err;
+ }
+
+ res_size = resource_size(&res);
+
+ if (!request_mem_region(res.start, res_size, DRV_NAME)) {
+ dev_err(&ofdev->dev, "couldn't request %#llx..%#llx\n",
+ (unsigned long long)res.start,
+ (unsigned long long)res.end);
+ return -EBUSY;
+ }
+
+ base = ioremap_nocache(res.start, res_size);
+ if (!base) {
+ dev_err(&ofdev->dev, "couldn't ioremap %#llx..%#llx\n",
+ (unsigned long long)res.start,
+ (unsigned long long)res.end);
+ err = -ENOMEM;
+ goto exit_release_mem;
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (irq == NO_IRQ) {
+ dev_err(&ofdev->dev, "no irq found\n");
+ err = -ENODEV;
+ goto exit_unmap_mem;
+ }
+
+ dev = alloc_sja1000dev(0);
+ if (!dev) {
+ err = -ENOMEM;
+ goto exit_dispose_irq;
+ }
+
+ priv = netdev_priv(dev);
+
+ priv->read_reg = sja1000_ofp_read_reg;
+ priv->write_reg = sja1000_ofp_write_reg;
+
+ prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size);
+ if (prop && (prop_size == sizeof(u32)))
+ priv->can.clock.freq = *prop / 2;
+ else
+ priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */
+
+ prop = of_get_property(np, "nxp,tx-output-mode", &prop_size);
+ if (prop && (prop_size == sizeof(u32)))
+ priv->ocr |= *prop & OCR_MODE_MASK;
+ else
+ priv->ocr |= OCR_MODE_NORMAL; /* default */
+
+ prop = of_get_property(np, "nxp,tx-output-config", &prop_size);
+ if (prop && (prop_size == sizeof(u32)))
+ priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK;
+ else
+ priv->ocr |= OCR_TX0_PULLDOWN; /* default */
+
+ prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size);
+ if (prop && (prop_size == sizeof(u32)) && *prop) {
+ u32 divider = priv->can.clock.freq * 2 / *prop;
+
+ if (divider > 1)
+ priv->cdr |= divider / 2 - 1;
+ else
+ priv->cdr |= CDR_CLKOUT_MASK;
+ } else {
+ priv->cdr |= CDR_CLK_OFF; /* default */
+ }
+
+ prop = of_get_property(np, "nxp,no-comparator-bypass", NULL);
+ if (!prop)
+ priv->cdr |= CDR_CBP; /* default */
+
+ priv->irq_flags = IRQF_SHARED;
+ priv->reg_base = base;
+
+ dev->irq = irq;
+
+ dev_info(&ofdev->dev,
+ "reg_base=0x%p irq=%d clock=%d ocr=0x%02x cdr=0x%02x\n",
+ priv->reg_base, dev->irq, priv->can.clock.freq,
+ priv->ocr, priv->cdr);
+
+ dev_set_drvdata(&ofdev->dev, dev);
+ SET_NETDEV_DEV(dev, &ofdev->dev);
+
+ err = register_sja1000dev(dev);
+ if (err) {
+ dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
+ DRV_NAME, err);
+ goto exit_free_sja1000;
+ }
+
+ return 0;
+
+exit_free_sja1000:
+ free_sja1000dev(dev);
+exit_dispose_irq:
+ irq_dispose_mapping(irq);
+exit_unmap_mem:
+ iounmap(base);
+exit_release_mem:
+ release_mem_region(res.start, res_size);
+
+ return err;
+}
+
+static struct of_device_id __devinitdata sja1000_ofp_table[] = {
+ {.compatible = "nxp,sja1000"},
+ {},
+};
+
+static struct of_platform_driver sja1000_ofp_driver = {
+ .owner = THIS_MODULE,
+ .name = DRV_NAME,
+ .probe = sja1000_ofp_probe,
+ .remove = __devexit_p(sja1000_ofp_remove),
+ .match_table = sja1000_ofp_table,
+};
+
+static int __init sja1000_ofp_init(void)
+{
+ return of_register_platform_driver(&sja1000_ofp_driver);
+}
+module_init(sja1000_ofp_init);
+
+static void __exit sja1000_ofp_exit(void)
+{
+ return of_unregister_platform_driver(&sja1000_ofp_driver);
+};
+module_exit(sja1000_ofp_exit);
diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c
new file mode 100644
index 00000000000..628374c2a05
--- /dev/null
+++ b/drivers/net/can/sja1000/sja1000_platform.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2005 Sascha Hauer, Pengutronix
+ * Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/platform/sja1000.h>
+#include <linux/io.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "sja1000_platform"
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus");
+MODULE_LICENSE("GPL v2");
+
+static u8 sp_read_reg(const struct sja1000_priv *priv, int reg)
+{
+ return ioread8(priv->reg_base + reg);
+}
+
+static void sp_write_reg(const struct sja1000_priv *priv, int reg, u8 val)
+{
+ iowrite8(val, priv->reg_base + reg);
+}
+
+static int sp_probe(struct platform_device *pdev)
+{
+ int err;
+ void __iomem *addr;
+ struct net_device *dev;
+ struct sja1000_priv *priv;
+ struct resource *res_mem, *res_irq;
+ struct sja1000_platform_data *pdata;
+
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ dev_err(&pdev->dev, "No platform data provided!\n");
+ err = -ENODEV;
+ goto exit;
+ }
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res_mem || !res_irq) {
+ err = -ENODEV;
+ goto exit;
+ }
+
+ if (!request_mem_region(res_mem->start, resource_size(res_mem),
+ DRV_NAME)) {
+ err = -EBUSY;
+ goto exit;
+ }
+
+ addr = ioremap_nocache(res_mem->start, resource_size(res_mem));
+ if (!addr) {
+ err = -ENOMEM;
+ goto exit_release;
+ }
+
+ dev = alloc_sja1000dev(0);
+ if (!dev) {
+ err = -ENOMEM;
+ goto exit_iounmap;
+ }
+ priv = netdev_priv(dev);
+
+ dev->irq = res_irq->start;
+ priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK;
+ priv->reg_base = addr;
+ priv->read_reg = sp_read_reg;
+ priv->write_reg = sp_write_reg;
+ priv->can.clock.freq = pdata->clock;
+ priv->ocr = pdata->ocr;
+ priv->cdr = pdata->cdr;
+
+ dev_set_drvdata(&pdev->dev, dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ err = register_sja1000dev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
+ DRV_NAME, err);
+ goto exit_free;
+ }
+
+ dev_info(&pdev->dev, "%s device registered (reg_base=%p, irq=%d)\n",
+ DRV_NAME, priv->reg_base, dev->irq);
+ return 0;
+
+ exit_free:
+ free_sja1000dev(dev);
+ exit_iounmap:
+ iounmap(addr);
+ exit_release:
+ release_mem_region(res_mem->start, resource_size(res_mem));
+ exit:
+ return err;
+}
+
+static int sp_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = dev_get_drvdata(&pdev->dev);
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct resource *res;
+
+ unregister_sja1000dev(dev);
+ dev_set_drvdata(&pdev->dev, NULL);
+
+ if (priv->reg_base)
+ iounmap(priv->reg_base);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, resource_size(res));
+
+ free_sja1000dev(dev);
+
+ return 0;
+}
+
+static struct platform_driver sp_driver = {
+ .probe = sp_probe,
+ .remove = sp_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init sp_init(void)
+{
+ return platform_driver_register(&sp_driver);
+}
+
+static void __exit sp_exit(void)
+{
+ platform_driver_unregister(&sp_driver);
+}
+
+module_init(sp_init);
+module_exit(sp_exit);
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index f5222764061..eb066673c2a 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -2934,7 +2934,7 @@ static int cas_start_xmit(struct sk_buff *skb, struct net_device *dev)
* individual queues.
*/
if (cas_xmit_tx_ringN(cp, ring++ & N_TX_RINGS_MASK, skb))
- return 1;
+ return NETDEV_TX_BUSY;
dev->trans_start = jiffies;
return 0;
}
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h
index 4bd2455b0fe..699d22c5fe0 100644
--- a/drivers/net/chelsio/common.h
+++ b/drivers/net/chelsio/common.h
@@ -46,7 +46,7 @@
#include <linux/pci.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
#include <linux/crc32.h>
#include <linux/init.h>
#include <asm/io.h>
diff --git a/drivers/net/chelsio/cphy.h b/drivers/net/chelsio/cphy.h
index 79d855e267e..1f095a9fc73 100644
--- a/drivers/net/chelsio/cphy.h
+++ b/drivers/net/chelsio/cphy.h
@@ -43,10 +43,11 @@
struct mdio_ops {
void (*init)(adapter_t *adapter, const struct board_info *bi);
- int (*read)(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *val);
- int (*write)(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val);
+ int (*read)(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr);
+ int (*write)(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr, u16 val);
+ unsigned mode_support;
};
/* PHY interrupt types */
@@ -83,11 +84,12 @@ struct cphy_ops {
int (*set_speed_duplex)(struct cphy *phy, int speed, int duplex);
int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed,
int *duplex, int *fc);
+
+ u32 mmds;
};
/* A PHY instance */
struct cphy {
- int addr; /* PHY address */
int state; /* Link status state machine */
adapter_t *adapter; /* associated adapter */
@@ -101,56 +103,61 @@ struct cphy {
u32 elmer_gpo;
const struct cphy_ops *ops; /* PHY operations */
- int (*mdio_read)(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *val);
- int (*mdio_write)(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val);
+ struct mdio_if_info mdio;
struct cphy_instance *instance;
};
/* Convenience MDIO read/write wrappers */
-static inline int mdio_read(struct cphy *cphy, int mmd, int reg,
- unsigned int *valp)
+static inline int cphy_mdio_read(struct cphy *cphy, int mmd, int reg,
+ unsigned int *valp)
{
- return cphy->mdio_read(cphy->adapter, cphy->addr, mmd, reg, valp);
+ int rc = cphy->mdio.mdio_read(cphy->mdio.dev, cphy->mdio.prtad, mmd,
+ reg);
+ *valp = (rc >= 0) ? rc : -1;
+ return (rc >= 0) ? 0 : rc;
}
-static inline int mdio_write(struct cphy *cphy, int mmd, int reg,
- unsigned int val)
+static inline int cphy_mdio_write(struct cphy *cphy, int mmd, int reg,
+ unsigned int val)
{
- return cphy->mdio_write(cphy->adapter, cphy->addr, mmd, reg, val);
+ return cphy->mdio.mdio_write(cphy->mdio.dev, cphy->mdio.prtad, mmd,
+ reg, val);
}
static inline int simple_mdio_read(struct cphy *cphy, int reg,
unsigned int *valp)
{
- return mdio_read(cphy, 0, reg, valp);
+ return cphy_mdio_read(cphy, MDIO_DEVAD_NONE, reg, valp);
}
static inline int simple_mdio_write(struct cphy *cphy, int reg,
unsigned int val)
{
- return mdio_write(cphy, 0, reg, val);
+ return cphy_mdio_write(cphy, MDIO_DEVAD_NONE, reg, val);
}
/* Convenience initializer */
-static inline void cphy_init(struct cphy *phy, adapter_t *adapter,
+static inline void cphy_init(struct cphy *phy, struct net_device *dev,
int phy_addr, struct cphy_ops *phy_ops,
const struct mdio_ops *mdio_ops)
{
+ struct adapter *adapter = netdev_priv(dev);
phy->adapter = adapter;
- phy->addr = phy_addr;
phy->ops = phy_ops;
if (mdio_ops) {
- phy->mdio_read = mdio_ops->read;
- phy->mdio_write = mdio_ops->write;
+ phy->mdio.prtad = phy_addr;
+ phy->mdio.mmds = phy_ops->mmds;
+ phy->mdio.mode_support = mdio_ops->mode_support;
+ phy->mdio.mdio_read = mdio_ops->read;
+ phy->mdio.mdio_write = mdio_ops->write;
}
+ phy->mdio.dev = dev;
}
/* Operations of the PHY-instance factory */
struct gphy {
/* Construct a PHY instance with the given PHY address */
- struct cphy *(*create)(adapter_t *adapter, int phy_addr,
+ struct cphy *(*create)(struct net_device *dev, int phy_addr,
const struct mdio_ops *mdio_ops);
/*
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index fa06994f973..082cdb28b51 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -589,7 +589,7 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
}
cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
- cmd->phy_address = p->phy->addr;
+ cmd->phy_address = p->phy->mdio.prtad;
cmd->transceiver = XCVR_EXTERNAL;
cmd->autoneg = p->link_config.autoneg;
cmd->maxtxpkt = 0;
@@ -849,39 +849,9 @@ static const struct ethtool_ops t1_ethtool_ops = {
static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
{
struct adapter *adapter = dev->ml_priv;
- struct mii_ioctl_data *data = if_mii(req);
-
- switch (cmd) {
- case SIOCGMIIPHY:
- data->phy_id = adapter->port[dev->if_port].phy->addr;
- /* FALLTHRU */
- case SIOCGMIIREG: {
- struct cphy *phy = adapter->port[dev->if_port].phy;
- u32 val;
-
- if (!phy->mdio_read)
- return -EOPNOTSUPP;
- phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f,
- &val);
- data->val_out = val;
- break;
- }
- case SIOCSMIIREG: {
- struct cphy *phy = adapter->port[dev->if_port].phy;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- if (!phy->mdio_write)
- return -EOPNOTSUPP;
- phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f,
- data->val_in);
- break;
- }
+ struct mdio_if_info *mdio = &adapter->port[dev->if_port].phy->mdio;
- default:
- return -EOPNOTSUPP;
- }
- return 0;
+ return mdio_mii_ioctl(mdio, if_mii(req), cmd);
}
static int t1_change_mtu(struct net_device *dev, int new_mtu)
diff --git a/drivers/net/chelsio/mv88e1xxx.c b/drivers/net/chelsio/mv88e1xxx.c
index 0632be0d649..809047a99e9 100644
--- a/drivers/net/chelsio/mv88e1xxx.c
+++ b/drivers/net/chelsio/mv88e1xxx.c
@@ -353,15 +353,16 @@ static struct cphy_ops mv88e1xxx_ops = {
.get_link_status = mv88e1xxx_get_link_status,
};
-static struct cphy *mv88e1xxx_phy_create(adapter_t *adapter, int phy_addr,
+static struct cphy *mv88e1xxx_phy_create(struct net_device *dev, int phy_addr,
const struct mdio_ops *mdio_ops)
{
+ struct adapter *adapter = netdev_priv(dev);
struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL);
if (!cphy)
return NULL;
- cphy_init(cphy, adapter, phy_addr, &mv88e1xxx_ops, mdio_ops);
+ cphy_init(cphy, dev, phy_addr, &mv88e1xxx_ops, mdio_ops);
/* Configure particular PHY's to run in a different mode. */
if ((board_info(adapter)->caps & SUPPORTED_TP) &&
diff --git a/drivers/net/chelsio/mv88x201x.c b/drivers/net/chelsio/mv88x201x.c
index cd856041af3..f7136b2fd1e 100644
--- a/drivers/net/chelsio/mv88x201x.c
+++ b/drivers/net/chelsio/mv88x201x.c
@@ -53,7 +53,7 @@ static int led_init(struct cphy *cphy)
* Writing these bits maps control to another
* register. mmd(0x1) addr(0x7)
*/
- mdio_write(cphy, 0x3, 0x8304, 0xdddd);
+ cphy_mdio_write(cphy, MDIO_MMD_PCS, 0x8304, 0xdddd);
return 0;
}
@@ -62,14 +62,14 @@ static int led_link(struct cphy *cphy, u32 do_enable)
u32 led = 0;
#define LINK_ENABLE_BIT 0x1
- mdio_read(cphy, 0x1, 0x7, &led);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, &led);
if (do_enable & LINK_ENABLE_BIT) {
led |= LINK_ENABLE_BIT;
- mdio_write(cphy, 0x1, 0x7, led);
+ cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, led);
} else {
led &= ~LINK_ENABLE_BIT;
- mdio_write(cphy, 0x1, 0x7, led);
+ cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, led);
}
return 0;
}
@@ -86,7 +86,8 @@ static int mv88x201x_reset(struct cphy *cphy, int wait)
static int mv88x201x_interrupt_enable(struct cphy *cphy)
{
/* Enable PHY LASI interrupts. */
- mdio_write(cphy, 0x1, 0x9002, 0x1);
+ cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL,
+ MDIO_PMA_LASI_LSALARM);
/* Enable Marvell interrupts through Elmer0. */
if (t1_is_asic(cphy->adapter)) {
@@ -102,7 +103,7 @@ static int mv88x201x_interrupt_enable(struct cphy *cphy)
static int mv88x201x_interrupt_disable(struct cphy *cphy)
{
/* Disable PHY LASI interrupts. */
- mdio_write(cphy, 0x1, 0x9002, 0x0);
+ cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, 0x0);
/* Disable Marvell interrupts through Elmer0. */
if (t1_is_asic(cphy->adapter)) {
@@ -122,25 +123,25 @@ static int mv88x201x_interrupt_clear(struct cphy *cphy)
#ifdef MV88x2010_LINK_STATUS_BUGS
/* Required to read twice before clear takes affect. */
- mdio_read(cphy, 0x1, 0x9003, &val);
- mdio_read(cphy, 0x1, 0x9004, &val);
- mdio_read(cphy, 0x1, 0x9005, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_RXSTAT, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_TXSTAT, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT, &val);
/* Read this register after the others above it else
* the register doesn't clear correctly.
*/
- mdio_read(cphy, 0x1, 0x1, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
#endif
/* Clear link status. */
- mdio_read(cphy, 0x1, 0x1, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
/* Clear PHY LASI interrupts. */
- mdio_read(cphy, 0x1, 0x9005, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT, &val);
#ifdef MV88x2010_LINK_STATUS_BUGS
/* Do it again. */
- mdio_read(cphy, 0x1, 0x9003, &val);
- mdio_read(cphy, 0x1, 0x9004, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_RXSTAT, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_TXSTAT, &val);
#endif
/* Clear Marvell interrupts through Elmer0. */
@@ -172,13 +173,12 @@ static int mv88x201x_get_link_status(struct cphy *cphy, int *link_ok,
int *speed, int *duplex, int *fc)
{
u32 val = 0;
-#define LINK_STATUS_BIT 0x4
if (link_ok) {
/* Read link status. */
- mdio_read(cphy, 0x1, 0x1, &val);
- val &= LINK_STATUS_BIT;
- *link_ok = (val == LINK_STATUS_BIT);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
+ val &= MDIO_STAT1_LSTATUS;
+ *link_ok = (val == MDIO_STAT1_LSTATUS);
/* Turn on/off Link LED */
led_link(cphy, *link_ok);
}
@@ -205,9 +205,11 @@ static struct cphy_ops mv88x201x_ops = {
.interrupt_handler = mv88x201x_interrupt_handler,
.get_link_status = mv88x201x_get_link_status,
.set_loopback = mv88x201x_set_loopback,
+ .mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
+ MDIO_DEVS_PHYXS | MDIO_DEVS_WIS),
};
-static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr,
+static struct cphy *mv88x201x_phy_create(struct net_device *dev, int phy_addr,
const struct mdio_ops *mdio_ops)
{
u32 val;
@@ -216,15 +218,15 @@ static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr,
if (!cphy)
return NULL;
- cphy_init(cphy, adapter, phy_addr, &mv88x201x_ops, mdio_ops);
+ cphy_init(cphy, dev, phy_addr, &mv88x201x_ops, mdio_ops);
/* Commands the PHY to enable XFP's clock. */
- mdio_read(cphy, 0x3, 0x8300, &val);
- mdio_write(cphy, 0x3, 0x8300, val | 1);
+ cphy_mdio_read(cphy, MDIO_MMD_PCS, 0x8300, &val);
+ cphy_mdio_write(cphy, MDIO_MMD_PCS, 0x8300, val | 1);
/* Clear link status. Required because of a bug in the PHY. */
- mdio_read(cphy, 0x1, 0x8, &val);
- mdio_read(cphy, 0x3, 0x8, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT2, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PCS, MDIO_STAT2, &val);
/* Allows for Link,Ack LED turn on/off */
led_init(cphy);
diff --git a/drivers/net/chelsio/my3126.c b/drivers/net/chelsio/my3126.c
index 040acd29995..4c6028512d1 100644
--- a/drivers/net/chelsio/my3126.c
+++ b/drivers/net/chelsio/my3126.c
@@ -43,11 +43,11 @@ static int my3126_interrupt_handler(struct cphy *cphy)
adapter = cphy->adapter;
if (cphy->count == 50) {
- mdio_read(cphy, 0x1, 0x1, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
val16 = (u16) val;
status = cphy->bmsr ^ val16;
- if (status & BMSR_LSTATUS)
+ if (status & MDIO_STAT1_LSTATUS)
t1_link_changed(adapter, 0);
cphy->bmsr = val16;
@@ -114,14 +114,14 @@ static int my3126_get_link_status(struct cphy *cphy,
adapter_t *adapter;
adapter = cphy->adapter;
- mdio_read(cphy, 0x1, 0x1, &val);
+ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
val16 = (u16) val;
/* Populate elmer_gpo with the register value */
t1_tpi_read(adapter, A_ELMER0_GPO, &val);
cphy->elmer_gpo = val;
- *link_ok = (val16 & BMSR_LSTATUS);
+ *link_ok = (val16 & MDIO_STAT1_LSTATUS);
if (*link_ok) {
/* Turn on the LED. */
@@ -163,9 +163,11 @@ static struct cphy_ops my3126_ops = {
.interrupt_handler = my3126_interrupt_handler,
.get_link_status = my3126_get_link_status,
.set_loopback = my3126_set_loopback,
+ .mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
+ MDIO_DEVS_PHYXS),
};
-static struct cphy *my3126_phy_create(adapter_t *adapter,
+static struct cphy *my3126_phy_create(struct net_device *dev,
int phy_addr, const struct mdio_ops *mdio_ops)
{
struct cphy *cphy = kzalloc(sizeof (*cphy), GFP_KERNEL);
@@ -173,7 +175,7 @@ static struct cphy *my3126_phy_create(adapter_t *adapter,
if (!cphy)
return NULL;
- cphy_init(cphy, adapter, phy_addr, &my3126_ops, mdio_ops);
+ cphy_init(cphy, dev, phy_addr, &my3126_ops, mdio_ops);
INIT_DELAYED_WORK(&cphy->phy_update, my3216_poll);
cphy->bmsr = 0;
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 58f6fc055f6..3711d64e45e 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -1149,8 +1149,8 @@ static inline void write_tx_desc(struct cmdQ_e *e, dma_addr_t mapping,
unsigned int len, unsigned int gen,
unsigned int eop)
{
- if (unlikely(len > SGE_TX_DESC_MAX_PLEN))
- BUG();
+ BUG_ON(len > SGE_TX_DESC_MAX_PLEN);
+
e->addr_lo = (u32)mapping;
e->addr_hi = (u64)mapping >> 32;
e->len_gen = V_CMD_LEN(len) | V_CMD_GEN1(gen);
@@ -1879,7 +1879,6 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
cpl->vlan_valid = 0;
send:
- dev->trans_start = jiffies;
ret = t1_sge_tx(skb, adapter, 0, dev);
/* If transmit busy, and we reallocated skb's due to headroom limit,
diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c
index 7adf30230c4..17720c6e5bf 100644
--- a/drivers/net/chelsio/subr.c
+++ b/drivers/net/chelsio/subr.c
@@ -284,32 +284,29 @@ static void mi1_mdio_init(adapter_t *adapter, const struct board_info *bi)
/*
* Elmer MI1 MDIO read/write operations.
*/
-static int mi1_mdio_read(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *valp)
+static int mi1_mdio_read(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr)
{
+ struct adapter *adapter = dev->ml_priv;
u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
-
- if (mmd_addr)
- return -EINVAL;
+ unsigned int val;
spin_lock(&adapter->tpi_lock);
__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
__t1_tpi_write(adapter,
A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_READ);
mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
- __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
+ __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val);
spin_unlock(&adapter->tpi_lock);
- return 0;
+ return val;
}
-static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val)
+static int mi1_mdio_write(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr, u16 val)
{
+ struct adapter *adapter = dev->ml_priv;
u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
- if (mmd_addr)
- return -EINVAL;
-
spin_lock(&adapter->tpi_lock);
__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
@@ -324,16 +321,19 @@ static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr,
static const struct mdio_ops mi1_mdio_ops = {
.init = mi1_mdio_init,
.read = mi1_mdio_read,
- .write = mi1_mdio_write
+ .write = mi1_mdio_write,
+ .mode_support = MDIO_SUPPORTS_C22
};
#endif
#endif
-static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *valp)
+static int mi1_mdio_ext_read(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr)
{
+ struct adapter *adapter = dev->ml_priv;
u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
+ unsigned int val;
spin_lock(&adapter->tpi_lock);
@@ -350,14 +350,15 @@ static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
/* Read the data. */
- __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
+ __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val);
spin_unlock(&adapter->tpi_lock);
- return 0;
+ return val;
}
-static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val)
+static int mi1_mdio_ext_write(struct net_device *dev, int phy_addr,
+ int mmd_addr, u16 reg_addr, u16 val)
{
+ struct adapter *adapter = dev->ml_priv;
u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
spin_lock(&adapter->tpi_lock);
@@ -380,7 +381,8 @@ static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
static const struct mdio_ops mi1_mdio_ext_ops = {
.init = mi1_mdio_init,
.read = mi1_mdio_ext_read,
- .write = mi1_mdio_ext_write
+ .write = mi1_mdio_ext_write,
+ .mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22
};
enum {
@@ -1133,8 +1135,8 @@ int __devinit t1_init_sw_modules(adapter_t *adapter,
struct cmac *mac;
int phy_addr = bi->mdio_phybaseaddr + i;
- adapter->port[i].phy = bi->gphy->create(adapter, phy_addr,
- bi->mdio_ops);
+ adapter->port[i].phy = bi->gphy->create(adapter->port[i].dev,
+ phy_addr, bi->mdio_ops);
if (!adapter->port[i].phy) {
CH_ERR("%s: PHY %d initialization failed\n",
adapter->name, i);
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index 3f476c7c073..58afafbd3b9 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -202,7 +202,7 @@ struct cpmac_priv {
void __iomem *regs;
struct mii_bus *mii_bus;
struct phy_device *phy;
- char phy_name[BUS_ID_SIZE];
+ char phy_name[MII_BUS_ID_SIZE + 3];
int oldlink, oldspeed, oldduplex;
u32 msg_enable;
struct net_device *dev;
@@ -615,13 +615,13 @@ static void cpmac_end_xmit(struct net_device *dev, int queue)
dev_kfree_skb_irq(desc->skb);
desc->skb = NULL;
- if (netif_subqueue_stopped(dev, queue))
+ if (__netif_subqueue_stopped(dev, queue))
netif_wake_subqueue(dev, queue);
} else {
if (netif_msg_tx_err(priv) && net_ratelimit())
printk(KERN_WARNING
"%s: end_xmit: spurious interrupt\n", dev->name);
- if (netif_subqueue_stopped(dev, queue))
+ if (__netif_subqueue_stopped(dev, queue))
netif_wake_subqueue(dev, queue);
}
}
@@ -731,7 +731,6 @@ static void cpmac_clear_tx(struct net_device *dev)
static void cpmac_hw_error(struct work_struct *work)
{
- int i;
struct cpmac_priv *priv =
container_of(work, struct cpmac_priv, reset_work);
@@ -818,7 +817,6 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id)
static void cpmac_tx_timeout(struct net_device *dev)
{
- int i;
struct cpmac_priv *priv = netdev_priv(dev);
spin_lock(&priv->lock);
@@ -1093,11 +1091,24 @@ static int cpmac_stop(struct net_device *dev)
return 0;
}
+static const struct net_device_ops cpmac_netdev_ops = {
+ .ndo_open = cpmac_open,
+ .ndo_stop = cpmac_stop,
+ .ndo_start_xmit = cpmac_start_xmit,
+ .ndo_tx_timeout = cpmac_tx_timeout,
+ .ndo_set_multicast_list = cpmac_set_multicast_list,
+ .ndo_so_ioctl = cpmac_ioctl,
+ .ndo_set_config = cpmac_config,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int external_switch;
static int __devinit cpmac_probe(struct platform_device *pdev)
{
- int rc, phy_id, i;
+ int rc, phy_id;
char *mdio_bus_id = "0";
struct resource *mem;
struct cpmac_priv *priv;
@@ -1143,14 +1154,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
dev->irq = platform_get_irq_byname(pdev, "irq");
- dev->open = cpmac_open;
- dev->stop = cpmac_stop;
- dev->set_config = cpmac_config;
- dev->hard_start_xmit = cpmac_start_xmit;
- dev->do_ioctl = cpmac_ioctl;
- dev->set_multicast_list = cpmac_set_multicast_list;
- dev->tx_timeout = cpmac_tx_timeout;
- dev->ethtool_ops = &cpmac_ethtool_ops;
+ dev->netdev_ops = &cpmac_netdev_ops;
+ dev->ethtool_ops = &cpmac_ethtool_ops;
netif_napi_add(dev, &priv->napi, cpmac_poll, 64);
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index 7433b88eed7..3eee666a9cd 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -1551,7 +1551,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irq(&lp->lock);
if (net_debug) printk("cs89x0: Tx buffer not free!\n");
- return 1;
+ return NETDEV_TX_BUSY;
}
/* Write the contents of the packet */
writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
diff --git a/drivers/net/cxgb3/Makefile b/drivers/net/cxgb3/Makefile
index 34346798532..29aff78c782 100644
--- a/drivers/net/cxgb3/Makefile
+++ b/drivers/net/cxgb3/Makefile
@@ -5,4 +5,4 @@
obj-$(CONFIG_CHELSIO_T3) += cxgb3.o
cxgb3-objs := cxgb3_main.o ael1002.o vsc8211.o t3_hw.o mc5.o \
- xgmac.o sge.o l2t.o cxgb3_offload.o
+ xgmac.o sge.o l2t.o cxgb3_offload.o aq100x.o
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index c888e97c967..1694fad3872 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -195,7 +195,7 @@ struct sge_qset { /* an SGE queue set */
struct sge_rspq rspq;
struct sge_fl fl[SGE_RXQ_PER_SET];
struct sge_txq txq[SGE_TXQ_PER_SET];
- struct napi_gro_fraginfo lro_frag_tbl;
+ int nomem;
int lro_enabled;
void *lro_va;
struct net_device *netdev;
@@ -253,6 +253,8 @@ struct adapter {
struct mutex mdio_lock;
spinlock_t stats_lock;
spinlock_t work_lock;
+
+ struct sk_buff *nofail_skb;
};
static inline u32 t3_read_reg(struct adapter *adapter, u32 reg_addr)
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c
index e1b22490ff5..9fe008ec9ba 100644
--- a/drivers/net/cxgb3/ael1002.c
+++ b/drivers/net/cxgb3/ael1002.c
@@ -33,14 +33,6 @@
#include "regs.h"
enum {
- PMD_RSD = 10, /* PMA/PMD receive signal detect register */
- PCS_STAT1_X = 24, /* 10GBASE-X PCS status 1 register */
- PCS_STAT1_R = 32, /* 10GBASE-R PCS status 1 register */
- XS_LN_STAT = 24 /* XS lane status register */
-};
-
-enum {
- AEL100X_TX_DISABLE = 9,
AEL100X_TX_CONFIG1 = 0xc002,
AEL1002_PWR_DOWN_HI = 0xc011,
AEL1002_PWR_DOWN_LO = 0xc012,
@@ -52,12 +44,33 @@ enum {
AEL_I2C_STAT = 0xc30c,
AEL2005_GPIO_CTRL = 0xc214,
AEL2005_GPIO_STAT = 0xc215,
+
+ AEL2020_GPIO_INTR = 0xc103, /* Latch High (LH) */
+ AEL2020_GPIO_CTRL = 0xc108, /* Store Clear (SC) */
+ AEL2020_GPIO_STAT = 0xc10c, /* Read Only (RO) */
+ AEL2020_GPIO_CFG = 0xc110, /* Read Write (RW) */
+
+ AEL2020_GPIO_SDA = 0, /* IN: i2c serial data */
+ AEL2020_GPIO_MODDET = 1, /* IN: Module Detect */
+ AEL2020_GPIO_0 = 3, /* IN: unassigned */
+ AEL2020_GPIO_1 = 2, /* OUT: unassigned */
+ AEL2020_GPIO_LSTAT = AEL2020_GPIO_1, /* wired to link status LED */
};
enum { edc_none, edc_sr, edc_twinax };
/* PHY module I2C device address */
-#define MODULE_DEV_ADDR 0xa0
+enum {
+ MODULE_DEV_ADDR = 0xa0,
+ SFF_DEV_ADDR = 0xa2,
+};
+
+/* PHY transceiver type */
+enum {
+ phy_transtype_unknown = 0,
+ phy_transtype_sfp = 3,
+ phy_transtype_xfp = 6,
+};
#define AEL2005_MODDET_IRQ 4
@@ -74,8 +87,8 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
for (err = 0; rv->mmd_addr && !err; rv++) {
if (rv->clear_bits == 0xffff)
- err = mdio_write(phy, rv->mmd_addr, rv->reg_addr,
- rv->set_bits);
+ err = t3_mdio_write(phy, rv->mmd_addr, rv->reg_addr,
+ rv->set_bits);
else
err = t3_mdio_change_bits(phy, rv->mmd_addr,
rv->reg_addr, rv->clear_bits,
@@ -86,21 +99,54 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
static void ael100x_txon(struct cphy *phy)
{
- int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
+ int tx_on_gpio =
+ phy->mdio.prtad == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
msleep(100);
t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio);
msleep(30);
}
+/*
+ * Read an 8-bit word from a device attached to the PHY's i2c bus.
+ */
+static int ael_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
+{
+ int i, err;
+ unsigned int stat, data;
+
+ err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL_I2C_CTRL,
+ (dev_addr << 8) | (1 << 8) | word_addr);
+ if (err)
+ return err;
+
+ for (i = 0; i < 200; i++) {
+ msleep(1);
+ err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_STAT, &stat);
+ if (err)
+ return err;
+ if ((stat & 3) == 1) {
+ err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_DATA,
+ &data);
+ if (err)
+ return err;
+ return data >> 8;
+ }
+ }
+ CH_WARN(phy->adapter, "PHY %u i2c read of dev.addr %#x.%#x timed out\n",
+ phy->mdio.prtad, dev_addr, word_addr);
+ return -ETIMEDOUT;
+}
+
static int ael1002_power_down(struct cphy *phy, int enable)
{
int err;
- err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable);
+ err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS, !!enable);
if (!err)
- err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
- BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
+ err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
+ MDIO_MMD_PMAPMD, MDIO_CTRL1,
+ MDIO_CTRL1_LPOWER, enable);
return err;
}
@@ -109,11 +155,11 @@ static int ael1002_reset(struct cphy *phy, int wait)
int err;
if ((err = ael1002_power_down(phy, 0)) ||
- (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) ||
- (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) ||
- (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) ||
- (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) ||
- (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN,
+ (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL100X_TX_CONFIG1, 1)) ||
+ (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_HI, 0)) ||
+ (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_LO, 0)) ||
+ (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_XFI_EQL, 0x18)) ||
+ (err = t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL1002_LB_EN,
0, 1 << 5)))
return err;
return 0;
@@ -132,12 +178,15 @@ static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed,
{
if (link_ok) {
unsigned int stat0, stat1, stat2;
- int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
+ int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD,
+ MDIO_PMA_RXDET, &stat0);
if (!err)
- err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1);
+ err = t3_mdio_read(phy, MDIO_MMD_PCS,
+ MDIO_PCS_10GBRT_STAT1, &stat1);
if (!err)
- err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
+ err = t3_mdio_read(phy, MDIO_MMD_PHYXS,
+ MDIO_PHYXS_LNSTAT, &stat2);
if (err)
return err;
*link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1;
@@ -157,6 +206,7 @@ static struct cphy_ops ael1002_ops = {
.intr_handler = ael1002_intr_noop,
.get_link_status = get_link_status_r,
.power_down = ael1002_power_down,
+ .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
};
int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter,
@@ -171,13 +221,13 @@ int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter,
static int ael1006_reset(struct cphy *phy, int wait)
{
- return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
+ return t3_phy_reset(phy, MDIO_MMD_PMAPMD, wait);
}
static int ael1006_power_down(struct cphy *phy, int enable)
{
- return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
- BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
+ return mdio_set_flag(&phy->mdio, phy->mdio.prtad, MDIO_MMD_PMAPMD,
+ MDIO_CTRL1, MDIO_CTRL1_LPOWER, enable);
}
static struct cphy_ops ael1006_ops = {
@@ -188,6 +238,7 @@ static struct cphy_ops ael1006_ops = {
.intr_handler = t3_phy_lasi_intr_handler,
.get_link_status = get_link_status_r,
.power_down = ael1006_power_down,
+ .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
};
int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
@@ -200,12 +251,57 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
return 0;
}
+/*
+ * Decode our module type.
+ */
+static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms)
+{
+ int v;
+
+ if (delay_ms)
+ msleep(delay_ms);
+
+ /* see SFF-8472 for below */
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 3);
+ if (v < 0)
+ return v;
+
+ if (v == 0x10)
+ return phy_modtype_sr;
+ if (v == 0x20)
+ return phy_modtype_lr;
+ if (v == 0x40)
+ return phy_modtype_lrm;
+
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6);
+ if (v < 0)
+ return v;
+ if (v != 4)
+ goto unknown;
+
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 10);
+ if (v < 0)
+ return v;
+
+ if (v & 0x80) {
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
+ if (v < 0)
+ return v;
+ return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax;
+ }
+unknown:
+ return phy_modtype_unknown;
+}
+
+/*
+ * Code to support the Aeluros/NetLogic 2005 10Gb PHY.
+ */
static int ael2005_setup_sr_edc(struct cphy *phy)
{
static struct reg_val regs[] = {
- { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 },
- { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a },
- { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 },
+ { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x181 },
+ { MDIO_MMD_PMAPMD, 0xc010, 0xffff, 0x448a },
+ { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 },
{ 0, 0, 0, 0 }
};
static u16 sr_edc[] = {
@@ -490,8 +586,8 @@ static int ael2005_setup_sr_edc(struct cphy *phy)
msleep(50);
for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2)
- err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i],
- sr_edc[i + 1]);
+ err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, sr_edc[i],
+ sr_edc[i + 1]);
if (!err)
phy->priv = edc_sr;
return err;
@@ -500,12 +596,12 @@ static int ael2005_setup_sr_edc(struct cphy *phy)
static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
{
static struct reg_val regs[] = {
- { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 },
+ { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5a00 },
{ 0, 0, 0, 0 }
};
static struct reg_val preemphasis[] = {
- { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 },
- { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 },
+ { MDIO_MMD_PMAPMD, 0xc014, 0xffff, 0xfe16 },
+ { MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 },
{ 0, 0, 0, 0 }
};
static u16 twinax_edc[] = {
@@ -887,132 +983,73 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
msleep(50);
for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
- err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i],
- twinax_edc[i + 1]);
+ err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i],
+ twinax_edc[i + 1]);
if (!err)
phy->priv = edc_twinax;
return err;
}
-static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
-{
- int i, err;
- unsigned int stat, data;
-
- err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
- (dev_addr << 8) | (1 << 8) | word_addr);
- if (err)
- return err;
-
- for (i = 0; i < 5; i++) {
- msleep(1);
- err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
- if (err)
- return err;
- if ((stat & 3) == 1) {
- err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA,
- &data);
- if (err)
- return err;
- return data >> 8;
- }
- }
- CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n",
- phy->addr, word_addr);
- return -ETIMEDOUT;
-}
-
-static int get_module_type(struct cphy *phy, int delay_ms)
+static int ael2005_get_module_type(struct cphy *phy, int delay_ms)
{
int v;
unsigned int stat;
- v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat);
+ v = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, &stat);
if (v)
return v;
if (stat & (1 << 8)) /* module absent */
return phy_modtype_none;
- if (delay_ms)
- msleep(delay_ms);
-
- /* see SFF-8472 for below */
- v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 3);
- if (v < 0)
- return v;
-
- if (v == 0x10)
- return phy_modtype_sr;
- if (v == 0x20)
- return phy_modtype_lr;
- if (v == 0x40)
- return phy_modtype_lrm;
-
- v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 6);
- if (v < 0)
- return v;
- if (v != 4)
- goto unknown;
-
- v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 10);
- if (v < 0)
- return v;
-
- if (v & 0x80) {
- v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
- if (v < 0)
- return v;
- return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax;
- }
-unknown:
- return phy_modtype_unknown;
+ return ael2xxx_get_module_type(phy, delay_ms);
}
static int ael2005_intr_enable(struct cphy *phy)
{
- int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200);
+ int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x200);
return err ? err : t3_phy_lasi_intr_enable(phy);
}
static int ael2005_intr_disable(struct cphy *phy)
{
- int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100);
+ int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x100);
return err ? err : t3_phy_lasi_intr_disable(phy);
}
static int ael2005_intr_clear(struct cphy *phy)
{
- int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00);
+ int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0xd00);
return err ? err : t3_phy_lasi_intr_clear(phy);
}
static int ael2005_reset(struct cphy *phy, int wait)
{
static struct reg_val regs0[] = {
- { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 },
- { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 },
- { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 },
- { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
- { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 },
- { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
- { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 },
+ { MDIO_MMD_PMAPMD, 0xc001, 0, 1 << 5 },
+ { MDIO_MMD_PMAPMD, 0xc017, 0, 1 << 5 },
+ { MDIO_MMD_PMAPMD, 0xc013, 0xffff, 0xf341 },
+ { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 },
+ { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8100 },
+ { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 },
+ { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0 },
{ 0, 0, 0, 0 }
};
static struct reg_val regs1[] = {
- { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 },
- { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 },
+ { MDIO_MMD_PMAPMD, 0xca00, 0xffff, 0x0080 },
+ { MDIO_MMD_PMAPMD, 0xca12, 0xffff, 0 },
{ 0, 0, 0, 0 }
};
int err;
unsigned int lasi_ctrl;
- err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
+ err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL,
+ &lasi_ctrl);
if (err)
return err;
- err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0);
+ err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 0);
if (err)
return err;
@@ -1024,7 +1061,7 @@ static int ael2005_reset(struct cphy *phy, int wait)
msleep(50);
- err = get_module_type(phy, 0);
+ err = ael2005_get_module_type(phy, 0);
if (err < 0)
return err;
phy->modtype = err;
@@ -1051,18 +1088,18 @@ static int ael2005_intr_handler(struct cphy *phy)
unsigned int stat;
int ret, edc_needed, cause = 0;
- ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat);
+ ret = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_STAT, &stat);
if (ret)
return ret;
if (stat & AEL2005_MODDET_IRQ) {
- ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL,
- 0xd00);
+ ret = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL,
+ 0xd00);
if (ret)
return ret;
/* modules have max 300 ms init time after hot plug */
- ret = get_module_type(phy, 300);
+ ret = ael2005_get_module_type(phy, 300);
if (ret < 0)
return ret;
@@ -1098,6 +1135,7 @@ static struct cphy_ops ael2005_ops = {
.intr_handler = ael2005_intr_handler,
.get_link_status = get_link_status_r,
.power_down = ael1002_power_down,
+ .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
};
int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
@@ -1107,11 +1145,667 @@ int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
SUPPORTED_IRQ, "10GBASE-R");
msleep(125);
- return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0,
+ return t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS, 0,
1 << 5);
}
/*
+ * Setup EDC and other parameters for operation with an optical module.
+ */
+static int ael2020_setup_sr_edc(struct cphy *phy)
+{
+ static struct reg_val regs[] = {
+ /* set CDR offset to 10 */
+ { MDIO_MMD_PMAPMD, 0xcc01, 0xffff, 0x488a },
+
+ /* adjust 10G RX bias current */
+ { MDIO_MMD_PMAPMD, 0xcb1b, 0xffff, 0x0200 },
+ { MDIO_MMD_PMAPMD, 0xcb1c, 0xffff, 0x00f0 },
+ { MDIO_MMD_PMAPMD, 0xcc06, 0xffff, 0x00e0 },
+
+ /* end */
+ { 0, 0, 0, 0 }
+ };
+ int err;
+
+ err = set_phy_regs(phy, regs);
+ msleep(50);
+ if (err)
+ return err;
+
+ phy->priv = edc_sr;
+ return 0;
+}
+
+/*
+ * Setup EDC and other parameters for operation with an TWINAX module.
+ */
+static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
+{
+ /* set uC to 40MHz */
+ static struct reg_val uCclock40MHz[] = {
+ { MDIO_MMD_PMAPMD, 0xff28, 0xffff, 0x4001 },
+ { MDIO_MMD_PMAPMD, 0xff2a, 0xffff, 0x0002 },
+ { 0, 0, 0, 0 }
+ };
+
+ /* activate uC clock */
+ static struct reg_val uCclockActivate[] = {
+ { MDIO_MMD_PMAPMD, 0xd000, 0xffff, 0x5200 },
+ { 0, 0, 0, 0 }
+ };
+
+ /* set PC to start of SRAM and activate uC */
+ static struct reg_val uCactivate[] = {
+ { MDIO_MMD_PMAPMD, 0xd080, 0xffff, 0x0100 },
+ { MDIO_MMD_PMAPMD, 0xd092, 0xffff, 0x0000 },
+ { 0, 0, 0, 0 }
+ };
+
+ /* TWINAX EDC firmware */
+ static u16 twinax_edc[] = {
+ 0xd800, 0x4009,
+ 0xd801, 0x2fff,
+ 0xd802, 0x300f,
+ 0xd803, 0x40aa,
+ 0xd804, 0x401c,
+ 0xd805, 0x401e,
+ 0xd806, 0x2ff4,
+ 0xd807, 0x3dc4,
+ 0xd808, 0x2035,
+ 0xd809, 0x3035,
+ 0xd80a, 0x6524,
+ 0xd80b, 0x2cb2,
+ 0xd80c, 0x3012,
+ 0xd80d, 0x1002,
+ 0xd80e, 0x26e2,
+ 0xd80f, 0x3022,
+ 0xd810, 0x1002,
+ 0xd811, 0x27d2,
+ 0xd812, 0x3022,
+ 0xd813, 0x1002,
+ 0xd814, 0x2822,
+ 0xd815, 0x3012,
+ 0xd816, 0x1002,
+ 0xd817, 0x2492,
+ 0xd818, 0x3022,
+ 0xd819, 0x1002,
+ 0xd81a, 0x2772,
+ 0xd81b, 0x3012,
+ 0xd81c, 0x1002,
+ 0xd81d, 0x23d2,
+ 0xd81e, 0x3022,
+ 0xd81f, 0x1002,
+ 0xd820, 0x22cd,
+ 0xd821, 0x301d,
+ 0xd822, 0x27f2,
+ 0xd823, 0x3022,
+ 0xd824, 0x1002,
+ 0xd825, 0x5553,
+ 0xd826, 0x0307,
+ 0xd827, 0x2522,
+ 0xd828, 0x3022,
+ 0xd829, 0x1002,
+ 0xd82a, 0x2142,
+ 0xd82b, 0x3012,
+ 0xd82c, 0x1002,
+ 0xd82d, 0x4016,
+ 0xd82e, 0x5e63,
+ 0xd82f, 0x0344,
+ 0xd830, 0x2142,
+ 0xd831, 0x3012,
+ 0xd832, 0x1002,
+ 0xd833, 0x400e,
+ 0xd834, 0x2522,
+ 0xd835, 0x3022,
+ 0xd836, 0x1002,
+ 0xd837, 0x2b52,
+ 0xd838, 0x3012,
+ 0xd839, 0x1002,
+ 0xd83a, 0x2742,
+ 0xd83b, 0x3022,
+ 0xd83c, 0x1002,
+ 0xd83d, 0x25e2,
+ 0xd83e, 0x3022,
+ 0xd83f, 0x1002,
+ 0xd840, 0x2fa4,
+ 0xd841, 0x3dc4,
+ 0xd842, 0x6624,
+ 0xd843, 0x414b,
+ 0xd844, 0x56b3,
+ 0xd845, 0x03c6,
+ 0xd846, 0x866b,
+ 0xd847, 0x400c,
+ 0xd848, 0x2712,
+ 0xd849, 0x3012,
+ 0xd84a, 0x1002,
+ 0xd84b, 0x2c4b,
+ 0xd84c, 0x309b,
+ 0xd84d, 0x56b3,
+ 0xd84e, 0x03c3,
+ 0xd84f, 0x866b,
+ 0xd850, 0x400c,
+ 0xd851, 0x2272,
+ 0xd852, 0x3022,
+ 0xd853, 0x1002,
+ 0xd854, 0x2742,
+ 0xd855, 0x3022,
+ 0xd856, 0x1002,
+ 0xd857, 0x25e2,
+ 0xd858, 0x3022,
+ 0xd859, 0x1002,
+ 0xd85a, 0x2fb4,
+ 0xd85b, 0x3dc4,
+ 0xd85c, 0x6624,
+ 0xd85d, 0x56b3,
+ 0xd85e, 0x03c3,
+ 0xd85f, 0x866b,
+ 0xd860, 0x401c,
+ 0xd861, 0x2c45,
+ 0xd862, 0x3095,
+ 0xd863, 0x5b53,
+ 0xd864, 0x2372,
+ 0xd865, 0x3012,
+ 0xd866, 0x13c2,
+ 0xd867, 0x5cc3,
+ 0xd868, 0x2712,
+ 0xd869, 0x3012,
+ 0xd86a, 0x1312,
+ 0xd86b, 0x2b52,
+ 0xd86c, 0x3012,
+ 0xd86d, 0x1002,
+ 0xd86e, 0x2742,
+ 0xd86f, 0x3022,
+ 0xd870, 0x1002,
+ 0xd871, 0x2582,
+ 0xd872, 0x3022,
+ 0xd873, 0x1002,
+ 0xd874, 0x2142,
+ 0xd875, 0x3012,
+ 0xd876, 0x1002,
+ 0xd877, 0x628f,
+ 0xd878, 0x2985,
+ 0xd879, 0x33a5,
+ 0xd87a, 0x25e2,
+ 0xd87b, 0x3022,
+ 0xd87c, 0x1002,
+ 0xd87d, 0x5653,
+ 0xd87e, 0x03d2,
+ 0xd87f, 0x401e,
+ 0xd880, 0x6f72,
+ 0xd881, 0x1002,
+ 0xd882, 0x628f,
+ 0xd883, 0x2304,
+ 0xd884, 0x3c84,
+ 0xd885, 0x6436,
+ 0xd886, 0xdff4,
+ 0xd887, 0x6436,
+ 0xd888, 0x2ff5,
+ 0xd889, 0x3005,
+ 0xd88a, 0x8656,
+ 0xd88b, 0xdfba,
+ 0xd88c, 0x56a3,
+ 0xd88d, 0xd05a,
+ 0xd88e, 0x2972,
+ 0xd88f, 0x3012,
+ 0xd890, 0x1392,
+ 0xd891, 0xd05a,
+ 0xd892, 0x56a3,
+ 0xd893, 0xdfba,
+ 0xd894, 0x0383,
+ 0xd895, 0x6f72,
+ 0xd896, 0x1002,
+ 0xd897, 0x2b45,
+ 0xd898, 0x3005,
+ 0xd899, 0x4178,
+ 0xd89a, 0x5653,
+ 0xd89b, 0x0384,
+ 0xd89c, 0x2a62,
+ 0xd89d, 0x3012,
+ 0xd89e, 0x1002,
+ 0xd89f, 0x2f05,
+ 0xd8a0, 0x3005,
+ 0xd8a1, 0x41c8,
+ 0xd8a2, 0x5653,
+ 0xd8a3, 0x0382,
+ 0xd8a4, 0x0002,
+ 0xd8a5, 0x4218,
+ 0xd8a6, 0x2474,
+ 0xd8a7, 0x3c84,
+ 0xd8a8, 0x6437,
+ 0xd8a9, 0xdff4,
+ 0xd8aa, 0x6437,
+ 0xd8ab, 0x2ff5,
+ 0xd8ac, 0x3c05,
+ 0xd8ad, 0x8757,
+ 0xd8ae, 0xb888,
+ 0xd8af, 0x9787,
+ 0xd8b0, 0xdff4,
+ 0xd8b1, 0x6724,
+ 0xd8b2, 0x866a,
+ 0xd8b3, 0x6f72,
+ 0xd8b4, 0x1002,
+ 0xd8b5, 0x2641,
+ 0xd8b6, 0x3021,
+ 0xd8b7, 0x1001,
+ 0xd8b8, 0xc620,
+ 0xd8b9, 0x0000,
+ 0xd8ba, 0xc621,
+ 0xd8bb, 0x0000,
+ 0xd8bc, 0xc622,
+ 0xd8bd, 0x00ce,
+ 0xd8be, 0xc623,
+ 0xd8bf, 0x007f,
+ 0xd8c0, 0xc624,
+ 0xd8c1, 0x0032,
+ 0xd8c2, 0xc625,
+ 0xd8c3, 0x0000,
+ 0xd8c4, 0xc627,
+ 0xd8c5, 0x0000,
+ 0xd8c6, 0xc628,
+ 0xd8c7, 0x0000,
+ 0xd8c8, 0xc62c,
+ 0xd8c9, 0x0000,
+ 0xd8ca, 0x0000,
+ 0xd8cb, 0x2641,
+ 0xd8cc, 0x3021,
+ 0xd8cd, 0x1001,
+ 0xd8ce, 0xc502,
+ 0xd8cf, 0x53ac,
+ 0xd8d0, 0xc503,
+ 0xd8d1, 0x2cd3,
+ 0xd8d2, 0xc600,
+ 0xd8d3, 0x2a6e,
+ 0xd8d4, 0xc601,
+ 0xd8d5, 0x2a2c,
+ 0xd8d6, 0xc605,
+ 0xd8d7, 0x5557,
+ 0xd8d8, 0xc60c,
+ 0xd8d9, 0x5400,
+ 0xd8da, 0xc710,
+ 0xd8db, 0x0700,
+ 0xd8dc, 0xc711,
+ 0xd8dd, 0x0f06,
+ 0xd8de, 0xc718,
+ 0xd8df, 0x0700,
+ 0xd8e0, 0xc719,
+ 0xd8e1, 0x0f06,
+ 0xd8e2, 0xc720,
+ 0xd8e3, 0x4700,
+ 0xd8e4, 0xc721,
+ 0xd8e5, 0x0f06,
+ 0xd8e6, 0xc728,
+ 0xd8e7, 0x0700,
+ 0xd8e8, 0xc729,
+ 0xd8e9, 0x1207,
+ 0xd8ea, 0xc801,
+ 0xd8eb, 0x7f50,
+ 0xd8ec, 0xc802,
+ 0xd8ed, 0x7760,
+ 0xd8ee, 0xc803,
+ 0xd8ef, 0x7fce,
+ 0xd8f0, 0xc804,
+ 0xd8f1, 0x520e,
+ 0xd8f2, 0xc805,
+ 0xd8f3, 0x5c11,
+ 0xd8f4, 0xc806,
+ 0xd8f5, 0x3c51,
+ 0xd8f6, 0xc807,
+ 0xd8f7, 0x4061,
+ 0xd8f8, 0xc808,
+ 0xd8f9, 0x49c1,
+ 0xd8fa, 0xc809,
+ 0xd8fb, 0x3840,
+ 0xd8fc, 0xc80a,
+ 0xd8fd, 0x0000,
+ 0xd8fe, 0xc821,
+ 0xd8ff, 0x0002,
+ 0xd900, 0xc822,
+ 0xd901, 0x0046,
+ 0xd902, 0xc844,
+ 0xd903, 0x182f,
+ 0xd904, 0xc013,
+ 0xd905, 0xf341,
+ 0xd906, 0xc084,
+ 0xd907, 0x0030,
+ 0xd908, 0xc904,
+ 0xd909, 0x1401,
+ 0xd90a, 0xcb0c,
+ 0xd90b, 0x0004,
+ 0xd90c, 0xcb0e,
+ 0xd90d, 0xa00a,
+ 0xd90e, 0xcb0f,
+ 0xd90f, 0xc0c0,
+ 0xd910, 0xcb10,
+ 0xd911, 0xc0c0,
+ 0xd912, 0xcb11,
+ 0xd913, 0x00a0,
+ 0xd914, 0xcb12,
+ 0xd915, 0x0007,
+ 0xd916, 0xc241,
+ 0xd917, 0xa000,
+ 0xd918, 0xc243,
+ 0xd919, 0x7fe0,
+ 0xd91a, 0xc604,
+ 0xd91b, 0x000e,
+ 0xd91c, 0xc609,
+ 0xd91d, 0x00f5,
+ 0xd91e, 0xc611,
+ 0xd91f, 0x000e,
+ 0xd920, 0xc660,
+ 0xd921, 0x9600,
+ 0xd922, 0xc687,
+ 0xd923, 0x0004,
+ 0xd924, 0xc60a,
+ 0xd925, 0x04f5,
+ 0xd926, 0x0000,
+ 0xd927, 0x2641,
+ 0xd928, 0x3021,
+ 0xd929, 0x1001,
+ 0xd92a, 0xc620,
+ 0xd92b, 0x14e5,
+ 0xd92c, 0xc621,
+ 0xd92d, 0xc53d,
+ 0xd92e, 0xc622,
+ 0xd92f, 0x3cbe,
+ 0xd930, 0xc623,
+ 0xd931, 0x4452,
+ 0xd932, 0xc624,
+ 0xd933, 0xc5c5,
+ 0xd934, 0xc625,
+ 0xd935, 0xe01e,
+ 0xd936, 0xc627,
+ 0xd937, 0x0000,
+ 0xd938, 0xc628,
+ 0xd939, 0x0000,
+ 0xd93a, 0xc62c,
+ 0xd93b, 0x0000,
+ 0xd93c, 0x0000,
+ 0xd93d, 0x2b84,
+ 0xd93e, 0x3c74,
+ 0xd93f, 0x6435,
+ 0xd940, 0xdff4,
+ 0xd941, 0x6435,
+ 0xd942, 0x2806,
+ 0xd943, 0x3006,
+ 0xd944, 0x8565,
+ 0xd945, 0x2b24,
+ 0xd946, 0x3c24,
+ 0xd947, 0x6436,
+ 0xd948, 0x1002,
+ 0xd949, 0x2b24,
+ 0xd94a, 0x3c24,
+ 0xd94b, 0x6436,
+ 0xd94c, 0x4045,
+ 0xd94d, 0x8656,
+ 0xd94e, 0x5663,
+ 0xd94f, 0x0302,
+ 0xd950, 0x401e,
+ 0xd951, 0x1002,
+ 0xd952, 0x2807,
+ 0xd953, 0x31a7,
+ 0xd954, 0x20c4,
+ 0xd955, 0x3c24,
+ 0xd956, 0x6724,
+ 0xd957, 0x1002,
+ 0xd958, 0x2807,
+ 0xd959, 0x3187,
+ 0xd95a, 0x20c4,
+ 0xd95b, 0x3c24,
+ 0xd95c, 0x6724,
+ 0xd95d, 0x1002,
+ 0xd95e, 0x24f4,
+ 0xd95f, 0x3c64,
+ 0xd960, 0x6436,
+ 0xd961, 0xdff4,
+ 0xd962, 0x6436,
+ 0xd963, 0x1002,
+ 0xd964, 0x2006,
+ 0xd965, 0x3d76,
+ 0xd966, 0xc161,
+ 0xd967, 0x6134,
+ 0xd968, 0x6135,
+ 0xd969, 0x5443,
+ 0xd96a, 0x0303,
+ 0xd96b, 0x6524,
+ 0xd96c, 0x00fb,
+ 0xd96d, 0x1002,
+ 0xd96e, 0x20d4,
+ 0xd96f, 0x3c24,
+ 0xd970, 0x2025,
+ 0xd971, 0x3005,
+ 0xd972, 0x6524,
+ 0xd973, 0x1002,
+ 0xd974, 0xd019,
+ 0xd975, 0x2104,
+ 0xd976, 0x3c24,
+ 0xd977, 0x2105,
+ 0xd978, 0x3805,
+ 0xd979, 0x6524,
+ 0xd97a, 0xdff4,
+ 0xd97b, 0x4005,
+ 0xd97c, 0x6524,
+ 0xd97d, 0x2e8d,
+ 0xd97e, 0x303d,
+ 0xd97f, 0x2408,
+ 0xd980, 0x35d8,
+ 0xd981, 0x5dd3,
+ 0xd982, 0x0307,
+ 0xd983, 0x8887,
+ 0xd984, 0x63a7,
+ 0xd985, 0x8887,
+ 0xd986, 0x63a7,
+ 0xd987, 0xdffd,
+ 0xd988, 0x00f9,
+ 0xd989, 0x1002,
+ 0xd98a, 0x0000,
+ };
+ int i, err;
+
+ /* set uC clock and activate it */
+ err = set_phy_regs(phy, uCclock40MHz);
+ msleep(500);
+ if (err)
+ return err;
+ err = set_phy_regs(phy, uCclockActivate);
+ msleep(500);
+ if (err)
+ return err;
+
+ /* write TWINAX EDC firmware into PHY */
+ for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
+ err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i],
+ twinax_edc[i + 1]);
+ /* activate uC */
+ err = set_phy_regs(phy, uCactivate);
+ if (!err)
+ phy->priv = edc_twinax;
+ return err;
+}
+
+/*
+ * Return Module Type.
+ */
+static int ael2020_get_module_type(struct cphy *phy, int delay_ms)
+{
+ int v;
+ unsigned int stat;
+
+ v = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_STAT, &stat);
+ if (v)
+ return v;
+
+ if (stat & (0x1 << (AEL2020_GPIO_MODDET*4))) {
+ /* module absent */
+ return phy_modtype_none;
+ }
+
+ return ael2xxx_get_module_type(phy, delay_ms);
+}
+
+/*
+ * Enable PHY interrupts. We enable "Module Detection" interrupts (on any
+ * state transition) and then generic Link Alarm Status Interrupt (LASI).
+ */
+static int ael2020_intr_enable(struct cphy *phy)
+{
+ int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
+ 0x2 << (AEL2020_GPIO_MODDET*4));
+ return err ? err : t3_phy_lasi_intr_enable(phy);
+}
+
+/*
+ * Disable PHY interrupts. The mirror of the above ...
+ */
+static int ael2020_intr_disable(struct cphy *phy)
+{
+ int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
+ 0x1 << (AEL2020_GPIO_MODDET*4));
+ return err ? err : t3_phy_lasi_intr_disable(phy);
+}
+
+/*
+ * Clear PHY interrupt state.
+ */
+static int ael2020_intr_clear(struct cphy *phy)
+{
+ /*
+ * The GPIO Interrupt register on the AEL2020 is a "Latching High"
+ * (LH) register which is cleared to the current state when it's read.
+ * Thus, we simply read the register and discard the result.
+ */
+ unsigned int stat;
+ int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_INTR, &stat);
+ return err ? err : t3_phy_lasi_intr_clear(phy);
+}
+
+/*
+ * Reset the PHY and put it into a canonical operating state.
+ */
+static int ael2020_reset(struct cphy *phy, int wait)
+{
+ static struct reg_val regs0[] = {
+ /* Erratum #2: CDRLOL asserted, causing PMA link down status */
+ { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x3101 },
+
+ /* force XAUI to send LF when RX_LOS is asserted */
+ { MDIO_MMD_PMAPMD, 0xcd40, 0xffff, 0x0001 },
+
+ /* RX_LOS pin is active high */
+ { MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS,
+ 0x0020, 0x0020 },
+
+ /* output Module's Loss Of Signal (LOS) to LED */
+ { MDIO_MMD_PMAPMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT,
+ 0xffff, 0x0004 },
+ { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
+ 0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) },
+
+ /* end */
+ { 0, 0, 0, 0 }
+ };
+ int err;
+ unsigned int lasi_ctrl;
+
+ /* grab current interrupt state */
+ err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL,
+ &lasi_ctrl);
+ if (err)
+ return err;
+
+ err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 125);
+ if (err)
+ return err;
+ msleep(100);
+
+ /* basic initialization for all module types */
+ phy->priv = edc_none;
+ err = set_phy_regs(phy, regs0);
+ if (err)
+ return err;
+
+ /* determine module type and perform appropriate initialization */
+ err = ael2020_get_module_type(phy, 0);
+ if (err < 0)
+ return err;
+ phy->modtype = (u8)err;
+ if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
+ err = ael2020_setup_twinax_edc(phy, err);
+ else
+ err = ael2020_setup_sr_edc(phy);
+ if (err)
+ return err;
+
+ /* reset wipes out interrupts, reenable them if they were on */
+ if (lasi_ctrl & 1)
+ err = ael2005_intr_enable(phy);
+ return err;
+}
+
+/*
+ * Handle a PHY interrupt.
+ */
+static int ael2020_intr_handler(struct cphy *phy)
+{
+ unsigned int stat;
+ int ret, edc_needed, cause = 0;
+
+ ret = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_INTR, &stat);
+ if (ret)
+ return ret;
+
+ if (stat & (0x1 << AEL2020_GPIO_MODDET)) {
+ /* modules have max 300 ms init time after hot plug */
+ ret = ael2020_get_module_type(phy, 300);
+ if (ret < 0)
+ return ret;
+
+ phy->modtype = (u8)ret;
+ if (ret == phy_modtype_none)
+ edc_needed = phy->priv; /* on unplug retain EDC */
+ else if (ret == phy_modtype_twinax ||
+ ret == phy_modtype_twinax_long)
+ edc_needed = edc_twinax;
+ else
+ edc_needed = edc_sr;
+
+ if (edc_needed != phy->priv) {
+ ret = ael2020_reset(phy, 0);
+ return ret ? ret : cphy_cause_module_change;
+ }
+ cause = cphy_cause_module_change;
+ }
+
+ ret = t3_phy_lasi_intr_handler(phy);
+ if (ret < 0)
+ return ret;
+
+ ret |= cause;
+ return ret ? ret : cphy_cause_link_change;
+}
+
+static struct cphy_ops ael2020_ops = {
+ .reset = ael2020_reset,
+ .intr_enable = ael2020_intr_enable,
+ .intr_disable = ael2020_intr_disable,
+ .intr_clear = ael2020_intr_clear,
+ .intr_handler = ael2020_intr_handler,
+ .get_link_status = get_link_status_r,
+ .power_down = ael1002_power_down,
+ .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
+};
+
+int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
+ const struct mdio_ops *mdio_ops)
+{
+ cphy_init(phy, adapter, phy_addr, &ael2020_ops, mdio_ops,
+ SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
+ SUPPORTED_IRQ, "10GBASE-R");
+ msleep(125);
+ return 0;
+}
+
+/*
* Get link status for a 10GBASE-X device.
*/
static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed,
@@ -1119,12 +1813,15 @@ static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed,
{
if (link_ok) {
unsigned int stat0, stat1, stat2;
- int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
+ int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD,
+ MDIO_PMA_RXDET, &stat0);
if (!err)
- err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1);
+ err = t3_mdio_read(phy, MDIO_MMD_PCS,
+ MDIO_PCS_10GBX_STAT1, &stat1);
if (!err)
- err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
+ err = t3_mdio_read(phy, MDIO_MMD_PHYXS,
+ MDIO_PHYXS_LNSTAT, &stat2);
if (err)
return err;
*link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1;
@@ -1144,6 +1841,7 @@ static struct cphy_ops qt2045_ops = {
.intr_handler = t3_phy_lasi_intr_handler,
.get_link_status = get_link_status_x,
.power_down = ael1006_power_down,
+ .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
};
int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter,
@@ -1159,9 +1857,10 @@ int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter,
* Some cards where the PHY is supposed to be at address 0 actually
* have it at 1.
*/
- if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) &&
+ if (!phy_addr &&
+ !t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &stat) &&
stat == 0xffff)
- phy->addr = 1;
+ phy->mdio.prtad = 1;
return 0;
}
@@ -1175,15 +1874,16 @@ static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
{
if (link_ok) {
unsigned int status;
+ int prtad = phy->mdio.prtad;
status = t3_read_reg(phy->adapter,
- XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
+ XGM_REG(A_XGM_SERDES_STAT0, prtad)) |
t3_read_reg(phy->adapter,
- XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) |
+ XGM_REG(A_XGM_SERDES_STAT1, prtad)) |
t3_read_reg(phy->adapter,
- XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) |
+ XGM_REG(A_XGM_SERDES_STAT2, prtad)) |
t3_read_reg(phy->adapter,
- XGM_REG(A_XGM_SERDES_STAT3, phy->addr));
+ XGM_REG(A_XGM_SERDES_STAT3, prtad));
*link_ok = !(status & F_LOWSIG0);
}
if (speed)
@@ -1211,7 +1911,7 @@ static struct cphy_ops xaui_direct_ops = {
int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
int phy_addr, const struct mdio_ops *mdio_ops)
{
- cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops,
+ cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops,
SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
"10GBASE-CX4");
return 0;
diff --git a/drivers/net/cxgb3/aq100x.c b/drivers/net/cxgb3/aq100x.c
new file mode 100644
index 00000000000..b1fd5bf836e
--- /dev/null
+++ b/drivers/net/cxgb3/aq100x.c
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "common.h"
+#include "regs.h"
+
+enum {
+ /* MDIO_DEV_PMA_PMD registers */
+ AQ_LINK_STAT = 0xe800,
+ AQ_IMASK_PMA = 0xf000,
+
+ /* MDIO_DEV_XGXS registers */
+ AQ_XAUI_RX_CFG = 0xc400,
+ AQ_XAUI_TX_CFG = 0xe400,
+
+ /* MDIO_DEV_ANEG registers */
+ AQ_1G_CTRL = 0xc400,
+ AQ_ANEG_STAT = 0xc800,
+
+ /* MDIO_DEV_VEND1 registers */
+ AQ_FW_VERSION = 0x0020,
+ AQ_IFLAG_GLOBAL = 0xfc00,
+ AQ_IMASK_GLOBAL = 0xff00,
+};
+
+enum {
+ IMASK_PMA = 1 << 2,
+ IMASK_GLOBAL = 1 << 15,
+ ADV_1G_FULL = 1 << 15,
+ ADV_1G_HALF = 1 << 14,
+ ADV_10G_FULL = 1 << 12,
+ AQ_RESET = (1 << 14) | (1 << 15),
+ AQ_LOWPOWER = 1 << 12,
+};
+
+static int aq100x_reset(struct cphy *phy, int wait)
+{
+ /*
+ * Ignore the caller specified wait time; always wait for the reset to
+ * complete. Can take up to 3s.
+ */
+ int err = t3_phy_reset(phy, MDIO_MMD_VEND1, 3000);
+
+ if (err)
+ CH_WARN(phy->adapter, "PHY%d: reset failed (0x%x).\n",
+ phy->mdio.prtad, err);
+
+ return err;
+}
+
+static int aq100x_intr_enable(struct cphy *phy)
+{
+ int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AQ_IMASK_PMA, IMASK_PMA);
+ if (err)
+ return err;
+
+ err = t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, IMASK_GLOBAL);
+ return err;
+}
+
+static int aq100x_intr_disable(struct cphy *phy)
+{
+ return t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, 0);
+}
+
+static int aq100x_intr_clear(struct cphy *phy)
+{
+ unsigned int v;
+
+ t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &v);
+ t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v);
+
+ return 0;
+}
+
+static int aq100x_intr_handler(struct cphy *phy)
+{
+ int err;
+ unsigned int cause, v;
+
+ err = t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &cause);
+ if (err)
+ return err;
+
+ /* Read (and reset) the latching version of the status */
+ t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v);
+
+ return cphy_cause_link_change;
+}
+
+static int aq100x_power_down(struct cphy *phy, int off)
+{
+ return mdio_set_flag(&phy->mdio, phy->mdio.prtad,
+ MDIO_MMD_PMAPMD, MDIO_CTRL1,
+ MDIO_CTRL1_LPOWER, off);
+}
+
+static int aq100x_autoneg_enable(struct cphy *phy)
+{
+ int err;
+
+ err = aq100x_power_down(phy, 0);
+ if (!err)
+ err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
+ MDIO_MMD_AN, MDIO_CTRL1,
+ BMCR_ANENABLE | BMCR_ANRESTART, 1);
+
+ return err;
+}
+
+static int aq100x_autoneg_restart(struct cphy *phy)
+{
+ int err;
+
+ err = aq100x_power_down(phy, 0);
+ if (!err)
+ err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
+ MDIO_MMD_AN, MDIO_CTRL1,
+ BMCR_ANENABLE | BMCR_ANRESTART, 1);
+
+ return err;
+}
+
+static int aq100x_advertise(struct cphy *phy, unsigned int advertise_map)
+{
+ unsigned int adv;
+ int err;
+
+ /* 10G advertisement */
+ adv = 0;
+ if (advertise_map & ADVERTISED_10000baseT_Full)
+ adv |= ADV_10G_FULL;
+ err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
+ ADV_10G_FULL, adv);
+ if (err)
+ return err;
+
+ /* 1G advertisement */
+ adv = 0;
+ if (advertise_map & ADVERTISED_1000baseT_Full)
+ adv |= ADV_1G_FULL;
+ if (advertise_map & ADVERTISED_1000baseT_Half)
+ adv |= ADV_1G_HALF;
+ err = t3_mdio_change_bits(phy, MDIO_MMD_AN, AQ_1G_CTRL,
+ ADV_1G_FULL | ADV_1G_HALF, adv);
+ if (err)
+ return err;
+
+ /* 100M, pause advertisement */
+ adv = 0;
+ if (advertise_map & ADVERTISED_100baseT_Half)
+ adv |= ADVERTISE_100HALF;
+ if (advertise_map & ADVERTISED_100baseT_Full)
+ adv |= ADVERTISE_100FULL;
+ if (advertise_map & ADVERTISED_Pause)
+ adv |= ADVERTISE_PAUSE_CAP;
+ if (advertise_map & ADVERTISED_Asym_Pause)
+ adv |= ADVERTISE_PAUSE_ASYM;
+ err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_ADVERTISE,
+ 0xfe0, adv);
+
+ return err;
+}
+
+static int aq100x_set_loopback(struct cphy *phy, int mmd, int dir, int enable)
+{
+ return mdio_set_flag(&phy->mdio, phy->mdio.prtad,
+ MDIO_MMD_PMAPMD, MDIO_CTRL1,
+ BMCR_LOOPBACK, enable);
+}
+
+static int aq100x_set_speed_duplex(struct cphy *phy, int speed, int duplex)
+{
+ /* no can do */
+ return -1;
+}
+
+static int aq100x_get_link_status(struct cphy *phy, int *link_ok,
+ int *speed, int *duplex, int *fc)
+{
+ int err;
+ unsigned int v;
+
+ if (link_ok) {
+ err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AQ_LINK_STAT, &v);
+ if (err)
+ return err;
+
+ *link_ok = v & 1;
+ if (!*link_ok)
+ return 0;
+ }
+
+ err = t3_mdio_read(phy, MDIO_MMD_AN, AQ_ANEG_STAT, &v);
+ if (err)
+ return err;
+
+ if (speed) {
+ switch (v & 0x6) {
+ case 0x6:
+ *speed = SPEED_10000;
+ break;
+ case 0x4:
+ *speed = SPEED_1000;
+ break;
+ case 0x2:
+ *speed = SPEED_100;
+ break;
+ case 0x0:
+ *speed = SPEED_10;
+ break;
+ }
+ }
+
+ if (duplex)
+ *duplex = v & 1 ? DUPLEX_FULL : DUPLEX_HALF;
+
+ return 0;
+}
+
+static struct cphy_ops aq100x_ops = {
+ .reset = aq100x_reset,
+ .intr_enable = aq100x_intr_enable,
+ .intr_disable = aq100x_intr_disable,
+ .intr_clear = aq100x_intr_clear,
+ .intr_handler = aq100x_intr_handler,
+ .autoneg_enable = aq100x_autoneg_enable,
+ .autoneg_restart = aq100x_autoneg_restart,
+ .advertise = aq100x_advertise,
+ .set_loopback = aq100x_set_loopback,
+ .set_speed_duplex = aq100x_set_speed_duplex,
+ .get_link_status = aq100x_get_link_status,
+ .power_down = aq100x_power_down,
+ .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
+};
+
+int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
+ const struct mdio_ops *mdio_ops)
+{
+ unsigned int v, v2, gpio, wait;
+ int err;
+
+ cphy_init(phy, adapter, phy_addr, &aq100x_ops, mdio_ops,
+ SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full |
+ SUPPORTED_Autoneg | SUPPORTED_AUI, "1000/10GBASE-T");
+
+ /*
+ * The PHY has been out of reset ever since the system powered up. So
+ * we do a hard reset over here.
+ */
+ gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL;
+ t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0);
+ msleep(1);
+ t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio);
+
+ /*
+ * Give it enough time to load the firmware and get ready for mdio.
+ */
+ msleep(1000);
+ wait = 500; /* in 10ms increments */
+ do {
+ err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
+ if (err || v == 0xffff) {
+
+ /* Allow prep_adapter to succeed when ffff is read */
+
+ CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n",
+ phy_addr, err, v);
+ goto done;
+ }
+
+ v &= AQ_RESET;
+ if (v)
+ msleep(10);
+ } while (v && --wait);
+ if (v) {
+ CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n",
+ phy_addr, v);
+
+ goto done; /* let prep_adapter succeed */
+ }
+
+ /* Datasheet says 3s max but this has been observed */
+ wait = (500 - wait) * 10 + 1000;
+ if (wait > 3000)
+ CH_WARN(adapter, "PHY%d: reset took %ums\n", phy_addr, wait);
+
+ /* Firmware version check. */
+ t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_FW_VERSION, &v);
+ if (v != 30) {
+ CH_WARN(adapter, "PHY%d: unsupported firmware %d\n",
+ phy_addr, v);
+ return 0; /* allow t3_prep_adapter to succeed */
+ }
+
+ /*
+ * The PHY should start in really-low-power mode. Prepare it for normal
+ * operations.
+ */
+ err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
+ if (err)
+ return err;
+ if (v & AQ_LOWPOWER) {
+ err = t3_mdio_change_bits(phy, MDIO_MMD_VEND1, MDIO_CTRL1,
+ AQ_LOWPOWER, 0);
+ if (err)
+ return err;
+ msleep(10);
+ } else
+ CH_WARN(adapter, "PHY%d does not start in low power mode.\n",
+ phy_addr);
+
+ /*
+ * Verify XAUI settings, but let prep succeed no matter what.
+ */
+ v = v2 = 0;
+ t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_RX_CFG, &v);
+ t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_TX_CFG, &v2);
+ if (v != 0x1b || v2 != 0x1b)
+ CH_WARN(adapter,
+ "PHY%d: incorrect XAUI settings (0x%x, 0x%x).\n",
+ phy_addr, v, v2);
+
+done:
+ return err;
+}
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index e508dc32f3e..d21b705501a 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -39,7 +39,7 @@
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/ethtool.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
#include "version.h"
#define CH_ERR(adap, fmt, ...) dev_err(&adap->pdev->dev, fmt, ## __VA_ARGS__)
@@ -184,10 +184,11 @@ struct cphy;
struct adapter;
struct mdio_ops {
- int (*read)(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *val);
- int (*write)(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val);
+ int (*read)(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr);
+ int (*write)(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr, u16 val);
+ unsigned mode_support;
};
struct adapter_info {
@@ -520,27 +521,6 @@ enum {
MAC_RXFIFO_SIZE = 32768
};
-/* IEEE 802.3 specified MDIO devices */
-enum {
- MDIO_DEV_PMA_PMD = 1,
- MDIO_DEV_WIS = 2,
- MDIO_DEV_PCS = 3,
- MDIO_DEV_XGXS = 4,
- MDIO_DEV_ANEG = 7,
- MDIO_DEV_VEND1 = 30,
- MDIO_DEV_VEND2 = 31
-};
-
-/* LASI control and status registers */
-enum {
- RX_ALARM_CTRL = 0x9000,
- TX_ALARM_CTRL = 0x9001,
- LASI_CTRL = 0x9002,
- RX_ALARM_STAT = 0x9003,
- TX_ALARM_STAT = 0x9004,
- LASI_STAT = 0x9005
-};
-
/* PHY loopback direction */
enum {
PHY_LOOPBACK_TX = 1,
@@ -583,11 +563,12 @@ struct cphy_ops {
int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed,
int *duplex, int *fc);
int (*power_down)(struct cphy *phy, int enable);
+
+ u32 mmds;
};
/* A PHY instance */
struct cphy {
- u8 addr; /* PHY address */
u8 modtype; /* PHY module type */
short priv; /* scratch pad */
unsigned int caps; /* PHY capabilities */
@@ -595,23 +576,23 @@ struct cphy {
const char *desc; /* PHY description */
unsigned long fifo_errors; /* FIFO over/under-flows */
const struct cphy_ops *ops; /* PHY operations */
- int (*mdio_read)(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *val);
- int (*mdio_write)(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val);
+ struct mdio_if_info mdio;
};
/* Convenience MDIO read/write wrappers */
-static inline int mdio_read(struct cphy *phy, int mmd, int reg,
- unsigned int *valp)
+static inline int t3_mdio_read(struct cphy *phy, int mmd, int reg,
+ unsigned int *valp)
{
- return phy->mdio_read(phy->adapter, phy->addr, mmd, reg, valp);
+ int rc = phy->mdio.mdio_read(phy->mdio.dev, phy->mdio.prtad, mmd, reg);
+ *valp = (rc >= 0) ? rc : -1;
+ return (rc >= 0) ? 0 : rc;
}
-static inline int mdio_write(struct cphy *phy, int mmd, int reg,
- unsigned int val)
+static inline int t3_mdio_write(struct cphy *phy, int mmd, int reg,
+ unsigned int val)
{
- return phy->mdio_write(phy->adapter, phy->addr, mmd, reg, val);
+ return phy->mdio.mdio_write(phy->mdio.dev, phy->mdio.prtad, mmd,
+ reg, val);
}
/* Convenience initializer */
@@ -620,14 +601,16 @@ static inline void cphy_init(struct cphy *phy, struct adapter *adapter,
const struct mdio_ops *mdio_ops,
unsigned int caps, const char *desc)
{
- phy->addr = phy_addr;
phy->caps = caps;
phy->adapter = adapter;
phy->desc = desc;
phy->ops = phy_ops;
if (mdio_ops) {
- phy->mdio_read = mdio_ops->read;
- phy->mdio_write = mdio_ops->write;
+ phy->mdio.prtad = phy_addr;
+ phy->mdio.mmds = phy_ops->mmds;
+ phy->mdio.mode_support = mdio_ops->mode_support;
+ phy->mdio.mdio_read = mdio_ops->read;
+ phy->mdio.mdio_write = mdio_ops->write;
}
}
@@ -819,8 +802,12 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
int phy_addr, const struct mdio_ops *mdio_ops);
int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
int phy_addr, const struct mdio_ops *mdio_ops);
+int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter,
+ int phy_addr, const struct mdio_ops *mdio_ops);
int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
const struct mdio_ops *mdio_ops);
int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
int phy_addr, const struct mdio_ops *mdio_ops);
+int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter,
+ int phy_addr, const struct mdio_ops *mdio_ops);
#endif /* __CHELSIO_COMMON_H */
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 17858b9a583..538dda4422d 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -37,7 +37,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
#include <linux/sockios.h>
#include <linux/workqueue.h>
#include <linux/proc_fs.h>
@@ -91,6 +91,8 @@ static const struct pci_device_id cxgb3_pci_tbl[] = {
CH_DEVICE(0x31, 3), /* T3B20 */
CH_DEVICE(0x32, 1), /* T3B02 */
CH_DEVICE(0x35, 6), /* T3C20-derived T3C10 */
+ CH_DEVICE(0x36, 3), /* S320E-CR */
+ CH_DEVICE(0x37, 7), /* N320E-G2 */
{0,}
};
@@ -431,40 +433,78 @@ static int init_tp_parity(struct adapter *adap)
for (i = 0; i < 16; i++) {
struct cpl_smt_write_req *req;
- skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
+ skb = alloc_skb(sizeof(*req), GFP_KERNEL);
+ if (!skb)
+ skb = adap->nofail_skb;
+ if (!skb)
+ goto alloc_skb_fail;
+
req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req));
memset(req, 0, sizeof(*req));
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i));
req->iff = i;
t3_mgmt_tx(adap, skb);
+ if (skb == adap->nofail_skb) {
+ await_mgmt_replies(adap, cnt, i + 1);
+ adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
+ if (!adap->nofail_skb)
+ goto alloc_skb_fail;
+ }
}
for (i = 0; i < 2048; i++) {
struct cpl_l2t_write_req *req;
- skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
+ skb = alloc_skb(sizeof(*req), GFP_KERNEL);
+ if (!skb)
+ skb = adap->nofail_skb;
+ if (!skb)
+ goto alloc_skb_fail;
+
req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req));
memset(req, 0, sizeof(*req));
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, i));
req->params = htonl(V_L2T_W_IDX(i));
t3_mgmt_tx(adap, skb);
+ if (skb == adap->nofail_skb) {
+ await_mgmt_replies(adap, cnt, 16 + i + 1);
+ adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
+ if (!adap->nofail_skb)
+ goto alloc_skb_fail;
+ }
}
for (i = 0; i < 2048; i++) {
struct cpl_rte_write_req *req;
- skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
+ skb = alloc_skb(sizeof(*req), GFP_KERNEL);
+ if (!skb)
+ skb = adap->nofail_skb;
+ if (!skb)
+ goto alloc_skb_fail;
+
req = (struct cpl_rte_write_req *)__skb_put(skb, sizeof(*req));
memset(req, 0, sizeof(*req));
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RTE_WRITE_REQ, i));
req->l2t_idx = htonl(V_L2T_W_IDX(i));
t3_mgmt_tx(adap, skb);
+ if (skb == adap->nofail_skb) {
+ await_mgmt_replies(adap, cnt, 16 + 2048 + i + 1);
+ adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
+ if (!adap->nofail_skb)
+ goto alloc_skb_fail;
+ }
}
- skb = alloc_skb(sizeof(*greq), GFP_KERNEL | __GFP_NOFAIL);
+ skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
+ if (!skb)
+ skb = adap->nofail_skb;
+ if (!skb)
+ goto alloc_skb_fail;
+
greq = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*greq));
memset(greq, 0, sizeof(*greq));
greq->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
@@ -473,8 +513,17 @@ static int init_tp_parity(struct adapter *adap)
t3_mgmt_tx(adap, skb);
i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1);
+ if (skb == adap->nofail_skb) {
+ i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1);
+ adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
+ }
+
t3_tp_set_offload_mode(adap, 0);
return i;
+
+alloc_skb_fail:
+ t3_tp_set_offload_mode(adap, 0);
+ return -ENOMEM;
}
/**
@@ -869,7 +918,12 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
struct mngt_pktsched_wr *req;
int ret;
- skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
+ skb = alloc_skb(sizeof(*req), GFP_KERNEL);
+ if (!skb)
+ skb = adap->nofail_skb;
+ if (!skb)
+ return -ENOMEM;
+
req = (struct mngt_pktsched_wr *)skb_put(skb, sizeof(*req));
req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT));
req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET;
@@ -879,6 +933,12 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
req->max = hi;
req->binding = port;
ret = t3_mgmt_tx(adap, skb);
+ if (skb == adap->nofail_skb) {
+ adap->nofail_skb = alloc_skb(sizeof(struct cpl_set_tcb_field),
+ GFP_KERNEL);
+ if (!adap->nofail_skb)
+ ret = -ENOMEM;
+ }
return ret;
}
@@ -1593,7 +1653,7 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
}
cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
- cmd->phy_address = p->phy.addr;
+ cmd->phy_address = p->phy.mdio.prtad;
cmd->transceiver = XCVR_EXTERNAL;
cmd->autoneg = p->link_config.autoneg;
cmd->maxtxpkt = 0;
@@ -2308,70 +2368,25 @@ static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
struct mii_ioctl_data *data = if_mii(req);
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
- int ret, mmd;
switch (cmd) {
- case SIOCGMIIPHY:
- data->phy_id = pi->phy.addr;
+ case SIOCGMIIREG:
+ case SIOCSMIIREG:
+ /* Convert phy_id from older PRTAD/DEVAD format */
+ if (is_10G(adapter) &&
+ !mdio_phy_id_is_c45(data->phy_id) &&
+ (data->phy_id & 0x1f00) &&
+ !(data->phy_id & 0xe0e0))
+ data->phy_id = mdio_phy_id_c45(data->phy_id >> 8,
+ data->phy_id & 0x1f);
/* FALLTHRU */
- case SIOCGMIIREG:{
- u32 val;
- struct cphy *phy = &pi->phy;
-
- if (!phy->mdio_read)
- return -EOPNOTSUPP;
- if (is_10G(adapter)) {
- mmd = data->phy_id >> 8;
- if (!mmd)
- mmd = MDIO_DEV_PCS;
- else if (mmd > MDIO_DEV_VEND2)
- return -EINVAL;
-
- ret =
- phy->mdio_read(adapter, data->phy_id & 0x1f,
- mmd, data->reg_num, &val);
- } else
- ret =
- phy->mdio_read(adapter, data->phy_id & 0x1f,
- 0, data->reg_num & 0x1f,
- &val);
- if (!ret)
- data->val_out = val;
- break;
- }
- case SIOCSMIIREG:{
- struct cphy *phy = &pi->phy;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- if (!phy->mdio_write)
- return -EOPNOTSUPP;
- if (is_10G(adapter)) {
- mmd = data->phy_id >> 8;
- if (!mmd)
- mmd = MDIO_DEV_PCS;
- else if (mmd > MDIO_DEV_VEND2)
- return -EINVAL;
-
- ret =
- phy->mdio_write(adapter,
- data->phy_id & 0x1f, mmd,
- data->reg_num,
- data->val_in);
- } else
- ret =
- phy->mdio_write(adapter,
- data->phy_id & 0x1f, 0,
- data->reg_num & 0x1f,
- data->val_in);
- break;
- }
+ case SIOCGMIIPHY:
+ return mdio_mii_ioctl(&pi->phy.mdio, data, cmd);
case SIOCCHIOCTL:
return cxgb_extension_ioctl(dev, req->ifr_data);
default:
return -EOPNOTSUPP;
}
- return ret;
}
static int cxgb_change_mtu(struct net_device *dev, int new_mtu)
@@ -3063,6 +3078,14 @@ static int __devinit init_one(struct pci_dev *pdev,
goto out_disable_device;
}
+ adapter->nofail_skb =
+ alloc_skb(sizeof(struct cpl_set_tcb_field), GFP_KERNEL);
+ if (!adapter->nofail_skb) {
+ dev_err(&pdev->dev, "cannot allocate nofail buffer\n");
+ err = -ENOMEM;
+ goto out_free_adapter;
+ }
+
adapter->regs = ioremap_nocache(mmio_start, mmio_len);
if (!adapter->regs) {
dev_err(&pdev->dev, "cannot map device registers\n");
@@ -3106,7 +3129,6 @@ static int __devinit init_one(struct pci_dev *pdev,
netdev->mem_start = mmio_start;
netdev->mem_end = mmio_start + mmio_len - 1;
netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
- netdev->features |= NETIF_F_LLTX;
netdev->features |= NETIF_F_GRO;
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
@@ -3220,6 +3242,8 @@ static void __devexit remove_one(struct pci_dev *pdev)
free_netdev(adapter->port[i]);
iounmap(adapter->regs);
+ if (adapter->nofail_skb)
+ kfree_skb(adapter->nofail_skb);
kfree(adapter);
pci_release_regions(pdev);
pci_disable_device(pdev);
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index 620d80be6aa..f9f54b57b28 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -566,13 +566,31 @@ static void t3_process_tid_release_list(struct work_struct *work)
spin_unlock_bh(&td->tid_release_lock);
skb = alloc_skb(sizeof(struct cpl_tid_release),
- GFP_KERNEL | __GFP_NOFAIL);
+ GFP_KERNEL);
+ if (!skb)
+ skb = td->nofail_skb;
+ if (!skb) {
+ spin_lock_bh(&td->tid_release_lock);
+ p->ctx = (void *)td->tid_release_list;
+ td->tid_release_list = (struct t3c_tid_entry *)p;
+ break;
+ }
mk_tid_release(skb, p - td->tid_maps.tid_tab);
cxgb3_ofld_send(tdev, skb);
p->ctx = NULL;
+ if (skb == td->nofail_skb)
+ td->nofail_skb =
+ alloc_skb(sizeof(struct cpl_tid_release),
+ GFP_KERNEL);
spin_lock_bh(&td->tid_release_lock);
}
+ td->release_list_incomplete = (td->tid_release_list == NULL) ? 0 : 1;
spin_unlock_bh(&td->tid_release_lock);
+
+ if (!td->nofail_skb)
+ td->nofail_skb =
+ alloc_skb(sizeof(struct cpl_tid_release),
+ GFP_KERNEL);
}
/* use ctx as a next pointer in the tid release list */
@@ -585,7 +603,7 @@ void cxgb3_queue_tid_release(struct t3cdev *tdev, unsigned int tid)
p->ctx = (void *)td->tid_release_list;
p->client = NULL;
td->tid_release_list = p;
- if (!p->ctx)
+ if (!p->ctx || td->release_list_incomplete)
schedule_work(&td->tid_release_task);
spin_unlock_bh(&td->tid_release_lock);
}
@@ -1274,6 +1292,9 @@ int cxgb3_offload_activate(struct adapter *adapter)
if (list_empty(&adapter_list))
register_netevent_notifier(&nb);
+ t->nofail_skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_KERNEL);
+ t->release_list_incomplete = 0;
+
add_adapter(adapter);
return 0;
@@ -1298,6 +1319,8 @@ void cxgb3_offload_deactivate(struct adapter *adapter)
T3C_DATA(tdev) = NULL;
t3_free_l2t(L2DATA(tdev));
L2DATA(tdev) = NULL;
+ if (t->nofail_skb)
+ kfree_skb(t->nofail_skb);
kfree(t);
}
diff --git a/drivers/net/cxgb3/cxgb3_offload.h b/drivers/net/cxgb3/cxgb3_offload.h
index a8e8e5fcdf8..55945f422ae 100644
--- a/drivers/net/cxgb3/cxgb3_offload.h
+++ b/drivers/net/cxgb3/cxgb3_offload.h
@@ -191,6 +191,9 @@ struct t3c_data {
struct t3c_tid_entry *tid_release_list;
spinlock_t tid_release_lock;
struct work_struct tid_release_task;
+
+ struct sk_buff *nofail_skb;
+ unsigned int release_list_incomplete;
};
/*
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index b3ee2bc1a00..29c79eb43be 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -653,7 +653,8 @@ static void t3_reset_qset(struct sge_qset *q)
q->txq_stopped = 0;
q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */
q->rx_reclaim_timer.function = NULL;
- q->lro_frag_tbl.nr_frags = q->lro_frag_tbl.len = 0;
+ q->nomem = 0;
+ napi_free_frags(&q->napi);
}
@@ -1239,7 +1240,6 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
q = &qs->txq[TXQ_ETH];
txq = netdev_get_tx_queue(dev, qidx);
- spin_lock(&q->lock);
reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);
credits = q->size - q->in_use;
@@ -1250,7 +1250,6 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
dev_err(&adap->pdev->dev,
"%s: Tx ring %u full while queue awake!\n",
dev->name, q->cntxt_id & 7);
- spin_unlock(&q->lock);
return NETDEV_TX_BUSY;
}
@@ -1284,9 +1283,6 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
if (vlan_tx_tag_present(skb) && pi->vlan_grp)
qs->port_stats[SGE_PSTAT_VLANINS]++;
- dev->trans_start = jiffies;
- spin_unlock(&q->lock);
-
/*
* We do not use Tx completion interrupts to free DMAd Tx packets.
* This is good for performamce but means that we rely on new Tx
@@ -2073,20 +2069,19 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
struct sge_fl *fl, int len, int complete)
{
struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
+ struct sk_buff *skb = NULL;
struct cpl_rx_pkt *cpl;
- struct skb_frag_struct *rx_frag = qs->lro_frag_tbl.frags;
- int nr_frags = qs->lro_frag_tbl.nr_frags;
- int frag_len = qs->lro_frag_tbl.len;
+ struct skb_frag_struct *rx_frag;
+ int nr_frags;
int offset = 0;
- if (!nr_frags) {
- offset = 2 + sizeof(struct cpl_rx_pkt);
- qs->lro_va = cpl = sd->pg_chunk.va + 2;
+ if (!qs->nomem) {
+ skb = napi_get_frags(&qs->napi);
+ qs->nomem = !skb;
}
fl->credits--;
- len -= offset;
pci_dma_sync_single_for_cpu(adap->pdev,
pci_unmap_addr(sd, dma_addr),
fl->buf_size - SGE_PG_RSVD,
@@ -2099,21 +2094,38 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
fl->alloc_size,
PCI_DMA_FROMDEVICE);
+ if (!skb) {
+ put_page(sd->pg_chunk.page);
+ if (complete)
+ qs->nomem = 0;
+ return;
+ }
+
+ rx_frag = skb_shinfo(skb)->frags;
+ nr_frags = skb_shinfo(skb)->nr_frags;
+
+ if (!nr_frags) {
+ offset = 2 + sizeof(struct cpl_rx_pkt);
+ qs->lro_va = sd->pg_chunk.va + 2;
+ }
+ len -= offset;
+
prefetch(qs->lro_va);
rx_frag += nr_frags;
rx_frag->page = sd->pg_chunk.page;
rx_frag->page_offset = sd->pg_chunk.offset + offset;
rx_frag->size = len;
- frag_len += len;
- qs->lro_frag_tbl.nr_frags++;
- qs->lro_frag_tbl.len = frag_len;
+ skb->len += len;
+ skb->data_len += len;
+ skb->truesize += len;
+ skb_shinfo(skb)->nr_frags++;
if (!complete)
return;
- qs->lro_frag_tbl.ip_summed = CHECKSUM_UNNECESSARY;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
cpl = qs->lro_va;
if (unlikely(cpl->vlan_valid)) {
@@ -2122,15 +2134,11 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
struct vlan_group *grp = pi->vlan_grp;
if (likely(grp != NULL)) {
- vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan),
- &qs->lro_frag_tbl);
- goto out;
+ vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan));
+ return;
}
}
- napi_gro_frags(&qs->napi, &qs->lro_frag_tbl);
-
-out:
- qs->lro_frag_tbl.nr_frags = qs->lro_frag_tbl.len = 0;
+ napi_gro_frags(&qs->napi);
}
/**
@@ -2299,8 +2307,6 @@ no_mem:
if (fl->use_pages) {
void *addr = fl->sdesc[fl->cidx].pg_chunk.va;
- prefetch(&qs->lro_frag_tbl);
-
prefetch(addr);
#if L1_CACHE_BYTES < 128
prefetch(addr + L1_CACHE_BYTES);
@@ -2846,11 +2852,12 @@ static void sge_timer_tx(unsigned long data)
unsigned int tbd[SGE_TXQ_PER_SET] = {0, 0};
unsigned long next_period;
- if (spin_trylock(&qs->txq[TXQ_ETH].lock)) {
- tbd[TXQ_ETH] = reclaim_completed_tx(adap, &qs->txq[TXQ_ETH],
- TX_RECLAIM_TIMER_CHUNK);
- spin_unlock(&qs->txq[TXQ_ETH].lock);
+ if (__netif_tx_trylock(qs->tx_q)) {
+ tbd[TXQ_ETH] = reclaim_completed_tx(adap, &qs->txq[TXQ_ETH],
+ TX_RECLAIM_TIMER_CHUNK);
+ __netif_tx_unlock(qs->tx_q);
}
+
if (spin_trylock(&qs->txq[TXQ_OFLD].lock)) {
tbd[TXQ_OFLD] = reclaim_completed_tx(adap, &qs->txq[TXQ_OFLD],
TX_RECLAIM_TIMER_CHUNK);
@@ -2858,8 +2865,8 @@ static void sge_timer_tx(unsigned long data)
}
next_period = TX_RECLAIM_PERIOD >>
- (max(tbd[TXQ_ETH], tbd[TXQ_OFLD]) /
- TX_RECLAIM_TIMER_CHUNK);
+ (max(tbd[TXQ_ETH], tbd[TXQ_OFLD]) /
+ TX_RECLAIM_TIMER_CHUNK);
mod_timer(&qs->tx_reclaim_timer, jiffies + next_period);
}
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 4950d5d789a..870d44992c7 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -204,35 +204,33 @@ static void mi1_init(struct adapter *adap, const struct adapter_info *ai)
/*
* MI1 read/write operations for clause 22 PHYs.
*/
-static int t3_mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *valp)
+static int t3_mi1_read(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr)
{
+ struct port_info *pi = netdev_priv(dev);
+ struct adapter *adapter = pi->adapter;
int ret;
u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
- if (mmd_addr)
- return -EINVAL;
-
mutex_lock(&adapter->mdio_lock);
t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1));
t3_write_reg(adapter, A_MI1_ADDR, addr);
t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2));
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10);
if (!ret)
- *valp = t3_read_reg(adapter, A_MI1_DATA);
+ ret = t3_read_reg(adapter, A_MI1_DATA);
mutex_unlock(&adapter->mdio_lock);
return ret;
}
-static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val)
+static int t3_mi1_write(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr, u16 val)
{
+ struct port_info *pi = netdev_priv(dev);
+ struct adapter *adapter = pi->adapter;
int ret;
u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
- if (mmd_addr)
- return -EINVAL;
-
mutex_lock(&adapter->mdio_lock);
t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1));
t3_write_reg(adapter, A_MI1_ADDR, addr);
@@ -244,8 +242,9 @@ static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr,
}
static const struct mdio_ops mi1_mdio_ops = {
- t3_mi1_read,
- t3_mi1_write
+ .read = t3_mi1_read,
+ .write = t3_mi1_write,
+ .mode_support = MDIO_SUPPORTS_C22
};
/*
@@ -268,9 +267,11 @@ static int mi1_wr_addr(struct adapter *adapter, int phy_addr, int mmd_addr,
/*
* MI1 read/write operations for indirect-addressed PHYs.
*/
-static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *valp)
+static int mi1_ext_read(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr)
{
+ struct port_info *pi = netdev_priv(dev);
+ struct adapter *adapter = pi->adapter;
int ret;
mutex_lock(&adapter->mdio_lock);
@@ -280,15 +281,17 @@ static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr,
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0,
MDIO_ATTEMPTS, 10);
if (!ret)
- *valp = t3_read_reg(adapter, A_MI1_DATA);
+ ret = t3_read_reg(adapter, A_MI1_DATA);
}
mutex_unlock(&adapter->mdio_lock);
return ret;
}
-static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val)
+static int mi1_ext_write(struct net_device *dev, int phy_addr, int mmd_addr,
+ u16 reg_addr, u16 val)
{
+ struct port_info *pi = netdev_priv(dev);
+ struct adapter *adapter = pi->adapter;
int ret;
mutex_lock(&adapter->mdio_lock);
@@ -304,8 +307,9 @@ static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr,
}
static const struct mdio_ops mi1_mdio_ext_ops = {
- mi1_ext_read,
- mi1_ext_write
+ .read = mi1_ext_read,
+ .write = mi1_ext_write,
+ .mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22
};
/**
@@ -325,10 +329,10 @@ int t3_mdio_change_bits(struct cphy *phy, int mmd, int reg, unsigned int clear,
int ret;
unsigned int val;
- ret = mdio_read(phy, mmd, reg, &val);
+ ret = t3_mdio_read(phy, mmd, reg, &val);
if (!ret) {
val &= ~clear;
- ret = mdio_write(phy, mmd, reg, val | set);
+ ret = t3_mdio_write(phy, mmd, reg, val | set);
}
return ret;
}
@@ -348,15 +352,16 @@ int t3_phy_reset(struct cphy *phy, int mmd, int wait)
int err;
unsigned int ctl;
- err = t3_mdio_change_bits(phy, mmd, MII_BMCR, BMCR_PDOWN, BMCR_RESET);
+ err = t3_mdio_change_bits(phy, mmd, MDIO_CTRL1, MDIO_CTRL1_LPOWER,
+ MDIO_CTRL1_RESET);
if (err || !wait)
return err;
do {
- err = mdio_read(phy, mmd, MII_BMCR, &ctl);
+ err = t3_mdio_read(phy, mmd, MDIO_CTRL1, &ctl);
if (err)
return err;
- ctl &= BMCR_RESET;
+ ctl &= MDIO_CTRL1_RESET;
if (ctl)
msleep(1);
} while (ctl && --wait);
@@ -377,7 +382,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert)
int err;
unsigned int val = 0;
- err = mdio_read(phy, 0, MII_CTRL1000, &val);
+ err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_CTRL1000, &val);
if (err)
return err;
@@ -387,7 +392,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert)
if (advert & ADVERTISED_1000baseT_Full)
val |= ADVERTISE_1000FULL;
- err = mdio_write(phy, 0, MII_CTRL1000, val);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_CTRL1000, val);
if (err)
return err;
@@ -404,7 +409,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert)
val |= ADVERTISE_PAUSE_CAP;
if (advert & ADVERTISED_Asym_Pause)
val |= ADVERTISE_PAUSE_ASYM;
- return mdio_write(phy, 0, MII_ADVERTISE, val);
+ return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val);
}
/**
@@ -427,7 +432,7 @@ int t3_phy_advertise_fiber(struct cphy *phy, unsigned int advert)
val |= ADVERTISE_1000XPAUSE;
if (advert & ADVERTISED_Asym_Pause)
val |= ADVERTISE_1000XPSE_ASYM;
- return mdio_write(phy, 0, MII_ADVERTISE, val);
+ return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val);
}
/**
@@ -444,7 +449,7 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex)
int err;
unsigned int ctl;
- err = mdio_read(phy, 0, MII_BMCR, &ctl);
+ err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_BMCR, &ctl);
if (err)
return err;
@@ -462,34 +467,36 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex)
}
if (ctl & BMCR_SPEED1000) /* auto-negotiation required for GigE */
ctl |= BMCR_ANENABLE;
- return mdio_write(phy, 0, MII_BMCR, ctl);
+ return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_BMCR, ctl);
}
int t3_phy_lasi_intr_enable(struct cphy *phy)
{
- return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1);
+ return t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL,
+ MDIO_PMA_LASI_LSALARM);
}
int t3_phy_lasi_intr_disable(struct cphy *phy)
{
- return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0);
+ return t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, 0);
}
int t3_phy_lasi_intr_clear(struct cphy *phy)
{
u32 val;
- return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val);
+ return t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT, &val);
}
int t3_phy_lasi_intr_handler(struct cphy *phy)
{
unsigned int status;
- int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status);
+ int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT,
+ &status);
if (err)
return err;
- return (status & 1) ? cphy_cause_link_change : 0;
+ return (status & MDIO_PMA_LASI_LSALARM) ? cphy_cause_link_change : 0;
}
static const struct adapter_info t3_adap_info[] = {
@@ -519,6 +526,11 @@ static const struct adapter_info t3_adap_info[] = {
F_GPIO10_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
{ S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
&mi1_mdio_ext_ops, "Chelsio T310" },
+ {1, 0, 0,
+ F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN |
+ F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL,
+ { S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
+ &mi1_mdio_ext_ops, "Chelsio N320E-G2" },
};
/*
@@ -545,6 +557,8 @@ static const struct port_type_info port_types[] = {
{ t3_qt2045_phy_prep },
{ t3_ael1006_phy_prep },
{ NULL },
+ { t3_aq100x_phy_prep },
+ { t3_ael2020_phy_prep },
};
#define VPD_ENTRY(name, len) \
@@ -3864,6 +3878,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
return -EINVAL;
}
+ p->phy.mdio.dev = adapter->port[i];
ret = pti->phy_prep(&p->phy, adapter, ai->phy_base_addr + j,
ai->mdio_ops);
if (ret)
@@ -3923,7 +3938,7 @@ int t3_replay_prep_adapter(struct adapter *adapter)
;
pti = &port_types[adapter->params.vpd.port_type[j]];
- ret = pti->phy_prep(&p->phy, adapter, p->phy.addr, NULL);
+ ret = pti->phy_prep(&p->phy, adapter, p->phy.mdio.prtad, NULL);
if (ret)
return ret;
p->phy.ops->power_down(&p->phy, 1);
diff --git a/drivers/net/cxgb3/version.h b/drivers/net/cxgb3/version.h
index 7bf963ec554..9d0bd9dd9ab 100644
--- a/drivers/net/cxgb3/version.h
+++ b/drivers/net/cxgb3/version.h
@@ -35,10 +35,10 @@
#define DRV_DESC "Chelsio T3 Network Driver"
#define DRV_NAME "cxgb3"
/* Driver version */
-#define DRV_VERSION "1.1.2-ko"
+#define DRV_VERSION "1.1.3-ko"
/* Firmware version */
#define FW_VERSION_MAJOR 7
-#define FW_VERSION_MINOR 1
+#define FW_VERSION_MINOR 4
#define FW_VERSION_MICRO 0
#endif /* __CHELSIO_VERSION_H */
diff --git a/drivers/net/cxgb3/vsc8211.c b/drivers/net/cxgb3/vsc8211.c
index d07130971b8..4f9a1c2724f 100644
--- a/drivers/net/cxgb3/vsc8211.c
+++ b/drivers/net/cxgb3/vsc8211.c
@@ -91,17 +91,18 @@ enum {
*/
static int vsc8211_reset(struct cphy *cphy, int wait)
{
- return t3_phy_reset(cphy, 0, 0);
+ return t3_phy_reset(cphy, MDIO_DEVAD_NONE, 0);
}
static int vsc8211_intr_enable(struct cphy *cphy)
{
- return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, INTR_MASK);
+ return t3_mdio_write(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_ENABLE,
+ INTR_MASK);
}
static int vsc8211_intr_disable(struct cphy *cphy)
{
- return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, 0);
+ return t3_mdio_write(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_ENABLE, 0);
}
static int vsc8211_intr_clear(struct cphy *cphy)
@@ -109,18 +110,20 @@ static int vsc8211_intr_clear(struct cphy *cphy)
u32 val;
/* Clear PHY interrupts by reading the register. */
- return mdio_read(cphy, 0, VSC8211_INTR_STATUS, &val);
+ return t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_STATUS, &val);
}
static int vsc8211_autoneg_enable(struct cphy *cphy)
{
- return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE,
+ return t3_mdio_change_bits(cphy, MDIO_DEVAD_NONE, MII_BMCR,
+ BMCR_PDOWN | BMCR_ISOLATE,
BMCR_ANENABLE | BMCR_ANRESTART);
}
static int vsc8211_autoneg_restart(struct cphy *cphy)
{
- return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE,
+ return t3_mdio_change_bits(cphy, MDIO_DEVAD_NONE, MII_BMCR,
+ BMCR_PDOWN | BMCR_ISOLATE,
BMCR_ANRESTART);
}
@@ -130,9 +133,9 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
unsigned int bmcr, status, lpa, adv;
int err, sp = -1, dplx = -1, pause = 0;
- err = mdio_read(cphy, 0, MII_BMCR, &bmcr);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMCR, &bmcr);
if (!err)
- err = mdio_read(cphy, 0, MII_BMSR, &status);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, &status);
if (err)
return err;
@@ -142,7 +145,8 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
* once more to get the current link state.
*/
if (!(status & BMSR_LSTATUS))
- err = mdio_read(cphy, 0, MII_BMSR, &status);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR,
+ &status);
if (err)
return err;
*link_ok = (status & BMSR_LSTATUS) != 0;
@@ -156,7 +160,8 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
else
sp = SPEED_10;
} else if (status & BMSR_ANEGCOMPLETE) {
- err = mdio_read(cphy, 0, VSC8211_AUX_CTRL_STAT, &status);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_AUX_CTRL_STAT,
+ &status);
if (err)
return err;
@@ -170,9 +175,11 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
sp = SPEED_1000;
if (fc && dplx == DUPLEX_FULL) {
- err = mdio_read(cphy, 0, MII_LPA, &lpa);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_LPA,
+ &lpa);
if (!err)
- err = mdio_read(cphy, 0, MII_ADVERTISE, &adv);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE,
+ MII_ADVERTISE, &adv);
if (err)
return err;
@@ -202,9 +209,9 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok,
unsigned int bmcr, status, lpa, adv;
int err, sp = -1, dplx = -1, pause = 0;
- err = mdio_read(cphy, 0, MII_BMCR, &bmcr);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMCR, &bmcr);
if (!err)
- err = mdio_read(cphy, 0, MII_BMSR, &status);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, &status);
if (err)
return err;
@@ -214,7 +221,8 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok,
* once more to get the current link state.
*/
if (!(status & BMSR_LSTATUS))
- err = mdio_read(cphy, 0, MII_BMSR, &status);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR,
+ &status);
if (err)
return err;
*link_ok = (status & BMSR_LSTATUS) != 0;
@@ -228,9 +236,10 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok,
else
sp = SPEED_10;
} else if (status & BMSR_ANEGCOMPLETE) {
- err = mdio_read(cphy, 0, MII_LPA, &lpa);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_LPA, &lpa);
if (!err)
- err = mdio_read(cphy, 0, MII_ADVERTISE, &adv);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_ADVERTISE,
+ &adv);
if (err)
return err;
@@ -270,23 +279,23 @@ static int vsc8211_set_automdi(struct cphy *phy, int enable)
{
int err;
- err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0x52b5);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0x52b5);
if (err)
return err;
- err = mdio_write(phy, 0, 18, 0x12);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 18, 0x12);
if (err)
return err;
- err = mdio_write(phy, 0, 17, enable ? 0x2803 : 0x3003);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 17, enable ? 0x2803 : 0x3003);
if (err)
return err;
- err = mdio_write(phy, 0, 16, 0x87fa);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 16, 0x87fa);
if (err)
return err;
- err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0);
if (err)
return err;
@@ -315,7 +324,7 @@ static int vsc8211_intr_handler(struct cphy *cphy)
unsigned int cause;
int err, cphy_cause = 0;
- err = mdio_read(cphy, 0, VSC8211_INTR_STATUS, &cause);
+ err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_STATUS, &cause);
if (err)
return err;
@@ -367,12 +376,13 @@ int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter,
SUPPORTED_TP | SUPPORTED_IRQ, "10/100/1000BASE-T");
msleep(20); /* PHY needs ~10ms to start responding to MDIO */
- err = mdio_read(phy, 0, VSC8211_EXT_CTRL, &val);
+ err = t3_mdio_read(phy, MDIO_DEVAD_NONE, VSC8211_EXT_CTRL, &val);
if (err)
return err;
if (val & VSC_CTRL_MEDIA_MODE_HI) {
/* copper interface, just need to configure the LEDs */
- return mdio_write(phy, 0, VSC8211_LED_CTRL, 0x100);
+ return t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_LED_CTRL,
+ 0x100);
}
phy->caps = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
@@ -380,20 +390,20 @@ int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter,
phy->desc = "1000BASE-X";
phy->ops = &vsc8211_fiber_ops;
- err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 1);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 1);
if (err)
return err;
- err = mdio_write(phy, 0, VSC8211_SIGDET_CTRL, 1);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_SIGDET_CTRL, 1);
if (err)
return err;
- err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0);
if (err)
return err;
- err = mdio_write(phy, 0, VSC8211_EXT_CTRL,
- val | VSC_CTRL_CLAUSE37_VIEW);
+ err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_CTRL,
+ val | VSC_CTRL_CLAUSE37_VIEW);
if (err)
return err;
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
new file mode 100644
index 00000000000..0e9b9f9632c
--- /dev/null
+++ b/drivers/net/davinci_emac.c
@@ -0,0 +1,2830 @@
+/*
+ * DaVinci Ethernet Medium Access Controller
+ *
+ * DaVinci EMAC is based upon CPPI 3.0 TI DMA engine
+ *
+ * Copyright (C) 2009 Texas Instruments.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ---------------------------------------------------------------------------
+ * History:
+ * 0-5 A number of folks worked on this driver in bits and pieces but the major
+ * contribution came from Suraj Iyer and Anant Gole
+ * 6.0 Anant Gole - rewrote the driver as per Linux conventions
+ * 6.1 Chaithrika U S - added support for Gigabit and RMII features,
+ * PHY layer usage
+ */
+
+/** Pending Items in this driver:
+ * 1. Use Linux cache infrastcture for DMA'ed memory (dma_xxx functions)
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/in.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/highmem.h>
+#include <linux/proc_fs.h>
+#include <linux/ctype.h>
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/semaphore.h>
+#include <linux/phy.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include <asm/irq.h>
+#include <asm/page.h>
+
+#include <mach/emac.h>
+
+static int debug_level;
+module_param(debug_level, int, 0);
+MODULE_PARM_DESC(debug_level, "DaVinci EMAC debug level (NETIF_MSG bits)");
+
+/* Netif debug messages possible */
+#define DAVINCI_EMAC_DEBUG (NETIF_MSG_DRV | \
+ NETIF_MSG_PROBE | \
+ NETIF_MSG_LINK | \
+ NETIF_MSG_TIMER | \
+ NETIF_MSG_IFDOWN | \
+ NETIF_MSG_IFUP | \
+ NETIF_MSG_RX_ERR | \
+ NETIF_MSG_TX_ERR | \
+ NETIF_MSG_TX_QUEUED | \
+ NETIF_MSG_INTR | \
+ NETIF_MSG_TX_DONE | \
+ NETIF_MSG_RX_STATUS | \
+ NETIF_MSG_PKTDATA | \
+ NETIF_MSG_HW | \
+ NETIF_MSG_WOL)
+
+/* version info */
+#define EMAC_MAJOR_VERSION 6
+#define EMAC_MINOR_VERSION 1
+#define EMAC_MODULE_VERSION "6.1"
+MODULE_VERSION(EMAC_MODULE_VERSION);
+static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
+
+/* Configuration items */
+#define EMAC_DEF_PASS_CRC (0) /* Do not pass CRC upto frames */
+#define EMAC_DEF_QOS_EN (0) /* EMAC proprietary QoS disabled */
+#define EMAC_DEF_NO_BUFF_CHAIN (0) /* No buffer chain */
+#define EMAC_DEF_MACCTRL_FRAME_EN (0) /* Discard Maccontrol frames */
+#define EMAC_DEF_SHORT_FRAME_EN (0) /* Discard short frames */
+#define EMAC_DEF_ERROR_FRAME_EN (0) /* Discard error frames */
+#define EMAC_DEF_PROM_EN (0) /* Promiscous disabled */
+#define EMAC_DEF_PROM_CH (0) /* Promiscous channel is 0 */
+#define EMAC_DEF_BCAST_EN (1) /* Broadcast enabled */
+#define EMAC_DEF_BCAST_CH (0) /* Broadcast channel is 0 */
+#define EMAC_DEF_MCAST_EN (1) /* Multicast enabled */
+#define EMAC_DEF_MCAST_CH (0) /* Multicast channel is 0 */
+
+#define EMAC_DEF_TXPRIO_FIXED (1) /* TX Priority is fixed */
+#define EMAC_DEF_TXPACING_EN (0) /* TX pacing NOT supported*/
+
+#define EMAC_DEF_BUFFER_OFFSET (0) /* Buffer offset to DMA (future) */
+#define EMAC_DEF_MIN_ETHPKTSIZE (60) /* Minimum ethernet pkt size */
+#define EMAC_DEF_MAX_FRAME_SIZE (1500 + 14 + 4 + 4)
+#define EMAC_DEF_TX_CH (0) /* Default 0th channel */
+#define EMAC_DEF_RX_CH (0) /* Default 0th channel */
+#define EMAC_DEF_MDIO_TICK_MS (10) /* typically 1 tick=1 ms) */
+#define EMAC_DEF_MAX_TX_CH (1) /* Max TX channels configured */
+#define EMAC_DEF_MAX_RX_CH (1) /* Max RX channels configured */
+#define EMAC_POLL_WEIGHT (64) /* Default NAPI poll weight */
+
+/* Buffer descriptor parameters */
+#define EMAC_DEF_TX_MAX_SERVICE (32) /* TX max service BD's */
+#define EMAC_DEF_RX_MAX_SERVICE (64) /* should = netdev->weight */
+
+/* EMAC register related defines */
+#define EMAC_ALL_MULTI_REG_VALUE (0xFFFFFFFF)
+#define EMAC_NUM_MULTICAST_BITS (64)
+#define EMAC_TEARDOWN_VALUE (0xFFFFFFFC)
+#define EMAC_TX_CONTROL_TX_ENABLE_VAL (0x1)
+#define EMAC_RX_CONTROL_RX_ENABLE_VAL (0x1)
+#define EMAC_MAC_HOST_ERR_INTMASK_VAL (0x2)
+#define EMAC_RX_UNICAST_CLEAR_ALL (0xFF)
+#define EMAC_INT_MASK_CLEAR (0xFF)
+
+/* RX MBP register bit positions */
+#define EMAC_RXMBP_PASSCRC_MASK BIT(30)
+#define EMAC_RXMBP_QOSEN_MASK BIT(29)
+#define EMAC_RXMBP_NOCHAIN_MASK BIT(28)
+#define EMAC_RXMBP_CMFEN_MASK BIT(24)
+#define EMAC_RXMBP_CSFEN_MASK BIT(23)
+#define EMAC_RXMBP_CEFEN_MASK BIT(22)
+#define EMAC_RXMBP_CAFEN_MASK BIT(21)
+#define EMAC_RXMBP_PROMCH_SHIFT (16)
+#define EMAC_RXMBP_PROMCH_MASK (0x7 << 16)
+#define EMAC_RXMBP_BROADEN_MASK BIT(13)
+#define EMAC_RXMBP_BROADCH_SHIFT (8)
+#define EMAC_RXMBP_BROADCH_MASK (0x7 << 8)
+#define EMAC_RXMBP_MULTIEN_MASK BIT(5)
+#define EMAC_RXMBP_MULTICH_SHIFT (0)
+#define EMAC_RXMBP_MULTICH_MASK (0x7)
+#define EMAC_RXMBP_CHMASK (0x7)
+
+/* EMAC register definitions/bit maps used */
+# define EMAC_MBP_RXPROMISC (0x00200000)
+# define EMAC_MBP_PROMISCCH(ch) (((ch) & 0x7) << 16)
+# define EMAC_MBP_RXBCAST (0x00002000)
+# define EMAC_MBP_BCASTCHAN(ch) (((ch) & 0x7) << 8)
+# define EMAC_MBP_RXMCAST (0x00000020)
+# define EMAC_MBP_MCASTCHAN(ch) ((ch) & 0x7)
+
+/* EMAC mac_control register */
+#define EMAC_MACCONTROL_TXPTYPE (0x200)
+#define EMAC_MACCONTROL_TXPACEEN (0x40)
+#define EMAC_MACCONTROL_MIIEN (0x20)
+#define EMAC_MACCONTROL_GIGABITEN (0x80)
+#define EMAC_MACCONTROL_GIGABITEN_SHIFT (7)
+#define EMAC_MACCONTROL_FULLDUPLEXEN (0x1)
+#define EMAC_MACCONTROL_RMIISPEED_MASK BIT(15)
+
+/* GIGABIT MODE related bits */
+#define EMAC_DM646X_MACCONTORL_GMIIEN BIT(5)
+#define EMAC_DM646X_MACCONTORL_GIG BIT(7)
+#define EMAC_DM646X_MACCONTORL_GIGFORCE BIT(17)
+
+/* EMAC mac_status register */
+#define EMAC_MACSTATUS_TXERRCODE_MASK (0xF00000)
+#define EMAC_MACSTATUS_TXERRCODE_SHIFT (20)
+#define EMAC_MACSTATUS_TXERRCH_MASK (0x7)
+#define EMAC_MACSTATUS_TXERRCH_SHIFT (16)
+#define EMAC_MACSTATUS_RXERRCODE_MASK (0xF000)
+#define EMAC_MACSTATUS_RXERRCODE_SHIFT (12)
+#define EMAC_MACSTATUS_RXERRCH_MASK (0x7)
+#define EMAC_MACSTATUS_RXERRCH_SHIFT (8)
+
+/* EMAC RX register masks */
+#define EMAC_RX_MAX_LEN_MASK (0xFFFF)
+#define EMAC_RX_BUFFER_OFFSET_MASK (0xFFFF)
+
+/* MAC_IN_VECTOR (0x180) register bit fields */
+#define EMAC_DM644X_MAC_IN_VECTOR_HOST_INT (0x20000)
+#define EMAC_DM644X_MAC_IN_VECTOR_STATPEND_INT (0x10000)
+#define EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC (0x0100)
+#define EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC (0x01)
+
+/** NOTE:: For DM646x the IN_VECTOR has changed */
+#define EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC BIT(EMAC_DEF_RX_CH)
+#define EMAC_DM646X_MAC_IN_VECTOR_TX_INT_VEC BIT(16 + EMAC_DEF_TX_CH)
+
+/* CPPI bit positions */
+#define EMAC_CPPI_SOP_BIT BIT(31)
+#define EMAC_CPPI_EOP_BIT BIT(30)
+#define EMAC_CPPI_OWNERSHIP_BIT BIT(29)
+#define EMAC_CPPI_EOQ_BIT BIT(28)
+#define EMAC_CPPI_TEARDOWN_COMPLETE_BIT BIT(27)
+#define EMAC_CPPI_PASS_CRC_BIT BIT(26)
+#define EMAC_RX_BD_BUF_SIZE (0xFFFF)
+#define EMAC_BD_LENGTH_FOR_CACHE (16) /* only CPPI bytes */
+#define EMAC_RX_BD_PKT_LENGTH_MASK (0xFFFF)
+
+/* Max hardware defines */
+#define EMAC_MAX_TXRX_CHANNELS (8) /* Max hardware channels */
+#define EMAC_DEF_MAX_MULTICAST_ADDRESSES (64) /* Max mcast addr's */
+
+/* EMAC Peripheral Device Register Memory Layout structure */
+#define EMAC_TXIDVER 0x0
+#define EMAC_TXCONTROL 0x4
+#define EMAC_TXTEARDOWN 0x8
+#define EMAC_RXIDVER 0x10
+#define EMAC_RXCONTROL 0x14
+#define EMAC_RXTEARDOWN 0x18
+#define EMAC_TXINTSTATRAW 0x80
+#define EMAC_TXINTSTATMASKED 0x84
+#define EMAC_TXINTMASKSET 0x88
+#define EMAC_TXINTMASKCLEAR 0x8C
+#define EMAC_MACINVECTOR 0x90
+
+#define EMAC_DM646X_MACEOIVECTOR 0x94
+
+#define EMAC_RXINTSTATRAW 0xA0
+#define EMAC_RXINTSTATMASKED 0xA4
+#define EMAC_RXINTMASKSET 0xA8
+#define EMAC_RXINTMASKCLEAR 0xAC
+#define EMAC_MACINTSTATRAW 0xB0
+#define EMAC_MACINTSTATMASKED 0xB4
+#define EMAC_MACINTMASKSET 0xB8
+#define EMAC_MACINTMASKCLEAR 0xBC
+
+#define EMAC_RXMBPENABLE 0x100
+#define EMAC_RXUNICASTSET 0x104
+#define EMAC_RXUNICASTCLEAR 0x108
+#define EMAC_RXMAXLEN 0x10C
+#define EMAC_RXBUFFEROFFSET 0x110
+#define EMAC_RXFILTERLOWTHRESH 0x114
+
+#define EMAC_MACCONTROL 0x160
+#define EMAC_MACSTATUS 0x164
+#define EMAC_EMCONTROL 0x168
+#define EMAC_FIFOCONTROL 0x16C
+#define EMAC_MACCONFIG 0x170
+#define EMAC_SOFTRESET 0x174
+#define EMAC_MACSRCADDRLO 0x1D0
+#define EMAC_MACSRCADDRHI 0x1D4
+#define EMAC_MACHASH1 0x1D8
+#define EMAC_MACHASH2 0x1DC
+#define EMAC_MACADDRLO 0x500
+#define EMAC_MACADDRHI 0x504
+#define EMAC_MACINDEX 0x508
+
+/* EMAC HDP and Completion registors */
+#define EMAC_TXHDP(ch) (0x600 + (ch * 4))
+#define EMAC_RXHDP(ch) (0x620 + (ch * 4))
+#define EMAC_TXCP(ch) (0x640 + (ch * 4))
+#define EMAC_RXCP(ch) (0x660 + (ch * 4))
+
+/* EMAC statistics registers */
+#define EMAC_RXGOODFRAMES 0x200
+#define EMAC_RXBCASTFRAMES 0x204
+#define EMAC_RXMCASTFRAMES 0x208
+#define EMAC_RXPAUSEFRAMES 0x20C
+#define EMAC_RXCRCERRORS 0x210
+#define EMAC_RXALIGNCODEERRORS 0x214
+#define EMAC_RXOVERSIZED 0x218
+#define EMAC_RXJABBER 0x21C
+#define EMAC_RXUNDERSIZED 0x220
+#define EMAC_RXFRAGMENTS 0x224
+#define EMAC_RXFILTERED 0x228
+#define EMAC_RXQOSFILTERED 0x22C
+#define EMAC_RXOCTETS 0x230
+#define EMAC_TXGOODFRAMES 0x234
+#define EMAC_TXBCASTFRAMES 0x238
+#define EMAC_TXMCASTFRAMES 0x23C
+#define EMAC_TXPAUSEFRAMES 0x240
+#define EMAC_TXDEFERRED 0x244
+#define EMAC_TXCOLLISION 0x248
+#define EMAC_TXSINGLECOLL 0x24C
+#define EMAC_TXMULTICOLL 0x250
+#define EMAC_TXEXCESSIVECOLL 0x254
+#define EMAC_TXLATECOLL 0x258
+#define EMAC_TXUNDERRUN 0x25C
+#define EMAC_TXCARRIERSENSE 0x260
+#define EMAC_TXOCTETS 0x264
+#define EMAC_NETOCTETS 0x280
+#define EMAC_RXSOFOVERRUNS 0x284
+#define EMAC_RXMOFOVERRUNS 0x288
+#define EMAC_RXDMAOVERRUNS 0x28C
+
+/* EMAC DM644x control registers */
+#define EMAC_CTRL_EWCTL (0x4)
+#define EMAC_CTRL_EWINTTCNT (0x8)
+
+/* EMAC MDIO related */
+/* Mask & Control defines */
+#define MDIO_CONTROL_CLKDIV (0xFF)
+#define MDIO_CONTROL_ENABLE BIT(30)
+#define MDIO_USERACCESS_GO BIT(31)
+#define MDIO_USERACCESS_WRITE BIT(30)
+#define MDIO_USERACCESS_READ (0)
+#define MDIO_USERACCESS_REGADR (0x1F << 21)
+#define MDIO_USERACCESS_PHYADR (0x1F << 16)
+#define MDIO_USERACCESS_DATA (0xFFFF)
+#define MDIO_USERPHYSEL_LINKSEL BIT(7)
+#define MDIO_VER_MODID (0xFFFF << 16)
+#define MDIO_VER_REVMAJ (0xFF << 8)
+#define MDIO_VER_REVMIN (0xFF)
+
+#define MDIO_USERACCESS(inst) (0x80 + (inst * 8))
+#define MDIO_USERPHYSEL(inst) (0x84 + (inst * 8))
+#define MDIO_CONTROL (0x04)
+
+/* EMAC DM646X control module registers */
+#define EMAC_DM646X_CMRXINTEN (0x14)
+#define EMAC_DM646X_CMTXINTEN (0x18)
+
+/* EMAC EOI codes for C0 */
+#define EMAC_DM646X_MAC_EOI_C0_RXEN (0x01)
+#define EMAC_DM646X_MAC_EOI_C0_TXEN (0x02)
+
+/** net_buf_obj: EMAC network bufferdata structure
+ *
+ * EMAC network buffer data structure
+ */
+struct emac_netbufobj {
+ void *buf_token;
+ char *data_ptr;
+ int length;
+};
+
+/** net_pkt_obj: EMAC network packet data structure
+ *
+ * EMAC network packet data structure - supports buffer list (for future)
+ */
+struct emac_netpktobj {
+ void *pkt_token; /* data token may hold tx/rx chan id */
+ struct emac_netbufobj *buf_list; /* array of network buffer objects */
+ int num_bufs;
+ int pkt_length;
+};
+
+/** emac_tx_bd: EMAC TX Buffer descriptor data structure
+ *
+ * EMAC TX Buffer descriptor data structure
+ */
+struct emac_tx_bd {
+ int h_next;
+ int buff_ptr;
+ int off_b_len;
+ int mode; /* SOP, EOP, ownership, EOQ, teardown,Qstarv, length */
+ struct emac_tx_bd __iomem *next;
+ void *buf_token;
+};
+
+/** emac_txch: EMAC TX Channel data structure
+ *
+ * EMAC TX Channel data structure
+ */
+struct emac_txch {
+ /* Config related */
+ u32 num_bd;
+ u32 service_max;
+
+ /* CPPI specific */
+ u32 alloc_size;
+ void __iomem *bd_mem;
+ struct emac_tx_bd __iomem *bd_pool_head;
+ struct emac_tx_bd __iomem *active_queue_head;
+ struct emac_tx_bd __iomem *active_queue_tail;
+ struct emac_tx_bd __iomem *last_hw_bdprocessed;
+ u32 queue_active;
+ u32 teardown_pending;
+ u32 *tx_complete;
+
+ /** statistics */
+ u32 proc_count; /* TX: # of times emac_tx_bdproc is called */
+ u32 mis_queued_packets;
+ u32 queue_reinit;
+ u32 end_of_queue_add;
+ u32 out_of_tx_bd;
+ u32 no_active_pkts; /* IRQ when there were no packets to process */
+ u32 active_queue_count;
+};
+
+/** emac_rx_bd: EMAC RX Buffer descriptor data structure
+ *
+ * EMAC RX Buffer descriptor data structure
+ */
+struct emac_rx_bd {
+ int h_next;
+ int buff_ptr;
+ int off_b_len;
+ int mode;
+ struct emac_rx_bd __iomem *next;
+ void *data_ptr;
+ void *buf_token;
+};
+
+/** emac_rxch: EMAC RX Channel data structure
+ *
+ * EMAC RX Channel data structure
+ */
+struct emac_rxch {
+ /* configuration info */
+ u32 num_bd;
+ u32 service_max;
+ u32 buf_size;
+ char mac_addr[6];
+
+ /** CPPI specific */
+ u32 alloc_size;
+ void __iomem *bd_mem;
+ struct emac_rx_bd __iomem *bd_pool_head;
+ struct emac_rx_bd __iomem *active_queue_head;
+ struct emac_rx_bd __iomem *active_queue_tail;
+ u32 queue_active;
+ u32 teardown_pending;
+
+ /* packet and buffer objects */
+ struct emac_netpktobj pkt_queue;
+ struct emac_netbufobj buf_queue;
+
+ /** statistics */
+ u32 proc_count; /* number of times emac_rx_bdproc is called */
+ u32 processed_bd;
+ u32 recycled_bd;
+ u32 out_of_rx_bd;
+ u32 out_of_rx_buffers;
+ u32 queue_reinit;
+ u32 end_of_queue_add;
+ u32 end_of_queue;
+ u32 mis_queued_packets;
+};
+
+/* emac_priv: EMAC private data structure
+ *
+ * EMAC adapter private data structure
+ */
+struct emac_priv {
+ u32 msg_enable;
+ struct net_device *ndev;
+ struct platform_device *pdev;
+ struct napi_struct napi;
+ char mac_addr[6];
+ spinlock_t tx_lock;
+ spinlock_t rx_lock;
+ void __iomem *remap_addr;
+ u32 emac_base_phys;
+ void __iomem *emac_base;
+ void __iomem *ctrl_base;
+ void __iomem *emac_ctrl_ram;
+ u32 ctrl_ram_size;
+ struct emac_txch *txch[EMAC_DEF_MAX_TX_CH];
+ struct emac_rxch *rxch[EMAC_DEF_MAX_RX_CH];
+ u32 link; /* 1=link on, 0=link off */
+ u32 speed; /* 0=Auto Neg, 1=No PHY, 10,100, 1000 - mbps */
+ u32 duplex; /* Link duplex: 0=Half, 1=Full */
+ u32 rx_buf_size;
+ u32 isr_count;
+ u8 rmii_en;
+ u8 version;
+ struct net_device_stats net_dev_stats;
+ u32 mac_hash1;
+ u32 mac_hash2;
+ u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS];
+ u32 rx_addr_type;
+ /* periodic timer required for MDIO polling */
+ struct timer_list periodic_timer;
+ u32 periodic_ticks;
+ u32 timer_active;
+ u32 phy_mask;
+ /* mii_bus,phy members */
+ struct mii_bus *mii_bus;
+ struct phy_device *phydev;
+ spinlock_t lock;
+};
+
+/* clock frequency for EMAC */
+static struct clk *emac_clk;
+static unsigned long emac_bus_frequency;
+static unsigned long mdio_max_freq;
+
+/* EMAC internal utility function */
+static inline u32 emac_virt_to_phys(void __iomem *addr)
+{
+ return (u32 __force) io_v2p(addr);
+}
+
+/* Cache macros - Packet buffers would be from skb pool which is cached */
+#define EMAC_VIRT_NOCACHE(addr) (addr)
+#define EMAC_CACHE_INVALIDATE(addr, size) \
+ dma_cache_maint((void *)addr, size, DMA_FROM_DEVICE)
+#define EMAC_CACHE_WRITEBACK(addr, size) \
+ dma_cache_maint((void *)addr, size, DMA_TO_DEVICE)
+#define EMAC_CACHE_WRITEBACK_INVALIDATE(addr, size) \
+ dma_cache_maint((void *)addr, size, DMA_BIDIRECTIONAL)
+
+/* DM644x does not have BD's in cached memory - so no cache functions */
+#define BD_CACHE_INVALIDATE(addr, size)
+#define BD_CACHE_WRITEBACK(addr, size)
+#define BD_CACHE_WRITEBACK_INVALIDATE(addr, size)
+
+/* EMAC TX Host Error description strings */
+static char *emac_txhost_errcodes[16] = {
+ "No error", "SOP error", "Ownership bit not set in SOP buffer",
+ "Zero Next Buffer Descriptor Pointer Without EOP",
+ "Zero Buffer Pointer", "Zero Buffer Length", "Packet Length Error",
+ "Reserved", "Reserved", "Reserved", "Reserved", "Reserved",
+ "Reserved", "Reserved", "Reserved", "Reserved"
+};
+
+/* EMAC RX Host Error description strings */
+static char *emac_rxhost_errcodes[16] = {
+ "No error", "Reserved", "Ownership bit not set in input buffer",
+ "Reserved", "Zero Buffer Pointer", "Reserved", "Reserved",
+ "Reserved", "Reserved", "Reserved", "Reserved", "Reserved",
+ "Reserved", "Reserved", "Reserved", "Reserved"
+};
+
+/* Helper macros */
+#define emac_read(reg) ioread32(priv->emac_base + (reg))
+#define emac_write(reg, val) iowrite32(val, priv->emac_base + (reg))
+
+#define emac_ctrl_read(reg) ioread32((priv->ctrl_base + (reg)))
+#define emac_ctrl_write(reg, val) iowrite32(val, (priv->ctrl_base + (reg)))
+
+#define emac_mdio_read(reg) ioread32(bus->priv + (reg))
+#define emac_mdio_write(reg, val) iowrite32(val, (bus->priv + (reg)))
+
+/**
+ * emac_dump_regs: Dump important EMAC registers to debug terminal
+ * @priv: The DaVinci EMAC private adapter structure
+ *
+ * Executes ethtool set cmd & sets phy mode
+ *
+ */
+static void emac_dump_regs(struct emac_priv *priv)
+{
+ struct device *emac_dev = &priv->ndev->dev;
+
+ /* Print important registers in EMAC */
+ dev_info(emac_dev, "EMAC Basic registers\n");
+ dev_info(emac_dev, "EMAC: EWCTL: %08X, EWINTTCNT: %08X\n",
+ emac_ctrl_read(EMAC_CTRL_EWCTL),
+ emac_ctrl_read(EMAC_CTRL_EWINTTCNT));
+ dev_info(emac_dev, "EMAC: TXID: %08X %s, RXID: %08X %s\n",
+ emac_read(EMAC_TXIDVER),
+ ((emac_read(EMAC_TXCONTROL)) ? "enabled" : "disabled"),
+ emac_read(EMAC_RXIDVER),
+ ((emac_read(EMAC_RXCONTROL)) ? "enabled" : "disabled"));
+ dev_info(emac_dev, "EMAC: TXIntRaw:%08X, TxIntMasked: %08X, "\
+ "TxIntMasSet: %08X\n", emac_read(EMAC_TXINTSTATRAW),
+ emac_read(EMAC_TXINTSTATMASKED), emac_read(EMAC_TXINTMASKSET));
+ dev_info(emac_dev, "EMAC: RXIntRaw:%08X, RxIntMasked: %08X, "\
+ "RxIntMasSet: %08X\n", emac_read(EMAC_RXINTSTATRAW),
+ emac_read(EMAC_RXINTSTATMASKED), emac_read(EMAC_RXINTMASKSET));
+ dev_info(emac_dev, "EMAC: MacIntRaw:%08X, MacIntMasked: %08X, "\
+ "MacInVector=%08X\n", emac_read(EMAC_MACINTSTATRAW),
+ emac_read(EMAC_MACINTSTATMASKED), emac_read(EMAC_MACINVECTOR));
+ dev_info(emac_dev, "EMAC: EmuControl:%08X, FifoControl: %08X\n",
+ emac_read(EMAC_EMCONTROL), emac_read(EMAC_FIFOCONTROL));
+ dev_info(emac_dev, "EMAC: MBPEnable:%08X, RXUnicastSet: %08X, "\
+ "RXMaxLen=%08X\n", emac_read(EMAC_RXMBPENABLE),
+ emac_read(EMAC_RXUNICASTSET), emac_read(EMAC_RXMAXLEN));
+ dev_info(emac_dev, "EMAC: MacControl:%08X, MacStatus: %08X, "\
+ "MacConfig=%08X\n", emac_read(EMAC_MACCONTROL),
+ emac_read(EMAC_MACSTATUS), emac_read(EMAC_MACCONFIG));
+ dev_info(emac_dev, "EMAC: TXHDP[0]:%08X, RXHDP[0]: %08X\n",
+ emac_read(EMAC_TXHDP(0)), emac_read(EMAC_RXHDP(0)));
+ dev_info(emac_dev, "EMAC Statistics\n");
+ dev_info(emac_dev, "EMAC: rx_good_frames:%d\n",
+ emac_read(EMAC_RXGOODFRAMES));
+ dev_info(emac_dev, "EMAC: rx_broadcast_frames:%d\n",
+ emac_read(EMAC_RXBCASTFRAMES));
+ dev_info(emac_dev, "EMAC: rx_multicast_frames:%d\n",
+ emac_read(EMAC_RXMCASTFRAMES));
+ dev_info(emac_dev, "EMAC: rx_pause_frames:%d\n",
+ emac_read(EMAC_RXPAUSEFRAMES));
+ dev_info(emac_dev, "EMAC: rx_crcerrors:%d\n",
+ emac_read(EMAC_RXCRCERRORS));
+ dev_info(emac_dev, "EMAC: rx_align_code_errors:%d\n",
+ emac_read(EMAC_RXALIGNCODEERRORS));
+ dev_info(emac_dev, "EMAC: rx_oversized_frames:%d\n",
+ emac_read(EMAC_RXOVERSIZED));
+ dev_info(emac_dev, "EMAC: rx_jabber_frames:%d\n",
+ emac_read(EMAC_RXJABBER));
+ dev_info(emac_dev, "EMAC: rx_undersized_frames:%d\n",
+ emac_read(EMAC_RXUNDERSIZED));
+ dev_info(emac_dev, "EMAC: rx_fragments:%d\n",
+ emac_read(EMAC_RXFRAGMENTS));
+ dev_info(emac_dev, "EMAC: rx_filtered_frames:%d\n",
+ emac_read(EMAC_RXFILTERED));
+ dev_info(emac_dev, "EMAC: rx_qos_filtered_frames:%d\n",
+ emac_read(EMAC_RXQOSFILTERED));
+ dev_info(emac_dev, "EMAC: rx_octets:%d\n",
+ emac_read(EMAC_RXOCTETS));
+ dev_info(emac_dev, "EMAC: tx_goodframes:%d\n",
+ emac_read(EMAC_TXGOODFRAMES));
+ dev_info(emac_dev, "EMAC: tx_bcastframes:%d\n",
+ emac_read(EMAC_TXBCASTFRAMES));
+ dev_info(emac_dev, "EMAC: tx_mcastframes:%d\n",
+ emac_read(EMAC_TXMCASTFRAMES));
+ dev_info(emac_dev, "EMAC: tx_pause_frames:%d\n",
+ emac_read(EMAC_TXPAUSEFRAMES));
+ dev_info(emac_dev, "EMAC: tx_deferred_frames:%d\n",
+ emac_read(EMAC_TXDEFERRED));
+ dev_info(emac_dev, "EMAC: tx_collision_frames:%d\n",
+ emac_read(EMAC_TXCOLLISION));
+ dev_info(emac_dev, "EMAC: tx_single_coll_frames:%d\n",
+ emac_read(EMAC_TXSINGLECOLL));
+ dev_info(emac_dev, "EMAC: tx_mult_coll_frames:%d\n",
+ emac_read(EMAC_TXMULTICOLL));
+ dev_info(emac_dev, "EMAC: tx_excessive_collisions:%d\n",
+ emac_read(EMAC_TXEXCESSIVECOLL));
+ dev_info(emac_dev, "EMAC: tx_late_collisions:%d\n",
+ emac_read(EMAC_TXLATECOLL));
+ dev_info(emac_dev, "EMAC: tx_underrun:%d\n",
+ emac_read(EMAC_TXUNDERRUN));
+ dev_info(emac_dev, "EMAC: tx_carrier_sense_errors:%d\n",
+ emac_read(EMAC_TXCARRIERSENSE));
+ dev_info(emac_dev, "EMAC: tx_octets:%d\n",
+ emac_read(EMAC_TXOCTETS));
+ dev_info(emac_dev, "EMAC: net_octets:%d\n",
+ emac_read(EMAC_NETOCTETS));
+ dev_info(emac_dev, "EMAC: rx_sof_overruns:%d\n",
+ emac_read(EMAC_RXSOFOVERRUNS));
+ dev_info(emac_dev, "EMAC: rx_mof_overruns:%d\n",
+ emac_read(EMAC_RXMOFOVERRUNS));
+ dev_info(emac_dev, "EMAC: rx_dma_overruns:%d\n",
+ emac_read(EMAC_RXDMAOVERRUNS));
+}
+
+/*************************************************************************
+ * EMAC MDIO/Phy Functionality
+ *************************************************************************/
+/**
+ * emac_get_drvinfo: Get EMAC driver information
+ * @ndev: The DaVinci EMAC network adapter
+ * @info: ethtool info structure containing name and version
+ *
+ * Returns EMAC driver information (name and version)
+ *
+ */
+static void emac_get_drvinfo(struct net_device *ndev,
+ struct ethtool_drvinfo *info)
+{
+ strcpy(info->driver, emac_version_string);
+ strcpy(info->version, EMAC_MODULE_VERSION);
+}
+
+/**
+ * emac_get_settings: Get EMAC settings
+ * @ndev: The DaVinci EMAC network adapter
+ * @ecmd: ethtool command
+ *
+ * Executes ethool get command
+ *
+ */
+static int emac_get_settings(struct net_device *ndev,
+ struct ethtool_cmd *ecmd)
+{
+ struct emac_priv *priv = netdev_priv(ndev);
+ if (priv->phy_mask)
+ return phy_ethtool_gset(priv->phydev, ecmd);
+ else
+ return -EOPNOTSUPP;
+
+}
+
+/**
+ * emac_set_settings: Set EMAC settings
+ * @ndev: The DaVinci EMAC network adapter
+ * @ecmd: ethtool command
+ *
+ * Executes ethool set command
+ *
+ */
+static int emac_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd)
+{
+ struct emac_priv *priv = netdev_priv(ndev);
+ if (priv->phy_mask)
+ return phy_ethtool_sset(priv->phydev, ecmd);
+ else
+ return -EOPNOTSUPP;
+
+}
+
+/**
+ * ethtool_ops: DaVinci EMAC Ethtool structure
+ *
+ * Ethtool support for EMAC adapter
+ *
+ */
+static const struct ethtool_ops ethtool_ops = {
+ .get_drvinfo = emac_get_drvinfo,
+ .get_settings = emac_get_settings,
+ .set_settings = emac_set_settings,
+ .get_link = ethtool_op_get_link,
+};
+
+/**
+ * emac_update_phystatus: Update Phy status
+ * @priv: The DaVinci EMAC private adapter structure
+ *
+ * Updates phy status and takes action for network queue if required
+ * based upon link status
+ *
+ */
+static void emac_update_phystatus(struct emac_priv *priv)
+{
+ u32 mac_control;
+ u32 new_duplex;
+ u32 cur_duplex;
+ struct net_device *ndev = priv->ndev;
+
+ mac_control = emac_read(EMAC_MACCONTROL);
+ cur_duplex = (mac_control & EMAC_MACCONTROL_FULLDUPLEXEN) ?
+ DUPLEX_FULL : DUPLEX_HALF;
+ if (priv->phy_mask)
+ new_duplex = priv->phydev->duplex;
+ else
+ new_duplex = DUPLEX_FULL;
+
+ /* We get called only if link has changed (speed/duplex/status) */
+ if ((priv->link) && (new_duplex != cur_duplex)) {
+ priv->duplex = new_duplex;
+ if (DUPLEX_FULL == priv->duplex)
+ mac_control |= (EMAC_MACCONTROL_FULLDUPLEXEN);
+ else
+ mac_control &= ~(EMAC_MACCONTROL_FULLDUPLEXEN);
+ }
+
+ if (priv->speed == SPEED_1000 && (priv->version == EMAC_VERSION_2)) {
+ mac_control = emac_read(EMAC_MACCONTROL);
+ mac_control |= (EMAC_DM646X_MACCONTORL_GMIIEN |
+ EMAC_DM646X_MACCONTORL_GIG |
+ EMAC_DM646X_MACCONTORL_GIGFORCE);
+ } else {
+ /* Clear the GIG bit and GIGFORCE bit */
+ mac_control &= ~(EMAC_DM646X_MACCONTORL_GIGFORCE |
+ EMAC_DM646X_MACCONTORL_GIG);
+
+ if (priv->rmii_en && (priv->speed == SPEED_100))
+ mac_control |= EMAC_MACCONTROL_RMIISPEED_MASK;
+ else
+ mac_control &= ~EMAC_MACCONTROL_RMIISPEED_MASK;
+ }
+
+ /* Update mac_control if changed */
+ emac_write(EMAC_MACCONTROL, mac_control);
+
+ if (priv->link) {
+ /* link ON */
+ if (!netif_carrier_ok(ndev))
+ netif_carrier_on(ndev);
+ /* reactivate the transmit queue if it is stopped */
+ if (netif_running(ndev) && netif_queue_stopped(ndev))
+ netif_wake_queue(ndev);
+ } else {
+ /* link OFF */
+ if (netif_carrier_ok(ndev))
+ netif_carrier_off(ndev);
+ if (!netif_queue_stopped(ndev))
+ netif_stop_queue(ndev);
+ }
+}
+
+/**
+ * hash_get: Calculate hash value from mac address
+ * @addr: mac address to delete from hash table
+ *
+ * Calculates hash value from mac address
+ *
+ */
+static u32 hash_get(u8 *addr)
+{
+ u32 hash;
+ u8 tmpval;
+ int cnt;
+ hash = 0;
+
+ for (cnt = 0; cnt < 2; cnt++) {
+ tmpval = *addr++;
+ hash ^= (tmpval >> 2) ^ (tmpval << 4);
+ tmpval = *addr++;
+ hash ^= (tmpval >> 4) ^ (tmpval << 2);
+ tmpval = *addr++;
+ hash ^= (tmpval >> 6) ^ (tmpval);
+ }
+
+ return hash & 0x3F;
+}
+
+/**
+ * hash_add: Hash function to add mac addr from hash table
+ * @priv: The DaVinci EMAC private adapter structure
+ * mac_addr: mac address to delete from hash table
+ *
+ * Adds mac address to the internal hash table
+ *
+ */
+static int hash_add(struct emac_priv *priv, u8 *mac_addr)
+{
+ struct device *emac_dev = &priv->ndev->dev;
+ u32 rc = 0;
+ u32 hash_bit;
+ u32 hash_value = hash_get(mac_addr);
+
+ if (hash_value >= EMAC_NUM_MULTICAST_BITS) {
+ if (netif_msg_drv(priv)) {
+ dev_err(emac_dev, "DaVinci EMAC: hash_add(): Invalid "\
+ "Hash %08x, should not be greater than %08x",
+ hash_value, (EMAC_NUM_MULTICAST_BITS - 1));
+ }
+ return -1;
+ }
+
+ /* set the hash bit only if not previously set */
+ if (priv->multicast_hash_cnt[hash_value] == 0) {
+ rc = 1; /* hash value changed */
+ if (hash_value < 32) {
+ hash_bit = BIT(hash_value);
+ priv->mac_hash1 |= hash_bit;
+ } else {
+ hash_bit = BIT((hash_value - 32));
+ priv->mac_hash2 |= hash_bit;
+ }
+ }
+
+ /* incr counter for num of mcast addr's mapped to "this" hash bit */
+ ++priv->multicast_hash_cnt[hash_value];
+
+ return rc;
+}
+
+/**
+ * hash_del: Hash function to delete mac addr from hash table
+ * @priv: The DaVinci EMAC private adapter structure
+ * mac_addr: mac address to delete from hash table
+ *
+ * Removes mac address from the internal hash table
+ *
+ */
+static int hash_del(struct emac_priv *priv, u8 *mac_addr)
+{
+ u32 hash_value;
+ u32 hash_bit;
+
+ hash_value = hash_get(mac_addr);
+ if (priv->multicast_hash_cnt[hash_value] > 0) {
+ /* dec cntr for num of mcast addr's mapped to this hash bit */
+ --priv->multicast_hash_cnt[hash_value];
+ }
+
+ /* if counter still > 0, at least one multicast address refers
+ * to this hash bit. so return 0 */
+ if (priv->multicast_hash_cnt[hash_value] > 0)
+ return 0;
+
+ if (hash_value < 32) {
+ hash_bit = BIT(hash_value);
+ priv->mac_hash1 &= ~hash_bit;
+ } else {
+ hash_bit = BIT((hash_value - 32));
+ priv->mac_hash2 &= ~hash_bit;
+ }
+
+ /* return 1 to indicate change in mac_hash registers reqd */
+ return 1;
+}
+
+/* EMAC multicast operation */
+#define EMAC_MULTICAST_ADD 0
+#define EMAC_MULTICAST_DEL 1
+#define EMAC_ALL_MULTI_SET 2
+#define EMAC_ALL_MULTI_CLR 3
+
+/**
+ * emac_add_mcast: Set multicast address in the EMAC adapter (Internal)
+ * @priv: The DaVinci EMAC private adapter structure
+ * @action: multicast operation to perform
+ * mac_addr: mac address to set
+ *
+ * Set multicast addresses in EMAC adapter - internal function
+ *
+ */
+static void emac_add_mcast(struct emac_priv *priv, u32 action, u8 *mac_addr)
+{
+ struct device *emac_dev = &priv->ndev->dev;
+ int update = -1;
+
+ switch (action) {
+ case EMAC_MULTICAST_ADD:
+ update = hash_add(priv, mac_addr);
+ break;
+ case EMAC_MULTICAST_DEL:
+ update = hash_del(priv, mac_addr);
+ break;
+ case EMAC_ALL_MULTI_SET:
+ update = 1;
+ priv->mac_hash1 = EMAC_ALL_MULTI_REG_VALUE;
+ priv->mac_hash2 = EMAC_ALL_MULTI_REG_VALUE;
+ break;
+ case EMAC_ALL_MULTI_CLR:
+ update = 1;
+ priv->mac_hash1 = 0;
+ priv->mac_hash2 = 0;
+ memset(&(priv->multicast_hash_cnt[0]), 0,
+ sizeof(priv->multicast_hash_cnt[0]) *
+ EMAC_NUM_MULTICAST_BITS);
+ break;
+ default:
+ if (netif_msg_drv(priv))
+ dev_err(emac_dev, "DaVinci EMAC: add_mcast"\
+ ": bad operation %d", action);
+ break;
+ }
+
+ /* write to the hardware only if the register status chances */
+ if (update > 0) {
+ emac_write(EMAC_MACHASH1, priv->mac_hash1);
+ emac_write(EMAC_MACHASH2, priv->mac_hash2);
+ }
+}
+
+/**
+ * emac_dev_mcast_set: Set multicast address in the EMAC adapter
+ * @ndev: The DaVinci EMAC network adapter
+ *
+ * Set multicast addresses in EMAC adapter
+ *
+ */
+static void emac_dev_mcast_set(struct net_device *ndev)
+{
+ u32 mbp_enable;
+ struct emac_priv *priv = netdev_priv(ndev);
+
+ mbp_enable = emac_read(EMAC_RXMBPENABLE);
+ if (ndev->flags & IFF_PROMISC) {
+ mbp_enable &= (~EMAC_MBP_PROMISCCH(EMAC_DEF_PROM_CH));
+ mbp_enable |= (EMAC_MBP_RXPROMISC);
+ } else {
+ mbp_enable = (mbp_enable & ~EMAC_MBP_RXPROMISC);
+ if ((ndev->flags & IFF_ALLMULTI) ||
+ (ndev->mc_count > EMAC_DEF_MAX_MULTICAST_ADDRESSES)) {
+ mbp_enable = (mbp_enable | EMAC_MBP_RXMCAST);
+ emac_add_mcast(priv, EMAC_ALL_MULTI_SET, NULL);
+ }
+ if (ndev->mc_count > 0) {
+ struct dev_mc_list *mc_ptr;
+ mbp_enable = (mbp_enable | EMAC_MBP_RXMCAST);
+ emac_add_mcast(priv, EMAC_ALL_MULTI_CLR, NULL);
+ /* program multicast address list into EMAC hardware */
+ for (mc_ptr = ndev->mc_list; mc_ptr;
+ mc_ptr = mc_ptr->next) {
+ emac_add_mcast(priv, EMAC_MULTICAST_ADD,
+ (u8 *)mc_ptr->dmi_addr);
+ }
+ } else {
+ mbp_enable = (mbp_enable & ~EMAC_MBP_RXMCAST);
+ emac_add_mcast(priv, EMAC_ALL_MULTI_CLR, NULL);
+ }
+ }
+ /* Set mbp config register */
+ emac_write(EMAC_RXMBPENABLE, mbp_enable);
+}
+
+/*************************************************************************
+ * EMAC Hardware manipulation
+ *************************************************************************/
+
+/**
+ * emac_int_disable: Disable EMAC module interrupt (from adapter)
+ * @priv: The DaVinci EMAC private adapter structure
+ *
+ * Disable EMAC interrupt on the adapter
+ *
+ */
+static void emac_int_disable(struct emac_priv *priv)
+{
+ if (priv->version == EMAC_VERSION_2) {
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ /* Program C0_Int_En to zero to turn off
+ * interrupts to the CPU */
+ emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0x0);
+ emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0x0);
+ /* NOTE: Rx Threshold and Misc interrupts are not disabled */
+
+ local_irq_restore(flags);
+
+ } else {
+ /* Set DM644x control registers for interrupt control */
+ emac_ctrl_write(EMAC_CTRL_EWCTL, 0x0);
+ }
+}
+
+/**
+ * emac_int_enable: Enable EMAC module interrupt (from adapter)
+ * @priv: The DaVinci EMAC private adapter structure
+ *
+ * Enable EMAC interrupt on the adapter
+ *
+ */
+static void emac_int_enable(struct emac_priv *priv)
+{
+ if (priv->version == EMAC_VERSION_2) {
+ emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0xff);
+ emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0xff);
+
+ /* In addition to turning on interrupt Enable, we need
+ * ack by writing appropriate values to the EOI
+ * register */
+
+ /* NOTE: Rx Threshold and Misc interrupts are not enabled */
+
+ /* ack rxen only then a new pulse will be generated */
+ emac_write(EMAC_DM646X_MACEOIVECTOR,
+ EMAC_DM646X_MAC_EOI_C0_RXEN);
+
+ /* ack txen- only then a new pulse will be generated */
+ emac_write(EMAC_DM646X_MACEOIVECTOR,
+ EMAC_DM646X_MAC_EOI_C0_TXEN);
+
+ } else {
+ /* Set DM644x control registers for interrupt control */
+ emac_ctrl_write(EMAC_CTRL_EWCTL, 0x1);
+ }
+}
+
+/**
+ * emac_irq: EMAC interrupt handler
+ * @irq: interrupt number
+ * @dev_id: EMAC network adapter data structure ptr
+ *
+ * EMAC Interrupt handler - we only schedule NAPI and not process any packets
+ * here. EVen the interrupt status is checked (TX/RX/Err) in NAPI poll function
+ *
+ * Returns interrupt handled condition
+ */
+static irqreturn_t emac_irq(int irq, void *dev_id)
+{
+ struct net_device *ndev = (struct net_device *)dev_id;
+ struct emac_priv *priv = netdev_priv(ndev);
+
+ ++priv->isr_count;
+ if (likely(netif_running(priv->ndev))) {
+ emac_int_disable(priv);
+ napi_schedule(&priv->napi);
+ } else {
+ /* we are closing down, so dont process anything */
+ }
+ return IRQ_HANDLED;
+}
+
+/** EMAC on-chip buffer descriptor memory
+ *
+ * WARNING: Please note that the on chip memory is used for both TX and RX
+ * buffer descriptor queues and is equally divided between TX and RX desc's
+ * If the number of TX or RX descriptors change this memory pointers need
+ * to be adjusted. If external memory is allocated then these pointers can
+ * pointer to the memory
+ *
+ */
+#define EMAC_TX_BD_MEM(priv) ((priv)->emac_ctrl_ram)
+#define EMAC_RX_BD_MEM(priv) ((priv)->emac_ctrl_ram + \
+ (((priv)->ctrl_ram_size) >> 1))
+
+/**
+ * emac_init_txch: TX channel initialization
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ *
+ * Called during device init to setup a TX channel (allocate buffer desc
+ * create free pool and keep ready for transmission
+ *
+ * Returns success(0) or mem alloc failures error code
+ */
+static int emac_init_txch(struct emac_priv *priv, u32 ch)
+{
+ struct device *emac_dev = &priv->ndev->dev;
+ u32 cnt, bd_size;
+ void __iomem *mem;
+ struct emac_tx_bd __iomem *curr_bd;
+ struct emac_txch *txch = NULL;
+
+ txch = kzalloc(sizeof(struct emac_txch), GFP_KERNEL);
+ if (NULL == txch) {
+ dev_err(emac_dev, "DaVinci EMAC: TX Ch mem alloc failed");
+ return -ENOMEM;
+ }
+ priv->txch[ch] = txch;
+ txch->service_max = EMAC_DEF_TX_MAX_SERVICE;
+ txch->active_queue_head = NULL;
+ txch->active_queue_tail = NULL;
+ txch->queue_active = 0;
+ txch->teardown_pending = 0;
+
+ /* allocate memory for TX CPPI channel on a 4 byte boundry */
+ txch->tx_complete = kzalloc(txch->service_max * sizeof(u32),
+ GFP_KERNEL);
+ if (NULL == txch->tx_complete) {
+ dev_err(emac_dev, "DaVinci EMAC: Tx service mem alloc failed");
+ kfree(txch);
+ return -ENOMEM;
+ }
+
+ /* allocate buffer descriptor pool align every BD on four word
+ * boundry for future requirements */
+ bd_size = (sizeof(struct emac_tx_bd) + 0xF) & ~0xF;
+ txch->num_bd = (priv->ctrl_ram_size >> 1) / bd_size;
+ txch->alloc_size = (((bd_size * txch->num_bd) + 0xF) & ~0xF);
+
+ /* alloc TX BD memory */
+ txch->bd_mem = EMAC_TX_BD_MEM(priv);
+ __memzero((void __force *)txch->bd_mem, txch->alloc_size);
+
+ /* initialize the BD linked list */
+ mem = (void __force __iomem *)
+ (((u32 __force) txch->bd_mem + 0xF) & ~0xF);
+ txch->bd_pool_head = NULL;
+ for (cnt = 0; cnt < txch->num_bd; cnt++) {
+ curr_bd = mem + (cnt * bd_size);
+ curr_bd->next = txch->bd_pool_head;
+ txch->bd_pool_head = curr_bd;
+ }
+
+ /* reset statistics counters */
+ txch->out_of_tx_bd = 0;
+ txch->no_active_pkts = 0;
+ txch->active_queue_count = 0;
+
+ return 0;
+}
+
+/**
+ * emac_cleanup_txch: Book-keep function to clean TX channel resources
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: TX channel number
+ *
+ * Called to clean up TX channel resources
+ *
+ */
+static void emac_cleanup_txch(struct emac_priv *priv, u32 ch)
+{
+ struct emac_txch *txch = priv->txch[ch];
+
+ if (txch) {
+ if (txch->bd_mem)
+ txch->bd_mem = NULL;
+ kfree(txch->tx_complete);
+ kfree(txch);
+ priv->txch[ch] = NULL;
+ }
+}
+
+/**
+ * emac_net_tx_complete: TX packet completion function
+ * @priv: The DaVinci EMAC private adapter structure
+ * @net_data_tokens: packet token - skb pointer
+ * @num_tokens: number of skb's to free
+ * @ch: TX channel number
+ *
+ * Frees the skb once packet is transmitted
+ *
+ */
+static int emac_net_tx_complete(struct emac_priv *priv,
+ void **net_data_tokens,
+ int num_tokens, u32 ch)
+{
+ u32 cnt;
+
+ if (unlikely(num_tokens && netif_queue_stopped(priv->ndev)))
+ netif_start_queue(priv->ndev);
+ for (cnt = 0; cnt < num_tokens; cnt++) {
+ struct sk_buff *skb = (struct sk_buff *)net_data_tokens[cnt];
+ if (skb == NULL)
+ continue;
+ priv->net_dev_stats.tx_packets++;
+ priv->net_dev_stats.tx_bytes += skb->len;
+ dev_kfree_skb_any(skb);
+ }
+ return 0;
+}
+
+/**
+ * emac_txch_teardown: TX channel teardown
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: TX channel number
+ *
+ * Called to teardown TX channel
+ *
+ */
+static void emac_txch_teardown(struct emac_priv *priv, u32 ch)
+{
+ struct device *emac_dev = &priv->ndev->dev;
+ u32 teardown_cnt = 0xFFFFFFF0; /* Some high value */
+ struct emac_txch *txch = priv->txch[ch];
+ struct emac_tx_bd __iomem *curr_bd;
+
+ while ((emac_read(EMAC_TXCP(ch)) & EMAC_TEARDOWN_VALUE) !=
+ EMAC_TEARDOWN_VALUE) {
+ /* wait till tx teardown complete */
+ cpu_relax(); /* TODO: check if this helps ... */
+ --teardown_cnt;
+ if (0 == teardown_cnt) {
+ dev_err(emac_dev, "EMAC: TX teardown aborted\n");
+ break;
+ }
+ }
+ emac_write(EMAC_TXCP(ch), EMAC_TEARDOWN_VALUE);
+
+ /* process sent packets and return skb's to upper layer */
+ if (1 == txch->queue_active) {
+ curr_bd = txch->active_queue_head;
+ while (curr_bd != NULL) {
+ emac_net_tx_complete(priv, (void __force *)
+ &curr_bd->buf_token, 1, ch);
+ if (curr_bd != txch->active_queue_tail)
+ curr_bd = curr_bd->next;
+ else
+ break;
+ }
+ txch->bd_pool_head = txch->active_queue_head;
+ txch->active_queue_head =
+ txch->active_queue_tail = NULL;
+ }
+}
+
+/**
+ * emac_stop_txch: Stop TX channel operation
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: TX channel number
+ *
+ * Called to stop TX channel operation
+ *
+ */
+static void emac_stop_txch(struct emac_priv *priv, u32 ch)
+{
+ struct emac_txch *txch = priv->txch[ch];
+
+ if (txch) {
+ txch->teardown_pending = 1;
+ emac_write(EMAC_TXTEARDOWN, 0);
+ emac_txch_teardown(priv, ch);
+ txch->teardown_pending = 0;
+ emac_write(EMAC_TXINTMASKCLEAR, BIT(ch));
+ }
+}
+
+/**
+ * emac_tx_bdproc: TX buffer descriptor (packet) processing
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: TX channel number to process buffer descriptors for
+ * @budget: number of packets allowed to process
+ * @pending: indication to caller that packets are pending to process
+ *
+ * Processes TX buffer descriptors after packets are transmitted - checks
+ * ownership bit on the TX * descriptor and requeues it to free pool & frees
+ * the SKB buffer. Only "budget" number of packets are processed and
+ * indication of pending packets provided to the caller
+ *
+ * Returns number of packets processed
+ */
+static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
+{
+ struct device *emac_dev = &priv->ndev->dev;
+ unsigned long flags;
+ u32 frame_status;
+ u32 pkts_processed = 0;
+ u32 tx_complete_cnt = 0;
+ struct emac_tx_bd __iomem *curr_bd;
+ struct emac_txch *txch = priv->txch[ch];
+ u32 *tx_complete_ptr = txch->tx_complete;
+
+ if (unlikely(1 == txch->teardown_pending)) {
+ if (netif_msg_tx_err(priv) && net_ratelimit()) {
+ dev_err(emac_dev, "DaVinci EMAC:emac_tx_bdproc: "\
+ "teardown pending\n");
+ }
+ return 0; /* dont handle any pkt completions */
+ }
+
+ ++txch->proc_count;
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ curr_bd = txch->active_queue_head;
+ if (NULL == curr_bd) {
+ emac_write(EMAC_TXCP(ch),
+ emac_virt_to_phys(txch->last_hw_bdprocessed));
+ txch->no_active_pkts++;
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ return 0;
+ }
+ BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+ frame_status = curr_bd->mode;
+ while ((curr_bd) &&
+ ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
+ (pkts_processed < budget)) {
+ emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd));
+ txch->active_queue_head = curr_bd->next;
+ if (frame_status & EMAC_CPPI_EOQ_BIT) {
+ if (curr_bd->next) { /* misqueued packet */
+ emac_write(EMAC_TXHDP(ch), curr_bd->h_next);
+ ++txch->mis_queued_packets;
+ } else {
+ txch->queue_active = 0; /* end of queue */
+ }
+ }
+ *tx_complete_ptr = (u32) curr_bd->buf_token;
+ ++tx_complete_ptr;
+ ++tx_complete_cnt;
+ curr_bd->next = txch->bd_pool_head;
+ txch->bd_pool_head = curr_bd;
+ --txch->active_queue_count;
+ pkts_processed++;
+ txch->last_hw_bdprocessed = curr_bd;
+ curr_bd = txch->active_queue_head;
+ if (curr_bd) {
+ BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+ frame_status = curr_bd->mode;
+ }
+ } /* end of pkt processing loop */
+
+ emac_net_tx_complete(priv,
+ (void *)&txch->tx_complete[0],
+ tx_complete_cnt, ch);
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ return pkts_processed;
+}
+
+#define EMAC_ERR_TX_OUT_OF_BD -1
+
+/**
+ * emac_send: EMAC Transmit function (internal)
+ * @priv: The DaVinci EMAC private adapter structure
+ * @pkt: packet pointer (contains skb ptr)
+ * @ch: TX channel number
+ *
+ * Called by the transmit function to queue the packet in EMAC hardware queue
+ *
+ * Returns success(0) or error code (typically out of desc's)
+ */
+static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch)
+{
+ unsigned long flags;
+ struct emac_tx_bd __iomem *curr_bd;
+ struct emac_txch *txch;
+ struct emac_netbufobj *buf_list;
+
+ txch = priv->txch[ch];
+ buf_list = pkt->buf_list; /* get handle to the buffer array */
+
+ /* check packet size and pad if short */
+ if (pkt->pkt_length < EMAC_DEF_MIN_ETHPKTSIZE) {
+ buf_list->length += (EMAC_DEF_MIN_ETHPKTSIZE - pkt->pkt_length);
+ pkt->pkt_length = EMAC_DEF_MIN_ETHPKTSIZE;
+ }
+
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ curr_bd = txch->bd_pool_head;
+ if (curr_bd == NULL) {
+ txch->out_of_tx_bd++;
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ return EMAC_ERR_TX_OUT_OF_BD;
+ }
+
+ txch->bd_pool_head = curr_bd->next;
+ curr_bd->buf_token = buf_list->buf_token;
+ /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
+ curr_bd->buff_ptr = virt_to_phys(buf_list->data_ptr);
+ curr_bd->off_b_len = buf_list->length;
+ curr_bd->h_next = 0;
+ curr_bd->next = NULL;
+ curr_bd->mode = (EMAC_CPPI_SOP_BIT | EMAC_CPPI_OWNERSHIP_BIT |
+ EMAC_CPPI_EOP_BIT | pkt->pkt_length);
+
+ /* flush the packet from cache if write back cache is present */
+ BD_CACHE_WRITEBACK_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+
+ /* send the packet */
+ if (txch->active_queue_head == NULL) {
+ txch->active_queue_head = curr_bd;
+ txch->active_queue_tail = curr_bd;
+ if (1 != txch->queue_active) {
+ emac_write(EMAC_TXHDP(ch),
+ emac_virt_to_phys(curr_bd));
+ txch->queue_active = 1;
+ }
+ ++txch->queue_reinit;
+ } else {
+ register struct emac_tx_bd __iomem *tail_bd;
+ register u32 frame_status;
+
+ tail_bd = txch->active_queue_tail;
+ tail_bd->next = curr_bd;
+ txch->active_queue_tail = curr_bd;
+ tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
+ tail_bd->h_next = (int)emac_virt_to_phys(curr_bd);
+ frame_status = tail_bd->mode;
+ if (frame_status & EMAC_CPPI_EOQ_BIT) {
+ emac_write(EMAC_TXHDP(ch), emac_virt_to_phys(curr_bd));
+ frame_status &= ~(EMAC_CPPI_EOQ_BIT);
+ tail_bd->mode = frame_status;
+ ++txch->end_of_queue_add;
+ }
+ }
+ txch->active_queue_count++;
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ return 0;
+}
+
+/**
+ * emac_dev_xmit: EMAC Transmit function
+ * @skb: SKB pointer
+ * @ndev: The DaVinci EMAC network adapter
+ *
+ * Called by the system to transmit a packet - we queue the packet in
+ * EMAC hardware transmit queue
+ *
+ * Returns success(NETDEV_TX_OK) or error code (typically out of desc's)
+ */
+static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct device *emac_dev = &ndev->dev;
+ int ret_code;
+ struct emac_netbufobj tx_buf; /* buffer obj-only single frame support */
+ struct emac_netpktobj tx_packet; /* packet object */
+ struct emac_priv *priv = netdev_priv(ndev);
+
+ /* If no link, return */
+ if (unlikely(!priv->link)) {
+ if (netif_msg_tx_err(priv) && net_ratelimit())
+ dev_err(emac_dev, "DaVinci EMAC: No link to transmit");
+ return NETDEV_TX_BUSY;
+ }
+
+ /* Build the buffer and packet objects - Since only single fragment is
+ * supported, need not set length and token in both packet & object.
+ * Doing so for completeness sake & to show that this needs to be done
+ * in multifragment case
+ */
+ tx_packet.buf_list = &tx_buf;
+ tx_packet.num_bufs = 1; /* only single fragment supported */
+ tx_packet.pkt_length = skb->len;
+ tx_packet.pkt_token = (void *)skb;
+ tx_buf.length = skb->len;
+ tx_buf.buf_token = (void *)skb;
+ tx_buf.data_ptr = skb->data;
+ EMAC_CACHE_WRITEBACK((unsigned long)skb->data, skb->len);
+ ndev->trans_start = jiffies;
+ ret_code = emac_send(priv, &tx_packet, EMAC_DEF_TX_CH);
+ if (unlikely(ret_code != 0)) {
+ if (ret_code == EMAC_ERR_TX_OUT_OF_BD) {
+ if (netif_msg_tx_err(priv) && net_ratelimit())
+ dev_err(emac_dev, "DaVinci EMAC: xmit() fatal"\
+ " err. Out of TX BD's");
+ netif_stop_queue(priv->ndev);
+ }
+ priv->net_dev_stats.tx_dropped++;
+ return NETDEV_TX_BUSY;
+ }
+
+ return NETDEV_TX_OK;
+}
+
+/**
+ * emac_dev_tx_timeout: EMAC Transmit timeout function
+ * @ndev: The DaVinci EMAC network adapter
+ *
+ * Called when system detects that a skb timeout period has expired
+ * potentially due to a fault in the adapter in not being able to send
+ * it out on the wire. We teardown the TX channel assuming a hardware
+ * error and re-initialize the TX channel for hardware operation
+ *
+ */
+static void emac_dev_tx_timeout(struct net_device *ndev)
+{
+ struct emac_priv *priv = netdev_priv(ndev);
+ struct device *emac_dev = &ndev->dev;
+
+ if (netif_msg_tx_err(priv))
+ dev_err(emac_dev, "DaVinci EMAC: xmit timeout, restarting TX");
+
+ priv->net_dev_stats.tx_errors++;
+ emac_int_disable(priv);
+ emac_stop_txch(priv, EMAC_DEF_TX_CH);
+ emac_cleanup_txch(priv, EMAC_DEF_TX_CH);
+ emac_init_txch(priv, EMAC_DEF_TX_CH);
+ emac_write(EMAC_TXHDP(0), 0);
+ emac_write(EMAC_TXINTMASKSET, BIT(EMAC_DEF_TX_CH));
+ emac_int_enable(priv);
+}
+
+/**
+ * emac_net_alloc_rx_buf: Allocate a skb for RX
+ * @priv: The DaVinci EMAC private adapter structure
+ * @buf_size: size of SKB data buffer to allocate
+ * @data_token: data token returned (skb handle for storing in buffer desc)
+ * @ch: RX channel number
+ *
+ * Called during RX channel setup - allocates skb buffer of required size
+ * and provides the skb handle and allocated buffer data pointer to caller
+ *
+ * Returns skb data pointer or 0 on failure to alloc skb
+ */
+static void *emac_net_alloc_rx_buf(struct emac_priv *priv, int buf_size,
+ void **data_token, u32 ch)
+{
+ struct net_device *ndev = priv->ndev;
+ struct device *emac_dev = &ndev->dev;
+ struct sk_buff *p_skb;
+
+ p_skb = dev_alloc_skb(buf_size);
+ if (unlikely(NULL == p_skb)) {
+ if (netif_msg_rx_err(priv) && net_ratelimit())
+ dev_err(emac_dev, "DaVinci EMAC: failed to alloc skb");
+ return NULL;
+ }
+
+ /* set device pointer in skb and reserve space for extra bytes */
+ p_skb->dev = ndev;
+ skb_reserve(p_skb, NET_IP_ALIGN);
+ *data_token = (void *) p_skb;
+ EMAC_CACHE_WRITEBACK_INVALIDATE((unsigned long)p_skb->data, buf_size);
+ return p_skb->data;
+}
+
+/**
+ * emac_init_rxch: RX channel initialization
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ * @param: mac address for RX channel
+ *
+ * Called during device init to setup a RX channel (allocate buffers and
+ * buffer descriptors, create queue and keep ready for reception
+ *
+ * Returns success(0) or mem alloc failures error code
+ */
+static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param)
+{
+ struct device *emac_dev = &priv->ndev->dev;
+ u32 cnt, bd_size;
+ void __iomem *mem;
+ struct emac_rx_bd __iomem *curr_bd;
+ struct emac_rxch *rxch = NULL;
+
+ rxch = kzalloc(sizeof(struct emac_rxch), GFP_KERNEL);
+ if (NULL == rxch) {
+ dev_err(emac_dev, "DaVinci EMAC: RX Ch mem alloc failed");
+ return -ENOMEM;
+ }
+ priv->rxch[ch] = rxch;
+ rxch->buf_size = priv->rx_buf_size;
+ rxch->service_max = EMAC_DEF_RX_MAX_SERVICE;
+ rxch->queue_active = 0;
+ rxch->teardown_pending = 0;
+
+ /* save mac address */
+ for (cnt = 0; cnt < 6; cnt++)
+ rxch->mac_addr[cnt] = param[cnt];
+
+ /* allocate buffer descriptor pool align every BD on four word
+ * boundry for future requirements */
+ bd_size = (sizeof(struct emac_rx_bd) + 0xF) & ~0xF;
+ rxch->num_bd = (priv->ctrl_ram_size >> 1) / bd_size;
+ rxch->alloc_size = (((bd_size * rxch->num_bd) + 0xF) & ~0xF);
+ rxch->bd_mem = EMAC_RX_BD_MEM(priv);
+ __memzero((void __force *)rxch->bd_mem, rxch->alloc_size);
+ rxch->pkt_queue.buf_list = &rxch->buf_queue;
+
+ /* allocate RX buffer and initialize the BD linked list */
+ mem = (void __force __iomem *)
+ (((u32 __force) rxch->bd_mem + 0xF) & ~0xF);
+ rxch->active_queue_head = NULL;
+ rxch->active_queue_tail = mem;
+ for (cnt = 0; cnt < rxch->num_bd; cnt++) {
+ curr_bd = mem + (cnt * bd_size);
+ /* for future use the last parameter contains the BD ptr */
+ curr_bd->data_ptr = emac_net_alloc_rx_buf(priv,
+ rxch->buf_size,
+ (void __force **)&curr_bd->buf_token,
+ EMAC_DEF_RX_CH);
+ if (curr_bd->data_ptr == NULL) {
+ dev_err(emac_dev, "DaVinci EMAC: RX buf mem alloc " \
+ "failed for ch %d\n", ch);
+ kfree(rxch);
+ return -ENOMEM;
+ }
+
+ /* populate the hardware descriptor */
+ curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head);
+ /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
+ curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr);
+ curr_bd->off_b_len = rxch->buf_size;
+ curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
+
+ /* write back to hardware memory */
+ BD_CACHE_WRITEBACK_INVALIDATE((u32) curr_bd,
+ EMAC_BD_LENGTH_FOR_CACHE);
+ curr_bd->next = rxch->active_queue_head;
+ rxch->active_queue_head = curr_bd;
+ }
+
+ /* At this point rxCppi->activeQueueHead points to the first
+ RX BD ready to be given to RX HDP and rxch->active_queue_tail
+ points to the last RX BD
+ */
+ return 0;
+}
+
+/**
+ * emac_rxch_teardown: RX channel teardown
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ *
+ * Called during device stop to teardown RX channel
+ *
+ */
+static void emac_rxch_teardown(struct emac_priv *priv, u32 ch)
+{
+ struct device *emac_dev = &priv->ndev->dev;
+ u32 teardown_cnt = 0xFFFFFFF0; /* Some high value */
+
+ while ((emac_read(EMAC_RXCP(ch)) & EMAC_TEARDOWN_VALUE) !=
+ EMAC_TEARDOWN_VALUE) {
+ /* wait till tx teardown complete */
+ cpu_relax(); /* TODO: check if this helps ... */
+ --teardown_cnt;
+ if (0 == teardown_cnt) {
+ dev_err(emac_dev, "EMAC: RX teardown aborted\n");
+ break;
+ }
+ }
+ emac_write(EMAC_RXCP(ch), EMAC_TEARDOWN_VALUE);
+}
+
+/**
+ * emac_stop_rxch: Stop RX channel operation
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ *
+ * Called during device stop to stop RX channel operation
+ *
+ */
+static void emac_stop_rxch(struct emac_priv *priv, u32 ch)
+{
+ struct emac_rxch *rxch = priv->rxch[ch];
+
+ if (rxch) {
+ rxch->teardown_pending = 1;
+ emac_write(EMAC_RXTEARDOWN, ch);
+ /* wait for teardown complete */
+ emac_rxch_teardown(priv, ch);
+ rxch->teardown_pending = 0;
+ emac_write(EMAC_RXINTMASKCLEAR, BIT(ch));
+ }
+}
+
+/**
+ * emac_cleanup_rxch: Book-keep function to clean RX channel resources
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ *
+ * Called during device stop to clean up RX channel resources
+ *
+ */
+static void emac_cleanup_rxch(struct emac_priv *priv, u32 ch)
+{
+ struct emac_rxch *rxch = priv->rxch[ch];
+ struct emac_rx_bd __iomem *curr_bd;
+
+ if (rxch) {
+ /* free the receive buffers previously allocated */
+ curr_bd = rxch->active_queue_head;
+ while (curr_bd) {
+ if (curr_bd->buf_token) {
+ dev_kfree_skb_any((struct sk_buff *)\
+ curr_bd->buf_token);
+ }
+ curr_bd = curr_bd->next;
+ }
+ if (rxch->bd_mem)
+ rxch->bd_mem = NULL;
+ kfree(rxch);
+ priv->rxch[ch] = NULL;
+ }
+}
+
+/**
+ * emac_set_type0addr: Set EMAC Type0 mac address
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ * @mac_addr: MAC address to set in device
+ *
+ * Called internally to set Type0 mac address of the adapter (Device)
+ *
+ * Returns success (0) or appropriate error code (none as of now)
+ */
+static void emac_set_type0addr(struct emac_priv *priv, u32 ch, char *mac_addr)
+{
+ u32 val;
+ val = ((mac_addr[5] << 8) | (mac_addr[4]));
+ emac_write(EMAC_MACSRCADDRLO, val);
+
+ val = ((mac_addr[3] << 24) | (mac_addr[2] << 16) | \
+ (mac_addr[1] << 8) | (mac_addr[0]));
+ emac_write(EMAC_MACSRCADDRHI, val);
+ val = emac_read(EMAC_RXUNICASTSET);
+ val |= BIT(ch);
+ emac_write(EMAC_RXUNICASTSET, val);
+ val = emac_read(EMAC_RXUNICASTCLEAR);
+ val &= ~BIT(ch);
+ emac_write(EMAC_RXUNICASTCLEAR, val);
+}
+
+/**
+ * emac_set_type1addr: Set EMAC Type1 mac address
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ * @mac_addr: MAC address to set in device
+ *
+ * Called internally to set Type1 mac address of the adapter (Device)
+ *
+ * Returns success (0) or appropriate error code (none as of now)
+ */
+static void emac_set_type1addr(struct emac_priv *priv, u32 ch, char *mac_addr)
+{
+ u32 val;
+ emac_write(EMAC_MACINDEX, ch);
+ val = ((mac_addr[5] << 8) | mac_addr[4]);
+ emac_write(EMAC_MACADDRLO, val);
+ val = ((mac_addr[3] << 24) | (mac_addr[2] << 16) | \
+ (mac_addr[1] << 8) | (mac_addr[0]));
+ emac_write(EMAC_MACADDRHI, val);
+ emac_set_type0addr(priv, ch, mac_addr);
+}
+
+/**
+ * emac_set_type2addr: Set EMAC Type2 mac address
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ * @mac_addr: MAC address to set in device
+ * @index: index into RX address entries
+ * @match: match parameter for RX address matching logic
+ *
+ * Called internally to set Type2 mac address of the adapter (Device)
+ *
+ * Returns success (0) or appropriate error code (none as of now)
+ */
+static void emac_set_type2addr(struct emac_priv *priv, u32 ch,
+ char *mac_addr, int index, int match)
+{
+ u32 val;
+ emac_write(EMAC_MACINDEX, index);
+ val = ((mac_addr[3] << 24) | (mac_addr[2] << 16) | \
+ (mac_addr[1] << 8) | (mac_addr[0]));
+ emac_write(EMAC_MACADDRHI, val);
+ val = ((mac_addr[5] << 8) | mac_addr[4] | ((ch & 0x7) << 16) | \
+ (match << 19) | BIT(20));
+ emac_write(EMAC_MACADDRLO, val);
+ emac_set_type0addr(priv, ch, mac_addr);
+}
+
+/**
+ * emac_setmac: Set mac address in the adapter (internal function)
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ * @mac_addr: MAC address to set in device
+ *
+ * Called internally to set the mac address of the adapter (Device)
+ *
+ * Returns success (0) or appropriate error code (none as of now)
+ */
+static void emac_setmac(struct emac_priv *priv, u32 ch, char *mac_addr)
+{
+ struct device *emac_dev = &priv->ndev->dev;
+
+ if (priv->rx_addr_type == 0) {
+ emac_set_type0addr(priv, ch, mac_addr);
+ } else if (priv->rx_addr_type == 1) {
+ u32 cnt;
+ for (cnt = 0; cnt < EMAC_MAX_TXRX_CHANNELS; cnt++)
+ emac_set_type1addr(priv, ch, mac_addr);
+ } else if (priv->rx_addr_type == 2) {
+ emac_set_type2addr(priv, ch, mac_addr, ch, 1);
+ emac_set_type0addr(priv, ch, mac_addr);
+ } else {
+ if (netif_msg_drv(priv))
+ dev_err(emac_dev, "DaVinci EMAC: Wrong addressing\n");
+ }
+}
+
+/**
+ * emac_dev_setmac_addr: Set mac address in the adapter
+ * @ndev: The DaVinci EMAC network adapter
+ * @addr: MAC address to set in device
+ *
+ * Called by the system to set the mac address of the adapter (Device)
+ *
+ * Returns success (0) or appropriate error code (none as of now)
+ */
+static int emac_dev_setmac_addr(struct net_device *ndev, void *addr)
+{
+ struct emac_priv *priv = netdev_priv(ndev);
+ struct emac_rxch *rxch = priv->rxch[EMAC_DEF_RX_CH];
+ struct device *emac_dev = &priv->ndev->dev;
+ struct sockaddr *sa = addr;
+
+ /* Store mac addr in priv and rx channel and set it in EMAC hw */
+ memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len);
+ memcpy(rxch->mac_addr, sa->sa_data, ndev->addr_len);
+ memcpy(ndev->dev_addr, sa->sa_data, ndev->addr_len);
+ emac_setmac(priv, EMAC_DEF_RX_CH, rxch->mac_addr);
+
+ if (netif_msg_drv(priv))
+ dev_notice(emac_dev, "DaVinci EMAC: emac_dev_setmac_addr %pM\n",
+ priv->mac_addr);
+
+ return 0;
+}
+
+/**
+ * emac_addbd_to_rx_queue: Recycle RX buffer descriptor
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number to process buffer descriptors for
+ * @curr_bd: current buffer descriptor
+ * @buffer: buffer pointer for descriptor
+ * @buf_token: buffer token (stores skb information)
+ *
+ * Prepares the recycled buffer descriptor and addes it to hardware
+ * receive queue - if queue empty this descriptor becomes the head
+ * else addes the descriptor to end of queue
+ *
+ */
+static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch,
+ struct emac_rx_bd __iomem *curr_bd,
+ char *buffer, void *buf_token)
+{
+ struct emac_rxch *rxch = priv->rxch[ch];
+
+ /* populate the hardware descriptor */
+ curr_bd->h_next = 0;
+ /* FIXME buff_ptr = dma_map_single(... buffer ...) */
+ curr_bd->buff_ptr = virt_to_phys(buffer);
+ curr_bd->off_b_len = rxch->buf_size;
+ curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
+ curr_bd->next = NULL;
+ curr_bd->data_ptr = buffer;
+ curr_bd->buf_token = buf_token;
+
+ /* write back */
+ BD_CACHE_WRITEBACK_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+ if (rxch->active_queue_head == NULL) {
+ rxch->active_queue_head = curr_bd;
+ rxch->active_queue_tail = curr_bd;
+ if (0 != rxch->queue_active) {
+ emac_write(EMAC_RXHDP(ch),
+ emac_virt_to_phys(rxch->active_queue_head));
+ rxch->queue_active = 1;
+ }
+ } else {
+ struct emac_rx_bd __iomem *tail_bd;
+ u32 frame_status;
+
+ tail_bd = rxch->active_queue_tail;
+ rxch->active_queue_tail = curr_bd;
+ tail_bd->next = curr_bd;
+ tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
+ tail_bd->h_next = emac_virt_to_phys(curr_bd);
+ frame_status = tail_bd->mode;
+ if (frame_status & EMAC_CPPI_EOQ_BIT) {
+ emac_write(EMAC_RXHDP(ch),
+ emac_virt_to_phys(curr_bd));
+ frame_status &= ~(EMAC_CPPI_EOQ_BIT);
+ tail_bd->mode = frame_status;
+ ++rxch->end_of_queue_add;
+ }
+ }
+ ++rxch->recycled_bd;
+}
+
+/**
+ * emac_net_rx_cb: Prepares packet and sends to upper layer
+ * @priv: The DaVinci EMAC private adapter structure
+ * @net_pkt_list: Network packet list (received packets)
+ *
+ * Invalidates packet buffer memory and sends the received packet to upper
+ * layer
+ *
+ * Returns success or appropriate error code (none as of now)
+ */
+static int emac_net_rx_cb(struct emac_priv *priv,
+ struct emac_netpktobj *net_pkt_list)
+{
+ struct sk_buff *p_skb;
+ p_skb = (struct sk_buff *)net_pkt_list->pkt_token;
+ /* set length of packet */
+ skb_put(p_skb, net_pkt_list->pkt_length);
+ EMAC_CACHE_INVALIDATE((unsigned long)p_skb->data, p_skb->len);
+ p_skb->protocol = eth_type_trans(p_skb, priv->ndev);
+ p_skb->dev->last_rx = jiffies;
+ netif_receive_skb(p_skb);
+ priv->net_dev_stats.rx_bytes += net_pkt_list->pkt_length;
+ priv->net_dev_stats.rx_packets++;
+ return 0;
+}
+
+/**
+ * emac_rx_bdproc: RX buffer descriptor (packet) processing
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number to process buffer descriptors for
+ * @budget: number of packets allowed to process
+ * @pending: indication to caller that packets are pending to process
+ *
+ * Processes RX buffer descriptors - checks ownership bit on the RX buffer
+ * descriptor, sends the receive packet to upper layer, allocates a new SKB
+ * and recycles the buffer descriptor (requeues it in hardware RX queue).
+ * Only "budget" number of packets are processed and indication of pending
+ * packets provided to the caller.
+ *
+ * Returns number of packets processed (and indication of pending packets)
+ */
+static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
+{
+ unsigned long flags;
+ u32 frame_status;
+ u32 pkts_processed = 0;
+ char *new_buffer;
+ struct emac_rx_bd __iomem *curr_bd;
+ struct emac_rx_bd __iomem *last_bd;
+ struct emac_netpktobj *curr_pkt, pkt_obj;
+ struct emac_netbufobj buf_obj;
+ struct emac_netbufobj *rx_buf_obj;
+ void *new_buf_token;
+ struct emac_rxch *rxch = priv->rxch[ch];
+
+ if (unlikely(1 == rxch->teardown_pending))
+ return 0;
+ ++rxch->proc_count;
+ spin_lock_irqsave(&priv->rx_lock, flags);
+ pkt_obj.buf_list = &buf_obj;
+ curr_pkt = &pkt_obj;
+ curr_bd = rxch->active_queue_head;
+ BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+ frame_status = curr_bd->mode;
+
+ while ((curr_bd) &&
+ ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
+ (pkts_processed < budget)) {
+
+ new_buffer = emac_net_alloc_rx_buf(priv, rxch->buf_size,
+ &new_buf_token, EMAC_DEF_RX_CH);
+ if (unlikely(NULL == new_buffer)) {
+ ++rxch->out_of_rx_buffers;
+ goto end_emac_rx_bdproc;
+ }
+
+ /* populate received packet data structure */
+ rx_buf_obj = &curr_pkt->buf_list[0];
+ rx_buf_obj->data_ptr = (char *)curr_bd->data_ptr;
+ rx_buf_obj->length = curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE;
+ rx_buf_obj->buf_token = curr_bd->buf_token;
+ curr_pkt->pkt_token = curr_pkt->buf_list->buf_token;
+ curr_pkt->num_bufs = 1;
+ curr_pkt->pkt_length =
+ (frame_status & EMAC_RX_BD_PKT_LENGTH_MASK);
+ emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd));
+ ++rxch->processed_bd;
+ last_bd = curr_bd;
+ curr_bd = last_bd->next;
+ rxch->active_queue_head = curr_bd;
+
+ /* check if end of RX queue ? */
+ if (frame_status & EMAC_CPPI_EOQ_BIT) {
+ if (curr_bd) {
+ ++rxch->mis_queued_packets;
+ emac_write(EMAC_RXHDP(ch),
+ emac_virt_to_phys(curr_bd));
+ } else {
+ ++rxch->end_of_queue;
+ rxch->queue_active = 0;
+ }
+ }
+
+ /* recycle BD */
+ emac_addbd_to_rx_queue(priv, ch, last_bd, new_buffer,
+ new_buf_token);
+
+ /* return the packet to the user - BD ptr passed in
+ * last parameter for potential *future* use */
+ spin_unlock_irqrestore(&priv->rx_lock, flags);
+ emac_net_rx_cb(priv, curr_pkt);
+ spin_lock_irqsave(&priv->rx_lock, flags);
+ curr_bd = rxch->active_queue_head;
+ if (curr_bd) {
+ BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+ frame_status = curr_bd->mode;
+ }
+ ++pkts_processed;
+ }
+
+end_emac_rx_bdproc:
+ spin_unlock_irqrestore(&priv->rx_lock, flags);
+ return pkts_processed;
+}
+
+/**
+ * emac_hw_enable: Enable EMAC hardware for packet transmission/reception
+ * @priv: The DaVinci EMAC private adapter structure
+ *
+ * Enables EMAC hardware for packet processing - enables PHY, enables RX
+ * for packet reception and enables device interrupts and then NAPI
+ *
+ * Returns success (0) or appropriate error code (none right now)
+ */
+static int emac_hw_enable(struct emac_priv *priv)
+{
+ u32 ch, val, mbp_enable, mac_control;
+
+ /* Soft reset */
+ emac_write(EMAC_SOFTRESET, 1);
+ while (emac_read(EMAC_SOFTRESET))
+ cpu_relax();
+
+ /* Disable interrupt & Set pacing for more interrupts initially */
+ emac_int_disable(priv);
+
+ /* Full duplex enable bit set when auto negotiation happens */
+ mac_control =
+ (((EMAC_DEF_TXPRIO_FIXED) ? (EMAC_MACCONTROL_TXPTYPE) : 0x0) |
+ ((priv->speed == 1000) ? EMAC_MACCONTROL_GIGABITEN : 0x0) |
+ ((EMAC_DEF_TXPACING_EN) ? (EMAC_MACCONTROL_TXPACEEN) : 0x0) |
+ ((priv->duplex == DUPLEX_FULL) ? 0x1 : 0));
+ emac_write(EMAC_MACCONTROL, mac_control);
+
+ mbp_enable =
+ (((EMAC_DEF_PASS_CRC) ? (EMAC_RXMBP_PASSCRC_MASK) : 0x0) |
+ ((EMAC_DEF_QOS_EN) ? (EMAC_RXMBP_QOSEN_MASK) : 0x0) |
+ ((EMAC_DEF_NO_BUFF_CHAIN) ? (EMAC_RXMBP_NOCHAIN_MASK) : 0x0) |
+ ((EMAC_DEF_MACCTRL_FRAME_EN) ? (EMAC_RXMBP_CMFEN_MASK) : 0x0) |
+ ((EMAC_DEF_SHORT_FRAME_EN) ? (EMAC_RXMBP_CSFEN_MASK) : 0x0) |
+ ((EMAC_DEF_ERROR_FRAME_EN) ? (EMAC_RXMBP_CEFEN_MASK) : 0x0) |
+ ((EMAC_DEF_PROM_EN) ? (EMAC_RXMBP_CAFEN_MASK) : 0x0) |
+ ((EMAC_DEF_PROM_CH & EMAC_RXMBP_CHMASK) << \
+ EMAC_RXMBP_PROMCH_SHIFT) |
+ ((EMAC_DEF_BCAST_EN) ? (EMAC_RXMBP_BROADEN_MASK) : 0x0) |
+ ((EMAC_DEF_BCAST_CH & EMAC_RXMBP_CHMASK) << \
+ EMAC_RXMBP_BROADCH_SHIFT) |
+ ((EMAC_DEF_MCAST_EN) ? (EMAC_RXMBP_MULTIEN_MASK) : 0x0) |
+ ((EMAC_DEF_MCAST_CH & EMAC_RXMBP_CHMASK) << \
+ EMAC_RXMBP_MULTICH_SHIFT));
+ emac_write(EMAC_RXMBPENABLE, mbp_enable);
+ emac_write(EMAC_RXMAXLEN, (EMAC_DEF_MAX_FRAME_SIZE &
+ EMAC_RX_MAX_LEN_MASK));
+ emac_write(EMAC_RXBUFFEROFFSET, (EMAC_DEF_BUFFER_OFFSET &
+ EMAC_RX_BUFFER_OFFSET_MASK));
+ emac_write(EMAC_RXFILTERLOWTHRESH, 0);
+ emac_write(EMAC_RXUNICASTCLEAR, EMAC_RX_UNICAST_CLEAR_ALL);
+ priv->rx_addr_type = (emac_read(EMAC_MACCONFIG) >> 8) & 0xFF;
+
+ val = emac_read(EMAC_TXCONTROL);
+ val |= EMAC_TX_CONTROL_TX_ENABLE_VAL;
+ emac_write(EMAC_TXCONTROL, val);
+ val = emac_read(EMAC_RXCONTROL);
+ val |= EMAC_RX_CONTROL_RX_ENABLE_VAL;
+ emac_write(EMAC_RXCONTROL, val);
+ emac_write(EMAC_MACINTMASKSET, EMAC_MAC_HOST_ERR_INTMASK_VAL);
+
+ for (ch = 0; ch < EMAC_DEF_MAX_TX_CH; ch++) {
+ emac_write(EMAC_TXHDP(ch), 0);
+ emac_write(EMAC_TXINTMASKSET, BIT(ch));
+ }
+ for (ch = 0; ch < EMAC_DEF_MAX_RX_CH; ch++) {
+ struct emac_rxch *rxch = priv->rxch[ch];
+ emac_setmac(priv, ch, rxch->mac_addr);
+ emac_write(EMAC_RXINTMASKSET, BIT(ch));
+ rxch->queue_active = 1;
+ emac_write(EMAC_RXHDP(ch),
+ emac_virt_to_phys(rxch->active_queue_head));
+ }
+
+ /* Enable MII */
+ val = emac_read(EMAC_MACCONTROL);
+ val |= (EMAC_MACCONTROL_MIIEN);
+ emac_write(EMAC_MACCONTROL, val);
+
+ /* Enable NAPI and interrupts */
+ napi_enable(&priv->napi);
+ emac_int_enable(priv);
+ return 0;
+
+}
+
+/**
+ * emac_poll: EMAC NAPI Poll function
+ * @ndev: The DaVinci EMAC network adapter
+ * @budget: Number of receive packets to process (as told by NAPI layer)
+ *
+ * NAPI Poll function implemented to process packets as per budget. We check
+ * the type of interrupt on the device and accordingly call the TX or RX
+ * packet processing functions. We follow the budget for RX processing and
+ * also put a cap on number of TX pkts processed through config param. The
+ * NAPI schedule function is called if more packets pending.
+ *
+ * Returns number of packets received (in most cases; else TX pkts - rarely)
+ */
+static int emac_poll(struct napi_struct *napi, int budget)
+{
+ unsigned int mask;
+ struct emac_priv *priv = container_of(napi, struct emac_priv, napi);
+ struct net_device *ndev = priv->ndev;
+ struct device *emac_dev = &ndev->dev;
+ u32 status = 0;
+ u32 num_pkts = 0;
+
+ if (!netif_running(ndev))
+ return 0;
+
+ /* Check interrupt vectors and call packet processing */
+ status = emac_read(EMAC_MACINVECTOR);
+
+ mask = EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC;
+
+ if (priv->version == EMAC_VERSION_2)
+ mask = EMAC_DM646X_MAC_IN_VECTOR_TX_INT_VEC;
+
+ if (status & mask) {
+ num_pkts = emac_tx_bdproc(priv, EMAC_DEF_TX_CH,
+ EMAC_DEF_TX_MAX_SERVICE);
+ } /* TX processing */
+
+ if (num_pkts)
+ return budget;
+
+ mask = EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC;
+
+ if (priv->version == EMAC_VERSION_2)
+ mask = EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC;
+
+ if (status & mask) {
+ num_pkts = emac_rx_bdproc(priv, EMAC_DEF_RX_CH, budget);
+ } /* RX processing */
+
+ if (num_pkts < budget) {
+ napi_complete(napi);
+ emac_int_enable(priv);
+ }
+
+ if (unlikely(status & EMAC_DM644X_MAC_IN_VECTOR_HOST_INT)) {
+ u32 ch, cause;
+ dev_err(emac_dev, "DaVinci EMAC: Fatal Hardware Error\n");
+ netif_stop_queue(ndev);
+ napi_disable(&priv->napi);
+
+ status = emac_read(EMAC_MACSTATUS);
+ cause = ((status & EMAC_MACSTATUS_TXERRCODE_MASK) >>
+ EMAC_MACSTATUS_TXERRCODE_SHIFT);
+ if (cause) {
+ ch = ((status & EMAC_MACSTATUS_TXERRCH_MASK) >>
+ EMAC_MACSTATUS_TXERRCH_SHIFT);
+ if (net_ratelimit()) {
+ dev_err(emac_dev, "TX Host error %s on ch=%d\n",
+ &emac_txhost_errcodes[cause][0], ch);
+ }
+ }
+ cause = ((status & EMAC_MACSTATUS_RXERRCODE_MASK) >>
+ EMAC_MACSTATUS_RXERRCODE_SHIFT);
+ if (cause) {
+ ch = ((status & EMAC_MACSTATUS_RXERRCH_MASK) >>
+ EMAC_MACSTATUS_RXERRCH_SHIFT);
+ if (netif_msg_hw(priv) && net_ratelimit())
+ dev_err(emac_dev, "RX Host error %s on ch=%d\n",
+ &emac_rxhost_errcodes[cause][0], ch);
+ }
+ } /* Host error processing */
+
+ return num_pkts;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/**
+ * emac_poll_controller: EMAC Poll controller function
+ * @ndev: The DaVinci EMAC network adapter
+ *
+ * Polled functionality used by netconsole and others in non interrupt mode
+ *
+ */
+void emac_poll_controller(struct net_device *ndev)
+{
+ struct emac_priv *priv = netdev_priv(ndev);
+
+ emac_int_disable(priv);
+ emac_irq(ndev->irq, priv);
+ emac_int_enable(priv);
+}
+#endif
+
+/* PHY/MII bus related */
+
+/* Wait until mdio is ready for next command */
+#define MDIO_WAIT_FOR_USER_ACCESS\
+ while ((emac_mdio_read((MDIO_USERACCESS(0))) &\
+ MDIO_USERACCESS_GO) != 0)
+
+static int emac_mii_read(struct mii_bus *bus, int phy_id, int phy_reg)
+{
+ unsigned int phy_data = 0;
+ unsigned int phy_control;
+
+ /* Wait until mdio is ready for next command */
+ MDIO_WAIT_FOR_USER_ACCESS;
+
+ phy_control = (MDIO_USERACCESS_GO |
+ MDIO_USERACCESS_READ |
+ ((phy_reg << 21) & MDIO_USERACCESS_REGADR) |
+ ((phy_id << 16) & MDIO_USERACCESS_PHYADR) |
+ (phy_data & MDIO_USERACCESS_DATA));
+ emac_mdio_write(MDIO_USERACCESS(0), phy_control);
+
+ /* Wait until mdio is ready for next command */
+ MDIO_WAIT_FOR_USER_ACCESS;
+
+ return emac_mdio_read(MDIO_USERACCESS(0)) & MDIO_USERACCESS_DATA;
+
+}
+
+static int emac_mii_write(struct mii_bus *bus, int phy_id,
+ int phy_reg, u16 phy_data)
+{
+
+ unsigned int control;
+
+ /* until mdio is ready for next command */
+ MDIO_WAIT_FOR_USER_ACCESS;
+
+ control = (MDIO_USERACCESS_GO |
+ MDIO_USERACCESS_WRITE |
+ ((phy_reg << 21) & MDIO_USERACCESS_REGADR) |
+ ((phy_id << 16) & MDIO_USERACCESS_PHYADR) |
+ (phy_data & MDIO_USERACCESS_DATA));
+ emac_mdio_write(MDIO_USERACCESS(0), control);
+
+ return 0;
+}
+
+static int emac_mii_reset(struct mii_bus *bus)
+{
+ unsigned int clk_div;
+ int mdio_bus_freq = emac_bus_frequency;
+
+ if (mdio_max_freq & mdio_bus_freq)
+ clk_div = ((mdio_bus_freq / mdio_max_freq) - 1);
+ else
+ clk_div = 0xFF;
+
+ clk_div &= MDIO_CONTROL_CLKDIV;
+
+ /* Set enable and clock divider in MDIOControl */
+ emac_mdio_write(MDIO_CONTROL, (clk_div | MDIO_CONTROL_ENABLE));
+
+ return 0;
+
+}
+
+static int mii_irqs[PHY_MAX_ADDR] = { PHY_POLL, PHY_POLL };
+
+/* emac_driver: EMAC MII bus structure */
+
+static struct mii_bus *emac_mii;
+
+static void emac_adjust_link(struct net_device *ndev)
+{
+ struct emac_priv *priv = netdev_priv(ndev);
+ struct phy_device *phydev = priv->phydev;
+ unsigned long flags;
+ int new_state = 0;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (phydev->link) {
+ /* check the mode of operation - full/half duplex */
+ if (phydev->duplex != priv->duplex) {
+ new_state = 1;
+ priv->duplex = phydev->duplex;
+ }
+ if (phydev->speed != priv->speed) {
+ new_state = 1;
+ priv->speed = phydev->speed;
+ }
+ if (!priv->link) {
+ new_state = 1;
+ priv->link = 1;
+ }
+
+ } else if (priv->link) {
+ new_state = 1;
+ priv->link = 0;
+ priv->speed = 0;
+ priv->duplex = ~0;
+ }
+ if (new_state) {
+ emac_update_phystatus(priv);
+ phy_print_status(priv->phydev);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/*************************************************************************
+ * Linux Driver Model
+ *************************************************************************/
+
+/**
+ * emac_devioctl: EMAC adapter ioctl
+ * @ndev: The DaVinci EMAC network adapter
+ * @ifrq: request parameter
+ * @cmd: command parameter
+ *
+ * EMAC driver ioctl function
+ *
+ * Returns success(0) or appropriate error code
+ */
+static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd)
+{
+ dev_warn(&ndev->dev, "DaVinci EMAC: ioctl not supported\n");
+
+ if (!(netif_running(ndev)))
+ return -EINVAL;
+
+ /* TODO: Add phy read and write and private statistics get feature */
+
+ return -EOPNOTSUPP;
+}
+
+/**
+ * emac_dev_open: EMAC device open
+ * @ndev: The DaVinci EMAC network adapter
+ *
+ * Called when system wants to start the interface. We init TX/RX channels
+ * and enable the hardware for packet reception/transmission and start the
+ * network queue.
+ *
+ * Returns 0 for a successful open, or appropriate error code
+ */
+static int emac_dev_open(struct net_device *ndev)
+{
+ struct device *emac_dev = &ndev->dev;
+ u32 rc, cnt, ch;
+ int phy_addr;
+ struct resource *res;
+ int q, m;
+ int i = 0;
+ int k = 0;
+ struct emac_priv *priv = netdev_priv(ndev);
+
+ netif_carrier_off(ndev);
+ for (cnt = 0; cnt <= ETH_ALEN; cnt++)
+ ndev->dev_addr[cnt] = priv->mac_addr[cnt];
+
+ /* Configuration items */
+ priv->rx_buf_size = EMAC_DEF_MAX_FRAME_SIZE + NET_IP_ALIGN;
+
+ /* Clear basic hardware */
+ for (ch = 0; ch < EMAC_MAX_TXRX_CHANNELS; ch++) {
+ emac_write(EMAC_TXHDP(ch), 0);
+ emac_write(EMAC_RXHDP(ch), 0);
+ emac_write(EMAC_RXHDP(ch), 0);
+ emac_write(EMAC_RXINTMASKCLEAR, EMAC_INT_MASK_CLEAR);
+ emac_write(EMAC_TXINTMASKCLEAR, EMAC_INT_MASK_CLEAR);
+ }
+ priv->mac_hash1 = 0;
+ priv->mac_hash2 = 0;
+ emac_write(EMAC_MACHASH1, 0);
+ emac_write(EMAC_MACHASH2, 0);
+
+ /* multi ch not supported - open 1 TX, 1RX ch by default */
+ rc = emac_init_txch(priv, EMAC_DEF_TX_CH);
+ if (0 != rc) {
+ dev_err(emac_dev, "DaVinci EMAC: emac_init_txch() failed");
+ return rc;
+ }
+ rc = emac_init_rxch(priv, EMAC_DEF_RX_CH, priv->mac_addr);
+ if (0 != rc) {
+ dev_err(emac_dev, "DaVinci EMAC: emac_init_rxch() failed");
+ return rc;
+ }
+
+ /* Request IRQ */
+
+ while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k))) {
+ for (i = res->start; i <= res->end; i++) {
+ if (request_irq(i, emac_irq, IRQF_DISABLED,
+ ndev->name, ndev))
+ goto rollback;
+ }
+ k++;
+ }
+
+ /* Start/Enable EMAC hardware */
+ emac_hw_enable(priv);
+
+ /* find the first phy */
+ priv->phydev = NULL;
+ if (priv->phy_mask) {
+ emac_mii_reset(priv->mii_bus);
+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+ if (priv->mii_bus->phy_map[phy_addr]) {
+ priv->phydev = priv->mii_bus->phy_map[phy_addr];
+ break;
+ }
+ }
+
+ if (!priv->phydev) {
+ printk(KERN_ERR "%s: no PHY found\n", ndev->name);
+ return -1;
+ }
+
+ priv->phydev = phy_connect(ndev, dev_name(&priv->phydev->dev),
+ &emac_adjust_link, 0, PHY_INTERFACE_MODE_MII);
+
+ if (IS_ERR(priv->phydev)) {
+ printk(KERN_ERR "%s: Could not attach to PHY\n",
+ ndev->name);
+ return PTR_ERR(priv->phydev);
+ }
+
+ priv->link = 0;
+ priv->speed = 0;
+ priv->duplex = ~0;
+
+ printk(KERN_INFO "%s: attached PHY driver [%s] "
+ "(mii_bus:phy_addr=%s, id=%x)\n", ndev->name,
+ priv->phydev->drv->name, dev_name(&priv->phydev->dev),
+ priv->phydev->phy_id);
+ } else{
+ /* No PHY , fix the link, speed and duplex settings */
+ priv->link = 1;
+ priv->speed = SPEED_100;
+ priv->duplex = DUPLEX_FULL;
+ emac_update_phystatus(priv);
+ }
+
+ if (!netif_running(ndev)) /* debug only - to avoid compiler warning */
+ emac_dump_regs(priv);
+
+ if (netif_msg_drv(priv))
+ dev_notice(emac_dev, "DaVinci EMAC: Opened %s\n", ndev->name);
+
+ if (priv->phy_mask)
+ phy_start(priv->phydev);
+
+ return 0;
+
+rollback:
+
+ dev_err(emac_dev, "DaVinci EMAC: request_irq() failed");
+
+ for (q = k; k >= 0; k--) {
+ for (m = i; m >= res->start; m--)
+ free_irq(m, ndev);
+ res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k-1);
+ m = res->end;
+ }
+ return -EBUSY;
+}
+
+/**
+ * emac_dev_stop: EMAC device stop
+ * @ndev: The DaVinci EMAC network adapter
+ *
+ * Called when system wants to stop or down the interface. We stop the network
+ * queue, disable interrupts and cleanup TX/RX channels.
+ *
+ * We return the statistics in net_device_stats structure pulled from emac
+ */
+static int emac_dev_stop(struct net_device *ndev)
+{
+ struct resource *res;
+ int i = 0;
+ int irq_num;
+ struct emac_priv *priv = netdev_priv(ndev);
+ struct device *emac_dev = &ndev->dev;
+
+ /* inform the upper layers. */
+ netif_stop_queue(ndev);
+ napi_disable(&priv->napi);
+
+ netif_carrier_off(ndev);
+ emac_int_disable(priv);
+ emac_stop_txch(priv, EMAC_DEF_TX_CH);
+ emac_stop_rxch(priv, EMAC_DEF_RX_CH);
+ emac_cleanup_txch(priv, EMAC_DEF_TX_CH);
+ emac_cleanup_rxch(priv, EMAC_DEF_RX_CH);
+ emac_write(EMAC_SOFTRESET, 1);
+
+ if (priv->phydev)
+ phy_disconnect(priv->phydev);
+
+ /* Free IRQ */
+ while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, i))) {
+ for (irq_num = res->start; irq_num <= res->end; irq_num++)
+ free_irq(irq_num, priv->ndev);
+ i++;
+ }
+
+ if (netif_msg_drv(priv))
+ dev_notice(emac_dev, "DaVinci EMAC: %s stopped\n", ndev->name);
+
+ return 0;
+}
+
+/**
+ * emac_dev_getnetstats: EMAC get statistics function
+ * @ndev: The DaVinci EMAC network adapter
+ *
+ * Called when system wants to get statistics from the device.
+ *
+ * We return the statistics in net_device_stats structure pulled from emac
+ */
+static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev)
+{
+ struct emac_priv *priv = netdev_priv(ndev);
+
+ /* update emac hardware stats and reset the registers*/
+
+ priv->net_dev_stats.multicast += emac_read(EMAC_RXMCASTFRAMES);
+ emac_write(EMAC_RXMCASTFRAMES, EMAC_ALL_MULTI_REG_VALUE);
+
+ priv->net_dev_stats.collisions += (emac_read(EMAC_TXCOLLISION) +
+ emac_read(EMAC_TXSINGLECOLL) +
+ emac_read(EMAC_TXMULTICOLL));
+ emac_write(EMAC_TXCOLLISION, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_TXSINGLECOLL, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_TXMULTICOLL, EMAC_ALL_MULTI_REG_VALUE);
+
+ priv->net_dev_stats.rx_length_errors += (emac_read(EMAC_RXOVERSIZED) +
+ emac_read(EMAC_RXJABBER) +
+ emac_read(EMAC_RXUNDERSIZED));
+ emac_write(EMAC_RXOVERSIZED, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_RXJABBER, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_RXUNDERSIZED, EMAC_ALL_MULTI_REG_VALUE);
+
+ priv->net_dev_stats.rx_over_errors += (emac_read(EMAC_RXSOFOVERRUNS) +
+ emac_read(EMAC_RXMOFOVERRUNS));
+ emac_write(EMAC_RXSOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
+ emac_write(EMAC_RXMOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
+
+ priv->net_dev_stats.rx_fifo_errors += emac_read(EMAC_RXDMAOVERRUNS);
+ emac_write(EMAC_RXDMAOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
+
+ priv->net_dev_stats.tx_carrier_errors +=
+ emac_read(EMAC_TXCARRIERSENSE);
+ emac_write(EMAC_TXCARRIERSENSE, EMAC_ALL_MULTI_REG_VALUE);
+
+ priv->net_dev_stats.tx_fifo_errors = emac_read(EMAC_TXUNDERRUN);
+ emac_write(EMAC_TXUNDERRUN, EMAC_ALL_MULTI_REG_VALUE);
+
+ return &priv->net_dev_stats;
+}
+
+static const struct net_device_ops emac_netdev_ops = {
+ .ndo_open = emac_dev_open,
+ .ndo_stop = emac_dev_stop,
+ .ndo_start_xmit = emac_dev_xmit,
+ .ndo_set_multicast_list = emac_dev_mcast_set,
+ .ndo_set_mac_address = emac_dev_setmac_addr,
+ .ndo_do_ioctl = emac_devioctl,
+ .ndo_tx_timeout = emac_dev_tx_timeout,
+ .ndo_get_stats = emac_dev_getnetstats,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = emac_poll_controller,
+#endif
+};
+
+/**
+ * davinci_emac_probe: EMAC device probe
+ * @pdev: The DaVinci EMAC device that we are removing
+ *
+ * Called when probing for emac devicesr. We get details of instances and
+ * resource information from platform init and register a network device
+ * and allocate resources necessary for driver to perform
+ */
+static int __devinit davinci_emac_probe(struct platform_device *pdev)
+{
+ int rc = 0;
+ struct resource *res;
+ struct net_device *ndev;
+ struct emac_priv *priv;
+ unsigned long size;
+ struct emac_platform_data *pdata;
+ struct device *emac_dev;
+
+ /* obtain emac clock from kernel */
+ emac_clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(emac_clk)) {
+ printk(KERN_ERR "DaVinci EMAC: Failed to get EMAC clock\n");
+ return -EBUSY;
+ }
+ emac_bus_frequency = clk_get_rate(emac_clk);
+ /* TODO: Probe PHY here if possible */
+
+ ndev = alloc_etherdev(sizeof(struct emac_priv));
+ if (!ndev) {
+ printk(KERN_ERR "DaVinci EMAC: Error allocating net_device\n");
+ clk_put(emac_clk);
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, ndev);
+ priv = netdev_priv(ndev);
+ priv->pdev = pdev;
+ priv->ndev = ndev;
+ priv->msg_enable = netif_msg_init(debug_level, DAVINCI_EMAC_DEBUG);
+
+ spin_lock_init(&priv->tx_lock);
+ spin_lock_init(&priv->rx_lock);
+ spin_lock_init(&priv->lock);
+
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ printk(KERN_ERR "DaVinci EMAC: No platfrom data\n");
+ return -ENODEV;
+ }
+
+ /* MAC addr and PHY mask , RMII enable info from platform_data */
+ memcpy(priv->mac_addr, pdata->mac_addr, 6);
+ priv->phy_mask = pdata->phy_mask;
+ priv->rmii_en = pdata->rmii_en;
+ priv->version = pdata->version;
+ emac_dev = &ndev->dev;
+ /* Get EMAC platform data */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(emac_dev, "DaVinci EMAC: Error getting res\n");
+ rc = -ENOENT;
+ goto probe_quit;
+ }
+
+ priv->emac_base_phys = res->start + pdata->ctrl_reg_offset;
+ size = res->end - res->start + 1;
+ if (!request_mem_region(res->start, size, ndev->name)) {
+ dev_err(emac_dev, "DaVinci EMAC: failed request_mem_region() \
+ for regs\n");
+ rc = -ENXIO;
+ goto probe_quit;
+ }
+
+ priv->remap_addr = ioremap(res->start, size);
+ if (!priv->remap_addr) {
+ dev_err(emac_dev, "Unable to map IO\n");
+ rc = -ENOMEM;
+ release_mem_region(res->start, size);
+ goto probe_quit;
+ }
+ priv->emac_base = priv->remap_addr + pdata->ctrl_reg_offset;
+ ndev->base_addr = (unsigned long)priv->remap_addr;
+
+ priv->ctrl_base = priv->remap_addr + pdata->ctrl_mod_reg_offset;
+ priv->ctrl_ram_size = pdata->ctrl_ram_size;
+ priv->emac_ctrl_ram = priv->remap_addr + pdata->ctrl_ram_offset;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_err(emac_dev, "DaVinci EMAC: Error getting irq res\n");
+ rc = -ENOENT;
+ goto no_irq_res;
+ }
+ ndev->irq = res->start;
+
+ if (!is_valid_ether_addr(priv->mac_addr)) {
+ /* Use random MAC if none passed */
+ random_ether_addr(priv->mac_addr);
+ printk(KERN_WARNING "%s: using random MAC addr: %pM\n",
+ __func__, priv->mac_addr);
+ }
+
+ ndev->netdev_ops = &emac_netdev_ops;
+ SET_ETHTOOL_OPS(ndev, &ethtool_ops);
+ netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT);
+
+ /* register the network device */
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+ rc = register_netdev(ndev);
+ if (rc) {
+ dev_err(emac_dev, "DaVinci EMAC: Error in register_netdev\n");
+ rc = -ENODEV;
+ goto netdev_reg_err;
+ }
+
+ clk_enable(emac_clk);
+
+ /* MII/Phy intialisation, mdio bus registration */
+ emac_mii = mdiobus_alloc();
+ if (emac_mii == NULL) {
+ dev_err(emac_dev, "DaVinci EMAC: Error allocating mii_bus\n");
+ rc = -ENOMEM;
+ goto mdio_alloc_err;
+ }
+
+ priv->mii_bus = emac_mii;
+ emac_mii->name = "emac-mii",
+ emac_mii->read = emac_mii_read,
+ emac_mii->write = emac_mii_write,
+ emac_mii->reset = emac_mii_reset,
+ emac_mii->irq = mii_irqs,
+ emac_mii->phy_mask = ~(priv->phy_mask);
+ emac_mii->parent = &pdev->dev;
+ emac_mii->priv = priv->remap_addr + pdata->mdio_reg_offset;
+ snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", priv->pdev->id);
+ mdio_max_freq = pdata->mdio_max_freq;
+ emac_mii->reset(emac_mii);
+
+ /* Register the MII bus */
+ rc = mdiobus_register(emac_mii);
+ if (rc)
+ goto mdiobus_quit;
+
+ if (netif_msg_probe(priv)) {
+ dev_notice(emac_dev, "DaVinci EMAC Probe found device "\
+ "(regs: %p, irq: %d)\n",
+ (void *)priv->emac_base_phys, ndev->irq);
+ }
+ return 0;
+
+mdiobus_quit:
+ mdiobus_free(emac_mii);
+
+netdev_reg_err:
+mdio_alloc_err:
+no_irq_res:
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, res->end - res->start + 1);
+ iounmap(priv->remap_addr);
+
+probe_quit:
+ clk_put(emac_clk);
+ free_netdev(ndev);
+ return rc;
+}
+
+/**
+ * davinci_emac_remove: EMAC device remove
+ * @pdev: The DaVinci EMAC device that we are removing
+ *
+ * Called when removing the device driver. We disable clock usage and release
+ * the resources taken up by the driver and unregister network device
+ */
+static int __devexit davinci_emac_remove(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct emac_priv *priv = netdev_priv(ndev);
+
+ dev_notice(&ndev->dev, "DaVinci EMAC: davinci_emac_remove()\n");
+
+ clk_disable(emac_clk);
+ platform_set_drvdata(pdev, NULL);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mdiobus_unregister(priv->mii_bus);
+ mdiobus_free(priv->mii_bus);
+
+ release_mem_region(res->start, res->end - res->start + 1);
+
+ unregister_netdev(ndev);
+ free_netdev(ndev);
+ iounmap(priv->remap_addr);
+
+ clk_disable(emac_clk);
+ clk_put(emac_clk);
+
+ return 0;
+}
+
+/**
+ * davinci_emac_driver: EMAC platform driver structure
+ *
+ * We implement only probe and remove functions - suspend/resume and
+ * others not supported by this module
+ */
+static struct platform_driver davinci_emac_driver = {
+ .driver = {
+ .name = "davinci_emac",
+ .owner = THIS_MODULE,
+ },
+ .probe = davinci_emac_probe,
+ .remove = __devexit_p(davinci_emac_remove),
+};
+
+/**
+ * davinci_emac_init: EMAC driver module init
+ *
+ * Called when initializing the driver. We register the driver with
+ * the platform.
+ */
+static int __init davinci_emac_init(void)
+{
+ return platform_driver_register(&davinci_emac_driver);
+}
+module_init(davinci_emac_init);
+
+/**
+ * davinci_emac_exit: EMAC driver module exit
+ *
+ * Called when exiting the driver completely. We unregister the driver with
+ * the platform and exit
+ */
+static void __exit davinci_emac_exit(void)
+{
+ platform_driver_unregister(&davinci_emac_driver);
+}
+module_exit(davinci_emac_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("DaVinci EMAC Maintainer: Anant Gole <anantgole@ti.com>");
+MODULE_AUTHOR("DaVinci EMAC Maintainer: Chaithrika U S <chaithrika@ti.com>");
+MODULE_DESCRIPTION("DaVinci EMAC Ethernet driver");
diff --git a/drivers/net/de600.c b/drivers/net/de600.c
index de63f1d41d3..e1af089064b 100644
--- a/drivers/net/de600.c
+++ b/drivers/net/de600.c
@@ -38,14 +38,6 @@ static const char version[] = "de600.c: $Revision: 1.41-2.5 $, Bjorn Ekwall (bj
/* Add more time here if your adapter won't work OK: */
#define DE600_SLOW_DOWN udelay(delay_time)
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifdef DE600_DEBUG
-#define PRINTK(x) if (de600_debug >= 2) printk x
-#else
-#define DE600_DEBUG 0
-#define PRINTK(x) /**/
-#endif
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
@@ -67,10 +59,6 @@ static const char version[] = "de600.c: $Revision: 1.41-2.5 $, Bjorn Ekwall (bj
#include "de600.h"
-static unsigned int de600_debug = DE600_DEBUG;
-module_param(de600_debug, int, 0);
-MODULE_PARM_DESC(de600_debug, "DE-600 debug level (0-2)");
-
static unsigned int check_lost = 1;
module_param(check_lost, bool, 0);
MODULE_PARM_DESC(check_lost, "If set then check for unplugged de600");
@@ -180,20 +168,20 @@ static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (free_tx_pages <= 0) { /* Do timeouts, to avoid hangs. */
tickssofar = jiffies - dev->trans_start;
if (tickssofar < 5)
- return 1;
+ return NETDEV_TX_BUSY;
/* else */
printk(KERN_WARNING "%s: transmit timed out (%d), %s?\n", dev->name, tickssofar, "network cable problem");
/* Restart the adapter. */
spin_lock_irqsave(&de600_lock, flags);
if (adapter_init(dev)) {
spin_unlock_irqrestore(&de600_lock, flags);
- return 1;
+ return NETDEV_TX_BUSY;
}
spin_unlock_irqrestore(&de600_lock, flags);
}
/* Start real output */
- PRINTK(("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages));
+ pr_debug("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages);
if ((len = skb->len) < RUNT)
len = RUNT;
@@ -211,7 +199,7 @@ static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) {
if (adapter_init(dev)) {
spin_unlock_irqrestore(&de600_lock, flags);
- return 1;
+ return NETDEV_TX_BUSY;
}
}
}
@@ -259,7 +247,7 @@ static irqreturn_t de600_interrupt(int irq, void *dev_id)
irq_status = de600_read_status(dev);
do {
- PRINTK(("de600_interrupt (%02X)\n", irq_status));
+ pr_debug("de600_interrupt (%02X)\n", irq_status);
if (irq_status & RX_GOOD)
de600_rx_intr(dev);
@@ -407,8 +395,7 @@ static struct net_device * __init de600_probe(void)
printk(KERN_INFO "%s: D-Link DE-600 pocket adapter", dev->name);
/* Alpha testers must have the version number to report bugs. */
- if (de600_debug > 1)
- printk(version);
+ pr_debug("%s", version);
/* probe for adapter */
err = -ENODEV;
diff --git a/drivers/net/de620.c b/drivers/net/de620.c
index d52f34cc952..55d2bb67cff 100644
--- a/drivers/net/de620.c
+++ b/drivers/net/de620.c
@@ -48,7 +48,6 @@ static const char version[] =
* Compile-time options: (see below for descriptions)
* -DDE620_IO=0x378 (lpt1)
* -DDE620_IRQ=7 (lpt1)
- * -DDE602_DEBUG=...
* -DSHUTDOWN_WHEN_LOST
* -DCOUNT_LOOPS
* -DLOWSPEED
@@ -98,15 +97,6 @@ static const char version[] =
#define SHUTDOWN_WHEN_LOST
*/
-/*
- * Enable debugging by "-DDE620_DEBUG=3" when compiling,
- * OR by enabling the following #define
- *
- * use 0 for production, 1 for verification, >2 for debug
- *
-#define DE620_DEBUG 3
- */
-
#ifdef LOWSPEED
/*
* Enable this #define if you want to see debugging output that show how long
@@ -160,14 +150,6 @@ typedef unsigned char byte;
#define RUNT 60 /* Too small Ethernet packet */
#define GIANT 1514 /* largest legal size packet, no fcs */
-#ifdef DE620_DEBUG /* Compile-time configurable */
-#define PRINTK(x) if (de620_debug >= 2) printk x
-#else
-#define DE620_DEBUG 0
-#define PRINTK(x) /**/
-#endif
-
-
/*
* Force media with insmod:
* insmod de620.o bnc=1
@@ -186,8 +168,6 @@ static int io = DE620_IO;
static int irq = DE620_IRQ;
static int clone = DE620_CLONE;
-static unsigned int de620_debug = DE620_DEBUG;
-
static spinlock_t de620_lock;
module_param(bnc, int, 0);
@@ -195,13 +175,11 @@ module_param(utp, int, 0);
module_param(io, int, 0);
module_param(irq, int, 0);
module_param(clone, int, 0);
-module_param(de620_debug, int, 0);
MODULE_PARM_DESC(bnc, "DE-620 set BNC medium (0-1)");
MODULE_PARM_DESC(utp, "DE-620 set UTP medium (0-1)");
MODULE_PARM_DESC(io, "DE-620 I/O base address,required");
MODULE_PARM_DESC(irq, "DE-620 IRQ number,required");
MODULE_PARM_DESC(clone, "Check also for non-D-Link DE-620 clones (0-1)");
-MODULE_PARM_DESC(de620_debug, "DE-620 debug level (0-2)");
/***********************************************
* *
@@ -533,9 +511,9 @@ static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Start real output */
- spin_lock_irqsave(&de620_lock, flags)
- PRINTK(("de620_start_xmit: len=%d, bufs 0x%02x\n",
- (int)skb->len, using_txbuf));
+ spin_lock_irqsave(&de620_lock, flags);
+ pr_debug("de620_start_xmit: len=%d, bufs 0x%02x\n",
+ (int)skb->len, using_txbuf);
/* select a free tx buffer. if there is one... */
switch (using_txbuf) {
@@ -553,7 +531,7 @@ static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
case (TXBF0 | TXBF1): /* NONE!!! */
printk(KERN_WARNING "%s: No tx-buffer available!\n", dev->name);
spin_unlock_irqrestore(&de620_lock, flags);
- return 1;
+ return NETDEV_TX_BUSY;
}
de620_write_block(dev, buffer, skb->len, len-skb->len);
@@ -585,12 +563,12 @@ de620_interrupt(int irq_in, void *dev_id)
/* Read the status register (_not_ the status port) */
irq_status = de620_get_register(dev, R_STS);
- PRINTK(("de620_interrupt (%2.2X)\n", irq_status));
+ pr_debug("de620_interrupt (%2.2X)\n", irq_status);
if (irq_status & RXGOOD) {
do {
again = de620_rx_intr(dev);
- PRINTK(("again=%d\n", again));
+ pr_debug("again=%d\n", again);
}
while (again && (++bogus_count < 100));
}
@@ -622,7 +600,7 @@ static int de620_rx_intr(struct net_device *dev)
byte pagelink;
byte curr_page;
- PRINTK(("de620_rx_intr: next_rx_page = %d\n", next_rx_page));
+ pr_debug("de620_rx_intr: next_rx_page = %d\n", next_rx_page);
/* Tell the adapter that we are going to read data, and from where */
de620_send_command(dev, W_CR | RRN);
@@ -631,8 +609,9 @@ static int de620_rx_intr(struct net_device *dev)
/* Deep breath, and away we goooooo */
de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf));
- PRINTK(("page status=0x%02x, nextpage=%d, packetsize=%d\n",
- header_buf.status, header_buf.Rx_NextPage, header_buf.Rx_ByteCount));
+ pr_debug("page status=0x%02x, nextpage=%d, packetsize=%d\n",
+ header_buf.status, header_buf.Rx_NextPage,
+ header_buf.Rx_ByteCount);
/* Plausible page header? */
pagelink = header_buf.Rx_NextPage;
@@ -683,7 +662,7 @@ static int de620_rx_intr(struct net_device *dev)
buffer = skb_put(skb,size);
/* copy the packet into the buffer */
de620_read_block(dev, buffer, size);
- PRINTK(("Read %d bytes\n", size));
+ pr_debug("Read %d bytes\n", size);
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb); /* deliver it "upstairs" */
/* count all receives */
@@ -696,7 +675,7 @@ static int de620_rx_intr(struct net_device *dev)
/* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */
curr_page = de620_get_register(dev, R_CPR);
de620_set_register(dev, W_NPRF, next_rx_page);
- PRINTK(("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page));
+ pr_debug("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page);
return (next_rx_page != curr_page); /* That was slightly tricky... */
}
@@ -830,8 +809,7 @@ struct net_device * __init de620_probe(int unit)
netdev_boot_setup_check(dev);
}
- if (de620_debug)
- printk(version);
+ pr_debug("%s", version);
printk(KERN_INFO "D-Link DE-620 pocket adapter");
@@ -878,14 +856,13 @@ struct net_device * __init de620_probe(int unit)
/* base_addr and irq are already set, see above! */
/* dump eeprom */
- if (de620_debug) {
- printk("\nEEPROM contents:\n");
- printk("RAM_Size = 0x%02X\n", nic_data.RAM_Size);
- printk("NodeID = %pM\n", nic_data.NodeID);
- printk("Model = %d\n", nic_data.Model);
- printk("Media = %d\n", nic_data.Media);
- printk("SCR = 0x%02x\n", nic_data.SCR);
- }
+ pr_debug("\nEEPROM contents:\n"
+ "RAM_Size = 0x%02X\n"
+ "NodeID = %pM\n"
+ "Model = %d\n"
+ "Media = %d\n"
+ "SCR = 0x%02x\n", nic_data.RAM_Size, nic_data.NodeID,
+ nic_data.Model, nic_data.Media, nic_data.SCR);
err = register_netdev(dev);
if (err)
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index b62405a6918..2b22e580c4d 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -895,6 +895,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_regs *ll = lp->ll;
volatile u16 *ib = (volatile u16 *)dev->mem_start;
+ unsigned long flags;
int entry, len;
len = skb->len;
@@ -907,6 +908,8 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->stats.tx_bytes += len;
+ spin_lock_irqsave(&lp->lock, flags);
+
entry = lp->tx_new;
*lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len);
*lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0;
@@ -925,6 +928,8 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Kick the lance: transmit now */
writereg(&ll->rdp, LE_C0_INEA | LE_C0_TDMD);
+ spin_unlock_irqrestore(&lp->lock, flags);
+
dev->trans_start = jiffies;
dev_kfree_skb(skb);
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
index 4ec055dc717..102b8d43971 100644
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -3318,7 +3318,7 @@ static int dfx_xmt_queue_pkt(
{
skb_pull(skb,3);
spin_unlock_irqrestore(&bp->lock, flags);
- return(1); /* requeue packet for later */
+ return NETDEV_TX_BUSY; /* requeue packet for later */
}
/*
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 357f565851e..97ea2d6d3fe 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -810,7 +810,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
dev->mem_start = 0;
- device->driver_data = dev;
+ dev_set_drvdata(device, dev);
SET_NETDEV_DEV (dev, device);
status = register_netdev(dev);
@@ -957,7 +957,7 @@ static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (TX_BUFFS_AVAIL)
netif_start_queue(dev);
} else
- status = -1;
+ status = NETDEV_TX_LOCKED;
out:
return status;
@@ -1614,7 +1614,7 @@ static int __devexit depca_device_remove (struct device *device)
struct depca_private *lp;
int bus;
- dev = device->driver_data;
+ dev = dev_get_drvdata(device);
lp = netdev_priv(dev);
unregister_netdev (dev);
@@ -1839,7 +1839,7 @@ static int load_packet(struct net_device *dev, struct sk_buff *skb)
lp->tx_new = (++end) & lp->txRingMask; /* update current pointers */
} else {
- status = -1;
+ status = NETDEV_TX_LOCKED;
}
return status;
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index 4a1b554654e..895d72143ee 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -539,7 +539,7 @@ rio_tx_timeout (struct net_device *dev)
dev->name, readl (ioaddr + TxStatus));
rio_free_tx(dev, 0);
dev->if_port = 0;
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
}
/* allocate and initialize Tx and Rx descriptors */
@@ -610,7 +610,7 @@ start_xmit (struct sk_buff *skb, struct net_device *dev)
if (np->link_status == 0) { /* Link Down */
dev_kfree_skb(skb);
- return 0;
+ return NETDEV_TX_OK;
}
ioaddr = dev->base_addr;
entry = np->cur_tx % TX_RING_SIZE;
@@ -665,9 +665,7 @@ start_xmit (struct sk_buff *skb, struct net_device *dev)
writel (0, dev->base_addr + TFDListPtr1);
}
- /* NETDEV WATCHDOG timer */
- dev->trans_start = jiffies;
- return 0;
+ return NETDEV_TX_OK;
}
static irqreturn_t
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index d8350860c0f..dd771dea6ae 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -756,7 +756,7 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
dm9000_dbg(db, 3, "%s:\n", __func__);
if (db->tx_pkt_cnt > 1)
- return 1;
+ return NETDEV_TX_BUSY;
spin_lock_irqsave(&db->lock, flags);
@@ -1170,6 +1170,21 @@ dm9000_stop(struct net_device *ndev)
return 0;
}
+static const struct net_device_ops dm9000_netdev_ops = {
+ .ndo_open = dm9000_open,
+ .ndo_stop = dm9000_stop,
+ .ndo_start_xmit = dm9000_start_xmit,
+ .ndo_tx_timeout = dm9000_timeout,
+ .ndo_set_multicast_list = dm9000_hash_table,
+ .ndo_do_ioctl = dm9000_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = dm9000_poll_controller,
+#endif
+};
+
#define res_size(_r) (((_r)->end - (_r)->start) + 1)
/*
@@ -1339,18 +1354,9 @@ dm9000_probe(struct platform_device *pdev)
/* driver system function */
ether_setup(ndev);
- ndev->open = &dm9000_open;
- ndev->hard_start_xmit = &dm9000_start_xmit;
- ndev->tx_timeout = &dm9000_timeout;
- ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
- ndev->stop = &dm9000_stop;
- ndev->set_multicast_list = &dm9000_hash_table;
- ndev->ethtool_ops = &dm9000_ethtool_ops;
- ndev->do_ioctl = &dm9000_ioctl;
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
- ndev->poll_controller = &dm9000_poll_controller;
-#endif
+ ndev->netdev_ops = &dm9000_netdev_ops;
+ ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
+ ndev->ethtool_ops = &dm9000_ethtool_ops;
db->msg_enable = NETIF_MSG_LINK;
db->mii.phy_id_mask = 0x1f;
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index af5364f4955..f7929e89eb0 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -143,6 +143,8 @@
* FIXES:
* 2005/12/02 - Michael O'Donnell <Michael.ODonnell at stratus dot com>
* - Stratus87247: protect MDI control register manipulations
+ * 2009/06/01 - Andreas Mohr <andi at lisas dot de>
+ * - add clean lowlevel I/O emulation for cards with MII-lacking PHYs
*/
#include <linux/module.h>
@@ -372,6 +374,7 @@ enum eeprom_op {
enum eeprom_offsets {
eeprom_cnfg_mdix = 0x03,
+ eeprom_phy_iface = 0x06,
eeprom_id = 0x0A,
eeprom_config_asf = 0x0D,
eeprom_smbus_addr = 0x90,
@@ -381,6 +384,18 @@ enum eeprom_cnfg_mdix {
eeprom_mdix_enabled = 0x0080,
};
+enum eeprom_phy_iface {
+ NoSuchPhy = 0,
+ I82553AB,
+ I82553C,
+ I82503,
+ DP83840,
+ S80C240,
+ S80C24,
+ I82555,
+ DP83840A = 10,
+};
+
enum eeprom_id {
eeprom_id_wol = 0x0020,
};
@@ -545,6 +560,7 @@ struct nic {
u32 msg_enable ____cacheline_aligned;
struct net_device *netdev;
struct pci_dev *pdev;
+ u16 (*mdio_ctrl)(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data);
struct rx *rxs ____cacheline_aligned;
struct rx *rx_to_use;
@@ -899,7 +915,21 @@ err_unlock:
return err;
}
-static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
+static int mdio_read(struct net_device *netdev, int addr, int reg)
+{
+ struct nic *nic = netdev_priv(netdev);
+ return nic->mdio_ctrl(nic, addr, mdi_read, reg, 0);
+}
+
+static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
+{
+ struct nic *nic = netdev_priv(netdev);
+
+ nic->mdio_ctrl(nic, addr, mdi_write, reg, data);
+}
+
+/* the standard mdio_ctrl() function for usual MII-compliant hardware */
+static u16 mdio_ctrl_hw(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
{
u32 data_out = 0;
unsigned int i;
@@ -938,30 +968,83 @@ static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
return (u16)data_out;
}
-static int mdio_read(struct net_device *netdev, int addr, int reg)
-{
- return mdio_ctrl(netdev_priv(netdev), addr, mdi_read, reg, 0);
+/* slightly tweaked mdio_ctrl() function for phy_82552_v specifics */
+static u16 mdio_ctrl_phy_82552_v(struct nic *nic,
+ u32 addr,
+ u32 dir,
+ u32 reg,
+ u16 data)
+{
+ if ((reg == MII_BMCR) && (dir == mdi_write)) {
+ if (data & (BMCR_ANRESTART | BMCR_ANENABLE)) {
+ u16 advert = mdio_read(nic->netdev, nic->mii.phy_id,
+ MII_ADVERTISE);
+
+ /*
+ * Workaround Si issue where sometimes the part will not
+ * autoneg to 100Mbps even when advertised.
+ */
+ if (advert & ADVERTISE_100FULL)
+ data |= BMCR_SPEED100 | BMCR_FULLDPLX;
+ else if (advert & ADVERTISE_100HALF)
+ data |= BMCR_SPEED100;
+ }
+ }
+ return mdio_ctrl_hw(nic, addr, dir, reg, data);
}
-static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
-{
- struct nic *nic = netdev_priv(netdev);
-
- if ((nic->phy == phy_82552_v) && (reg == MII_BMCR) &&
- (data & (BMCR_ANRESTART | BMCR_ANENABLE))) {
- u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
-
- /*
- * Workaround Si issue where sometimes the part will not
- * autoneg to 100Mbps even when advertised.
- */
- if (advert & ADVERTISE_100FULL)
- data |= BMCR_SPEED100 | BMCR_FULLDPLX;
- else if (advert & ADVERTISE_100HALF)
- data |= BMCR_SPEED100;
+/* Fully software-emulated mdio_ctrl() function for cards without
+ * MII-compliant PHYs.
+ * For now, this is mainly geared towards 80c24 support; in case of further
+ * requirements for other types (i82503, ...?) either extend this mechanism
+ * or split it, whichever is cleaner.
+ */
+static u16 mdio_ctrl_phy_mii_emulated(struct nic *nic,
+ u32 addr,
+ u32 dir,
+ u32 reg,
+ u16 data)
+{
+ /* might need to allocate a netdev_priv'ed register array eventually
+ * to be able to record state changes, but for now
+ * some fully hardcoded register handling ought to be ok I guess. */
+
+ if (dir == mdi_read) {
+ switch (reg) {
+ case MII_BMCR:
+ /* Auto-negotiation, right? */
+ return BMCR_ANENABLE |
+ BMCR_FULLDPLX;
+ case MII_BMSR:
+ return BMSR_LSTATUS /* for mii_link_ok() */ |
+ BMSR_ANEGCAPABLE |
+ BMSR_10FULL;
+ case MII_ADVERTISE:
+ /* 80c24 is a "combo card" PHY, right? */
+ return ADVERTISE_10HALF |
+ ADVERTISE_10FULL;
+ default:
+ DPRINTK(HW, DEBUG,
+ "%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n",
+ dir == mdi_read ? "READ" : "WRITE", addr, reg, data);
+ return 0xFFFF;
+ }
+ } else {
+ switch (reg) {
+ default:
+ DPRINTK(HW, DEBUG,
+ "%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n",
+ dir == mdi_read ? "READ" : "WRITE", addr, reg, data);
+ return 0xFFFF;
+ }
}
-
- mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data);
+}
+static inline int e100_phy_supports_mii(struct nic *nic)
+{
+ /* for now, just check it by comparing whether we
+ are using MII software emulation.
+ */
+ return (nic->mdio_ctrl != mdio_ctrl_phy_mii_emulated);
}
static void e100_get_defaults(struct nic *nic)
@@ -1013,7 +1096,8 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
config->standard_stat_counter = 0x1; /* 1=standard, 0=extended */
config->rx_discard_short_frames = 0x1; /* 1=discard, 0=pass */
config->tx_underrun_retry = 0x3; /* # of underrun retries */
- config->mii_mode = 0x1; /* 1=MII mode, 0=503 mode */
+ if (e100_phy_supports_mii(nic))
+ config->mii_mode = 1; /* 1=MII mode, 0=i82503 mode */
config->pad10 = 0x6;
config->no_source_addr_insertion = 0x1; /* 1=no, 0=yes */
config->preamble_length = 0x2; /* 0=1, 1=3, 2=7, 3=15 bytes */
@@ -1270,6 +1354,42 @@ static void e100_dump(struct nic *nic, struct cb *cb, struct sk_buff *skb)
offsetof(struct mem, dump_buf));
}
+static int e100_phy_check_without_mii(struct nic *nic)
+{
+ u8 phy_type;
+ int without_mii;
+
+ phy_type = (nic->eeprom[eeprom_phy_iface] >> 8) & 0x0f;
+
+ switch (phy_type) {
+ case NoSuchPhy: /* Non-MII PHY; UNTESTED! */
+ case I82503: /* Non-MII PHY; UNTESTED! */
+ case S80C24: /* Non-MII PHY; tested and working */
+ /* paragraph from the FreeBSD driver, "FXP_PHY_80C24":
+ * The Seeq 80c24 AutoDUPLEX(tm) Ethernet Interface Adapter
+ * doesn't have a programming interface of any sort. The
+ * media is sensed automatically based on how the link partner
+ * is configured. This is, in essence, manual configuration.
+ */
+ DPRINTK(PROBE, INFO,
+ "found MII-less i82503 or 80c24 or other PHY\n");
+
+ nic->mdio_ctrl = mdio_ctrl_phy_mii_emulated;
+ nic->mii.phy_id = 0; /* is this ok for an MII-less PHY? */
+
+ /* these might be needed for certain MII-less cards...
+ * nic->flags |= ich;
+ * nic->flags |= ich_10h_workaround; */
+
+ without_mii = 1;
+ break;
+ default:
+ without_mii = 0;
+ break;
+ }
+ return without_mii;
+}
+
#define NCONFIG_AUTO_SWITCH 0x0080
#define MII_NSC_CONG MII_RESV1
#define NSC_CONG_ENABLE 0x0100
@@ -1290,9 +1410,21 @@ static int e100_phy_init(struct nic *nic)
if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0))))
break;
}
- DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id);
- if (addr == 32)
- return -EAGAIN;
+ if (addr == 32) {
+ /* uhoh, no PHY detected: check whether we seem to be some
+ * weird, rare variant which is *known* to not have any MII.
+ * But do this AFTER MII checking only, since this does
+ * lookup of EEPROM values which may easily be unreliable. */
+ if (e100_phy_check_without_mii(nic))
+ return 0; /* simply return and hope for the best */
+ else {
+ /* for unknown cases log a fatal error */
+ DPRINTK(HW, ERR,
+ "Failed to locate any known PHY, aborting.\n");
+ return -EAGAIN;
+ }
+ } else
+ DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id);
/* Isolate all the PHY ids */
for (addr = 0; addr < 32; addr++)
@@ -1320,6 +1452,9 @@ static int e100_phy_init(struct nic *nic)
if (nic->phy == phy_82552_v) {
u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
+ /* assign special tweaked mdio_ctrl() function */
+ nic->mdio_ctrl = mdio_ctrl_phy_82552_v;
+
/* Workaround Si not advertising flow-control during autoneg */
advert |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
mdio_write(netdev, nic->mii.phy_id, MII_ADVERTISE, advert);
@@ -1581,7 +1716,7 @@ static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* This is a hard error - log it. */
DPRINTK(TX_ERR, DEBUG, "Out of Tx resources, returning skb\n");
netif_stop_queue(netdev);
- return 1;
+ return NETDEV_TX_BUSY;
}
netdev->trans_start = jiffies;
@@ -2585,6 +2720,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
nic->netdev = netdev;
nic->pdev = pdev;
nic->msg_enable = (1 << debug) - 1;
+ nic->mdio_ctrl = mdio_ctrl_hw;
pci_set_drvdata(pdev, netdev);
if ((err = pci_enable_device(pdev))) {
@@ -2822,12 +2958,13 @@ static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel
struct net_device *netdev = pci_get_drvdata(pdev);
struct nic *nic = netdev_priv(netdev);
- /* Similar to calling e100_down(), but avoids adapter I/O. */
- e100_close(netdev);
-
- /* Detach; put netif into a state similar to hotplug unplug. */
- napi_enable(&nic->napi);
netif_device_detach(netdev);
+
+ if (state == pci_channel_io_perm_failure)
+ return PCI_ERS_RESULT_DISCONNECT;
+
+ if (netif_running(netdev))
+ e100_down(nic);
pci_disable_device(pdev);
/* Request a slot reset. */
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index fffb006b7d9..8d36743c814 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -498,6 +498,8 @@ int e1000_up(struct e1000_adapter *adapter)
e1000_irq_enable(adapter);
+ netif_wake_queue(adapter->netdev);
+
/* fire a link change interrupt to start the watchdog */
ew32(ICS, E1000_ICS_LSC);
return 0;
@@ -1234,15 +1236,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
!e1000_check_mng_mode(hw))
e1000_get_hw_control(adapter);
- /* tell the stack to leave us alone until e1000_open() is called */
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
if (err)
goto err_register;
+ /* carrier off reporting is important to ethtool even BEFORE open */
+ netif_carrier_off(netdev);
+
DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
cards_found++;
@@ -1441,6 +1442,8 @@ static int e1000_open(struct net_device *netdev)
if (test_bit(__E1000_TESTING, &adapter->flags))
return -EBUSY;
+ netif_carrier_off(netdev);
+
/* allocate transmit descriptors */
err = e1000_setup_all_tx_resources(adapter);
if (err)
@@ -2327,7 +2330,8 @@ static void e1000_set_rx_mode(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- struct dev_addr_list *uc_ptr;
+ struct netdev_hw_addr *ha;
+ bool use_uc = false;
struct dev_addr_list *mc_ptr;
u32 rctl;
u32 hash_value;
@@ -2366,12 +2370,11 @@ static void e1000_set_rx_mode(struct net_device *netdev)
rctl |= E1000_RCTL_VFE;
}
- uc_ptr = NULL;
if (netdev->uc_count > rar_entries - 1) {
rctl |= E1000_RCTL_UPE;
} else if (!(netdev->flags & IFF_PROMISC)) {
rctl &= ~E1000_RCTL_UPE;
- uc_ptr = netdev->uc_list;
+ use_uc = true;
}
ew32(RCTL, rctl);
@@ -2389,13 +2392,20 @@ static void e1000_set_rx_mode(struct net_device *netdev)
* if there are not 14 addresses, go ahead and clear the filters
* -- with 82571 controllers only 0-13 entries are filled here
*/
+ i = 1;
+ if (use_uc)
+ list_for_each_entry(ha, &netdev->uc_list, list) {
+ if (i == rar_entries)
+ break;
+ e1000_rar_set(hw, ha->addr, i++);
+ }
+
+ WARN_ON(i == rar_entries);
+
mc_ptr = netdev->mc_list;
- for (i = 1; i < rar_entries; i++) {
- if (uc_ptr) {
- e1000_rar_set(hw, uc_ptr->da_addr, i);
- uc_ptr = uc_ptr->next;
- } else if (mc_ptr) {
+ for (; i < rar_entries; i++) {
+ if (mc_ptr) {
e1000_rar_set(hw, mc_ptr->da_addr, i);
mc_ptr = mc_ptr->next;
} else {
@@ -2405,7 +2415,6 @@ static void e1000_set_rx_mode(struct net_device *netdev)
E1000_WRITE_FLUSH();
}
}
- WARN_ON(uc_ptr != NULL);
/* load any remaining addresses into the hash table */
@@ -2590,7 +2599,6 @@ static void e1000_watchdog(unsigned long data)
ew32(TCTL, tctl);
netif_carrier_on(netdev);
- netif_wake_queue(netdev);
mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
adapter->smartspeed = 0;
} else {
@@ -2607,7 +2615,6 @@ static void e1000_watchdog(unsigned long data)
printk(KERN_INFO "e1000: %s NIC Link is Down\n",
netdev->name);
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
/* 80003ES2LAN workaround--
@@ -2645,6 +2652,8 @@ static void e1000_watchdog(unsigned long data)
* (Do the reset outside of interrupt context). */
adapter->tx_timeout_count++;
schedule_work(&adapter->reset_task);
+ /* return immediately since reset is imminent */
+ return;
}
}
@@ -2989,7 +2998,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
size -= 4;
buffer_info->length = size;
- buffer_info->dma = map[0] + offset;
+ buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
@@ -3030,7 +3039,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
size -= 4;
buffer_info->length = size;
- buffer_info->dma = map[f + 1] + offset;
+ buffer_info->dma = map[f] + offset;
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
@@ -3362,7 +3371,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (count) {
e1000_tx_queue(adapter, tx_ring, tx_flags, count);
- netdev->trans_start = jiffies;
/* Make sure there is space in the ring for the next send. */
e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 6c01a2072c8..b53b40ba88a 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -71,6 +71,7 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw);
static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
static s32 e1000_led_on_82574(struct e1000_hw *hw);
+static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
/**
* e1000_init_phy_params_82571 - Init PHY func ptrs.
@@ -212,6 +213,9 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
struct e1000_mac_info *mac = &hw->mac;
struct e1000_mac_operations *func = &mac->ops;
+ u32 swsm = 0;
+ u32 swsm2 = 0;
+ bool force_clear_smbi = false;
/* Set media type */
switch (adapter->pdev->device) {
@@ -276,6 +280,50 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
break;
}
+ /*
+ * Ensure that the inter-port SWSM.SMBI lock bit is clear before
+ * first NVM or PHY acess. This should be done for single-port
+ * devices, and for one port only on dual-port devices so that
+ * for those devices we can still use the SMBI lock to synchronize
+ * inter-port accesses to the PHY & NVM.
+ */
+ switch (hw->mac.type) {
+ case e1000_82571:
+ case e1000_82572:
+ swsm2 = er32(SWSM2);
+
+ if (!(swsm2 & E1000_SWSM2_LOCK)) {
+ /* Only do this for the first interface on this card */
+ ew32(SWSM2,
+ swsm2 | E1000_SWSM2_LOCK);
+ force_clear_smbi = true;
+ } else
+ force_clear_smbi = false;
+ break;
+ default:
+ force_clear_smbi = true;
+ break;
+ }
+
+ if (force_clear_smbi) {
+ /* Make sure SWSM.SMBI is clear */
+ swsm = er32(SWSM);
+ if (swsm & E1000_SWSM_SMBI) {
+ /* This bit should not be set on a first interface, and
+ * indicates that the bootagent or EFI code has
+ * improperly left this bit enabled
+ */
+ hw_dbg(hw, "Please update your 82571 Bootagent\n");
+ }
+ ew32(SWSM, swsm & ~E1000_SWSM_SMBI);
+ }
+
+ /*
+ * Initialze device specific counter of SMBI acquisition
+ * timeouts.
+ */
+ hw->dev_spec.e82571.smb_counter = 0;
+
return 0;
}
@@ -341,8 +389,10 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
if (e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1,
&eeprom_data) < 0)
break;
- if (eeprom_data & NVM_WORD1A_ASPM_MASK)
- adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
+ if (!(eeprom_data & NVM_WORD1A_ASPM_MASK)) {
+ adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
+ adapter->max_hw_frame_size = DEFAULT_JUMBO;
+ }
}
break;
default:
@@ -411,11 +461,37 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
{
u32 swsm;
- s32 timeout = hw->nvm.word_size + 1;
+ s32 sw_timeout = hw->nvm.word_size + 1;
+ s32 fw_timeout = hw->nvm.word_size + 1;
s32 i = 0;
+ /*
+ * If we have timedout 3 times on trying to acquire
+ * the inter-port SMBI semaphore, there is old code
+ * operating on the other port, and it is not
+ * releasing SMBI. Modify the number of times that
+ * we try for the semaphore to interwork with this
+ * older code.
+ */
+ if (hw->dev_spec.e82571.smb_counter > 2)
+ sw_timeout = 1;
+
+ /* Get the SW semaphore */
+ while (i < sw_timeout) {
+ swsm = er32(SWSM);
+ if (!(swsm & E1000_SWSM_SMBI))
+ break;
+
+ udelay(50);
+ i++;
+ }
+
+ if (i == sw_timeout) {
+ hw_dbg(hw, "Driver can't access device - SMBI bit is set.\n");
+ hw->dev_spec.e82571.smb_counter++;
+ }
/* Get the FW semaphore. */
- for (i = 0; i < timeout; i++) {
+ for (i = 0; i < fw_timeout; i++) {
swsm = er32(SWSM);
ew32(SWSM, swsm | E1000_SWSM_SWESMBI);
@@ -426,9 +502,9 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
udelay(50);
}
- if (i == timeout) {
+ if (i == fw_timeout) {
/* Release semaphores */
- e1000e_put_hw_semaphore(hw);
+ e1000_put_hw_semaphore_82571(hw);
hw_dbg(hw, "Driver can't access the NVM\n");
return -E1000_ERR_NVM;
}
@@ -447,9 +523,7 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
u32 swsm;
swsm = er32(SWSM);
-
- swsm &= ~E1000_SWSM_SWESMBI;
-
+ swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
ew32(SWSM, swsm);
}
@@ -1585,6 +1659,7 @@ static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw)
static struct e1000_mac_operations e82571_mac_ops = {
/* .check_mng_mode: mac type dependent */
/* .check_for_link: media type dependent */
+ .id_led_init = e1000e_id_led_init,
.cleanup_led = e1000e_cleanup_led_generic,
.clear_hw_cntrs = e1000_clear_hw_cntrs_82571,
.get_bus_info = e1000e_get_bus_info_pcie,
@@ -1596,6 +1671,7 @@ static struct e1000_mac_operations e82571_mac_ops = {
.init_hw = e1000_init_hw_82571,
.setup_link = e1000_setup_link_82571,
/* .setup_physical_interface: media type dependent */
+ .setup_led = e1000e_setup_led_generic,
};
static struct e1000_phy_operations e82_phy_ops_igp = {
@@ -1672,6 +1748,7 @@ struct e1000_info e1000_82571_info = {
| FLAG_TARC_SPEED_MODE_BIT /* errata */
| FLAG_APME_CHECK_PORT_B,
.pba = 38,
+ .max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_82571,
.mac_ops = &e82571_mac_ops,
.phy_ops = &e82_phy_ops_igp,
@@ -1688,6 +1765,7 @@ struct e1000_info e1000_82572_info = {
| FLAG_HAS_CTRLEXT_ON_LOAD
| FLAG_TARC_SPEED_MODE_BIT, /* errata */
.pba = 38,
+ .max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_82571,
.mac_ops = &e82571_mac_ops,
.phy_ops = &e82_phy_ops_igp,
@@ -1706,6 +1784,7 @@ struct e1000_info e1000_82573_info = {
| FLAG_HAS_ERT
| FLAG_HAS_SWSM_ON_LOAD,
.pba = 20,
+ .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
.get_variants = e1000_get_variants_82571,
.mac_ops = &e82571_mac_ops,
.phy_ops = &e82_phy_ops_m88,
@@ -1724,6 +1803,7 @@ struct e1000_info e1000_82574_info = {
| FLAG_HAS_AMT
| FLAG_HAS_CTRLEXT_ON_LOAD,
.pba = 20,
+ .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
.get_variants = e1000_get_variants_82571,
.mac_ops = &e82571_mac_ops,
.phy_ops = &e82_phy_ops_bm,
@@ -1740,6 +1820,7 @@ struct e1000_info e1000_82583_info = {
| FLAG_HAS_AMT
| FLAG_HAS_CTRLEXT_ON_LOAD,
.pba = 20,
+ .max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_82571,
.mac_ops = &e82571_mac_ops,
.phy_ops = &e82_phy_ops_bm,
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index 243aa499fe9..8890c97e112 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -56,6 +56,7 @@
/* Wake Up Control */
#define E1000_WUC_APME 0x00000001 /* APM Enable */
#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */
+#define E1000_WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */
/* Wake Up Filter Control */
#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
@@ -65,6 +66,13 @@
#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
+/* Wake Up Status */
+#define E1000_WUS_LNKC E1000_WUFC_LNKC
+#define E1000_WUS_MAG E1000_WUFC_MAG
+#define E1000_WUS_EX E1000_WUFC_EX
+#define E1000_WUS_MC E1000_WUFC_MC
+#define E1000_WUS_BC E1000_WUFC_BC
+
/* Extended Device Control */
#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
@@ -77,6 +85,7 @@
#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
+#define E1000_CTRL_EXT_PHYPDEN 0x00100000
/* Receive Descriptor bit definitions */
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
@@ -140,6 +149,7 @@
#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
#define E1000_RCTL_RDMTS_HALF 0x00000000 /* Rx desc min threshold size */
#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
+#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
#define E1000_RCTL_SZ_2048 0x00000000 /* Rx buffer size 2048 */
@@ -153,6 +163,7 @@
#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */
+#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
@@ -255,11 +266,16 @@
#define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX
/* LED Control */
+#define E1000_PHY_LED0_MODE_MASK 0x00000007
+#define E1000_PHY_LED0_IVRT 0x00000008
+#define E1000_PHY_LED0_MASK 0x0000001F
+
#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
#define E1000_LEDCTL_LED0_MODE_SHIFT 0
#define E1000_LEDCTL_LED0_IVRT 0x00000040
#define E1000_LEDCTL_LED0_BLINK 0x00000080
+#define E1000_LEDCTL_MODE_LINK_UP 0x2
#define E1000_LEDCTL_MODE_LED_ON 0xE
#define E1000_LEDCTL_MODE_LED_OFF 0xF
@@ -360,6 +376,8 @@
#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
+#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */
+
/* Interrupt Cause Read */
#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
@@ -469,6 +487,8 @@
#define AUTO_READ_DONE_TIMEOUT 10
/* Flow Control */
+#define E1000_FCRTH_RTH 0x0000FFF8 /* Mask Bits[15:3] for RTH */
+#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */
#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
/* Transmit Configuration Word */
@@ -674,6 +694,8 @@
#define IFE_C_E_PHY_ID 0x02A80310
#define BME1000_E_PHY_ID 0x01410CB0
#define BME1000_E_PHY_ID_R2 0x01410CB1
+#define I82577_E_PHY_ID 0x01540050
+#define I82578_E_PHY_ID 0x004DD040
/* M88E1000 Specific Registers */
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
@@ -727,6 +749,9 @@
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800
+#define I82578_EPSCR_DOWNSHIFT_ENABLE 0x0020
+#define I82578_EPSCR_DOWNSHIFT_COUNTER_MASK 0x001C
+
/* BME1000 PHY Specific Control Register */
#define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 44f0bf23daf..981936c1fb4 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -96,6 +96,51 @@ struct e1000_info;
/* Number of packet split data buffers (not including the header buffer) */
#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1)
+#define DEFAULT_JUMBO 9234
+
+/* BM/HV Specific Registers */
+#define BM_PORT_CTRL_PAGE 769
+
+#define PHY_UPPER_SHIFT 21
+#define BM_PHY_REG(page, reg) \
+ (((reg) & MAX_PHY_REG_ADDRESS) |\
+ (((page) & 0xFFFF) << PHY_PAGE_SHIFT) |\
+ (((reg) & ~MAX_PHY_REG_ADDRESS) << (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)))
+
+/* PHY Wakeup Registers and defines */
+#define BM_RCTL PHY_REG(BM_WUC_PAGE, 0)
+#define BM_WUC PHY_REG(BM_WUC_PAGE, 1)
+#define BM_WUFC PHY_REG(BM_WUC_PAGE, 2)
+#define BM_WUS PHY_REG(BM_WUC_PAGE, 3)
+#define BM_RAR_L(_i) (BM_PHY_REG(BM_WUC_PAGE, 16 + ((_i) << 2)))
+#define BM_RAR_M(_i) (BM_PHY_REG(BM_WUC_PAGE, 17 + ((_i) << 2)))
+#define BM_RAR_H(_i) (BM_PHY_REG(BM_WUC_PAGE, 18 + ((_i) << 2)))
+#define BM_RAR_CTRL(_i) (BM_PHY_REG(BM_WUC_PAGE, 19 + ((_i) << 2)))
+#define BM_MTA(_i) (BM_PHY_REG(BM_WUC_PAGE, 128 + ((_i) << 1)))
+
+#define BM_RCTL_UPE 0x0001 /* Unicast Promiscuous Mode */
+#define BM_RCTL_MPE 0x0002 /* Multicast Promiscuous Mode */
+#define BM_RCTL_MO_SHIFT 3 /* Multicast Offset Shift */
+#define BM_RCTL_MO_MASK (3 << 3) /* Multicast Offset Mask */
+#define BM_RCTL_BAM 0x0020 /* Broadcast Accept Mode */
+#define BM_RCTL_PMCF 0x0040 /* Pass MAC Control Frames */
+#define BM_RCTL_RFCE 0x0080 /* Rx Flow Control Enable */
+
+#define HV_SCC_UPPER PHY_REG(778, 16) /* Single Collision Count */
+#define HV_SCC_LOWER PHY_REG(778, 17)
+#define HV_ECOL_UPPER PHY_REG(778, 18) /* Excessive Collision Count */
+#define HV_ECOL_LOWER PHY_REG(778, 19)
+#define HV_MCC_UPPER PHY_REG(778, 20) /* Multiple Collision Count */
+#define HV_MCC_LOWER PHY_REG(778, 21)
+#define HV_LATECOL_UPPER PHY_REG(778, 23) /* Late Collision Count */
+#define HV_LATECOL_LOWER PHY_REG(778, 24)
+#define HV_COLC_UPPER PHY_REG(778, 25) /* Collision Count */
+#define HV_COLC_LOWER PHY_REG(778, 26)
+#define HV_DC_UPPER PHY_REG(778, 27) /* Defer Count */
+#define HV_DC_LOWER PHY_REG(778, 28)
+#define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */
+#define HV_TNCRS_LOWER PHY_REG(778, 30)
+
enum e1000_boards {
board_82571,
board_82572,
@@ -106,6 +151,7 @@ enum e1000_boards {
board_ich8lan,
board_ich9lan,
board_ich10lan,
+ board_pchlan,
};
struct e1000_queue_stats {
@@ -293,6 +339,7 @@ struct e1000_adapter {
u32 eeprom_wol;
u32 wol;
u32 pba;
+ u32 max_hw_frame_size;
bool fc_autoneg;
@@ -302,6 +349,7 @@ struct e1000_adapter {
unsigned int flags2;
struct work_struct downshift_task;
struct work_struct update_phy_task;
+ struct work_struct led_blink_task;
};
struct e1000_info {
@@ -309,6 +357,7 @@ struct e1000_info {
unsigned int flags;
unsigned int flags2;
u32 pba;
+ u32 max_hw_frame_size;
s32 (*get_variants)(struct e1000_adapter *);
struct e1000_mac_operations *mac_ops;
struct e1000_phy_operations *phy_ops;
@@ -351,6 +400,7 @@ struct e1000_info {
/* CRC Stripping defines */
#define FLAG2_CRC_STRIPPING (1 << 0)
+#define FLAG2_HAS_PHY_WAKEUP (1 << 1)
#define E1000_RX_DESC_PS(R, i) \
(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
@@ -404,6 +454,7 @@ extern struct e1000_info e1000_82583_info;
extern struct e1000_info e1000_ich8_info;
extern struct e1000_info e1000_ich9_info;
extern struct e1000_info e1000_ich10_info;
+extern struct e1000_info e1000_pch_info;
extern struct e1000_info e1000_es2_info;
extern s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num);
@@ -425,6 +476,7 @@ extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw);
extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw);
extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw);
extern s32 e1000e_check_for_serdes_link(struct e1000_hw *hw);
+extern s32 e1000e_setup_led_generic(struct e1000_hw *hw);
extern s32 e1000e_cleanup_led_generic(struct e1000_hw *hw);
extern s32 e1000e_led_on_generic(struct e1000_hw *hw);
extern s32 e1000e_led_off_generic(struct e1000_hw *hw);
@@ -493,6 +545,15 @@ extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw);
extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
extern s32 e1000e_check_downshift(struct e1000_hw *hw);
+extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data);
+extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data);
+extern s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow);
+extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw);
+extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
+extern s32 e1000_check_polarity_82577(struct e1000_hw *hw);
+extern s32 e1000_get_phy_info_82577(struct e1000_hw *hw);
+extern s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
+extern s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
{
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index 8964838c686..ae5d7368935 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -1366,6 +1366,7 @@ static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw)
}
static struct e1000_mac_operations es2_mac_ops = {
+ .id_led_init = e1000e_id_led_init,
.check_mng_mode = e1000e_check_mng_mode_generic,
/* check_for_link dependent on media type */
.cleanup_led = e1000e_cleanup_led_generic,
@@ -1379,6 +1380,7 @@ static struct e1000_mac_operations es2_mac_ops = {
.init_hw = e1000_init_hw_80003es2lan,
.setup_link = e1000e_setup_link,
/* setup_physical_interface dependent on media type */
+ .setup_led = e1000e_setup_led_generic,
};
static struct e1000_phy_operations es2_phy_ops = {
@@ -1422,6 +1424,7 @@ struct e1000_info e1000_es2_info = {
| FLAG_DISABLE_FC_PAUSE_TIME /* errata */
| FLAG_TIPG_MEDIUM_FOR_80003ESLAN,
.pba = 38,
+ .max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_80003es2lan,
.mac_ops = &es2_mac_ops,
.phy_ops = &es2_phy_ops,
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 4d25ede8836..1bf4d2a5d34 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -167,6 +167,15 @@ static int e1000_get_settings(struct net_device *netdev,
ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) ||
hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+
+ /* MDI-X => 2; MDI =>1; Invalid =>0 */
+ if ((hw->phy.media_type == e1000_media_type_copper) &&
+ !hw->mac.get_link_status)
+ ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X :
+ ETH_TP_MDI;
+ else
+ ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
+
return 0;
}
@@ -776,6 +785,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
u32 after;
u32 i;
u32 toggle;
+ u32 mask;
/*
* The status register is Read Only, so a write should fail.
@@ -788,17 +798,9 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
case e1000_80003es2lan:
toggle = 0x7FFFF3FF;
break;
- case e1000_82573:
- case e1000_82574:
- case e1000_82583:
- case e1000_ich8lan:
- case e1000_ich9lan:
- case e1000_ich10lan:
+ default:
toggle = 0x7FFFF033;
break;
- default:
- toggle = 0xFFFFF833;
- break;
}
before = er32(STATUS);
@@ -844,11 +846,18 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF);
REG_PATTERN_TEST(E1000_TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF);
+ mask = 0x8003FFFF;
+ switch (mac->type) {
+ case e1000_ich10lan:
+ case e1000_pchlan:
+ mask |= (1 << 18);
+ break;
+ default:
+ break;
+ }
for (i = 0; i < mac->rar_entry_count; i++)
REG_PATTERN_TEST_ARRAY(E1000_RA, ((i << 1) + 1),
- ((mac->type == e1000_ich10lan) ?
- 0x8007FFFF : 0x8003FFFF),
- 0xFFFFFFFF);
+ mask, 0xFFFFFFFF);
for (i = 0; i < mac->mta_reg_count; i++)
REG_PATTERN_TEST_ARRAY(E1000_MTA, i, 0xFFFFFFFF, 0xFFFFFFFF);
@@ -1786,15 +1795,22 @@ static int e1000_set_wol(struct net_device *netdev,
/* bit defines for adapter->led_status */
#define E1000_LED_ON 0
-static void e1000_led_blink_callback(unsigned long data)
+static void e1000e_led_blink_task(struct work_struct *work)
{
- struct e1000_adapter *adapter = (struct e1000_adapter *) data;
+ struct e1000_adapter *adapter = container_of(work,
+ struct e1000_adapter, led_blink_task);
if (test_and_change_bit(E1000_LED_ON, &adapter->led_status))
adapter->hw.mac.ops.led_off(&adapter->hw);
else
adapter->hw.mac.ops.led_on(&adapter->hw);
+}
+
+static void e1000_led_blink_callback(unsigned long data)
+{
+ struct e1000_adapter *adapter = (struct e1000_adapter *) data;
+ schedule_work(&adapter->led_blink_task);
mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL);
}
@@ -1807,7 +1823,9 @@ static int e1000_phys_id(struct net_device *netdev, u32 data)
data = INT_MAX;
if ((hw->phy.type == e1000_phy_ife) ||
+ (hw->mac.type == e1000_pchlan) ||
(hw->mac.type == e1000_82574)) {
+ INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task);
if (!adapter->blink_timer.function) {
init_timer(&adapter->blink_timer);
adapter->blink_timer.function =
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index d8b82296f41..163c1c0cfee 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -193,7 +193,11 @@ enum e1e_registers {
E1000_RXCSUM = 0x05000, /* Rx Checksum Control - RW */
E1000_RFCTL = 0x05008, /* Receive Filter Control */
E1000_MTA = 0x05200, /* Multicast Table Array - RW Array */
- E1000_RA = 0x05400, /* Receive Address - RW Array */
+ E1000_RAL_BASE = 0x05400, /* Receive Address Low - RW */
+#define E1000_RAL(_n) (E1000_RAL_BASE + ((_n) * 8))
+#define E1000_RA (E1000_RAL(0))
+ E1000_RAH_BASE = 0x05404, /* Receive Address High - RW */
+#define E1000_RAH(_n) (E1000_RAH_BASE + ((_n) * 8))
E1000_VFTA = 0x05600, /* VLAN Filter Table Array - RW Array */
E1000_WUC = 0x05800, /* Wakeup Control - RW */
E1000_WUFC = 0x05808, /* Wakeup Filter Control - RW */
@@ -210,6 +214,7 @@ enum e1e_registers {
E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */
E1000_SWSM = 0x05B50, /* SW Semaphore */
E1000_FWSM = 0x05B54, /* FW Semaphore */
+ E1000_SWSM2 = 0x05B58, /* Driver-only SW semaphore */
E1000_HICR = 0x08F00, /* Host Interface Control */
};
@@ -253,7 +258,7 @@ enum e1e_registers {
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
-#define IGP01E1000_PSSR_MDIX 0x0008
+#define IGP01E1000_PSSR_MDIX 0x0800
#define IGP01E1000_PSSR_SPEED_MASK 0xC000
#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
@@ -368,6 +373,10 @@ enum e1e_registers {
#define E1000_DEV_ID_ICH10_R_BM_V 0x10CE
#define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE
#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF
+#define E1000_DEV_ID_PCH_M_HV_LM 0x10EA
+#define E1000_DEV_ID_PCH_M_HV_LC 0x10EB
+#define E1000_DEV_ID_PCH_D_HV_DM 0x10EF
+#define E1000_DEV_ID_PCH_D_HV_DC 0x10F0
#define E1000_REVISION_4 4
@@ -383,6 +392,7 @@ enum e1000_mac_type {
e1000_ich8lan,
e1000_ich9lan,
e1000_ich10lan,
+ e1000_pchlan,
};
enum e1000_media_type {
@@ -417,6 +427,8 @@ enum e1000_phy_type {
e1000_phy_igp_3,
e1000_phy_ife,
e1000_phy_bm,
+ e1000_phy_82578,
+ e1000_phy_82577,
};
enum e1000_bus_width {
@@ -720,6 +732,7 @@ struct e1000_host_mng_command_info {
/* Function pointers and static data for the MAC. */
struct e1000_mac_operations {
+ s32 (*id_led_init)(struct e1000_hw *);
bool (*check_mng_mode)(struct e1000_hw *);
s32 (*check_for_link)(struct e1000_hw *);
s32 (*cleanup_led)(struct e1000_hw *);
@@ -733,11 +746,13 @@ struct e1000_mac_operations {
s32 (*init_hw)(struct e1000_hw *);
s32 (*setup_link)(struct e1000_hw *);
s32 (*setup_physical_interface)(struct e1000_hw *);
+ s32 (*setup_led)(struct e1000_hw *);
};
/* Function pointers for the PHY. */
struct e1000_phy_operations {
s32 (*acquire_phy)(struct e1000_hw *);
+ s32 (*check_polarity)(struct e1000_hw *);
s32 (*check_reset_block)(struct e1000_hw *);
s32 (*commit_phy)(struct e1000_hw *);
s32 (*force_speed_duplex)(struct e1000_hw *);
@@ -869,6 +884,7 @@ struct e1000_fc_info {
struct e1000_dev_spec_82571 {
bool laa_is_present;
bool alt_mac_addr_is_present;
+ u32 smb_counter;
};
struct e1000_shadow_ram {
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 6d1aab6316b..9e23f50fb9c 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -48,6 +48,10 @@
* 82567LF-3 Gigabit Network Connection
* 82567LM-3 Gigabit Network Connection
* 82567LM-4 Gigabit Network Connection
+ * 82577LM Gigabit Network Connection
+ * 82577LC Gigabit Network Connection
+ * 82578DM Gigabit Network Connection
+ * 82578DC Gigabit Network Connection
*/
#include <linux/netdevice.h>
@@ -116,6 +120,8 @@
#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300
#define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200
+#define HV_LED_CONFIG PHY_REG(768, 30) /* LED Configuration */
+
/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
/* Offset 04h HSFSTS */
union ich8_hws_flash_status {
@@ -186,6 +192,14 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw);
static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw);
static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw);
+static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw);
+static s32 e1000_led_on_ich8lan(struct e1000_hw *hw);
+static s32 e1000_led_off_ich8lan(struct e1000_hw *hw);
+static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw);
+static s32 e1000_setup_led_pchlan(struct e1000_hw *hw);
+static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw);
+static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
+static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
{
@@ -213,6 +227,41 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val)
#define ew32flash(reg,val) __ew32flash(hw, (reg), (val))
/**
+ * e1000_init_phy_params_pchlan - Initialize PHY function pointers
+ * @hw: pointer to the HW structure
+ *
+ * Initialize family-specific PHY parameters and function pointers.
+ **/
+static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val = 0;
+
+ phy->addr = 1;
+ phy->reset_delay_us = 100;
+
+ phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan;
+ phy->ops.read_phy_reg = e1000_read_phy_reg_hv;
+ phy->ops.write_phy_reg = e1000_write_phy_reg_hv;
+ phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+
+ phy->id = e1000_phy_unknown;
+ e1000e_get_phy_id(hw);
+ phy->type = e1000e_get_phy_type_from_id(phy->id);
+
+ if (phy->type == e1000_phy_82577) {
+ phy->ops.check_polarity = e1000_check_polarity_82577;
+ phy->ops.force_speed_duplex =
+ e1000_phy_force_speed_duplex_82577;
+ phy->ops.get_cable_length = e1000_get_cable_length_82577;
+ phy->ops.get_phy_info = e1000_get_phy_info_82577;
+ phy->ops.commit_phy = e1000e_phy_sw_reset;
+ }
+
+ return ret_val;
+}
+
+/**
* e1000_init_phy_params_ich8lan - Initialize PHY function pointers
* @hw: pointer to the HW structure
*
@@ -273,6 +322,8 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
break;
}
+ phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan;
+
return 0;
}
@@ -358,6 +409,36 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
/* Set if manageability features are enabled. */
mac->arc_subsystem_valid = 1;
+ /* LED operations */
+ switch (mac->type) {
+ case e1000_ich8lan:
+ case e1000_ich9lan:
+ case e1000_ich10lan:
+ /* ID LED init */
+ mac->ops.id_led_init = e1000e_id_led_init;
+ /* setup LED */
+ mac->ops.setup_led = e1000e_setup_led_generic;
+ /* cleanup LED */
+ mac->ops.cleanup_led = e1000_cleanup_led_ich8lan;
+ /* turn on/off LED */
+ mac->ops.led_on = e1000_led_on_ich8lan;
+ mac->ops.led_off = e1000_led_off_ich8lan;
+ break;
+ case e1000_pchlan:
+ /* ID LED init */
+ mac->ops.id_led_init = e1000_id_led_init_pchlan;
+ /* setup LED */
+ mac->ops.setup_led = e1000_setup_led_pchlan;
+ /* cleanup LED */
+ mac->ops.cleanup_led = e1000_cleanup_led_pchlan;
+ /* turn on/off LED */
+ mac->ops.led_on = e1000_led_on_pchlan;
+ mac->ops.led_off = e1000_led_off_pchlan;
+ break;
+ default:
+ break;
+ }
+
/* Enable PCS Lock-loss workaround for ICH8 */
if (mac->type == e1000_ich8lan)
e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, 1);
@@ -378,10 +459,18 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
if (rc)
return rc;
- rc = e1000_init_phy_params_ich8lan(hw);
+ if (hw->mac.type == e1000_pchlan)
+ rc = e1000_init_phy_params_pchlan(hw);
+ else
+ rc = e1000_init_phy_params_ich8lan(hw);
if (rc)
return rc;
+ if (adapter->hw.phy.type == e1000_phy_ife) {
+ adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
+ adapter->max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN;
+ }
+
if ((adapter->hw.mac.type == e1000_ich8lan) &&
(adapter->hw.phy.type == e1000_phy_igp_3))
adapter->flags |= FLAG_LSC_GIG_SPEED_DROP;
@@ -410,12 +499,15 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
while (timeout) {
extcnf_ctrl = er32(EXTCNF_CTRL);
- extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
- ew32(EXTCNF_CTRL, extcnf_ctrl);
- extcnf_ctrl = er32(EXTCNF_CTRL);
- if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
- break;
+ if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)) {
+ extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
+ ew32(EXTCNF_CTRL, extcnf_ctrl);
+
+ extcnf_ctrl = er32(EXTCNF_CTRL);
+ if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
+ break;
+ }
mdelay(1);
timeout--;
}
@@ -555,6 +647,53 @@ static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw)
}
/**
+ * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be
+ * done after every PHY reset.
+ **/
+static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
+{
+ s32 ret_val = 0;
+
+ if (hw->mac.type != e1000_pchlan)
+ return ret_val;
+
+ if (((hw->phy.type == e1000_phy_82577) &&
+ ((hw->phy.revision == 1) || (hw->phy.revision == 2))) ||
+ ((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) {
+ /* Disable generation of early preamble */
+ ret_val = e1e_wphy(hw, PHY_REG(769, 25), 0x4431);
+ if (ret_val)
+ return ret_val;
+
+ /* Preamble tuning for SSC */
+ ret_val = e1e_wphy(hw, PHY_REG(770, 16), 0xA204);
+ if (ret_val)
+ return ret_val;
+ }
+
+ if (hw->phy.type == e1000_phy_82578) {
+ /*
+ * Return registers to default by doing a soft reset then
+ * writing 0x3140 to the control register.
+ */
+ if (hw->phy.revision < 2) {
+ e1000e_phy_sw_reset(hw);
+ ret_val = e1e_wphy(hw, PHY_CONTROL, 0x3140);
+ }
+ }
+
+ /* Select page 0 */
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ return ret_val;
+ hw->phy.addr = 1;
+ e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
+ hw->phy.ops.release_phy(hw);
+
+ return ret_val;
+}
+
+/**
* e1000_phy_hw_reset_ich8lan - Performs a PHY reset
* @hw: pointer to the HW structure
*
@@ -575,6 +714,12 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
if (ret_val)
return ret_val;
+ if (hw->mac.type == e1000_pchlan) {
+ ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
+ if (ret_val)
+ return ret_val;
+ }
+
/*
* Initialize the PHY from the NVM on ICH platforms. This
* is needed due to an issue where the NVM configuration is
@@ -701,7 +846,7 @@ static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw)
phy->polarity_correction = (!(data & IFE_PSC_AUTO_POLARITY_DISABLE));
if (phy->polarity_correction) {
- ret_val = e1000_check_polarity_ife_ich8lan(hw);
+ ret_val = phy->ops.check_polarity(hw);
if (ret_val)
return ret_val;
} else {
@@ -741,6 +886,8 @@ static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw)
break;
case e1000_phy_igp_3:
case e1000_phy_bm:
+ case e1000_phy_82578:
+ case e1000_phy_82577:
return e1000e_get_phy_info_igp(hw);
break;
default:
@@ -1852,6 +1999,79 @@ static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data)
}
/**
+ * e1000_id_led_init_pchlan - store LED configurations
+ * @hw: pointer to the HW structure
+ *
+ * PCH does not control LEDs via the LEDCTL register, rather it uses
+ * the PHY LED configuration register.
+ *
+ * PCH also does not have an "always on" or "always off" mode which
+ * complicates the ID feature. Instead of using the "on" mode to indicate
+ * in ledctl_mode2 the LEDs to use for ID (see e1000e_id_led_init()),
+ * use "link_up" mode. The LEDs will still ID on request if there is no
+ * link based on logic in e1000_led_[on|off]_pchlan().
+ **/
+static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw)
+{
+ struct e1000_mac_info *mac = &hw->mac;
+ s32 ret_val;
+ const u32 ledctl_on = E1000_LEDCTL_MODE_LINK_UP;
+ const u32 ledctl_off = E1000_LEDCTL_MODE_LINK_UP | E1000_PHY_LED0_IVRT;
+ u16 data, i, temp, shift;
+
+ /* Get default ID LED modes */
+ ret_val = hw->nvm.ops.valid_led_default(hw, &data);
+ if (ret_val)
+ goto out;
+
+ mac->ledctl_default = er32(LEDCTL);
+ mac->ledctl_mode1 = mac->ledctl_default;
+ mac->ledctl_mode2 = mac->ledctl_default;
+
+ for (i = 0; i < 4; i++) {
+ temp = (data >> (i << 2)) & E1000_LEDCTL_LED0_MODE_MASK;
+ shift = (i * 5);
+ switch (temp) {
+ case ID_LED_ON1_DEF2:
+ case ID_LED_ON1_ON2:
+ case ID_LED_ON1_OFF2:
+ mac->ledctl_mode1 &= ~(E1000_PHY_LED0_MASK << shift);
+ mac->ledctl_mode1 |= (ledctl_on << shift);
+ break;
+ case ID_LED_OFF1_DEF2:
+ case ID_LED_OFF1_ON2:
+ case ID_LED_OFF1_OFF2:
+ mac->ledctl_mode1 &= ~(E1000_PHY_LED0_MASK << shift);
+ mac->ledctl_mode1 |= (ledctl_off << shift);
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+ switch (temp) {
+ case ID_LED_DEF1_ON2:
+ case ID_LED_ON1_ON2:
+ case ID_LED_OFF1_ON2:
+ mac->ledctl_mode2 &= ~(E1000_PHY_LED0_MASK << shift);
+ mac->ledctl_mode2 |= (ledctl_on << shift);
+ break;
+ case ID_LED_DEF1_OFF2:
+ case ID_LED_ON1_OFF2:
+ case ID_LED_OFF1_OFF2:
+ mac->ledctl_mode2 &= ~(E1000_PHY_LED0_MASK << shift);
+ mac->ledctl_mode2 |= (ledctl_off << shift);
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+ }
+
+out:
+ return ret_val;
+}
+
+/**
* e1000_get_bus_info_ich8lan - Get/Set the bus type and width
* @hw: pointer to the HW structure
*
@@ -1960,6 +2180,9 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
kab |= E1000_KABGTXD_BGSQLBIAS;
ew32(KABGTXD, kab);
+ if (hw->mac.type == e1000_pchlan)
+ ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
+
return ret_val;
}
@@ -1985,7 +2208,7 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
e1000_initialize_hw_bits_ich8lan(hw);
/* Initialize identification LED */
- ret_val = e1000e_id_led_init(hw);
+ ret_val = mac->ops.id_led_init(hw);
if (ret_val) {
hw_dbg(hw, "Error initializing identification LED\n");
return ret_val;
@@ -2031,6 +2254,16 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
ew32(CTRL_EXT, ctrl_ext);
/*
+ * The 82578 Rx buffer will stall if wakeup is enabled in host and
+ * the ME. Reading the BM_WUC register will clear the host wakeup bit.
+ * Reset the phy after disabling host wakeup to reset the Rx buffer.
+ */
+ if (hw->phy.type == e1000_phy_82578) {
+ e1e_rphy(hw, BM_WUC, &i);
+ e1000e_phy_hw_reset_generic(hw);
+ }
+
+ /*
* Clear all of the statistics registers (clear on read). It is
* important that we do this after we have tried to establish link
* because the symbol error count will increment wildly if there
@@ -2054,6 +2287,9 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
/* Extended Device Control */
reg = er32(CTRL_EXT);
reg |= (1 << 22);
+ /* Enable PHY low-power state when MAC is at D3 w/o WoL */
+ if (hw->mac.type >= e1000_pchlan)
+ reg |= E1000_CTRL_EXT_PHYPDEN;
ew32(CTRL_EXT, reg);
/* Transmit Descriptor Control 0 */
@@ -2112,8 +2348,13 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw)
* the default flow control setting, so we explicitly
* set it to full.
*/
- if (hw->fc.requested_mode == e1000_fc_default)
- hw->fc.requested_mode = e1000_fc_full;
+ if (hw->fc.requested_mode == e1000_fc_default) {
+ /* Workaround h/w hang when Tx flow control enabled */
+ if (hw->mac.type == e1000_pchlan)
+ hw->fc.requested_mode = e1000_fc_rx_pause;
+ else
+ hw->fc.requested_mode = e1000_fc_full;
+ }
/*
* Save off the requested flow control mode for use later. Depending
@@ -2130,6 +2371,14 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw)
return ret_val;
ew32(FCTTV, hw->fc.pause_time);
+ if ((hw->phy.type == e1000_phy_82578) ||
+ (hw->phy.type == e1000_phy_82577)) {
+ ret_val = hw->phy.ops.write_phy_reg(hw,
+ PHY_REG(BM_PORT_CTRL_PAGE, 27),
+ hw->fc.pause_time);
+ if (ret_val)
+ return ret_val;
+ }
return e1000e_set_fc_watermarks(hw);
}
@@ -2169,18 +2418,26 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
if (ret_val)
return ret_val;
- if (hw->phy.type == e1000_phy_igp_3) {
+ switch (hw->phy.type) {
+ case e1000_phy_igp_3:
ret_val = e1000e_copper_link_setup_igp(hw);
if (ret_val)
return ret_val;
- } else if (hw->phy.type == e1000_phy_bm) {
+ break;
+ case e1000_phy_bm:
+ case e1000_phy_82578:
ret_val = e1000e_copper_link_setup_m88(hw);
if (ret_val)
return ret_val;
- }
-
- if (hw->phy.type == e1000_phy_ife) {
- ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &reg_data);
+ break;
+ case e1000_phy_82577:
+ ret_val = e1000_copper_link_setup_82577(hw);
+ if (ret_val)
+ return ret_val;
+ break;
+ case e1000_phy_ife:
+ ret_val = hw->phy.ops.read_phy_reg(hw, IFE_PHY_MDIX_CONTROL,
+ &reg_data);
if (ret_val)
return ret_val;
@@ -2198,9 +2455,13 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
reg_data |= IFE_PMC_AUTO_MDIX;
break;
}
- ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, reg_data);
+ ret_val = hw->phy.ops.write_phy_reg(hw, IFE_PHY_MDIX_CONTROL,
+ reg_data);
if (ret_val)
return ret_val;
+ break;
+ default:
+ break;
}
return e1000e_setup_copper_link(hw);
}
@@ -2417,18 +2678,26 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
* 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation
* to a lower speed.
*
- * Should only be called for ICH9 and ICH10 devices.
+ * Should only be called for applicable parts.
**/
void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
{
u32 phy_ctrl;
- if ((hw->mac.type == e1000_ich10lan) ||
- (hw->mac.type == e1000_ich9lan)) {
+ switch (hw->mac.type) {
+ case e1000_ich9lan:
+ case e1000_ich10lan:
+ case e1000_pchlan:
phy_ctrl = er32(PHY_CTRL);
phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU |
E1000_PHY_CTRL_GBE_DISABLE;
ew32(PHY_CTRL, phy_ctrl);
+
+ /* Workaround SWFLAG unexpectedly set during S0->Sx */
+ if (hw->mac.type == e1000_pchlan)
+ udelay(500);
+ default:
+ break;
}
return;
@@ -2482,13 +2751,99 @@ static s32 e1000_led_off_ich8lan(struct e1000_hw *hw)
}
/**
+ * e1000_setup_led_pchlan - Configures SW controllable LED
+ * @hw: pointer to the HW structure
+ *
+ * This prepares the SW controllable LED for use.
+ **/
+static s32 e1000_setup_led_pchlan(struct e1000_hw *hw)
+{
+ return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG,
+ (u16)hw->mac.ledctl_mode1);
+}
+
+/**
+ * e1000_cleanup_led_pchlan - Restore the default LED operation
+ * @hw: pointer to the HW structure
+ *
+ * Return the LED back to the default configuration.
+ **/
+static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw)
+{
+ return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG,
+ (u16)hw->mac.ledctl_default);
+}
+
+/**
+ * e1000_led_on_pchlan - Turn LEDs on
+ * @hw: pointer to the HW structure
+ *
+ * Turn on the LEDs.
+ **/
+static s32 e1000_led_on_pchlan(struct e1000_hw *hw)
+{
+ u16 data = (u16)hw->mac.ledctl_mode2;
+ u32 i, led;
+
+ /*
+ * If no link, then turn LED on by setting the invert bit
+ * for each LED that's mode is "link_up" in ledctl_mode2.
+ */
+ if (!(er32(STATUS) & E1000_STATUS_LU)) {
+ for (i = 0; i < 3; i++) {
+ led = (data >> (i * 5)) & E1000_PHY_LED0_MASK;
+ if ((led & E1000_PHY_LED0_MODE_MASK) !=
+ E1000_LEDCTL_MODE_LINK_UP)
+ continue;
+ if (led & E1000_PHY_LED0_IVRT)
+ data &= ~(E1000_PHY_LED0_IVRT << (i * 5));
+ else
+ data |= (E1000_PHY_LED0_IVRT << (i * 5));
+ }
+ }
+
+ return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG, data);
+}
+
+/**
+ * e1000_led_off_pchlan - Turn LEDs off
+ * @hw: pointer to the HW structure
+ *
+ * Turn off the LEDs.
+ **/
+static s32 e1000_led_off_pchlan(struct e1000_hw *hw)
+{
+ u16 data = (u16)hw->mac.ledctl_mode1;
+ u32 i, led;
+
+ /*
+ * If no link, then turn LED off by clearing the invert bit
+ * for each LED that's mode is "link_up" in ledctl_mode1.
+ */
+ if (!(er32(STATUS) & E1000_STATUS_LU)) {
+ for (i = 0; i < 3; i++) {
+ led = (data >> (i * 5)) & E1000_PHY_LED0_MASK;
+ if ((led & E1000_PHY_LED0_MODE_MASK) !=
+ E1000_LEDCTL_MODE_LINK_UP)
+ continue;
+ if (led & E1000_PHY_LED0_IVRT)
+ data &= ~(E1000_PHY_LED0_IVRT << (i * 5));
+ else
+ data |= (E1000_PHY_LED0_IVRT << (i * 5));
+ }
+ }
+
+ return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG, data);
+}
+
+/**
* e1000_get_cfg_done_ich8lan - Read config done bit
* @hw: pointer to the HW structure
*
* Read the management control register for the config done bit for
* completion status. NOTE: silicon which is EEPROM-less will fail trying
* to read the config done bit, so an error is *ONLY* logged and returns
- * E1000_SUCCESS. If we were to return with error, EEPROM-less silicon
+ * 0. If we were to return with error, EEPROM-less silicon
* would not be able to be reset or change link.
**/
static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
@@ -2498,7 +2853,8 @@ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
e1000e_get_cfg_done(hw);
/* If EEPROM is not marked present, init the IGP 3 PHY manually */
- if (hw->mac.type != e1000_ich10lan) {
+ if ((hw->mac.type != e1000_ich10lan) &&
+ (hw->mac.type != e1000_pchlan)) {
if (((er32(EECD) & E1000_EECD_PRES) == 0) &&
(hw->phy.type == e1000_phy_igp_3)) {
e1000e_phy_init_script_igp3(hw);
@@ -2524,6 +2880,7 @@ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
{
u32 temp;
+ u16 phy_data;
e1000e_clear_hw_cntrs_base(hw);
@@ -2541,22 +2898,42 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
temp = er32(IAC);
temp = er32(ICRXOC);
+ /* Clear PHY statistics registers */
+ if ((hw->phy.type == e1000_phy_82578) ||
+ (hw->phy.type == e1000_phy_82577)) {
+ hw->phy.ops.read_phy_reg(hw, HV_SCC_UPPER, &phy_data);
+ hw->phy.ops.read_phy_reg(hw, HV_SCC_LOWER, &phy_data);
+ hw->phy.ops.read_phy_reg(hw, HV_ECOL_UPPER, &phy_data);
+ hw->phy.ops.read_phy_reg(hw, HV_ECOL_LOWER, &phy_data);
+ hw->phy.ops.read_phy_reg(hw, HV_MCC_UPPER, &phy_data);
+ hw->phy.ops.read_phy_reg(hw, HV_MCC_LOWER, &phy_data);
+ hw->phy.ops.read_phy_reg(hw, HV_LATECOL_UPPER, &phy_data);
+ hw->phy.ops.read_phy_reg(hw, HV_LATECOL_LOWER, &phy_data);
+ hw->phy.ops.read_phy_reg(hw, HV_COLC_UPPER, &phy_data);
+ hw->phy.ops.read_phy_reg(hw, HV_COLC_LOWER, &phy_data);
+ hw->phy.ops.read_phy_reg(hw, HV_DC_UPPER, &phy_data);
+ hw->phy.ops.read_phy_reg(hw, HV_DC_LOWER, &phy_data);
+ hw->phy.ops.read_phy_reg(hw, HV_TNCRS_UPPER, &phy_data);
+ hw->phy.ops.read_phy_reg(hw, HV_TNCRS_LOWER, &phy_data);
+ }
}
static struct e1000_mac_operations ich8_mac_ops = {
+ .id_led_init = e1000e_id_led_init,
.check_mng_mode = e1000_check_mng_mode_ich8lan,
.check_for_link = e1000e_check_for_copper_link,
- .cleanup_led = e1000_cleanup_led_ich8lan,
+ /* cleanup_led dependent on mac type */
.clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan,
.get_bus_info = e1000_get_bus_info_ich8lan,
.get_link_up_info = e1000_get_link_up_info_ich8lan,
- .led_on = e1000_led_on_ich8lan,
- .led_off = e1000_led_off_ich8lan,
+ /* led_on dependent on mac type */
+ /* led_off dependent on mac type */
.update_mc_addr_list = e1000e_update_mc_addr_list_generic,
.reset_hw = e1000_reset_hw_ich8lan,
.init_hw = e1000_init_hw_ich8lan,
.setup_link = e1000_setup_link_ich8lan,
.setup_physical_interface= e1000_setup_copper_link_ich8lan,
+ /* id_led_init dependent on mac type */
};
static struct e1000_phy_operations ich8_phy_ops = {
@@ -2595,6 +2972,7 @@ struct e1000_info e1000_ich8_info = {
| FLAG_HAS_FLASH
| FLAG_APME_IN_WUC,
.pba = 8,
+ .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
.get_variants = e1000_get_variants_ich8lan,
.mac_ops = &ich8_mac_ops,
.phy_ops = &ich8_phy_ops,
@@ -2613,6 +2991,7 @@ struct e1000_info e1000_ich9_info = {
| FLAG_HAS_FLASH
| FLAG_APME_IN_WUC,
.pba = 10,
+ .max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_ich8lan,
.mac_ops = &ich8_mac_ops,
.phy_ops = &ich8_phy_ops,
@@ -2631,6 +3010,25 @@ struct e1000_info e1000_ich10_info = {
| FLAG_HAS_FLASH
| FLAG_APME_IN_WUC,
.pba = 10,
+ .max_hw_frame_size = DEFAULT_JUMBO,
+ .get_variants = e1000_get_variants_ich8lan,
+ .mac_ops = &ich8_mac_ops,
+ .phy_ops = &ich8_phy_ops,
+ .nvm_ops = &ich8_nvm_ops,
+};
+
+struct e1000_info e1000_pch_info = {
+ .mac = e1000_pchlan,
+ .flags = FLAG_IS_ICH
+ | FLAG_HAS_WOL
+ | FLAG_RX_CSUM_ENABLED
+ | FLAG_HAS_CTRLEXT_ON_LOAD
+ | FLAG_HAS_AMT
+ | FLAG_HAS_FLASH
+ | FLAG_HAS_JUMBO_FRAMES
+ | FLAG_APME_IN_WUC,
+ .pba = 26,
+ .max_hw_frame_size = 4096,
.get_variants = e1000_get_variants_ich8lan,
.mac_ops = &ich8_mac_ops,
.phy_ops = &ich8_phy_ops,
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 18a4f5902f3..be6d9e99037 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -378,6 +378,12 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
mac->get_link_status = 0;
+ if (hw->phy.type == e1000_phy_82578) {
+ ret_val = e1000_link_stall_workaround_hv(hw);
+ if (ret_val)
+ return ret_val;
+ }
+
/*
* Check if there was DownShift, must be checked
* immediately after link-up
@@ -1406,6 +1412,38 @@ s32 e1000e_id_led_init(struct e1000_hw *hw)
}
/**
+ * e1000e_setup_led_generic - Configures SW controllable LED
+ * @hw: pointer to the HW structure
+ *
+ * This prepares the SW controllable LED for use and saves the current state
+ * of the LED so it can be later restored.
+ **/
+s32 e1000e_setup_led_generic(struct e1000_hw *hw)
+{
+ u32 ledctl;
+
+ if (hw->mac.ops.setup_led != e1000e_setup_led_generic) {
+ return -E1000_ERR_CONFIG;
+ }
+
+ if (hw->phy.media_type == e1000_media_type_fiber) {
+ ledctl = er32(LEDCTL);
+ hw->mac.ledctl_default = ledctl;
+ /* Turn off LED0 */
+ ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
+ E1000_LEDCTL_LED0_BLINK |
+ E1000_LEDCTL_LED0_MODE_MASK);
+ ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
+ E1000_LEDCTL_LED0_MODE_SHIFT);
+ ew32(LEDCTL, ledctl);
+ } else if (hw->phy.media_type == e1000_media_type_copper) {
+ ew32(LEDCTL, hw->mac.ledctl_mode1);
+ }
+
+ return 0;
+}
+
+/**
* e1000e_cleanup_led_generic - Set LED config to default operation
* @hw: pointer to the HW structure
*
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index ca82f19a7ed..677f60490f6 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -48,7 +48,7 @@
#include "e1000.h"
-#define DRV_VERSION "0.3.3.4-k4"
+#define DRV_VERSION "1.0.2-k2"
char e1000e_driver_name[] = "e1000e";
const char e1000e_driver_version[] = DRV_VERSION;
@@ -62,6 +62,7 @@ static const struct e1000_info *e1000_info_tbl[] = {
[board_ich8lan] = &e1000_ich8_info,
[board_ich9lan] = &e1000_ich9_info,
[board_ich10lan] = &e1000_ich10_info,
+ [board_pchlan] = &e1000_pch_info,
};
#ifdef DEBUG
@@ -2255,8 +2256,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
ew32(TARC(1), tarc);
}
- e1000e_config_collision_dist(hw);
-
/* Setup Transmit Descriptor Settings for eop descriptor */
adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
@@ -2269,6 +2268,8 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
ew32(TCTL, tctl);
+ e1000e_config_collision_dist(hw);
+
adapter->tx_queue_len = adapter->netdev->tx_queue_len;
}
@@ -2308,6 +2309,23 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
if (adapter->flags2 & FLAG2_CRC_STRIPPING)
rctl |= E1000_RCTL_SECRC;
+ /* Workaround Si errata on 82577 PHY - configure IPG for jumbos */
+ if ((hw->phy.type == e1000_phy_82577) && (rctl & E1000_RCTL_LPE)) {
+ u16 phy_data;
+
+ e1e_rphy(hw, PHY_REG(770, 26), &phy_data);
+ phy_data &= 0xfff8;
+ phy_data |= (1 << 2);
+ e1e_wphy(hw, PHY_REG(770, 26), phy_data);
+
+ e1e_rphy(hw, 22, &phy_data);
+ phy_data &= 0x0fff;
+ phy_data |= (1 << 14);
+ e1e_wphy(hw, 0x10, 0x2823);
+ e1e_wphy(hw, 0x11, 0x0003);
+ e1e_wphy(hw, 22, phy_data);
+ }
+
/* Setup buffer sizes */
rctl &= ~E1000_RCTL_SZ_4096;
rctl |= E1000_RCTL_BSEX;
@@ -2751,23 +2769,25 @@ void e1000e_reset(struct e1000_adapter *adapter)
/*
* flow control settings
*
- * The high water mark must be low enough to fit one full frame
+ * The high water mark must be low enough to fit two full frame
* (or the size used for early receive) above it in the Rx FIFO.
* Set it to the lower of:
* - 90% of the Rx FIFO size, and
* - the full Rx FIFO size minus the early receive size (for parts
* with ERT support assuming ERT set to E1000_ERT_2048), or
- * - the full Rx FIFO size minus one full frame
+ * - the full Rx FIFO size minus two full frames
*/
- if (adapter->flags & FLAG_HAS_ERT)
+ if ((adapter->flags & FLAG_HAS_ERT) &&
+ (adapter->netdev->mtu > ETH_DATA_LEN))
hwm = min(((pba << 10) * 9 / 10),
((pba << 10) - (E1000_ERT_2048 << 3)));
else
hwm = min(((pba << 10) * 9 / 10),
- ((pba << 10) - adapter->max_frame_size));
+ ((pba << 10) - (2 * adapter->max_frame_size)));
- fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */
- fc->low_water = fc->high_water - 8;
+ fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
+ fc->low_water = (fc->high_water - (2 * adapter->max_frame_size));
+ fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */
if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
fc->pause_time = 0xFFFF;
@@ -2787,6 +2807,8 @@ void e1000e_reset(struct e1000_adapter *adapter)
e1000_get_hw_control(adapter);
ew32(WUC, 0);
+ if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP)
+ e1e_wphy(&adapter->hw, BM_WUC, 0);
if (mac->ops.init_hw(hw))
e_err("Hardware Error\n");
@@ -2799,7 +2821,8 @@ void e1000e_reset(struct e1000_adapter *adapter)
e1000e_reset_adaptive(hw);
e1000_get_phy_info(hw);
- if (!(adapter->flags & FLAG_SMART_POWER_DOWN)) {
+ if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) &&
+ !(adapter->flags & FLAG_SMART_POWER_DOWN)) {
u16 phy_data = 0;
/*
* speed up time to link by disabling smart power down, ignore
@@ -2826,6 +2849,8 @@ int e1000e_up(struct e1000_adapter *adapter)
e1000_configure_msix(adapter);
e1000_irq_enable(adapter);
+ netif_wake_queue(adapter->netdev);
+
/* fire a link change interrupt to start the watchdog */
ew32(ICS, E1000_ICS_LSC);
return 0;
@@ -2848,7 +2873,7 @@ void e1000e_down(struct e1000_adapter *adapter)
ew32(RCTL, rctl & ~E1000_RCTL_EN);
/* flush and sleep below */
- netif_tx_stop_all_queues(netdev);
+ netif_stop_queue(netdev);
/* disable transmits in the hardware */
tctl = er32(TCTL);
@@ -3072,6 +3097,8 @@ static int e1000_open(struct net_device *netdev)
if (test_bit(__E1000_TESTING, &adapter->state))
return -EBUSY;
+ netif_carrier_off(netdev);
+
/* allocate transmit descriptors */
err = e1000e_setup_tx_resources(adapter);
if (err)
@@ -3128,7 +3155,7 @@ static int e1000_open(struct net_device *netdev)
e1000_irq_enable(adapter);
- netif_tx_start_all_queues(netdev);
+ netif_start_queue(netdev);
/* fire a link status change interrupt to start the watchdog */
ew32(ICS, E1000_ICS_LSC);
@@ -3262,6 +3289,7 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
struct pci_dev *pdev = adapter->pdev;
+ u16 phy_data;
/*
* Prevent stats update while adapter is being reset, or if the pci
@@ -3281,11 +3309,34 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
adapter->stats.roc += er32(ROC);
adapter->stats.mpc += er32(MPC);
- adapter->stats.scc += er32(SCC);
- adapter->stats.ecol += er32(ECOL);
- adapter->stats.mcc += er32(MCC);
- adapter->stats.latecol += er32(LATECOL);
- adapter->stats.dc += er32(DC);
+ if ((hw->phy.type == e1000_phy_82578) ||
+ (hw->phy.type == e1000_phy_82577)) {
+ e1e_rphy(hw, HV_SCC_UPPER, &phy_data);
+ e1e_rphy(hw, HV_SCC_LOWER, &phy_data);
+ adapter->stats.scc += phy_data;
+
+ e1e_rphy(hw, HV_ECOL_UPPER, &phy_data);
+ e1e_rphy(hw, HV_ECOL_LOWER, &phy_data);
+ adapter->stats.ecol += phy_data;
+
+ e1e_rphy(hw, HV_MCC_UPPER, &phy_data);
+ e1e_rphy(hw, HV_MCC_LOWER, &phy_data);
+ adapter->stats.mcc += phy_data;
+
+ e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data);
+ e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data);
+ adapter->stats.latecol += phy_data;
+
+ e1e_rphy(hw, HV_DC_UPPER, &phy_data);
+ e1e_rphy(hw, HV_DC_LOWER, &phy_data);
+ adapter->stats.dc += phy_data;
+ } else {
+ adapter->stats.scc += er32(SCC);
+ adapter->stats.ecol += er32(ECOL);
+ adapter->stats.mcc += er32(MCC);
+ adapter->stats.latecol += er32(LATECOL);
+ adapter->stats.dc += er32(DC);
+ }
adapter->stats.xonrxc += er32(XONRXC);
adapter->stats.xontxc += er32(XONTXC);
adapter->stats.xoffrxc += er32(XOFFRXC);
@@ -3303,13 +3354,28 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
hw->mac.tx_packet_delta = er32(TPT);
adapter->stats.tpt += hw->mac.tx_packet_delta;
- hw->mac.collision_delta = er32(COLC);
+ if ((hw->phy.type == e1000_phy_82578) ||
+ (hw->phy.type == e1000_phy_82577)) {
+ e1e_rphy(hw, HV_COLC_UPPER, &phy_data);
+ e1e_rphy(hw, HV_COLC_LOWER, &phy_data);
+ hw->mac.collision_delta = phy_data;
+ } else {
+ hw->mac.collision_delta = er32(COLC);
+ }
adapter->stats.colc += hw->mac.collision_delta;
adapter->stats.algnerrc += er32(ALGNERRC);
adapter->stats.rxerrc += er32(RXERRC);
- if ((hw->mac.type != e1000_82574) && (hw->mac.type != e1000_82583))
- adapter->stats.tncrs += er32(TNCRS);
+ if ((hw->phy.type == e1000_phy_82578) ||
+ (hw->phy.type == e1000_phy_82577)) {
+ e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data);
+ e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data);
+ adapter->stats.tncrs += phy_data;
+ } else {
+ if ((hw->mac.type != e1000_82574) &&
+ (hw->mac.type != e1000_82583))
+ adapter->stats.tncrs += er32(TNCRS);
+ }
adapter->stats.cexterr += er32(CEXTERR);
adapter->stats.tsctc += er32(TSCTC);
adapter->stats.tsctfc += er32(TSCTFC);
@@ -3598,7 +3664,6 @@ static void e1000_watchdog_task(struct work_struct *work)
phy->ops.cfg_on_link_up(hw);
netif_carrier_on(netdev);
- netif_tx_wake_all_queues(netdev);
if (!test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
@@ -3612,7 +3677,6 @@ static void e1000_watchdog_task(struct work_struct *work)
printk(KERN_INFO "e1000e: %s NIC Link is Down\n",
adapter->netdev->name);
netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
if (!test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ));
@@ -3649,6 +3713,8 @@ link_up:
*/
adapter->tx_timeout_count++;
schedule_work(&adapter->reset_task);
+ /* return immediately since reset is imminent */
+ return;
}
}
@@ -3850,7 +3916,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
buffer_info->length = size;
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
- buffer_info->dma = map[0] + offset;
+ buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
count++;
len -= size;
@@ -3881,7 +3947,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
buffer_info->length = size;
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
- buffer_info->dma = map[f + 1] + offset;
+ buffer_info->dma = map[f] + offset;
len -= size;
offset += size;
@@ -4145,7 +4211,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
if (count) {
e1000_tx_queue(adapter, tx_flags, count);
- netdev->trans_start = jiffies;
/* Make sure there is space in the ring for the next send. */
e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
@@ -4206,27 +4271,17 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
struct e1000_adapter *adapter = netdev_priv(netdev);
int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
- if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
- (max_frame > MAX_JUMBO_FRAME_SIZE)) {
- e_err("Invalid MTU setting\n");
+ /* Jumbo frame support */
+ if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
+ !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
+ e_err("Jumbo Frames not supported.\n");
return -EINVAL;
}
- /* Jumbo frame size limits */
- if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
- if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
- e_err("Jumbo Frames not supported.\n");
- return -EINVAL;
- }
- if (adapter->hw.phy.type == e1000_phy_ife) {
- e_err("Jumbo Frames not supported.\n");
- return -EINVAL;
- }
- }
-
-#define MAX_STD_JUMBO_FRAME_SIZE 9234
- if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
- e_err("MTU > 9216 not supported.\n");
+ /* Supported frame sizes */
+ if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
+ (max_frame > adapter->max_hw_frame_size)) {
+ e_err("Unsupported MTU setting\n");
return -EINVAL;
}
@@ -4346,6 +4401,81 @@ static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
}
}
+static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 i, mac_reg;
+ u16 phy_reg;
+ int retval = 0;
+
+ /* copy MAC RARs to PHY RARs */
+ for (i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
+ mac_reg = er32(RAL(i));
+ e1e_wphy(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF));
+ e1e_wphy(hw, BM_RAR_M(i), (u16)((mac_reg >> 16) & 0xFFFF));
+ mac_reg = er32(RAH(i));
+ e1e_wphy(hw, BM_RAR_H(i), (u16)(mac_reg & 0xFFFF));
+ e1e_wphy(hw, BM_RAR_CTRL(i), (u16)((mac_reg >> 16) & 0xFFFF));
+ }
+
+ /* copy MAC MTA to PHY MTA */
+ for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
+ mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
+ e1e_wphy(hw, BM_MTA(i), (u16)(mac_reg & 0xFFFF));
+ e1e_wphy(hw, BM_MTA(i) + 1, (u16)((mac_reg >> 16) & 0xFFFF));
+ }
+
+ /* configure PHY Rx Control register */
+ e1e_rphy(&adapter->hw, BM_RCTL, &phy_reg);
+ mac_reg = er32(RCTL);
+ if (mac_reg & E1000_RCTL_UPE)
+ phy_reg |= BM_RCTL_UPE;
+ if (mac_reg & E1000_RCTL_MPE)
+ phy_reg |= BM_RCTL_MPE;
+ phy_reg &= ~(BM_RCTL_MO_MASK);
+ if (mac_reg & E1000_RCTL_MO_3)
+ phy_reg |= (((mac_reg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
+ << BM_RCTL_MO_SHIFT);
+ if (mac_reg & E1000_RCTL_BAM)
+ phy_reg |= BM_RCTL_BAM;
+ if (mac_reg & E1000_RCTL_PMCF)
+ phy_reg |= BM_RCTL_PMCF;
+ mac_reg = er32(CTRL);
+ if (mac_reg & E1000_CTRL_RFCE)
+ phy_reg |= BM_RCTL_RFCE;
+ e1e_wphy(&adapter->hw, BM_RCTL, phy_reg);
+
+ /* enable PHY wakeup in MAC register */
+ ew32(WUFC, wufc);
+ ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
+
+ /* configure and enable PHY wakeup in PHY registers */
+ e1e_wphy(&adapter->hw, BM_WUFC, wufc);
+ e1e_wphy(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
+
+ /* activate PHY wakeup */
+ retval = hw->phy.ops.acquire_phy(hw);
+ if (retval) {
+ e_err("Could not acquire PHY\n");
+ return retval;
+ }
+ e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
+ (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
+ retval = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
+ if (retval) {
+ e_err("Could not read PHY page 769\n");
+ goto out;
+ }
+ phy_reg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
+ retval = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
+ if (retval)
+ e_err("Could not set PHY Host Wakeup bit\n");
+out:
+ hw->phy.ops.release_phy(hw);
+
+ return retval;
+}
+
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
{
struct net_device *netdev = pci_get_drvdata(pdev);
@@ -4388,8 +4518,9 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
#define E1000_CTRL_ADVD3WUC 0x00100000
/* phy power management enable */
#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
- ctrl |= E1000_CTRL_ADVD3WUC |
- E1000_CTRL_EN_PHY_PWR_MGMT;
+ ctrl |= E1000_CTRL_ADVD3WUC;
+ if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP))
+ ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT;
ew32(CTRL, ctrl);
if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
@@ -4407,8 +4538,17 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
/* Allow time for pending master requests to run */
e1000e_disable_pcie_master(&adapter->hw);
- ew32(WUC, E1000_WUC_PME_EN);
- ew32(WUFC, wufc);
+ if ((adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) &&
+ !(hw->mac.ops.check_mng_mode(hw))) {
+ /* enable wakeup by the PHY */
+ retval = e1000_init_phy_wakeup(adapter, wufc);
+ if (retval)
+ return retval;
+ } else {
+ /* enable wakeup by the MAC */
+ ew32(WUFC, wufc);
+ ew32(WUC, E1000_WUC_PME_EN);
+ }
} else {
ew32(WUC, 0);
ew32(WUFC, 0);
@@ -4551,8 +4691,37 @@ static int e1000_resume(struct pci_dev *pdev)
}
e1000e_power_up_phy(adapter);
+
+ /* report the system wakeup cause from S3/S4 */
+ if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
+ u16 phy_data;
+
+ e1e_rphy(&adapter->hw, BM_WUS, &phy_data);
+ if (phy_data) {
+ e_info("PHY Wakeup cause - %s\n",
+ phy_data & E1000_WUS_EX ? "Unicast Packet" :
+ phy_data & E1000_WUS_MC ? "Multicast Packet" :
+ phy_data & E1000_WUS_BC ? "Broadcast Packet" :
+ phy_data & E1000_WUS_MAG ? "Magic Packet" :
+ phy_data & E1000_WUS_LNKC ? "Link Status "
+ " Change" : "other");
+ }
+ e1e_wphy(&adapter->hw, BM_WUS, ~0);
+ } else {
+ u32 wus = er32(WUS);
+ if (wus) {
+ e_info("MAC Wakeup cause - %s\n",
+ wus & E1000_WUS_EX ? "Unicast Packet" :
+ wus & E1000_WUS_MC ? "Multicast Packet" :
+ wus & E1000_WUS_BC ? "Broadcast Packet" :
+ wus & E1000_WUS_MAG ? "Magic Packet" :
+ wus & E1000_WUS_LNKC ? "Link Status Change" :
+ "other");
+ }
+ ew32(WUS, ~0);
+ }
+
e1000e_reset(adapter);
- ew32(WUS, ~0);
e1000_init_manageability(adapter);
@@ -4842,6 +5011,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
adapter->flags2 = ei->flags2;
adapter->hw.adapter = adapter;
adapter->hw.mac.type = ei->mac;
+ adapter->max_hw_frame_size = ei->max_hw_frame_size;
adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
mmio_start = pci_resource_start(pdev, 0);
@@ -4997,6 +5167,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
/* APME bit in EEPROM is mapped to WUC.APME */
eeprom_data = er32(WUC);
eeprom_apme_mask = E1000_WUC_APME;
+ if (eeprom_data & E1000_WUC_PHY_WAKE)
+ adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP;
} else if (adapter->flags & FLAG_APME_IN_CTRL3) {
if (adapter->flags & FLAG_APME_CHECK_PORT_B &&
(adapter->hw.bus.func == 1))
@@ -5037,15 +5209,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (!(adapter->flags & FLAG_HAS_AMT))
e1000_get_hw_control(adapter);
- /* tell the stack to leave us alone until e1000_open() is called */
- netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
-
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
if (err)
goto err_register;
+ /* carrier off reporting is important to ethtool even BEFORE open */
+ netif_carrier_off(netdev);
+
e1000_print_device_info(adapter);
return 0;
@@ -5199,6 +5370,11 @@ static struct pci_device_id e1000_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LM), board_pchlan },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LC), board_pchlan },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan },
+
{ } /* terminate list */
};
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index e909f96698e..1342e0b1815 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -427,6 +427,8 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
e1000_validate_option(&crc_stripping, &opt, adapter);
if (crc_stripping == OPTION_ENABLED)
adapter->flags2 |= FLAG2_CRC_STRIPPING;
+ } else {
+ adapter->flags2 |= FLAG2_CRC_STRIPPING;
}
}
{ /* Kumeran Lock Loss Workaround */
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index dc4a9cba6a7..e23459cf3d0 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -37,6 +37,9 @@ static s32 e1000_wait_autoneg(struct e1000_hw *hw);
static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg);
static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
u16 *data, bool read);
+static u32 e1000_get_phy_addr_for_hv_page(u32 page);
+static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
+ u16 *data, bool read);
/* Cable length tables */
static const u16 e1000_m88_cable_length_table[] =
@@ -54,6 +57,55 @@ static const u16 e1000_igp_2_cable_length_table[] =
#define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
ARRAY_SIZE(e1000_igp_2_cable_length_table)
+#define BM_PHY_REG_PAGE(offset) \
+ ((u16)(((offset) >> PHY_PAGE_SHIFT) & 0xFFFF))
+#define BM_PHY_REG_NUM(offset) \
+ ((u16)(((offset) & MAX_PHY_REG_ADDRESS) |\
+ (((offset) >> (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)) &\
+ ~MAX_PHY_REG_ADDRESS)))
+
+#define HV_INTC_FC_PAGE_START 768
+#define I82578_ADDR_REG 29
+#define I82577_ADDR_REG 16
+#define I82577_CFG_REG 22
+#define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15)
+#define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */
+#define I82577_CTRL_REG 23
+#define I82577_CTRL_DOWNSHIFT_MASK (7 << 10)
+
+/* 82577 specific PHY registers */
+#define I82577_PHY_CTRL_2 18
+#define I82577_PHY_STATUS_2 26
+#define I82577_PHY_DIAG_STATUS 31
+
+/* I82577 PHY Status 2 */
+#define I82577_PHY_STATUS2_REV_POLARITY 0x0400
+#define I82577_PHY_STATUS2_MDIX 0x0800
+#define I82577_PHY_STATUS2_SPEED_MASK 0x0300
+#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200
+
+/* I82577 PHY Control 2 */
+#define I82577_PHY_CTRL2_AUTO_MDIX 0x0400
+#define I82577_PHY_CTRL2_FORCE_MDI_MDIX 0x0200
+
+/* I82577 PHY Diagnostics Status */
+#define I82577_DSTATUS_CABLE_LENGTH 0x03FC
+#define I82577_DSTATUS_CABLE_LENGTH_SHIFT 2
+
+/* BM PHY Copper Specific Control 1 */
+#define BM_CS_CTRL1 16
+
+/* BM PHY Copper Specific Status */
+#define BM_CS_STATUS 17
+#define BM_CS_STATUS_LINK_UP 0x0400
+#define BM_CS_STATUS_RESOLVED 0x0800
+#define BM_CS_STATUS_SPEED_MASK 0xC000
+#define BM_CS_STATUS_SPEED_1000 0x8000
+
+#define HV_MUX_DATA_CTRL PHY_REG(776, 16)
+#define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400
+#define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004
+
/**
* e1000e_check_reset_block_generic - Check if PHY reset is blocked
* @hw: pointer to the HW structure
@@ -82,23 +134,48 @@ s32 e1000e_check_reset_block_generic(struct e1000_hw *hw)
s32 e1000e_get_phy_id(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
+ s32 ret_val = 0;
u16 phy_id;
+ u16 retry_count = 0;
- ret_val = e1e_rphy(hw, PHY_ID1, &phy_id);
- if (ret_val)
- return ret_val;
+ if (!(phy->ops.read_phy_reg))
+ goto out;
- phy->id = (u32)(phy_id << 16);
- udelay(20);
- ret_val = e1e_rphy(hw, PHY_ID2, &phy_id);
- if (ret_val)
- return ret_val;
+ while (retry_count < 2) {
+ ret_val = e1e_rphy(hw, PHY_ID1, &phy_id);
+ if (ret_val)
+ goto out;
- phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
- phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
+ phy->id = (u32)(phy_id << 16);
+ udelay(20);
+ ret_val = e1e_rphy(hw, PHY_ID2, &phy_id);
+ if (ret_val)
+ goto out;
- return 0;
+ phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
+ phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
+
+ if (phy->id != 0 && phy->id != PHY_REVISION_MASK)
+ goto out;
+
+ /*
+ * If the PHY ID is still unknown, we may have an 82577i
+ * without link. We will try again after setting Slow
+ * MDIC mode. No harm in trying again in this case since
+ * the PHY ID is unknown at this point anyway
+ */
+ ret_val = e1000_set_mdio_slow_mode_hv(hw, true);
+ if (ret_val)
+ goto out;
+
+ retry_count++;
+ }
+out:
+ /* Revert to MDIO fast mode, if applicable */
+ if (retry_count)
+ ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
+
+ return ret_val;
}
/**
@@ -410,6 +487,43 @@ s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
}
/**
+ * e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link
+ * @hw: pointer to the HW structure
+ *
+ * Sets up Carrier-sense on Transmit and downshift values.
+ **/
+s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val;
+ u16 phy_data;
+
+ /* Enable CRS on TX. This must be set for half-duplex operation. */
+ ret_val = phy->ops.read_phy_reg(hw, I82577_CFG_REG, &phy_data);
+ if (ret_val)
+ goto out;
+
+ phy_data |= I82577_CFG_ASSERT_CRS_ON_TX;
+
+ /* Enable downshift */
+ phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
+
+ ret_val = phy->ops.write_phy_reg(hw, I82577_CFG_REG, phy_data);
+ if (ret_val)
+ goto out;
+
+ /* Set number of link attempts before downshift */
+ ret_val = phy->ops.read_phy_reg(hw, I82577_CTRL_REG, &phy_data);
+ if (ret_val)
+ goto out;
+ phy_data &= ~I82577_CTRL_DOWNSHIFT_MASK;
+ ret_val = phy->ops.write_phy_reg(hw, I82577_CTRL_REG, phy_data);
+
+out:
+ return ret_val;
+}
+
+/**
* e1000e_copper_link_setup_m88 - Setup m88 PHY's for copper link
* @hw: pointer to the HW structure
*
@@ -427,8 +541,8 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
if (ret_val)
return ret_val;
- /* For newer PHYs this bit is downshift enable */
- if (phy->type == e1000_phy_m88)
+ /* For BM PHY this bit is downshift enable */
+ if (phy->type != e1000_phy_bm)
phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
/*
@@ -520,10 +634,27 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
/* Commit the changes. */
ret_val = e1000e_commit_phy(hw);
- if (ret_val)
+ if (ret_val) {
hw_dbg(hw, "Error committing the PHY changes\n");
+ return ret_val;
+ }
- return ret_val;
+ if (phy->type == e1000_phy_82578) {
+ ret_val = phy->ops.read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+ &phy_data);
+ if (ret_val)
+ return ret_val;
+
+ /* 82578 PHY - set the downshift count to 1x. */
+ phy_data |= I82578_EPSCR_DOWNSHIFT_ENABLE;
+ phy_data &= ~I82578_EPSCR_DOWNSHIFT_COUNTER_MASK;
+ ret_val = phy->ops.write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+ phy_data);
+ if (ret_val)
+ return ret_val;
+ }
+
+ return 0;
}
/**
@@ -1251,6 +1382,8 @@ s32 e1000e_check_downshift(struct e1000_hw *hw)
switch (phy->type) {
case e1000_phy_m88:
case e1000_phy_gg82563:
+ case e1000_phy_82578:
+ case e1000_phy_82577:
offset = M88E1000_PHY_SPEC_STATUS;
mask = M88E1000_PSSR_DOWNSHIFT;
break;
@@ -1886,6 +2019,12 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
case BME1000_E_PHY_ID_R2:
phy_type = e1000_phy_bm;
break;
+ case I82578_E_PHY_ID:
+ phy_type = e1000_phy_82578;
+ break;
+ case I82577_E_PHY_ID:
+ phy_type = e1000_phy_82577;
+ break;
default:
phy_type = e1000_phy_unknown;
break;
@@ -2181,11 +2320,16 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
u16 *data, bool read)
{
s32 ret_val;
- u16 reg = ((u16)offset) & PHY_REG_MASK;
+ u16 reg = BM_PHY_REG_NUM(offset);
u16 phy_reg = 0;
u8 phy_acquired = 1;
+ /* Gig must be disabled for MDIO accesses to page 800 */
+ if ((hw->mac.type == e1000_pchlan) &&
+ (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)))
+ hw_dbg(hw, "Attempting to access page 800 while gig enabled\n");
+
ret_val = hw->phy.ops.acquire_phy(hw);
if (ret_val) {
phy_acquired = 0;
@@ -2289,3 +2433,524 @@ static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
return 0;
}
+
+s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow)
+{
+ s32 ret_val = 0;
+ u16 data = 0;
+
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ return ret_val;
+
+ /* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */
+ hw->phy.addr = 1;
+ ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
+ (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
+ if (ret_val) {
+ hw->phy.ops.release_phy(hw);
+ return ret_val;
+ }
+ ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1,
+ (0x2180 | (slow << 10)));
+
+ /* dummy read when reverting to fast mode - throw away result */
+ if (!slow)
+ e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data);
+
+ hw->phy.ops.release_phy(hw);
+
+ return ret_val;
+}
+
+/**
+ * e1000_read_phy_reg_hv - Read HV PHY register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to be read
+ * @data: pointer to the read data
+ *
+ * Acquires semaphore, if necessary, then reads the PHY register at offset
+ * and storing the retrieved information in data. Release any acquired
+ * semaphore before exiting.
+ **/
+s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+ s32 ret_val;
+ u16 page = BM_PHY_REG_PAGE(offset);
+ u16 reg = BM_PHY_REG_NUM(offset);
+ bool in_slow_mode = false;
+
+ /* Workaround failure in MDIO access while cable is disconnected */
+ if ((hw->phy.type == e1000_phy_82577) &&
+ !(er32(STATUS) & E1000_STATUS_LU)) {
+ ret_val = e1000_set_mdio_slow_mode_hv(hw, true);
+ if (ret_val)
+ goto out;
+
+ in_slow_mode = true;
+ }
+
+ /* Page 800 works differently than the rest so it has its own func */
+ if (page == BM_WUC_PAGE) {
+ ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset,
+ data, true);
+ goto out;
+ }
+
+ if (page > 0 && page < HV_INTC_FC_PAGE_START) {
+ ret_val = e1000_access_phy_debug_regs_hv(hw, offset,
+ data, true);
+ goto out;
+ }
+
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ goto out;
+
+ hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
+
+ if (page == HV_INTC_FC_PAGE_START)
+ page = 0;
+
+ if (reg > MAX_PHY_MULTI_PAGE_REG) {
+ if ((hw->phy.type != e1000_phy_82578) ||
+ ((reg != I82578_ADDR_REG) &&
+ (reg != I82578_ADDR_REG + 1))) {
+ u32 phy_addr = hw->phy.addr;
+
+ hw->phy.addr = 1;
+
+ /* Page is shifted left, PHY expects (page x 32) */
+ ret_val = e1000e_write_phy_reg_mdic(hw,
+ IGP01E1000_PHY_PAGE_SELECT,
+ (page << IGP_PAGE_SHIFT));
+ if (ret_val) {
+ hw->phy.ops.release_phy(hw);
+ goto out;
+ }
+ hw->phy.addr = phy_addr;
+ }
+ }
+
+ ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
+ data);
+ hw->phy.ops.release_phy(hw);
+
+out:
+ /* Revert to MDIO fast mode, if applicable */
+ if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
+ ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
+
+ return ret_val;
+}
+
+/**
+ * e1000_write_phy_reg_hv - Write HV PHY register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to write to
+ * @data: data to write at register offset
+ *
+ * Acquires semaphore, if necessary, then writes the data to PHY register
+ * at the offset. Release any acquired semaphores before exiting.
+ **/
+s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
+{
+ s32 ret_val;
+ u16 page = BM_PHY_REG_PAGE(offset);
+ u16 reg = BM_PHY_REG_NUM(offset);
+ bool in_slow_mode = false;
+
+ /* Workaround failure in MDIO access while cable is disconnected */
+ if ((hw->phy.type == e1000_phy_82577) &&
+ !(er32(STATUS) & E1000_STATUS_LU)) {
+ ret_val = e1000_set_mdio_slow_mode_hv(hw, true);
+ if (ret_val)
+ goto out;
+
+ in_slow_mode = true;
+ }
+
+ /* Page 800 works differently than the rest so it has its own func */
+ if (page == BM_WUC_PAGE) {
+ ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset,
+ &data, false);
+ goto out;
+ }
+
+ if (page > 0 && page < HV_INTC_FC_PAGE_START) {
+ ret_val = e1000_access_phy_debug_regs_hv(hw, offset,
+ &data, false);
+ goto out;
+ }
+
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ goto out;
+
+ hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
+
+ if (page == HV_INTC_FC_PAGE_START)
+ page = 0;
+
+ /*
+ * Workaround MDIO accesses being disabled after entering IEEE Power
+ * Down (whenever bit 11 of the PHY Control register is set)
+ */
+ if ((hw->phy.type == e1000_phy_82578) &&
+ (hw->phy.revision >= 1) &&
+ (hw->phy.addr == 2) &&
+ ((MAX_PHY_REG_ADDRESS & reg) == 0) &&
+ (data & (1 << 11))) {
+ u16 data2 = 0x7EFF;
+ hw->phy.ops.release_phy(hw);
+ ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3,
+ &data2, false);
+ if (ret_val)
+ goto out;
+
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ goto out;
+ }
+
+ if (reg > MAX_PHY_MULTI_PAGE_REG) {
+ if ((hw->phy.type != e1000_phy_82578) ||
+ ((reg != I82578_ADDR_REG) &&
+ (reg != I82578_ADDR_REG + 1))) {
+ u32 phy_addr = hw->phy.addr;
+
+ hw->phy.addr = 1;
+
+ /* Page is shifted left, PHY expects (page x 32) */
+ ret_val = e1000e_write_phy_reg_mdic(hw,
+ IGP01E1000_PHY_PAGE_SELECT,
+ (page << IGP_PAGE_SHIFT));
+ if (ret_val) {
+ hw->phy.ops.release_phy(hw);
+ goto out;
+ }
+ hw->phy.addr = phy_addr;
+ }
+ }
+
+ ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
+ data);
+ hw->phy.ops.release_phy(hw);
+
+out:
+ /* Revert to MDIO fast mode, if applicable */
+ if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
+ ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
+
+ return ret_val;
+}
+
+/**
+ * e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page
+ * @page: page to be accessed
+ **/
+static u32 e1000_get_phy_addr_for_hv_page(u32 page)
+{
+ u32 phy_addr = 2;
+
+ if (page >= HV_INTC_FC_PAGE_START)
+ phy_addr = 1;
+
+ return phy_addr;
+}
+
+/**
+ * e1000_access_phy_debug_regs_hv - Read HV PHY vendor specific high registers
+ * @hw: pointer to the HW structure
+ * @offset: register offset to be read or written
+ * @data: pointer to the data to be read or written
+ * @read: determines if operation is read or written
+ *
+ * Acquires semaphore, if necessary, then reads the PHY register at offset
+ * and storing the retreived information in data. Release any acquired
+ * semaphores before exiting. Note that the procedure to read these regs
+ * uses the address port and data port to read/write.
+ **/
+static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
+ u16 *data, bool read)
+{
+ s32 ret_val;
+ u32 addr_reg = 0;
+ u32 data_reg = 0;
+ u8 phy_acquired = 1;
+
+ /* This takes care of the difference with desktop vs mobile phy */
+ addr_reg = (hw->phy.type == e1000_phy_82578) ?
+ I82578_ADDR_REG : I82577_ADDR_REG;
+ data_reg = addr_reg + 1;
+
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val) {
+ hw_dbg(hw, "Could not acquire PHY\n");
+ phy_acquired = 0;
+ goto out;
+ }
+
+ /* All operations in this function are phy address 2 */
+ hw->phy.addr = 2;
+
+ /* masking with 0x3F to remove the page from offset */
+ ret_val = e1000e_write_phy_reg_mdic(hw, addr_reg, (u16)offset & 0x3F);
+ if (ret_val) {
+ hw_dbg(hw, "Could not write PHY the HV address register\n");
+ goto out;
+ }
+
+ /* Read or write the data value next */
+ if (read)
+ ret_val = e1000e_read_phy_reg_mdic(hw, data_reg, data);
+ else
+ ret_val = e1000e_write_phy_reg_mdic(hw, data_reg, *data);
+
+ if (ret_val) {
+ hw_dbg(hw, "Could not read data value from HV data register\n");
+ goto out;
+ }
+
+out:
+ if (phy_acquired == 1)
+ hw->phy.ops.release_phy(hw);
+ return ret_val;
+}
+
+/**
+ * e1000_link_stall_workaround_hv - Si workaround
+ * @hw: pointer to the HW structure
+ *
+ * This function works around a Si bug where the link partner can get
+ * a link up indication before the PHY does. If small packets are sent
+ * by the link partner they can be placed in the packet buffer without
+ * being properly accounted for by the PHY and will stall preventing
+ * further packets from being received. The workaround is to clear the
+ * packet buffer after the PHY detects link up.
+ **/
+s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw)
+{
+ s32 ret_val = 0;
+ u16 data;
+
+ if (hw->phy.type != e1000_phy_82578)
+ goto out;
+
+ /* check if link is up and at 1Gbps */
+ ret_val = hw->phy.ops.read_phy_reg(hw, BM_CS_STATUS, &data);
+ if (ret_val)
+ goto out;
+
+ data &= BM_CS_STATUS_LINK_UP |
+ BM_CS_STATUS_RESOLVED |
+ BM_CS_STATUS_SPEED_MASK;
+
+ if (data != (BM_CS_STATUS_LINK_UP |
+ BM_CS_STATUS_RESOLVED |
+ BM_CS_STATUS_SPEED_1000))
+ goto out;
+
+ mdelay(200);
+
+ /* flush the packets in the fifo buffer */
+ ret_val = hw->phy.ops.write_phy_reg(hw, HV_MUX_DATA_CTRL,
+ HV_MUX_DATA_CTRL_GEN_TO_MAC |
+ HV_MUX_DATA_CTRL_FORCE_SPEED);
+ if (ret_val)
+ goto out;
+
+ ret_val = hw->phy.ops.write_phy_reg(hw, HV_MUX_DATA_CTRL,
+ HV_MUX_DATA_CTRL_GEN_TO_MAC);
+
+out:
+ return ret_val;
+}
+
+/**
+ * e1000_check_polarity_82577 - Checks the polarity.
+ * @hw: pointer to the HW structure
+ *
+ * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
+ *
+ * Polarity is determined based on the PHY specific status register.
+ **/
+s32 e1000_check_polarity_82577(struct e1000_hw *hw)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val;
+ u16 data;
+
+ ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_STATUS_2, &data);
+
+ if (!ret_val)
+ phy->cable_polarity = (data & I82577_PHY_STATUS2_REV_POLARITY)
+ ? e1000_rev_polarity_reversed
+ : e1000_rev_polarity_normal;
+
+ return ret_val;
+}
+
+/**
+ * e1000_phy_force_speed_duplex_82577 - Force speed/duplex for I82577 PHY
+ * @hw: pointer to the HW structure
+ *
+ * Calls the PHY setup function to force speed and duplex. Clears the
+ * auto-crossover to force MDI manually. Waits for link and returns
+ * successful if link up is successful, else -E1000_ERR_PHY (-2).
+ **/
+s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val;
+ u16 phy_data;
+ bool link;
+
+ ret_val = phy->ops.read_phy_reg(hw, PHY_CONTROL, &phy_data);
+ if (ret_val)
+ goto out;
+
+ e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
+
+ ret_val = phy->ops.write_phy_reg(hw, PHY_CONTROL, phy_data);
+ if (ret_val)
+ goto out;
+
+ /*
+ * Clear Auto-Crossover to force MDI manually. 82577 requires MDI
+ * forced whenever speed and duplex are forced.
+ */
+ ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_CTRL_2, &phy_data);
+ if (ret_val)
+ goto out;
+
+ phy_data &= ~I82577_PHY_CTRL2_AUTO_MDIX;
+ phy_data &= ~I82577_PHY_CTRL2_FORCE_MDI_MDIX;
+
+ ret_val = phy->ops.write_phy_reg(hw, I82577_PHY_CTRL_2, phy_data);
+ if (ret_val)
+ goto out;
+
+ hw_dbg(hw, "I82577_PHY_CTRL_2: %X\n", phy_data);
+
+ udelay(1);
+
+ if (phy->autoneg_wait_to_complete) {
+ hw_dbg(hw, "Waiting for forced speed/duplex link on 82577 phy\n");
+
+ ret_val = e1000e_phy_has_link_generic(hw,
+ PHY_FORCE_LIMIT,
+ 100000,
+ &link);
+ if (ret_val)
+ goto out;
+
+ if (!link)
+ hw_dbg(hw, "Link taking longer than expected.\n");
+
+ /* Try once more */
+ ret_val = e1000e_phy_has_link_generic(hw,
+ PHY_FORCE_LIMIT,
+ 100000,
+ &link);
+ if (ret_val)
+ goto out;
+ }
+
+out:
+ return ret_val;
+}
+
+/**
+ * e1000_get_phy_info_82577 - Retrieve I82577 PHY information
+ * @hw: pointer to the HW structure
+ *
+ * Read PHY status to determine if link is up. If link is up, then
+ * set/determine 10base-T extended distance and polarity correction. Read
+ * PHY port status to determine MDI/MDIx and speed. Based on the speed,
+ * determine on the cable length, local and remote receiver.
+ **/
+s32 e1000_get_phy_info_82577(struct e1000_hw *hw)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val;
+ u16 data;
+ bool link;
+
+ ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
+ if (ret_val)
+ goto out;
+
+ if (!link) {
+ hw_dbg(hw, "Phy info is only valid if link is up\n");
+ ret_val = -E1000_ERR_CONFIG;
+ goto out;
+ }
+
+ phy->polarity_correction = true;
+
+ ret_val = e1000_check_polarity_82577(hw);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_STATUS_2, &data);
+ if (ret_val)
+ goto out;
+
+ phy->is_mdix = (data & I82577_PHY_STATUS2_MDIX) ? true : false;
+
+ if ((data & I82577_PHY_STATUS2_SPEED_MASK) ==
+ I82577_PHY_STATUS2_SPEED_1000MBPS) {
+ ret_val = hw->phy.ops.get_cable_length(hw);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.read_phy_reg(hw, PHY_1000T_STATUS, &data);
+ if (ret_val)
+ goto out;
+
+ phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
+ ? e1000_1000t_rx_status_ok
+ : e1000_1000t_rx_status_not_ok;
+
+ phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
+ ? e1000_1000t_rx_status_ok
+ : e1000_1000t_rx_status_not_ok;
+ } else {
+ phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
+ phy->local_rx = e1000_1000t_rx_status_undefined;
+ phy->remote_rx = e1000_1000t_rx_status_undefined;
+ }
+
+out:
+ return ret_val;
+}
+
+/**
+ * e1000_get_cable_length_82577 - Determine cable length for 82577 PHY
+ * @hw: pointer to the HW structure
+ *
+ * Reads the diagnostic status register and verifies result is valid before
+ * placing it in the phy_cable_length field.
+ **/
+s32 e1000_get_cable_length_82577(struct e1000_hw *hw)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val;
+ u16 phy_data, length;
+
+ ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_DIAG_STATUS, &phy_data);
+ if (ret_val)
+ goto out;
+
+ length = (phy_data & I82577_DSTATUS_CABLE_LENGTH) >>
+ I82577_DSTATUS_CABLE_LENGTH_SHIFT;
+
+ if (length == E1000_CABLE_LENGTH_UNDEFINED)
+ ret_val = E1000_ERR_PHY;
+
+ phy->cable_length = length;
+
+out:
+ return ret_val;
+}
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index b22dab9153f..147c4b088fb 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -3261,7 +3261,7 @@ static ssize_t ehea_probe_port(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ehea_adapter *adapter = dev->driver_data;
+ struct ehea_adapter *adapter = dev_get_drvdata(dev);
struct ehea_port *port;
struct device_node *eth_dn = NULL;
int i;
@@ -3316,7 +3316,7 @@ static ssize_t ehea_remove_port(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ehea_adapter *adapter = dev->driver_data;
+ struct ehea_adapter *adapter = dev_get_drvdata(dev);
struct ehea_port *port;
int i;
u32 logical_port_id;
@@ -3404,7 +3404,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
adapter->pd = EHEA_PD_ID;
- dev->dev.driver_data = adapter;
+ dev_set_drvdata(&dev->dev, adapter);
/* initialize adapter and ports */
@@ -3468,7 +3468,7 @@ out:
static int __devexit ehea_remove(struct of_device *dev)
{
- struct ehea_adapter *adapter = dev->dev.driver_data;
+ struct ehea_adapter *adapter = dev_get_drvdata(&dev->dev);
int i;
for (i = 0; i < EHEA_MAX_PORTS; i++)
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 9080f07da8f..8005b602f77 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -661,8 +661,6 @@ static int enic_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
if (vnic_wq_desc_avail(wq) < MAX_SKB_FRAGS + 1)
netif_stop_queue(netdev);
- netdev->trans_start = jiffies;
-
spin_unlock_irqrestore(&enic->wq_lock[0], flags);
return NETDEV_TX_OK;
diff --git a/drivers/net/eql.c b/drivers/net/eql.c
index 5210bb1027c..19b7dd98394 100644
--- a/drivers/net/eql.c
+++ b/drivers/net/eql.c
@@ -194,6 +194,7 @@ static void __init eql_setup(struct net_device *dev)
dev->type = ARPHRD_SLIP;
dev->tx_queue_len = 5; /* Hands them off fast */
+ dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
}
static int eql_open(struct net_device *dev)
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index 91a9b1a3376..ceb6a9c357a 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -811,7 +811,7 @@ static int ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (unlikely(skb->len > ETHOC_BUFSIZ)) {
priv->stats.tx_errors++;
- return -EMSGSIZE;
+ goto out;
}
entry = priv->cur_tx % priv->num_tx;
@@ -840,9 +840,9 @@ static int ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
dev->trans_start = jiffies;
- dev_kfree_skb(skb);
-
spin_unlock_irq(&priv->lock);
+out:
+ dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
index 1a685a04d4b..1e972328140 100644
--- a/drivers/net/ewrk3.c
+++ b/drivers/net/ewrk3.c
@@ -873,7 +873,7 @@ static int ewrk3_queue_pkt (struct sk_buff *skb, struct net_device *dev)
err_out:
ENABLE_IRQs;
spin_unlock_irq (&lp->hw_lock);
- return 1;
+ return NETDEV_TX_BUSY;
}
/*
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 682e7f0b558..0f19b743749 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -86,8 +86,7 @@ static unsigned char fec_mac_default[] = {
#endif
#endif /* CONFIG_M5272 */
-/* Forward declarations of some structures to support different PHYs
-*/
+/* Forward declarations of some structures to support different PHYs */
typedef struct {
uint mii_data;
@@ -123,8 +122,7 @@ typedef struct {
#error "FEC: descriptor ring size constants too large"
#endif
-/* Interrupt events/masks.
-*/
+/* Interrupt events/masks. */
#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
#define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
#define FEC_ENET_BABT ((uint)0x20000000) /* Babbling transmitter */
@@ -165,7 +163,7 @@ typedef struct {
*/
struct fec_enet_private {
/* Hardware registers of the FEC device */
- volatile fec_t *hwp;
+ void __iomem *hwp;
struct net_device *netdev;
@@ -174,16 +172,20 @@ struct fec_enet_private {
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
unsigned char *tx_bounce[TX_RING_SIZE];
struct sk_buff* tx_skbuff[TX_RING_SIZE];
+ struct sk_buff* rx_skbuff[RX_RING_SIZE];
ushort skb_cur;
ushort skb_dirty;
- /* CPM dual port RAM relative addresses.
- */
+ /* CPM dual port RAM relative addresses */
dma_addr_t bd_dma;
- cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */
- cbd_t *tx_bd_base;
- cbd_t *cur_rx, *cur_tx; /* The next free ring entry */
- cbd_t *dirty_tx; /* The ring entries to be free()ed. */
+ /* Address of Rx and Tx buffers */
+ struct bufdesc *rx_bd_base;
+ struct bufdesc *tx_bd_base;
+ /* The next free ring entry */
+ struct bufdesc *cur_rx, *cur_tx;
+ /* The ring entries to be free()ed */
+ struct bufdesc *dirty_tx;
+
uint tx_full;
/* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
spinlock_t hw_lock;
@@ -209,17 +211,13 @@ struct fec_enet_private {
int full_duplex;
};
-static int fec_enet_open(struct net_device *dev);
-static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
static void fec_enet_mii(struct net_device *dev);
static irqreturn_t fec_enet_interrupt(int irq, void * dev_id);
static void fec_enet_tx(struct net_device *dev);
static void fec_enet_rx(struct net_device *dev);
static int fec_enet_close(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
static void fec_restart(struct net_device *dev, int duplex);
static void fec_stop(struct net_device *dev);
-static void fec_set_mac_address(struct net_device *dev);
/* MII processing. We keep this as simple as possible. Requests are
@@ -241,19 +239,16 @@ static mii_list_t *mii_tail;
static int mii_queue(struct net_device *dev, int request,
void (*func)(uint, struct net_device *));
-/* Make MII read/write commands for the FEC.
-*/
+/* Make MII read/write commands for the FEC */
#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18))
#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | \
(VAL & 0xffff))
#define mk_mii_end 0
-/* Transmitter timeout.
-*/
-#define TX_TIMEOUT (2*HZ)
+/* Transmitter timeout */
+#define TX_TIMEOUT (2 * HZ)
-/* Register definitions for the PHY.
-*/
+/* Register definitions for the PHY */
#define MII_REG_CR 0 /* Control Register */
#define MII_REG_SR 1 /* Status Register */
@@ -288,18 +283,14 @@ static int mii_queue(struct net_device *dev, int request,
static int
fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct fec_enet_private *fep;
- volatile fec_t *fecp;
- volatile cbd_t *bdp;
+ struct fec_enet_private *fep = netdev_priv(dev);
+ struct bufdesc *bdp;
unsigned short status;
unsigned long flags;
- fep = netdev_priv(dev);
- fecp = (volatile fec_t*)dev->base_addr;
-
if (!fep->link) {
/* Link is down or autonegotiation is in progress. */
- return 1;
+ return NETDEV_TX_BUSY;
}
spin_lock_irqsave(&fep->hw_lock, flags);
@@ -307,30 +298,27 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
bdp = fep->cur_tx;
status = bdp->cbd_sc;
-#ifndef final_version
+
if (status & BD_ENET_TX_READY) {
/* Ooops. All transmit buffers are full. Bail out.
* This should not happen, since dev->tbusy should be set.
*/
printk("%s: tx queue full!.\n", dev->name);
spin_unlock_irqrestore(&fep->hw_lock, flags);
- return 1;
+ return NETDEV_TX_BUSY;
}
-#endif
- /* Clear all of the status flags.
- */
+ /* Clear all of the status flags */
status &= ~BD_ENET_TX_STATS;
- /* Set buffer length and buffer pointer.
- */
+ /* Set buffer length and buffer pointer */
bdp->cbd_bufaddr = __pa(skb->data);
bdp->cbd_datlen = skb->len;
/*
- * On some FEC implementations data must be aligned on
- * 4-byte boundaries. Use bounce buffers to copy data
- * and get it aligned. Ugh.
+ * On some FEC implementations data must be aligned on
+ * 4-byte boundaries. Use bounce buffers to copy data
+ * and get it aligned. Ugh.
*/
if (bdp->cbd_bufaddr & FEC_ALIGNMENT) {
unsigned int index;
@@ -339,8 +327,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]);
}
- /* Save skb pointer.
- */
+ /* Save skb pointer */
fep->tx_skbuff[fep->skb_cur] = skb;
dev->stats.tx_bytes += skb->len;
@@ -349,13 +336,12 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Push the data cache so the CPM does not get stale memory
* data.
*/
- dma_sync_single(NULL, bdp->cbd_bufaddr,
- bdp->cbd_datlen, DMA_TO_DEVICE);
+ bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data,
+ FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
/* Send it on its way. Tell FEC it's ready, interrupt when done,
* it's the last BD of the frame, and to put the CRC on the end.
*/
-
status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
| BD_ENET_TX_LAST | BD_ENET_TX_TC);
bdp->cbd_sc = status;
@@ -363,22 +349,20 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies;
/* Trigger transmission start */
- fecp->fec_x_des_active = 0;
+ writel(0, fep->hwp + FEC_X_DES_ACTIVE);
- /* If this was the last BD in the ring, start at the beginning again.
- */
- if (status & BD_ENET_TX_WRAP) {
+ /* If this was the last BD in the ring, start at the beginning again. */
+ if (status & BD_ENET_TX_WRAP)
bdp = fep->tx_bd_base;
- } else {
+ else
bdp++;
- }
if (bdp == fep->dirty_tx) {
fep->tx_full = 1;
netif_stop_queue(dev);
}
- fep->cur_tx = (cbd_t *)bdp;
+ fep->cur_tx = bdp;
spin_unlock_irqrestore(&fep->hw_lock, flags);
@@ -390,75 +374,33 @@ fec_timeout(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- printk("%s: transmit timed out.\n", dev->name);
dev->stats.tx_errors++;
-#ifndef final_version
- {
- int i;
- cbd_t *bdp;
-
- printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n",
- (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "",
- (unsigned long)fep->dirty_tx,
- (unsigned long)fep->cur_rx);
-
- bdp = fep->tx_bd_base;
- printk(" tx: %u buffers\n", TX_RING_SIZE);
- for (i = 0 ; i < TX_RING_SIZE; i++) {
- printk(" %08x: %04x %04x %08x\n",
- (uint) bdp,
- bdp->cbd_sc,
- bdp->cbd_datlen,
- (int) bdp->cbd_bufaddr);
- bdp++;
- }
- bdp = fep->rx_bd_base;
- printk(" rx: %lu buffers\n", (unsigned long) RX_RING_SIZE);
- for (i = 0 ; i < RX_RING_SIZE; i++) {
- printk(" %08x: %04x %04x %08x\n",
- (uint) bdp,
- bdp->cbd_sc,
- bdp->cbd_datlen,
- (int) bdp->cbd_bufaddr);
- bdp++;
- }
- }
-#endif
fec_restart(dev, fep->full_duplex);
netif_wake_queue(dev);
}
-/* The interrupt handler.
- * This is called from the MPC core interrupt.
- */
static irqreturn_t
fec_enet_interrupt(int irq, void * dev_id)
{
struct net_device *dev = dev_id;
- volatile fec_t *fecp;
+ struct fec_enet_private *fep = netdev_priv(dev);
uint int_events;
irqreturn_t ret = IRQ_NONE;
- fecp = (volatile fec_t*)dev->base_addr;
-
- /* Get the interrupt events that caused us to be here.
- */
do {
- int_events = fecp->fec_ievent;
- fecp->fec_ievent = int_events;
+ int_events = readl(fep->hwp + FEC_IEVENT);
+ writel(int_events, fep->hwp + FEC_IEVENT);
- /* Handle receive event in its own function.
- */
if (int_events & FEC_ENET_RXF) {
ret = IRQ_HANDLED;
fec_enet_rx(dev);
}
/* Transmit OK, or non-fatal error. Update the buffer
- descriptors. FEC handles all errors, we just discover
- them as part of the transmit process.
- */
+ * descriptors. FEC handles all errors, we just discover
+ * them as part of the transmit process.
+ */
if (int_events & FEC_ENET_TXF) {
ret = IRQ_HANDLED;
fec_enet_tx(dev);
@@ -479,7 +421,7 @@ static void
fec_enet_tx(struct net_device *dev)
{
struct fec_enet_private *fep;
- volatile cbd_t *bdp;
+ struct bufdesc *bdp;
unsigned short status;
struct sk_buff *skb;
@@ -488,7 +430,11 @@ fec_enet_tx(struct net_device *dev)
bdp = fep->dirty_tx;
while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
- if (bdp == fep->cur_tx && fep->tx_full == 0) break;
+ if (bdp == fep->cur_tx && fep->tx_full == 0)
+ break;
+
+ dma_unmap_single(&dev->dev, bdp->cbd_bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
+ bdp->cbd_bufaddr = 0;
skb = fep->tx_skbuff[fep->skb_dirty];
/* Check for errors. */
@@ -510,31 +456,27 @@ fec_enet_tx(struct net_device *dev)
dev->stats.tx_packets++;
}
-#ifndef final_version
if (status & BD_ENET_TX_READY)
printk("HEY! Enet xmit interrupt and TX_READY.\n");
-#endif
+
/* Deferred means some collisions occurred during transmit,
* but we eventually sent the packet OK.
*/
if (status & BD_ENET_TX_DEF)
dev->stats.collisions++;
- /* Free the sk buffer associated with this last transmit.
- */
+ /* Free the sk buffer associated with this last transmit */
dev_kfree_skb_any(skb);
fep->tx_skbuff[fep->skb_dirty] = NULL;
fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK;
- /* Update pointer to next buffer descriptor to be transmitted.
- */
+ /* Update pointer to next buffer descriptor to be transmitted */
if (status & BD_ENET_TX_WRAP)
bdp = fep->tx_bd_base;
else
bdp++;
- /* Since we have freed up a buffer, the ring is no longer
- * full.
+ /* Since we have freed up a buffer, the ring is no longer full
*/
if (fep->tx_full) {
fep->tx_full = 0;
@@ -542,7 +484,7 @@ fec_enet_tx(struct net_device *dev)
netif_wake_queue(dev);
}
}
- fep->dirty_tx = (cbd_t *)bdp;
+ fep->dirty_tx = bdp;
spin_unlock_irq(&fep->hw_lock);
}
@@ -555,9 +497,8 @@ fec_enet_tx(struct net_device *dev)
static void
fec_enet_rx(struct net_device *dev)
{
- struct fec_enet_private *fep;
- volatile fec_t *fecp;
- volatile cbd_t *bdp;
+ struct fec_enet_private *fep = netdev_priv(dev);
+ struct bufdesc *bdp;
unsigned short status;
struct sk_buff *skb;
ushort pkt_len;
@@ -567,9 +508,6 @@ fec_enet_rx(struct net_device *dev)
flush_cache_all();
#endif
- fep = netdev_priv(dev);
- fecp = (volatile fec_t*)dev->base_addr;
-
spin_lock_irq(&fep->hw_lock);
/* First, grab all of the stats for the incoming packet.
@@ -577,143 +515,121 @@ fec_enet_rx(struct net_device *dev)
*/
bdp = fep->cur_rx;
-while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
+ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
-#ifndef final_version
- /* Since we have allocated space to hold a complete frame,
- * the last indicator should be set.
- */
- if ((status & BD_ENET_RX_LAST) == 0)
- printk("FEC ENET: rcv is not +last\n");
-#endif
+ /* Since we have allocated space to hold a complete frame,
+ * the last indicator should be set.
+ */
+ if ((status & BD_ENET_RX_LAST) == 0)
+ printk("FEC ENET: rcv is not +last\n");
- if (!fep->opened)
- goto rx_processing_done;
+ if (!fep->opened)
+ goto rx_processing_done;
- /* Check for errors. */
- if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
+ /* Check for errors. */
+ if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
BD_ENET_RX_CR | BD_ENET_RX_OV)) {
- dev->stats.rx_errors++;
- if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
- /* Frame too long or too short. */
- dev->stats.rx_length_errors++;
+ dev->stats.rx_errors++;
+ if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
+ /* Frame too long or too short. */
+ dev->stats.rx_length_errors++;
+ }
+ if (status & BD_ENET_RX_NO) /* Frame alignment */
+ dev->stats.rx_frame_errors++;
+ if (status & BD_ENET_RX_CR) /* CRC Error */
+ dev->stats.rx_crc_errors++;
+ if (status & BD_ENET_RX_OV) /* FIFO overrun */
+ dev->stats.rx_fifo_errors++;
}
- if (status & BD_ENET_RX_NO) /* Frame alignment */
+
+ /* Report late collisions as a frame error.
+ * On this error, the BD is closed, but we don't know what we
+ * have in the buffer. So, just drop this frame on the floor.
+ */
+ if (status & BD_ENET_RX_CL) {
+ dev->stats.rx_errors++;
dev->stats.rx_frame_errors++;
- if (status & BD_ENET_RX_CR) /* CRC Error */
- dev->stats.rx_crc_errors++;
- if (status & BD_ENET_RX_OV) /* FIFO overrun */
- dev->stats.rx_fifo_errors++;
- }
+ goto rx_processing_done;
+ }
- /* Report late collisions as a frame error.
- * On this error, the BD is closed, but we don't know what we
- * have in the buffer. So, just drop this frame on the floor.
- */
- if (status & BD_ENET_RX_CL) {
- dev->stats.rx_errors++;
- dev->stats.rx_frame_errors++;
- goto rx_processing_done;
- }
+ /* Process the incoming frame. */
+ dev->stats.rx_packets++;
+ pkt_len = bdp->cbd_datlen;
+ dev->stats.rx_bytes += pkt_len;
+ data = (__u8*)__va(bdp->cbd_bufaddr);
- /* Process the incoming frame.
- */
- dev->stats.rx_packets++;
- pkt_len = bdp->cbd_datlen;
- dev->stats.rx_bytes += pkt_len;
- data = (__u8*)__va(bdp->cbd_bufaddr);
-
- dma_sync_single(NULL, (unsigned long)__pa(data),
- pkt_len - 4, DMA_FROM_DEVICE);
-
- /* This does 16 byte alignment, exactly what we need.
- * The packet length includes FCS, but we don't want to
- * include that when passing upstream as it messes up
- * bridging applications.
- */
- skb = dev_alloc_skb(pkt_len-4);
+ dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
+ DMA_FROM_DEVICE);
- if (skb == NULL) {
- printk("%s: Memory squeeze, dropping packet.\n", dev->name);
- dev->stats.rx_dropped++;
- } else {
- skb_put(skb,pkt_len-4); /* Make room */
- skb_copy_to_linear_data(skb, data, pkt_len-4);
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- }
- rx_processing_done:
+ /* This does 16 byte alignment, exactly what we need.
+ * The packet length includes FCS, but we don't want to
+ * include that when passing upstream as it messes up
+ * bridging applications.
+ */
+ skb = dev_alloc_skb(pkt_len - 4 + NET_IP_ALIGN);
- /* Clear the status flags for this buffer.
- */
- status &= ~BD_ENET_RX_STATS;
+ if (unlikely(!skb)) {
+ printk("%s: Memory squeeze, dropping packet.\n",
+ dev->name);
+ dev->stats.rx_dropped++;
+ } else {
+ skb_reserve(skb, NET_IP_ALIGN);
+ skb_put(skb, pkt_len - 4); /* Make room */
+ skb_copy_to_linear_data(skb, data, pkt_len - 4);
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
+ }
- /* Mark the buffer empty.
- */
- status |= BD_ENET_RX_EMPTY;
- bdp->cbd_sc = status;
+ bdp->cbd_bufaddr = dma_map_single(NULL, data, bdp->cbd_datlen,
+ DMA_FROM_DEVICE);
+rx_processing_done:
+ /* Clear the status flags for this buffer */
+ status &= ~BD_ENET_RX_STATS;
- /* Update BD pointer to next entry.
- */
- if (status & BD_ENET_RX_WRAP)
- bdp = fep->rx_bd_base;
- else
- bdp++;
+ /* Mark the buffer empty */
+ status |= BD_ENET_RX_EMPTY;
+ bdp->cbd_sc = status;
-#if 1
- /* Doing this here will keep the FEC running while we process
- * incoming frames. On a heavily loaded network, we should be
- * able to keep up at the expense of system resources.
- */
- fecp->fec_r_des_active = 0;
-#endif
- } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */
- fep->cur_rx = (cbd_t *)bdp;
-
-#if 0
- /* Doing this here will allow us to process all frames in the
- * ring before the FEC is allowed to put more there. On a heavily
- * loaded network, some frames may be lost. Unfortunately, this
- * increases the interrupt overhead since we can potentially work
- * our way back to the interrupt return only to come right back
- * here.
- */
- fecp->fec_r_des_active = 0;
-#endif
+ /* Update BD pointer to next entry */
+ if (status & BD_ENET_RX_WRAP)
+ bdp = fep->rx_bd_base;
+ else
+ bdp++;
+ /* Doing this here will keep the FEC running while we process
+ * incoming frames. On a heavily loaded network, we should be
+ * able to keep up at the expense of system resources.
+ */
+ writel(0, fep->hwp + FEC_R_DES_ACTIVE);
+ }
+ fep->cur_rx = bdp;
spin_unlock_irq(&fep->hw_lock);
}
-
/* called from interrupt context */
static void
fec_enet_mii(struct net_device *dev)
{
struct fec_enet_private *fep;
- volatile fec_t *ep;
mii_list_t *mip;
- uint mii_reg;
fep = netdev_priv(dev);
spin_lock_irq(&fep->mii_lock);
- ep = fep->hwp;
- mii_reg = ep->fec_mii_data;
-
if ((mip = mii_head) == NULL) {
printk("MII and no head!\n");
goto unlock;
}
if (mip->mii_func != NULL)
- (*(mip->mii_func))(mii_reg, dev);
+ (*(mip->mii_func))(readl(fep->hwp + FEC_MII_DATA), dev);
mii_head = mip->mii_next;
mip->mii_next = mii_free;
mii_free = mip;
if ((mip = mii_head) != NULL)
- ep->fec_mii_data = mip->mii_regval;
+ writel(mip->mii_regval, fep->hwp + FEC_MII_DATA);
unlock:
spin_unlock_irq(&fep->mii_lock);
@@ -727,8 +643,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
mii_list_t *mip;
int retval;
- /* Add PHY address to register command.
- */
+ /* Add PHY address to register command */
fep = netdev_priv(dev);
spin_lock_irqsave(&fep->mii_lock, flags);
@@ -745,7 +660,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
mii_tail = mip;
} else {
mii_head = mii_tail = mip;
- fep->hwp->fec_mii_data = regval;
+ writel(regval, fep->hwp + FEC_MII_DATA);
}
} else {
retval = 1;
@@ -1246,11 +1161,8 @@ static void __inline__ fec_phy_ack_intr(void)
static void __inline__ fec_get_mac(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- volatile fec_t *fecp;
unsigned char *iap, tmpaddr[ETH_ALEN];
- fecp = fep->hwp;
-
if (FEC_FLASHMAC) {
/*
* Get MAC address from FLASH.
@@ -1264,8 +1176,8 @@ static void __inline__ fec_get_mac(struct net_device *dev)
(iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
iap = fec_mac_default;
} else {
- *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
- *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
+ *((unsigned long *) &tmpaddr[0]) = readl(fep->hwp + FEC_ADDR_LOW);
+ *((unsigned short *) &tmpaddr[4]) = (readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
iap = &tmpaddr[0];
}
@@ -1375,11 +1287,6 @@ static void mii_relink(struct work_struct *work)
fec_restart(dev, duplex);
} else
fec_stop(dev);
-
-#if 0
- enable_irq(fep->mii_irq);
-#endif
-
}
/* mii_queue_relink is called in interrupt context from mii_link_interrupt */
@@ -1388,12 +1295,12 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev)
struct fec_enet_private *fep = netdev_priv(dev);
/*
- ** We cannot queue phy_task twice in the workqueue. It
- ** would cause an endless loop in the workqueue.
- ** Fortunately, if the last mii_relink entry has not yet been
- ** executed now, it will do the job for the current interrupt,
- ** which is just what we want.
- */
+ * We cannot queue phy_task twice in the workqueue. It
+ * would cause an endless loop in the workqueue.
+ * Fortunately, if the last mii_relink entry has not yet been
+ * executed now, it will do the job for the current interrupt,
+ * which is just what we want.
+ */
if (fep->mii_phy_task_queued)
return;
@@ -1424,8 +1331,7 @@ phy_cmd_t const phy_cmd_config[] = {
{ mk_mii_end, }
};
-/* Read remainder of PHY ID.
-*/
+/* Read remainder of PHY ID. */
static void
mii_discover_phy3(uint mii_reg, struct net_device *dev)
{
@@ -1457,17 +1363,14 @@ static void
mii_discover_phy(uint mii_reg, struct net_device *dev)
{
struct fec_enet_private *fep;
- volatile fec_t *fecp;
uint phytype;
fep = netdev_priv(dev);
- fecp = fep->hwp;
if (fep->phy_addr < 32) {
if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) {
- /* Got first part of ID, now get remainder.
- */
+ /* Got first part of ID, now get remainder */
fep->phy_id = phytype << 16;
mii_queue(dev, mk_mii_read(MII_REG_PHYIR2),
mii_discover_phy3);
@@ -1479,15 +1382,15 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
} else {
printk("FEC: No PHY device found.\n");
/* Disable external MII interface */
- fecp->fec_mii_speed = fep->phy_speed = 0;
+ writel(0, fep->hwp + FEC_MII_SPEED);
+ fep->phy_speed = 0;
#ifdef HAVE_mii_link_interrupt
fec_disable_phy_intr();
#endif
}
}
-/* This interrupt occurs when the PHY detects a link change.
-*/
+/* This interrupt occurs when the PHY detects a link change */
#ifdef HAVE_mii_link_interrupt
static irqreturn_t
mii_link_interrupt(int irq, void * dev_id)
@@ -1497,10 +1400,6 @@ mii_link_interrupt(int irq, void * dev_id)
fec_phy_ack_intr();
-#if 0
- disable_irq(fep->mii_irq); /* disable now, enable later */
-#endif
-
mii_do_cmd(dev, fep->phy->ack_int);
mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */
@@ -1508,19 +1407,91 @@ mii_link_interrupt(int irq, void * dev_id)
}
#endif
+static void fec_enet_free_buffers(struct net_device *dev)
+{
+ struct fec_enet_private *fep = netdev_priv(dev);
+ int i;
+ struct sk_buff *skb;
+ struct bufdesc *bdp;
+
+ bdp = fep->rx_bd_base;
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ skb = fep->rx_skbuff[i];
+
+ if (bdp->cbd_bufaddr)
+ dma_unmap_single(&dev->dev, bdp->cbd_bufaddr,
+ FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
+ if (skb)
+ dev_kfree_skb(skb);
+ bdp++;
+ }
+
+ bdp = fep->tx_bd_base;
+ for (i = 0; i < TX_RING_SIZE; i++)
+ kfree(fep->tx_bounce[i]);
+}
+
+static int fec_enet_alloc_buffers(struct net_device *dev)
+{
+ struct fec_enet_private *fep = netdev_priv(dev);
+ int i;
+ struct sk_buff *skb;
+ struct bufdesc *bdp;
+
+ bdp = fep->rx_bd_base;
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE);
+ if (!skb) {
+ fec_enet_free_buffers(dev);
+ return -ENOMEM;
+ }
+ fep->rx_skbuff[i] = skb;
+
+ bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data,
+ FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
+ bdp->cbd_sc = BD_ENET_RX_EMPTY;
+ bdp++;
+ }
+
+ /* Set the last buffer to wrap. */
+ bdp--;
+ bdp->cbd_sc |= BD_SC_WRAP;
+
+ bdp = fep->tx_bd_base;
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
+
+ bdp->cbd_sc = 0;
+ bdp->cbd_bufaddr = 0;
+ bdp++;
+ }
+
+ /* Set the last buffer to wrap. */
+ bdp--;
+ bdp->cbd_sc |= BD_SC_WRAP;
+
+ return 0;
+}
+
static int
fec_enet_open(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
+ int ret;
/* I should reset the ring buffers here, but I don't yet know
* a simple way to do that.
*/
- fec_set_mac_address(dev);
+
+ ret = fec_enet_alloc_buffers(dev);
+ if (ret)
+ return ret;
fep->sequence_done = 0;
fep->link = 0;
+ fec_restart(dev, 1);
+
if (fep->phy) {
mii_do_cmd(dev, fep->phy->ack_int);
mii_do_cmd(dev, fep->phy->config);
@@ -1537,21 +1508,17 @@ fec_enet_open(struct net_device *dev)
schedule();
mii_do_cmd(dev, fep->phy->startup);
-
- /* Set the initial link state to true. A lot of hardware
- * based on this device does not implement a PHY interrupt,
- * so we are never notified of link change.
- */
- fep->link = 1;
- } else {
- fep->link = 1; /* lets just try it and see */
- /* no phy, go full duplex, it's most likely a hub chip */
- fec_restart(dev, 1);
}
+ /* Set the initial link state to true. A lot of hardware
+ * based on this device does not implement a PHY interrupt,
+ * so we are never notified of link change.
+ */
+ fep->link = 1;
+
netif_start_queue(dev);
fep->opened = 1;
- return 0; /* Success */
+ return 0;
}
static int
@@ -1559,12 +1526,13 @@ fec_enet_close(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- /* Don't know what to do yet.
- */
+ /* Don't know what to do yet. */
fep->opened = 0;
netif_stop_queue(dev);
fec_stop(dev);
+ fec_enet_free_buffers(dev);
+
return 0;
}
@@ -1583,87 +1551,102 @@ fec_enet_close(struct net_device *dev)
static void set_multicast_list(struct net_device *dev)
{
- struct fec_enet_private *fep;
- volatile fec_t *ep;
+ struct fec_enet_private *fep = netdev_priv(dev);
struct dev_mc_list *dmi;
- unsigned int i, j, bit, data, crc;
+ unsigned int i, j, bit, data, crc, tmp;
unsigned char hash;
- fep = netdev_priv(dev);
- ep = fep->hwp;
+ if (dev->flags & IFF_PROMISC) {
+ tmp = readl(fep->hwp + FEC_R_CNTRL);
+ tmp |= 0x8;
+ writel(tmp, fep->hwp + FEC_R_CNTRL);
+ return;
+ }
- if (dev->flags&IFF_PROMISC) {
- ep->fec_r_cntrl |= 0x0008;
- } else {
+ tmp = readl(fep->hwp + FEC_R_CNTRL);
+ tmp &= ~0x8;
+ writel(tmp, fep->hwp + FEC_R_CNTRL);
+
+ if (dev->flags & IFF_ALLMULTI) {
+ /* Catch all multicast addresses, so set the
+ * filter to all 1's
+ */
+ writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+ writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
- ep->fec_r_cntrl &= ~0x0008;
+ return;
+ }
- if (dev->flags & IFF_ALLMULTI) {
- /* Catch all multicast addresses, so set the
- * filter to all 1's.
- */
- ep->fec_grp_hash_table_high = 0xffffffff;
- ep->fec_grp_hash_table_low = 0xffffffff;
- } else {
- /* Clear filter and add the addresses in hash register.
- */
- ep->fec_grp_hash_table_high = 0;
- ep->fec_grp_hash_table_low = 0;
-
- dmi = dev->mc_list;
-
- for (j = 0; j < dev->mc_count; j++, dmi = dmi->next)
- {
- /* Only support group multicast for now.
- */
- if (!(dmi->dmi_addr[0] & 1))
- continue;
-
- /* calculate crc32 value of mac address
- */
- crc = 0xffffffff;
-
- for (i = 0; i < dmi->dmi_addrlen; i++)
- {
- data = dmi->dmi_addr[i];
- for (bit = 0; bit < 8; bit++, data >>= 1)
- {
- crc = (crc >> 1) ^
- (((crc ^ data) & 1) ? CRC32_POLY : 0);
- }
- }
-
- /* only upper 6 bits (HASH_BITS) are used
- which point to specific bit in he hash registers
- */
- hash = (crc >> (32 - HASH_BITS)) & 0x3f;
-
- if (hash > 31)
- ep->fec_grp_hash_table_high |= 1 << (hash - 32);
- else
- ep->fec_grp_hash_table_low |= 1 << hash;
+ /* Clear filter and add the addresses in hash register
+ */
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+
+ dmi = dev->mc_list;
+
+ for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) {
+ /* Only support group multicast for now */
+ if (!(dmi->dmi_addr[0] & 1))
+ continue;
+
+ /* calculate crc32 value of mac address */
+ crc = 0xffffffff;
+
+ for (i = 0; i < dmi->dmi_addrlen; i++) {
+ data = dmi->dmi_addr[i];
+ for (bit = 0; bit < 8; bit++, data >>= 1) {
+ crc = (crc >> 1) ^
+ (((crc ^ data) & 1) ? CRC32_POLY : 0);
}
}
+
+ /* only upper 6 bits (HASH_BITS) are used
+ * which point to specific bit in he hash registers
+ */
+ hash = (crc >> (32 - HASH_BITS)) & 0x3f;
+
+ if (hash > 31) {
+ tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+ tmp |= 1 << (hash - 32);
+ writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+ } else {
+ tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+ tmp |= 1 << hash;
+ writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+ }
}
}
-/* Set a MAC change in hardware.
- */
-static void
-fec_set_mac_address(struct net_device *dev)
+/* Set a MAC change in hardware. */
+static int
+fec_set_mac_address(struct net_device *dev, void *p)
{
- volatile fec_t *fecp;
+ struct fec_enet_private *fep = netdev_priv(dev);
+ struct sockaddr *addr = p;
- fecp = ((struct fec_enet_private *)netdev_priv(dev))->hwp;
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
- /* Set station address. */
- fecp->fec_addr_low = dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
- (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24);
- fecp->fec_addr_high = (dev->dev_addr[5] << 16) |
- (dev->dev_addr[4] << 24);
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+ writel(dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
+ (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24),
+ fep->hwp + FEC_ADDR_LOW);
+ writel((dev->dev_addr[5] << 16) | (dev->dev_addr[4] << 24),
+ fep + FEC_ADDR_HIGH);
+ return 0;
}
+static const struct net_device_ops fec_netdev_ops = {
+ .ndo_open = fec_enet_open,
+ .ndo_stop = fec_enet_close,
+ .ndo_start_xmit = fec_enet_start_xmit,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_tx_timeout = fec_timeout,
+ .ndo_set_mac_address = fec_set_mac_address,
+};
+
/*
* XXX: We need to clean up on failure exits here.
*
@@ -1672,17 +1655,13 @@ fec_set_mac_address(struct net_device *dev)
int __init fec_enet_init(struct net_device *dev, int index)
{
struct fec_enet_private *fep = netdev_priv(dev);
- unsigned long mem_addr;
- volatile cbd_t *bdp;
- cbd_t *cbd_base;
- volatile fec_t *fecp;
- int i, j;
+ struct bufdesc *cbd_base;
+ int i;
- /* Allocate memory for buffer descriptors.
- */
- mem_addr = (unsigned long)dma_alloc_coherent(NULL, PAGE_SIZE,
- &fep->bd_dma, GFP_KERNEL);
- if (mem_addr == 0) {
+ /* Allocate memory for buffer descriptors. */
+ cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
+ GFP_KERNEL);
+ if (!cbd_base) {
printk("FEC: allocate descriptor memory failed?\n");
return -ENOMEM;
}
@@ -1690,146 +1669,47 @@ int __init fec_enet_init(struct net_device *dev, int index)
spin_lock_init(&fep->hw_lock);
spin_lock_init(&fep->mii_lock);
- /* Create an Ethernet device instance.
- */
- fecp = (volatile fec_t *)dev->base_addr;
-
fep->index = index;
- fep->hwp = fecp;
+ fep->hwp = (void __iomem *)dev->base_addr;
fep->netdev = dev;
- /* Whack a reset. We should wait for this.
- */
- fecp->fec_ecntrl = 1;
- udelay(10);
-
/* Set the Ethernet address */
#ifdef CONFIG_M5272
fec_get_mac(dev);
#else
{
unsigned long l;
- l = fecp->fec_addr_low;
+ l = readl(fep->hwp + FEC_ADDR_LOW);
dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24);
dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0);
- l = fecp->fec_addr_high;
+ l = readl(fep->hwp + FEC_ADDR_HIGH);
dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
}
#endif
- cbd_base = (cbd_t *)mem_addr;
-
- /* Set receive and transmit descriptor base.
- */
+ /* Set receive and transmit descriptor base. */
fep->rx_bd_base = cbd_base;
fep->tx_bd_base = cbd_base + RX_RING_SIZE;
- fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
- fep->cur_rx = fep->rx_bd_base;
-
- fep->skb_cur = fep->skb_dirty = 0;
-
- /* Initialize the receive buffer descriptors.
- */
- bdp = fep->rx_bd_base;
- for (i=0; i<FEC_ENET_RX_PAGES; i++) {
-
- /* Allocate a page.
- */
- mem_addr = __get_free_page(GFP_KERNEL);
- /* XXX: missing check for allocation failure */
-
- /* Initialize the BD for every fragment in the page.
- */
- for (j=0; j<FEC_ENET_RX_FRPPG; j++) {
- bdp->cbd_sc = BD_ENET_RX_EMPTY;
- bdp->cbd_bufaddr = __pa(mem_addr);
- mem_addr += FEC_ENET_RX_FRSIZE;
- bdp++;
- }
- }
-
- /* Set the last buffer to wrap.
- */
- bdp--;
- bdp->cbd_sc |= BD_SC_WRAP;
-
- /* ...and the same for transmmit.
- */
- bdp = fep->tx_bd_base;
- for (i=0, j=FEC_ENET_TX_FRPPG; i<TX_RING_SIZE; i++) {
- if (j >= FEC_ENET_TX_FRPPG) {
- mem_addr = __get_free_page(GFP_KERNEL);
- j = 1;
- } else {
- mem_addr += FEC_ENET_TX_FRSIZE;
- j++;
- }
- fep->tx_bounce[i] = (unsigned char *) mem_addr;
-
- /* Initialize the BD for every fragment in the page.
- */
- bdp->cbd_sc = 0;
- bdp->cbd_bufaddr = 0;
- bdp++;
- }
-
- /* Set the last buffer to wrap.
- */
- bdp--;
- bdp->cbd_sc |= BD_SC_WRAP;
-
- /* Set receive and transmit descriptor base.
- */
- fecp->fec_r_des_start = fep->bd_dma;
- fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
- * RX_RING_SIZE;
-
#ifdef HAVE_mii_link_interrupt
fec_request_mii_intr(dev);
#endif
-
- fecp->fec_grp_hash_table_high = 0;
- fecp->fec_grp_hash_table_low = 0;
- fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
- fecp->fec_ecntrl = 2;
- fecp->fec_r_des_active = 0;
-#ifndef CONFIG_M5272
- fecp->fec_hash_table_high = 0;
- fecp->fec_hash_table_low = 0;
-#endif
-
- /* The FEC Ethernet specific entries in the device structure. */
- dev->open = fec_enet_open;
- dev->hard_start_xmit = fec_enet_start_xmit;
- dev->tx_timeout = fec_timeout;
+ /* The FEC Ethernet specific entries in the device structure */
dev->watchdog_timeo = TX_TIMEOUT;
- dev->stop = fec_enet_close;
- dev->set_multicast_list = set_multicast_list;
+ dev->netdev_ops = &fec_netdev_ops;
for (i=0; i<NMII-1; i++)
mii_cmds[i].mii_next = &mii_cmds[i+1];
mii_free = mii_cmds;
- /* setup MII interface */
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
- fecp->fec_x_cntrl = 0x00;
-
- /*
- * Set MII speed to 2.5 MHz
- */
+ /* Set MII speed to 2.5 MHz */
fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
/ 2500000) / 2) & 0x3F) << 1;
- fecp->fec_mii_speed = fep->phy_speed;
fec_restart(dev, 0);
- /* Clear and enable interrupts */
- fecp->fec_ievent = 0xffc00000;
- fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
-
/* Queue up command to detect the PHY and initialize the
* remainder of the interface.
*/
@@ -1847,145 +1727,118 @@ int __init fec_enet_init(struct net_device *dev, int index)
static void
fec_restart(struct net_device *dev, int duplex)
{
- struct fec_enet_private *fep;
- volatile cbd_t *bdp;
- volatile fec_t *fecp;
+ struct fec_enet_private *fep = netdev_priv(dev);
+ struct bufdesc *bdp;
int i;
- fep = netdev_priv(dev);
- fecp = fep->hwp;
-
- /* Whack a reset. We should wait for this.
- */
- fecp->fec_ecntrl = 1;
+ /* Whack a reset. We should wait for this. */
+ writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
- /* Clear any outstanding interrupt.
- */
- fecp->fec_ievent = 0xffc00000;
+ /* Clear any outstanding interrupt. */
+ writel(0xffc00000, fep->hwp + FEC_IEVENT);
- /* Set station address.
- */
- fec_set_mac_address(dev);
+ /* Reset all multicast. */
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+#ifndef CONFIG_M5272
+ writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
+ writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
+#endif
- /* Reset all multicast.
- */
- fecp->fec_grp_hash_table_high = 0;
- fecp->fec_grp_hash_table_low = 0;
+ /* Set maximum receive buffer size. */
+ writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
- /* Set maximum receive buffer size.
- */
- fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
-
- /* Set receive and transmit descriptor base.
- */
- fecp->fec_r_des_start = fep->bd_dma;
- fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
- * RX_RING_SIZE;
+ /* Set receive and transmit descriptor base. */
+ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
+ writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE,
+ fep->hwp + FEC_X_DES_START);
fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
fep->cur_rx = fep->rx_bd_base;
- /* Reset SKB transmit buffers.
- */
+ /* Reset SKB transmit buffers. */
fep->skb_cur = fep->skb_dirty = 0;
- for (i=0; i<=TX_RING_MOD_MASK; i++) {
- if (fep->tx_skbuff[i] != NULL) {
+ for (i = 0; i <= TX_RING_MOD_MASK; i++) {
+ if (fep->tx_skbuff[i]) {
dev_kfree_skb_any(fep->tx_skbuff[i]);
fep->tx_skbuff[i] = NULL;
}
}
- /* Initialize the receive buffer descriptors.
- */
+ /* Initialize the receive buffer descriptors. */
bdp = fep->rx_bd_base;
- for (i=0; i<RX_RING_SIZE; i++) {
+ for (i = 0; i < RX_RING_SIZE; i++) {
- /* Initialize the BD for every fragment in the page.
- */
+ /* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = BD_ENET_RX_EMPTY;
bdp++;
}
- /* Set the last buffer to wrap.
- */
+ /* Set the last buffer to wrap */
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
- /* ...and the same for transmmit.
- */
+ /* ...and the same for transmit */
bdp = fep->tx_bd_base;
- for (i=0; i<TX_RING_SIZE; i++) {
+ for (i = 0; i < TX_RING_SIZE; i++) {
- /* Initialize the BD for every fragment in the page.
- */
+ /* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = 0;
bdp->cbd_bufaddr = 0;
bdp++;
}
- /* Set the last buffer to wrap.
- */
+ /* Set the last buffer to wrap */
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
- /* Enable MII mode.
- */
+ /* Enable MII mode */
if (duplex) {
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */
- fecp->fec_x_cntrl = 0x04; /* FD enable */
+ /* MII enable / FD enable */
+ writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
+ writel(0x04, fep->hwp + FEC_X_CNTRL);
} else {
- /* MII enable|No Rcv on Xmit */
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06;
- fecp->fec_x_cntrl = 0x00;
+ /* MII enable / No Rcv on Xmit */
+ writel(OPT_FRAME_SIZE | 0x06, fep->hwp + FEC_R_CNTRL);
+ writel(0x0, fep->hwp + FEC_X_CNTRL);
}
fep->full_duplex = duplex;
- /* Set MII speed.
- */
- fecp->fec_mii_speed = fep->phy_speed;
+ /* Set MII speed */
+ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
- /* And last, enable the transmit and receive processing.
- */
- fecp->fec_ecntrl = 2;
- fecp->fec_r_des_active = 0;
+ /* And last, enable the transmit and receive processing */
+ writel(2, fep->hwp + FEC_ECNTRL);
+ writel(0, fep->hwp + FEC_R_DES_ACTIVE);
- /* Enable interrupts we wish to service.
- */
- fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
+ /* Enable interrupts we wish to service */
+ writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII,
+ fep->hwp + FEC_IMASK);
}
static void
fec_stop(struct net_device *dev)
{
- volatile fec_t *fecp;
- struct fec_enet_private *fep;
-
- fep = netdev_priv(dev);
- fecp = fep->hwp;
+ struct fec_enet_private *fep = netdev_priv(dev);
- /*
- ** We cannot expect a graceful transmit stop without link !!!
- */
- if (fep->link)
- {
- fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */
+ /* We cannot expect a graceful transmit stop without link !!! */
+ if (fep->link) {
+ writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */
udelay(10);
- if (!(fecp->fec_ievent & FEC_ENET_GRA))
+ if (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_GRA))
printk("fec_stop : Graceful transmit stop did not complete !\n");
- }
+ }
- /* Whack a reset. We should wait for this.
- */
- fecp->fec_ecntrl = 1;
+ /* Whack a reset. We should wait for this. */
+ writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
- /* Clear outstanding MII command interrupts.
- */
- fecp->fec_ievent = FEC_ENET_MII;
+ /* Clear outstanding MII command interrupts. */
+ writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
- fecp->fec_imask = FEC_ENET_MII;
- fecp->fec_mii_speed = fep->phy_speed;
+ writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
+ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
}
static int __devinit
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 76c64c92e19..30b7dd67133 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -20,82 +20,55 @@
* registers in the same peripheral device on different models
* of the ColdFire!
*/
-typedef struct fec {
- unsigned long fec_reserved0;
- unsigned long fec_ievent; /* Interrupt event reg */
- unsigned long fec_imask; /* Interrupt mask reg */
- unsigned long fec_reserved1;
- unsigned long fec_r_des_active; /* Receive descriptor reg */
- unsigned long fec_x_des_active; /* Transmit descriptor reg */
- unsigned long fec_reserved2[3];
- unsigned long fec_ecntrl; /* Ethernet control reg */
- unsigned long fec_reserved3[6];
- unsigned long fec_mii_data; /* MII manage frame reg */
- unsigned long fec_mii_speed; /* MII speed control reg */
- unsigned long fec_reserved4[7];
- unsigned long fec_mib_ctrlstat; /* MIB control/status reg */
- unsigned long fec_reserved5[7];
- unsigned long fec_r_cntrl; /* Receive control reg */
- unsigned long fec_reserved6[15];
- unsigned long fec_x_cntrl; /* Transmit Control reg */
- unsigned long fec_reserved7[7];
- unsigned long fec_addr_low; /* Low 32bits MAC address */
- unsigned long fec_addr_high; /* High 16bits MAC address */
- unsigned long fec_opd; /* Opcode + Pause duration */
- unsigned long fec_reserved8[10];
- unsigned long fec_hash_table_high; /* High 32bits hash table */
- unsigned long fec_hash_table_low; /* Low 32bits hash table */
- unsigned long fec_grp_hash_table_high;/* High 32bits hash table */
- unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */
- unsigned long fec_reserved9[7];
- unsigned long fec_x_wmrk; /* FIFO transmit water mark */
- unsigned long fec_reserved10;
- unsigned long fec_r_bound; /* FIFO receive bound reg */
- unsigned long fec_r_fstart; /* FIFO receive start reg */
- unsigned long fec_reserved11[11];
- unsigned long fec_r_des_start; /* Receive descriptor ring */
- unsigned long fec_x_des_start; /* Transmit descriptor ring */
- unsigned long fec_r_buff_size; /* Maximum receive buff size */
-} fec_t;
+#define FEC_IEVENT 0x004 /* Interrupt event reg */
+#define FEC_IMASK 0x008 /* Interrupt mask reg */
+#define FEC_R_DES_ACTIVE 0x010 /* Receive descriptor reg */
+#define FEC_X_DES_ACTIVE 0x014 /* Transmit descriptor reg */
+#define FEC_ECNTRL 0x024 /* Ethernet control reg */
+#define FEC_MII_DATA 0x040 /* MII manage frame reg */
+#define FEC_MII_SPEED 0x044 /* MII speed control reg */
+#define FEC_MIB_CTRLSTAT 0x064 /* MIB control/status reg */
+#define FEC_R_CNTRL 0x084 /* Receive control reg */
+#define FEC_X_CNTRL 0x0c4 /* Transmit Control reg */
+#define FEC_ADDR_LOW 0x0e4 /* Low 32bits MAC address */
+#define FEC_ADDR_HIGH 0x0e8 /* High 16bits MAC address */
+#define FEC_OPD 0x0ec /* Opcode + Pause duration */
+#define FEC_HASH_TABLE_HIGH 0x118 /* High 32bits hash table */
+#define FEC_HASH_TABLE_LOW 0x11c /* Low 32bits hash table */
+#define FEC_GRP_HASH_TABLE_HIGH 0x120 /* High 32bits hash table */
+#define FEC_GRP_HASH_TABLE_LOW 0x124 /* Low 32bits hash table */
+#define FEC_X_WMRK 0x144 /* FIFO transmit water mark */
+#define FEC_R_BOUND 0x14c /* FIFO receive bound reg */
+#define FEC_R_FSTART 0x150 /* FIFO receive start reg */
+#define FEC_R_DES_START 0x180 /* Receive descriptor ring */
+#define FEC_X_DES_START 0x184 /* Transmit descriptor ring */
+#define FEC_R_BUFF_SIZE 0x188 /* Maximum receive buff size */
#else
-/*
- * Define device register set address map.
- */
-typedef struct fec {
- unsigned long fec_ecntrl; /* Ethernet control reg */
- unsigned long fec_ievent; /* Interrupt even reg */
- unsigned long fec_imask; /* Interrupt mask reg */
- unsigned long fec_ivec; /* Interrupt vec status reg */
- unsigned long fec_r_des_active; /* Receive descriptor reg */
- unsigned long fec_x_des_active; /* Transmit descriptor reg */
- unsigned long fec_reserved1[10];
- unsigned long fec_mii_data; /* MII manage frame reg */
- unsigned long fec_mii_speed; /* MII speed control reg */
- unsigned long fec_reserved2[17];
- unsigned long fec_r_bound; /* FIFO receive bound reg */
- unsigned long fec_r_fstart; /* FIFO receive start reg */
- unsigned long fec_reserved3[4];
- unsigned long fec_x_wmrk; /* FIFO transmit water mark */
- unsigned long fec_reserved4;
- unsigned long fec_x_fstart; /* FIFO transmit start reg */
- unsigned long fec_reserved5[21];
- unsigned long fec_r_cntrl; /* Receive control reg */
- unsigned long fec_max_frm_len; /* Maximum frame length reg */
- unsigned long fec_reserved6[14];
- unsigned long fec_x_cntrl; /* Transmit Control reg */
- unsigned long fec_reserved7[158];
- unsigned long fec_addr_low; /* Low 32bits MAC address */
- unsigned long fec_addr_high; /* High 16bits MAC address */
- unsigned long fec_grp_hash_table_high;/* High 32bits hash table */
- unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */
- unsigned long fec_r_des_start; /* Receive descriptor ring */
- unsigned long fec_x_des_start; /* Transmit descriptor ring */
- unsigned long fec_r_buff_size; /* Maximum receive buff size */
- unsigned long reserved8[9];
- unsigned long fec_fifo_ram[112]; /* FIFO RAM buffer */
-} fec_t;
+#define FEC_ECNTRL; 0x000 /* Ethernet control reg */
+#define FEC_IEVENT; 0x004 /* Interrupt even reg */
+#define FEC_IMASK; 0x008 /* Interrupt mask reg */
+#define FEC_IVEC; 0x00c /* Interrupt vec status reg */
+#define FEC_R_DES_ACTIVE; 0x010 /* Receive descriptor reg */
+#define FEC_X_DES_ACTIVE; 0x01c /* Transmit descriptor reg */
+#define FEC_MII_DATA 0x040 /* MII manage frame reg */
+#define FEC_MII_SPEED 0x044 /* MII speed control reg */
+#define FEC_R_BOUND 0x08c /* FIFO receive bound reg */
+#define FEC_R_FSTART 0x090 /* FIFO receive start reg */
+#define FEC_X_WMRK 0x0a4 /* FIFO transmit water mark */
+#define FEC_X_FSTART 0x0ac /* FIFO transmit start reg */
+#define FEC_R_CNTRL 0x104 /* Receive control reg */
+#define FEC_MAX_FRM_LEN 0x108 /* Maximum frame length reg */
+#define FEC_X_CNTRL 0x144 /* Transmit Control reg */
+#define FEC_ADDR_LOW 0x3c0 /* Low 32bits MAC address */
+#define FEC_ADDR_HIGH 0x3c4 /* High 16bits MAC address */
+#define FEC_GRP_HASH_TABLE_HIGH 0x3c8 /* High 32bits hash table */
+#define FEC_GRP_HASH_TABLE_LOW 0x3cc /* Low 32bits hash table */
+#define FEC_R_DES_START 0x3d0 /* Receive descriptor ring */
+#define FEC_X_DES_START 0x3d4 /* Transmit descriptor ring */
+#define FEC_R_BUFF_SIZE 0x3d8 /* Maximum receive buff size */
+#define FEC_FIFO_RAM 0x400 /* FIFO RAM buffer */
#endif /* CONFIG_M5272 */
@@ -104,17 +77,17 @@ typedef struct fec {
* Define the buffer descriptor structure.
*/
#ifdef CONFIG_ARCH_MXC
-typedef struct bufdesc {
+struct bufdesc {
unsigned short cbd_datlen; /* Data length */
unsigned short cbd_sc; /* Control and status info */
unsigned long cbd_bufaddr; /* Buffer address */
-} cbd_t;
+};
#else
-typedef struct bufdesc {
+struct bufdesc {
unsigned short cbd_sc; /* Control and status info */
unsigned short cbd_datlen; /* Data length */
unsigned long cbd_bufaddr; /* Buffer address */
-} cbd_t;
+};
#endif
/*
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index 8bbe7f61799..7d443405bbe 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -25,6 +25,7 @@
#include <linux/hardirq.h>
#include <linux/delay.h>
#include <linux/of_device.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <linux/netdevice.h>
@@ -43,11 +44,9 @@
#define DRIVER_NAME "mpc52xx-fec"
-#define FEC5200_PHYADDR_NONE (-1)
-#define FEC5200_PHYADDR_7WIRE (-2)
-
/* Private driver data structure */
struct mpc52xx_fec_priv {
+ struct net_device *ndev;
int duplex;
int speed;
int r_irq;
@@ -59,10 +58,11 @@ struct mpc52xx_fec_priv {
int msg_enable;
/* MDIO link details */
- int phy_addr;
- unsigned int phy_speed;
+ unsigned int mdio_speed;
+ struct device_node *phy_node;
struct phy_device *phydev;
enum phy_state link;
+ int seven_wire_mode;
};
@@ -211,85 +211,25 @@ static void mpc52xx_fec_adjust_link(struct net_device *dev)
phy_print_status(phydev);
}
-static int mpc52xx_fec_init_phy(struct net_device *dev)
-{
- struct mpc52xx_fec_priv *priv = netdev_priv(dev);
- struct phy_device *phydev;
- char phy_id[BUS_ID_SIZE];
-
- snprintf(phy_id, sizeof(phy_id), "%x:%02x",
- (unsigned int)dev->base_addr, priv->phy_addr);
-
- priv->link = PHY_DOWN;
- priv->speed = 0;
- priv->duplex = -1;
-
- phydev = phy_connect(dev, phy_id, &mpc52xx_fec_adjust_link, 0, PHY_INTERFACE_MODE_MII);
- if (IS_ERR(phydev)) {
- dev_err(&dev->dev, "phy_connect failed\n");
- return PTR_ERR(phydev);
- }
- dev_info(&dev->dev, "attached phy %i to driver %s\n",
- phydev->addr, phydev->drv->name);
-
- priv->phydev = phydev;
-
- return 0;
-}
-
-static int mpc52xx_fec_phy_start(struct net_device *dev)
-{
- struct mpc52xx_fec_priv *priv = netdev_priv(dev);
- int err;
-
- if (priv->phy_addr < 0)
- return 0;
-
- err = mpc52xx_fec_init_phy(dev);
- if (err) {
- dev_err(&dev->dev, "mpc52xx_fec_init_phy failed\n");
- return err;
- }
-
- /* reset phy - this also wakes it from PDOWN */
- phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
- phy_start(priv->phydev);
-
- return 0;
-}
-
-static void mpc52xx_fec_phy_stop(struct net_device *dev)
-{
- struct mpc52xx_fec_priv *priv = netdev_priv(dev);
-
- if (!priv->phydev)
- return;
-
- phy_disconnect(priv->phydev);
- /* power down phy */
- phy_stop(priv->phydev);
- phy_write(priv->phydev, MII_BMCR, BMCR_PDOWN);
-}
-
-static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv)
-{
- struct mpc52xx_fec __iomem *fec = priv->fec;
-
- if (priv->phydev)
- return;
-
- out_be32(&fec->mii_speed, priv->phy_speed);
-}
-
static int mpc52xx_fec_open(struct net_device *dev)
{
struct mpc52xx_fec_priv *priv = netdev_priv(dev);
int err = -EBUSY;
+ if (priv->phy_node) {
+ priv->phydev = of_phy_connect(priv->ndev, priv->phy_node,
+ mpc52xx_fec_adjust_link, 0, 0);
+ if (!priv->phydev) {
+ dev_err(&dev->dev, "of_phy_connect failed\n");
+ return -ENODEV;
+ }
+ phy_start(priv->phydev);
+ }
+
if (request_irq(dev->irq, &mpc52xx_fec_interrupt, IRQF_SHARED,
DRIVER_NAME "_ctrl", dev)) {
dev_err(&dev->dev, "ctrl interrupt request failed\n");
- goto out;
+ goto free_phy;
}
if (request_irq(priv->r_irq, &mpc52xx_fec_rx_interrupt, 0,
DRIVER_NAME "_rx", dev)) {
@@ -311,10 +251,6 @@ static int mpc52xx_fec_open(struct net_device *dev)
goto free_irqs;
}
- err = mpc52xx_fec_phy_start(dev);
- if (err)
- goto free_skbs;
-
bcom_enable(priv->rx_dmatsk);
bcom_enable(priv->tx_dmatsk);
@@ -324,16 +260,18 @@ static int mpc52xx_fec_open(struct net_device *dev)
return 0;
- free_skbs:
- mpc52xx_fec_free_rx_buffers(dev, priv->rx_dmatsk);
-
free_irqs:
free_irq(priv->t_irq, dev);
free_2irqs:
free_irq(priv->r_irq, dev);
free_ctrl_irq:
free_irq(dev->irq, dev);
- out:
+ free_phy:
+ if (priv->phydev) {
+ phy_stop(priv->phydev);
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
+ }
return err;
}
@@ -352,7 +290,12 @@ static int mpc52xx_fec_close(struct net_device *dev)
free_irq(priv->r_irq, dev);
free_irq(priv->t_irq, dev);
- mpc52xx_fec_phy_stop(dev);
+ if (priv->phydev) {
+ /* power down phy */
+ phy_stop(priv->phydev);
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
+ }
return 0;
}
@@ -696,7 +639,7 @@ static void mpc52xx_fec_hw_init(struct net_device *dev)
/* set phy speed.
* this can't be done in phy driver, since it needs to be called
* before fec stuff (even on resume) */
- mpc52xx_fec_phy_hw_init(priv);
+ out_be32(&fec->mii_speed, priv->mdio_speed);
}
/**
@@ -732,7 +675,7 @@ static void mpc52xx_fec_start(struct net_device *dev)
rcntrl = FEC_RX_BUFFER_SIZE << 16; /* max frame length */
rcntrl |= FEC_RCNTRL_FCE;
- if (priv->phy_addr != FEC5200_PHYADDR_7WIRE)
+ if (!priv->seven_wire_mode)
rcntrl |= FEC_RCNTRL_MII_MODE;
if (priv->duplex == DUPLEX_FULL)
@@ -798,8 +741,6 @@ static void mpc52xx_fec_stop(struct net_device *dev)
/* Stop FEC */
out_be32(&fec->ecntrl, in_be32(&fec->ecntrl) & ~FEC_ECNTRL_ETHER_EN);
-
- return;
}
/* reset fec and bestcomm tasks */
@@ -817,9 +758,11 @@ static void mpc52xx_fec_reset(struct net_device *dev)
mpc52xx_fec_hw_init(dev);
- phy_stop(priv->phydev);
- phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
- phy_start(priv->phydev);
+ if (priv->phydev) {
+ phy_stop(priv->phydev);
+ phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
+ phy_start(priv->phydev);
+ }
bcom_fec_rx_reset(priv->rx_dmatsk);
bcom_fec_tx_reset(priv->tx_dmatsk);
@@ -919,8 +862,6 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
struct net_device *ndev;
struct mpc52xx_fec_priv *priv = NULL;
struct resource mem;
- struct device_node *phy_node;
- const phandle *phy_handle;
const u32 *prop;
int prop_size;
@@ -933,6 +874,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
return -ENOMEM;
priv = netdev_priv(ndev);
+ priv->ndev = ndev;
/* Reserve FEC control zone */
rv = of_address_to_resource(op->node, 0, &mem);
@@ -956,6 +898,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
ndev->ethtool_ops = &mpc52xx_fec_ethtool_ops;
ndev->watchdog_timeo = FEC_WATCHDOG_TIMEOUT;
ndev->base_addr = mem.start;
+ SET_NETDEV_DEV(ndev, &op->dev);
spin_lock_init(&priv->lock);
@@ -1003,14 +946,9 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
*/
/* Start with safe defaults for link connection */
- priv->phy_addr = FEC5200_PHYADDR_NONE;
priv->speed = 100;
priv->duplex = DUPLEX_HALF;
- priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
-
- /* the 7-wire property means don't use MII mode */
- if (of_find_property(op->node, "fsl,7-wire-mode", NULL))
- priv->phy_addr = FEC5200_PHYADDR_7WIRE;
+ priv->mdio_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
/* The current speed preconfigures the speed of the MII link */
prop = of_get_property(op->node, "current-speed", &prop_size);
@@ -1019,43 +957,23 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF;
}
- /* If there is a phy handle, setup link to that phy */
- phy_handle = of_get_property(op->node, "phy-handle", &prop_size);
- if (phy_handle && (prop_size >= sizeof(phandle))) {
- phy_node = of_find_node_by_phandle(*phy_handle);
- prop = of_get_property(phy_node, "reg", &prop_size);
- if (prop && (prop_size >= sizeof(u32)))
- if ((*prop >= 0) && (*prop < PHY_MAX_ADDR))
- priv->phy_addr = *prop;
- of_node_put(phy_node);
+ /* If there is a phy handle, then get the PHY node */
+ priv->phy_node = of_parse_phandle(op->node, "phy-handle", 0);
+
+ /* the 7-wire property means don't use MII mode */
+ if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) {
+ priv->seven_wire_mode = 1;
+ dev_info(&ndev->dev, "using 7-wire PHY mode\n");
}
/* Hardware init */
mpc52xx_fec_hw_init(ndev);
-
mpc52xx_fec_reset_stats(ndev);
- SET_NETDEV_DEV(ndev, &op->dev);
-
- /* Register the new network device */
rv = register_netdev(ndev);
if (rv < 0)
goto probe_error;
- /* Now report the link setup */
- switch (priv->phy_addr) {
- case FEC5200_PHYADDR_NONE:
- dev_info(&ndev->dev, "Fixed speed MII link: %i%cD\n",
- priv->speed, priv->duplex ? 'F' : 'H');
- break;
- case FEC5200_PHYADDR_7WIRE:
- dev_info(&ndev->dev, "using 7-wire PHY mode\n");
- break;
- default:
- dev_info(&ndev->dev, "Using PHY at MDIO address %i\n",
- priv->phy_addr);
- }
-
/* We're done ! */
dev_set_drvdata(&op->dev, ndev);
@@ -1065,6 +983,10 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
/* Error handling - free everything that might be allocated */
probe_error:
+ if (priv->phy_node)
+ of_node_put(priv->phy_node);
+ priv->phy_node = NULL;
+
irq_dispose_mapping(ndev->irq);
if (priv->rx_dmatsk)
@@ -1093,6 +1015,10 @@ mpc52xx_fec_remove(struct of_device *op)
unregister_netdev(ndev);
+ if (priv->phy_node)
+ of_node_put(priv->phy_node);
+ priv->phy_node = NULL;
+
irq_dispose_mapping(ndev->irq);
bcom_fec_rx_release(priv->rx_dmatsk);
diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c
index dd9bfa42ac3..fec9f245116 100644
--- a/drivers/net/fec_mpc52xx_phy.c
+++ b/drivers/net/fec_mpc52xx_phy.c
@@ -14,12 +14,14 @@
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <linux/of_platform.h>
+#include <linux/of_mdio.h>
#include <asm/io.h>
#include <asm/mpc52xx.h>
#include "fec_mpc52xx.h"
struct mpc52xx_fec_mdio_priv {
struct mpc52xx_fec __iomem *regs;
+ int mdio_irqs[PHY_MAX_ADDR];
};
static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
@@ -27,7 +29,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
{
struct mpc52xx_fec_mdio_priv *priv = bus->priv;
struct mpc52xx_fec __iomem *fec;
- int tries = 100;
+ int tries = 3;
value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
@@ -38,7 +40,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
/* wait for it to finish, this takes about 23 us on lite5200b */
while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
- udelay(5);
+ msleep(1);
if (!tries)
return -ETIMEDOUT;
@@ -64,7 +66,6 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
{
struct device *dev = &of->dev;
struct device_node *np = of->node;
- struct device_node *child = NULL;
struct mii_bus *bus;
struct mpc52xx_fec_mdio_priv *priv;
struct resource res = {};
@@ -85,22 +86,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
bus->write = mpc52xx_fec_mdio_write;
/* setup irqs */
- bus->irq = kmalloc(sizeof(bus->irq[0]) * PHY_MAX_ADDR, GFP_KERNEL);
- if (bus->irq == NULL) {
- err = -ENOMEM;
- goto out_free;
- }
- for (i=0; i<PHY_MAX_ADDR; i++)
- bus->irq[i] = PHY_POLL;
-
- while ((child = of_get_next_child(np, child)) != NULL) {
- int irq = irq_of_parse_and_map(child, 0);
- if (irq != NO_IRQ) {
- const u32 *id = of_get_property(child, "reg", NULL);
- if (id)
- bus->irq[*id] = irq;
- }
- }
+ bus->irq = priv->mdio_irqs;
/* setup registers */
err = of_address_to_resource(np, 0, &res);
@@ -122,7 +108,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
out_be32(&priv->regs->mii_speed,
((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1);
- err = mdiobus_register(bus);
+ err = of_mdiobus_register(bus, np);
if (err)
goto out_unmap;
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 9f6a68fb7b4..b60a3041b64 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -77,27 +77,31 @@
* Hardware access:
*/
-#define DEV_NEED_TIMERIRQ 0x000001 /* set the timer irq flag in the irq mask */
-#define DEV_NEED_LINKTIMER 0x000002 /* poll link settings. Relies on the timer irq */
-#define DEV_HAS_LARGEDESC 0x000004 /* device supports jumbo frames and needs packet format 2 */
-#define DEV_HAS_HIGH_DMA 0x000008 /* device supports 64bit dma */
-#define DEV_HAS_CHECKSUM 0x000010 /* device supports tx and rx checksum offloads */
-#define DEV_HAS_VLAN 0x000020 /* device supports vlan tagging and striping */
-#define DEV_HAS_MSI 0x000040 /* device supports MSI */
-#define DEV_HAS_MSI_X 0x000080 /* device supports MSI-X */
-#define DEV_HAS_POWER_CNTRL 0x000100 /* device supports power savings */
-#define DEV_HAS_STATISTICS_V1 0x000200 /* device supports hw statistics version 1 */
-#define DEV_HAS_STATISTICS_V2 0x000600 /* device supports hw statistics version 2 */
-#define DEV_HAS_STATISTICS_V3 0x000e00 /* device supports hw statistics version 3 */
-#define DEV_HAS_TEST_EXTENDED 0x001000 /* device supports extended diagnostic test */
-#define DEV_HAS_MGMT_UNIT 0x002000 /* device supports management unit */
-#define DEV_HAS_CORRECT_MACADDR 0x004000 /* device supports correct mac address order */
-#define DEV_HAS_COLLISION_FIX 0x008000 /* device supports tx collision fix */
-#define DEV_HAS_PAUSEFRAME_TX_V1 0x010000 /* device supports tx pause frames version 1 */
-#define DEV_HAS_PAUSEFRAME_TX_V2 0x020000 /* device supports tx pause frames version 2 */
-#define DEV_HAS_PAUSEFRAME_TX_V3 0x040000 /* device supports tx pause frames version 3 */
-#define DEV_NEED_TX_LIMIT 0x080000 /* device needs to limit tx */
-#define DEV_HAS_GEAR_MODE 0x100000 /* device supports gear mode */
+#define DEV_NEED_TIMERIRQ 0x0000001 /* set the timer irq flag in the irq mask */
+#define DEV_NEED_LINKTIMER 0x0000002 /* poll link settings. Relies on the timer irq */
+#define DEV_HAS_LARGEDESC 0x0000004 /* device supports jumbo frames and needs packet format 2 */
+#define DEV_HAS_HIGH_DMA 0x0000008 /* device supports 64bit dma */
+#define DEV_HAS_CHECKSUM 0x0000010 /* device supports tx and rx checksum offloads */
+#define DEV_HAS_VLAN 0x0000020 /* device supports vlan tagging and striping */
+#define DEV_HAS_MSI 0x0000040 /* device supports MSI */
+#define DEV_HAS_MSI_X 0x0000080 /* device supports MSI-X */
+#define DEV_HAS_POWER_CNTRL 0x0000100 /* device supports power savings */
+#define DEV_HAS_STATISTICS_V1 0x0000200 /* device supports hw statistics version 1 */
+#define DEV_HAS_STATISTICS_V2 0x0000600 /* device supports hw statistics version 2 */
+#define DEV_HAS_STATISTICS_V3 0x0000e00 /* device supports hw statistics version 3 */
+#define DEV_HAS_TEST_EXTENDED 0x0001000 /* device supports extended diagnostic test */
+#define DEV_HAS_MGMT_UNIT 0x0002000 /* device supports management unit */
+#define DEV_HAS_CORRECT_MACADDR 0x0004000 /* device supports correct mac address order */
+#define DEV_HAS_COLLISION_FIX 0x0008000 /* device supports tx collision fix */
+#define DEV_HAS_PAUSEFRAME_TX_V1 0x0010000 /* device supports tx pause frames version 1 */
+#define DEV_HAS_PAUSEFRAME_TX_V2 0x0020000 /* device supports tx pause frames version 2 */
+#define DEV_HAS_PAUSEFRAME_TX_V3 0x0040000 /* device supports tx pause frames version 3 */
+#define DEV_NEED_TX_LIMIT 0x0080000 /* device needs to limit tx */
+#define DEV_NEED_TX_LIMIT2 0x0180000 /* device needs to limit tx, expect for some revs */
+#define DEV_HAS_GEAR_MODE 0x0200000 /* device supports gear mode */
+#define DEV_NEED_PHY_INIT_FIX 0x0400000 /* device needs specific phy workaround */
+#define DEV_NEED_LOW_POWER_FIX 0x0800000 /* device needs special power up workaround */
+#define DEV_NEED_MSI_FIX 0x1000000 /* device needs msi workaround */
enum {
NvRegIrqStatus = 0x000,
@@ -343,6 +347,7 @@ enum {
#define NVREG_POWERSTATE2_POWERUP_MASK 0x0F15
#define NVREG_POWERSTATE2_POWERUP_REV_A3 0x0001
#define NVREG_POWERSTATE2_PHY_RESET 0x0004
+#define NVREG_POWERSTATE2_GATE_CLOCKS 0x0F00
};
/* Big endian: should work, but is untested */
@@ -1023,6 +1028,23 @@ static int using_multi_irqs(struct net_device *dev)
return 1;
}
+static void nv_txrx_gate(struct net_device *dev, bool gate)
+{
+ struct fe_priv *np = get_nvpriv(dev);
+ u8 __iomem *base = get_hwbase(dev);
+ u32 powerstate;
+
+ if (!np->mac_in_use &&
+ (np->driver_data & DEV_HAS_POWER_CNTRL)) {
+ powerstate = readl(base + NvRegPowerState2);
+ if (gate)
+ powerstate |= NVREG_POWERSTATE2_GATE_CLOCKS;
+ else
+ powerstate &= ~NVREG_POWERSTATE2_GATE_CLOCKS;
+ writel(powerstate, base + NvRegPowerState2);
+ }
+}
+
static void nv_enable_irq(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
@@ -1253,14 +1275,7 @@ static int phy_init(struct net_device *dev)
}
}
if (np->phy_model == PHY_MODEL_REALTEK_8201) {
- if (np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_32 ||
- np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_33 ||
- np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_34 ||
- np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_35 ||
- np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_36 ||
- np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_37 ||
- np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_38 ||
- np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_39) {
+ if (np->driver_data & DEV_NEED_PHY_INIT_FIX) {
phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ);
phy_reserved |= PHY_REALTEK_INIT7;
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) {
@@ -1451,14 +1466,7 @@ static int phy_init(struct net_device *dev)
}
}
if (np->phy_model == PHY_MODEL_REALTEK_8201) {
- if (np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_32 ||
- np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_33 ||
- np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_34 ||
- np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_35 ||
- np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_36 ||
- np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_37 ||
- np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_38 ||
- np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_39) {
+ if (np->driver_data & DEV_NEED_PHY_INIT_FIX) {
phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ);
phy_reserved |= PHY_REALTEK_INIT7;
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) {
@@ -3403,12 +3411,14 @@ static void nv_linkchange(struct net_device *dev)
if (!netif_carrier_ok(dev)) {
netif_carrier_on(dev);
printk(KERN_INFO "%s: link up.\n", dev->name);
+ nv_txrx_gate(dev, false);
nv_start_rx(dev);
}
} else {
if (netif_carrier_ok(dev)) {
netif_carrier_off(dev);
printk(KERN_INFO "%s: link down.\n", dev->name);
+ nv_txrx_gate(dev, true);
nv_stop_rx(dev);
}
}
@@ -5336,6 +5346,7 @@ static int nv_open(struct net_device *dev)
mii_rw(dev, np->phyaddr, MII_BMCR,
mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ) & ~BMCR_PDOWN);
+ nv_txrx_gate(dev, false);
/* erase previous misconfiguration */
if (np->driver_data & DEV_HAS_POWER_CNTRL)
nv_mac_reset(dev);
@@ -5523,12 +5534,14 @@ static int nv_close(struct net_device *dev)
nv_drain_rxtx(dev);
if (np->wolenabled || !phy_power_down) {
+ nv_txrx_gate(dev, false);
writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags);
nv_start_rx(dev);
} else {
/* power down phy */
mii_rw(dev, np->phyaddr, MII_BMCR,
mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ)|BMCR_PDOWN);
+ nv_txrx_gate(dev, true);
}
/* FIXME: power down nic */
@@ -5821,8 +5834,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
/* take phy and nic out of low power mode */
powerstate = readl(base + NvRegPowerState2);
powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK;
- if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_12 ||
- id->device == PCI_DEVICE_ID_NVIDIA_NVENET_13) &&
+ if ((id->driver_data & DEV_NEED_LOW_POWER_FIX) &&
pci_dev->revision >= 0xA3)
powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3;
writel(powerstate, base + NvRegPowerState2);
@@ -5878,14 +5890,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
/* Limit the number of tx's outstanding for hw bug */
if (id->driver_data & DEV_NEED_TX_LIMIT) {
np->tx_limit = 1;
- if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_32 ||
- id->device == PCI_DEVICE_ID_NVIDIA_NVENET_33 ||
- id->device == PCI_DEVICE_ID_NVIDIA_NVENET_34 ||
- id->device == PCI_DEVICE_ID_NVIDIA_NVENET_35 ||
- id->device == PCI_DEVICE_ID_NVIDIA_NVENET_36 ||
- id->device == PCI_DEVICE_ID_NVIDIA_NVENET_37 ||
- id->device == PCI_DEVICE_ID_NVIDIA_NVENET_38 ||
- id->device == PCI_DEVICE_ID_NVIDIA_NVENET_39) &&
+ if ((id->driver_data & DEV_NEED_TX_LIMIT2) &&
pci_dev->revision >= 0xA2)
np->tx_limit = 0;
}
@@ -6135,7 +6140,8 @@ static int nv_resume(struct pci_dev *pdev)
for (i = 0;i <= np->register_size/sizeof(u32); i++)
writel(np->saved_config_space[i], base+i*sizeof(u32));
- pci_write_config_dword(pdev, NV_MSI_PRIV_OFFSET, NV_MSI_PRIV_VALUE);
+ if (np->driver_data & DEV_NEED_MSI_FIX)
+ pci_write_config_dword(pdev, NV_MSI_PRIV_OFFSET, NV_MSI_PRIV_VALUE);
/* restore phy state, including autoneg */
phy_init(dev);
@@ -6184,160 +6190,164 @@ static void nv_shutdown(struct pci_dev *pdev)
static struct pci_device_id pci_tbl[] = {
{ /* nForce Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_1),
+ PCI_DEVICE(0x10DE, 0x01C3),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
},
{ /* nForce2 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_2),
+ PCI_DEVICE(0x10DE, 0x0066),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
},
{ /* nForce3 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_3),
+ PCI_DEVICE(0x10DE, 0x00D6),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
},
{ /* nForce3 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_4),
+ PCI_DEVICE(0x10DE, 0x0086),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* nForce3 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_5),
+ PCI_DEVICE(0x10DE, 0x008C),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* nForce3 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_6),
+ PCI_DEVICE(0x10DE, 0x00E6),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* nForce3 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_7),
+ PCI_DEVICE(0x10DE, 0x00DF),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* CK804 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8),
+ PCI_DEVICE(0x10DE, 0x0056),
.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
},
{ /* CK804 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9),
+ PCI_DEVICE(0x10DE, 0x0057),
.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
},
{ /* MCP04 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10),
+ PCI_DEVICE(0x10DE, 0x0037),
.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
},
{ /* MCP04 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11),
+ PCI_DEVICE(0x10DE, 0x0038),
.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
},
{ /* MCP51 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
+ PCI_DEVICE(0x10DE, 0x0268),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1|DEV_NEED_LOW_POWER_FIX,
},
{ /* MCP51 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
+ PCI_DEVICE(0x10DE, 0x0269),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1|DEV_NEED_LOW_POWER_FIX,
},
{ /* MCP55 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT,
+ PCI_DEVICE(0x10DE, 0x0372),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT|DEV_NEED_MSI_FIX,
},
{ /* MCP55 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT,
+ PCI_DEVICE(0x10DE, 0x0373),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT|DEV_NEED_MSI_FIX,
},
{ /* MCP61 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ PCI_DEVICE(0x10DE, 0x03E5),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX,
},
{ /* MCP61 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ PCI_DEVICE(0x10DE, 0x03E6),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX,
},
{ /* MCP61 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ PCI_DEVICE(0x10DE, 0x03EE),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX,
},
{ /* MCP61 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ PCI_DEVICE(0x10DE, 0x03EF),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX,
},
{ /* MCP65 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x0450),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
},
{ /* MCP65 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x0451),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
},
{ /* MCP65 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x0452),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
},
{ /* MCP65 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x0453),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
},
{ /* MCP67 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x054C),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
},
{ /* MCP67 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x054D),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
},
{ /* MCP67 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x054E),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
},
{ /* MCP67 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x054F),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
},
{ /* MCP73 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x07DC),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
},
{ /* MCP73 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x07DD),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
},
{ /* MCP73 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x07DE),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
},
{ /* MCP73 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x07DF),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
},
{ /* MCP77 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x0760),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
},
{ /* MCP77 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x0761),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
},
{ /* MCP77 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x0762),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
},
{ /* MCP77 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x0763),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
},
{ /* MCP79 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x0AB0),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
},
{ /* MCP79 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x0AB1),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
},
{ /* MCP79 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x0AB2),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
},
{ /* MCP79 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ PCI_DEVICE(0x10DE, 0x0AB3),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
+ },
+ { /* MCP89 Ethernet Controller */
+ PCI_DEVICE(0x10DE, 0x0D7D),
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX,
},
{0,},
};
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index a9cbc3191a2..b892c3ad9a7 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -36,6 +36,8 @@
#include <linux/fs.h>
#include <linux/platform_device.h>
#include <linux/phy.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
@@ -752,9 +754,10 @@ static int fs_init_phy(struct net_device *dev)
fep->oldlink = 0;
fep->oldspeed = 0;
fep->oldduplex = -1;
- if(fep->fpi->bus_id)
- phydev = phy_connect(dev, fep->fpi->bus_id, &fs_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
+ if(fep->fpi->phy_node)
+ phydev = of_phy_connect(dev, fep->fpi->phy_node,
+ &fs_adjust_link, 0,
+ PHY_INTERFACE_MODE_MII);
else {
printk("No phy bus ID specified in BSP code\n");
return -EINVAL;
@@ -938,81 +941,6 @@ extern void fs_mii_disconnect(struct net_device *dev);
/**************************************************************************************/
-/* handy pointer to the immap */
-void __iomem *fs_enet_immap = NULL;
-
-static int setup_immap(void)
-{
-#ifdef CONFIG_CPM1
- fs_enet_immap = ioremap(IMAP_ADDR, 0x4000);
- WARN_ON(!fs_enet_immap);
-#elif defined(CONFIG_CPM2)
- fs_enet_immap = cpm2_immr;
-#endif
-
- return 0;
-}
-
-static void cleanup_immap(void)
-{
-#if defined(CONFIG_CPM1)
- iounmap(fs_enet_immap);
-#endif
-}
-
-/**************************************************************************************/
-
-static int __devinit find_phy(struct device_node *np,
- struct fs_platform_info *fpi)
-{
- struct device_node *phynode, *mdionode;
- int ret = 0, len, bus_id;
- const u32 *data;
-
- data = of_get_property(np, "fixed-link", NULL);
- if (data) {
- snprintf(fpi->bus_id, 16, "%x:%02x", 0, *data);
- return 0;
- }
-
- data = of_get_property(np, "phy-handle", &len);
- if (!data || len != 4)
- return -EINVAL;
-
- phynode = of_find_node_by_phandle(*data);
- if (!phynode)
- return -EINVAL;
-
- data = of_get_property(phynode, "reg", &len);
- if (!data || len != 4) {
- ret = -EINVAL;
- goto out_put_phy;
- }
-
- mdionode = of_get_parent(phynode);
- if (!mdionode) {
- ret = -EINVAL;
- goto out_put_phy;
- }
-
- bus_id = of_get_gpio(mdionode, 0);
- if (bus_id < 0) {
- struct resource res;
- ret = of_address_to_resource(mdionode, 0, &res);
- if (ret)
- goto out_put_mdio;
- bus_id = res.start;
- }
-
- snprintf(fpi->bus_id, 16, "%x:%02x", bus_id, *data);
-
-out_put_mdio:
- of_node_put(mdionode);
-out_put_phy:
- of_node_put(phynode);
- return ret;
-}
-
#ifdef CONFIG_FS_ENET_HAS_FEC
#define IS_FEC(match) ((match)->data == &fs_fec_ops)
#else
@@ -1062,9 +990,9 @@ static int __devinit fs_enet_probe(struct of_device *ofdev,
fpi->rx_copybreak = 240;
fpi->use_napi = 1;
fpi->napi_weight = 17;
-
- ret = find_phy(ofdev->node, fpi);
- if (ret)
+ fpi->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0);
+ if ((!fpi->phy_node) && (!of_get_property(ofdev->node, "fixed-link",
+ NULL)))
goto out_free_fpi;
privsize = sizeof(*fep) +
@@ -1136,6 +1064,7 @@ out_cleanup_data:
out_free_dev:
free_netdev(ndev);
dev_set_drvdata(&ofdev->dev, NULL);
+ of_node_put(fpi->phy_node);
out_free_fpi:
kfree(fpi);
return ret;
@@ -1151,7 +1080,7 @@ static int fs_enet_remove(struct of_device *ofdev)
fep->ops->free_bd(ndev);
fep->ops->cleanup_data(ndev);
dev_set_drvdata(fep->dev, NULL);
-
+ of_node_put(fep->fpi->phy_node);
free_netdev(ndev);
return 0;
}
@@ -1191,25 +1120,12 @@ static struct of_platform_driver fs_enet_driver = {
static int __init fs_init(void)
{
- int r = setup_immap();
- if (r != 0)
- return r;
-
- r = of_register_platform_driver(&fs_enet_driver);
- if (r != 0)
- goto out;
-
- return 0;
-
-out:
- cleanup_immap();
- return r;
+ return of_register_platform_driver(&fs_enet_driver);
}
static void __exit fs_cleanup(void)
{
of_unregister_platform_driver(&fs_enet_driver);
- cleanup_immap();
}
#ifdef CONFIG_NET_POLL_CONTROLLER
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index 85a4bab7f63..ef01e09781a 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -194,9 +194,4 @@ extern const struct fs_ops fs_scc_ops;
/*******************************************************************/
-/* handy pointer to the immap */
-extern void __iomem *fs_enet_immap;
-
-/*******************************************************************/
-
#endif
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index 14e575313c8..ca7bcb8ab3a 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -245,10 +245,6 @@ static void set_multicast_list(struct net_device *dev)
static void restart(struct net_device *dev)
{
-#ifdef CONFIG_DUET
- immap_t *immap = fs_enet_immap;
- u32 cptr;
-#endif
struct fs_enet_private *fep = netdev_priv(dev);
fec_t __iomem *fecp = fep->fec.fecp;
const struct fs_platform_info *fpi = fep->fpi;
@@ -315,36 +311,6 @@ static void restart(struct net_device *dev)
FW(fecp, ievent, 0xffc0);
FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29);
- /*
- * adjust to speed (only for DUET & RMII)
- */
-#ifdef CONFIG_DUET
- if (fpi->use_rmii) {
- cptr = in_be32(&immap->im_cpm.cp_cptr);
- switch (fs_get_fec_index(fpi->fs_no)) {
- case 0:
- cptr |= 0x100;
- if (fep->speed == 10)
- cptr |= 0x0000010;
- else if (fep->speed == 100)
- cptr &= ~0x0000010;
- break;
- case 1:
- cptr |= 0x80;
- if (fep->speed == 10)
- cptr |= 0x0000008;
- else if (fep->speed == 100)
- cptr &= ~0x0000008;
- break;
- default:
- BUG(); /* should never happen */
- break;
- }
- out_be32(&immap->im_cpm.cp_cptr, cptr);
- }
-#endif
-
-
FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
/*
* adjust to duplex mode
diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c
index 49b6645d7e0..93b481b0e3c 100644
--- a/drivers/net/fs_enet/mii-bitbang.c
+++ b/drivers/net/fs_enet/mii-bitbang.c
@@ -22,6 +22,7 @@
#include <linux/mii.h>
#include <linux/platform_device.h>
#include <linux/mdio-bitbang.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include "fs_enet.h"
@@ -149,31 +150,12 @@ static int __devinit fs_mii_bitbang_init(struct mii_bus *bus,
return 0;
}
-static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
-{
- const u32 *data;
- int len, id, irq;
-
- data = of_get_property(np, "reg", &len);
- if (!data || len != 4)
- return;
-
- id = *data;
- bus->phy_mask &= ~(1 << id);
-
- irq = of_irq_to_resource(np, 0, NULL);
- if (irq != NO_IRQ)
- bus->irq[id] = irq;
-}
-
static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
const struct of_device_id *match)
{
- struct device_node *np = NULL;
struct mii_bus *new_bus;
struct bb_info *bitbang;
int ret = -ENOMEM;
- int i;
bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
if (!bitbang)
@@ -196,17 +178,10 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
if (!new_bus->irq)
goto out_unmap_regs;
- for (i = 0; i < PHY_MAX_ADDR; i++)
- new_bus->irq[i] = -1;
-
- while ((np = of_get_next_child(ofdev->node, np)))
- if (!strcmp(np->type, "ethernet-phy"))
- add_phy(new_bus, np);
-
new_bus->parent = &ofdev->dev;
dev_set_drvdata(&ofdev->dev, new_bus);
- ret = mdiobus_register(new_bus);
+ ret = of_mdiobus_register(new_bus, ofdev->node);
if (ret)
goto out_free_irqs;
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index 28077cc1b94..75a09994d66 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -54,8 +54,7 @@ static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
fec_t __iomem *fecp = fec->fecp;
int i, ret = -1;
- if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
- BUG();
+ BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
/* Add PHY address to register command. */
out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_read(location));
@@ -79,8 +78,7 @@ static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location,
int i;
/* this must never happen */
- if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
- BUG();
+ BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
/* Add PHY address to register command. */
out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_write(location, val));
@@ -102,23 +100,6 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus)
return 0;
}
-static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
-{
- const u32 *data;
- int len, id, irq;
-
- data = of_get_property(np, "reg", &len);
- if (!data || len != 4)
- return;
-
- id = *data;
- bus->phy_mask &= ~(1 << id);
-
- irq = of_irq_to_resource(np, 0, NULL);
- if (irq != NO_IRQ)
- bus->irq[id] = irq;
-}
-
static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
const struct of_device_id *match)
{
@@ -165,17 +146,10 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
if (!new_bus->irq)
goto out_unmap_regs;
- for (i = 0; i < PHY_MAX_ADDR; i++)
- new_bus->irq[i] = -1;
-
- while ((np = of_get_next_child(ofdev->node, np)))
- if (!strcmp(np->type, "ethernet-phy"))
- add_phy(new_bus, np);
-
new_bus->parent = &ofdev->dev;
dev_set_drvdata(&ofdev->dev, new_bus);
- ret = mdiobus_register(new_bus);
+ ret = of_mdiobus_register(new_bus, ofdev->node);
if (ret)
goto out_free_irqs;
diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c
index aa1eb88c21f..3af581303ca 100644
--- a/drivers/net/fsl_pq_mdio.c
+++ b/drivers/net/fsl_pq_mdio.c
@@ -34,6 +34,7 @@
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/of.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <asm/io.h>
@@ -154,44 +155,6 @@ static int fsl_pq_mdio_reset(struct mii_bus *bus)
return 0;
}
-/* Allocate an array which provides irq #s for each PHY on the given bus */
-static int *create_irq_map(struct device_node *np)
-{
- int *irqs;
- int i;
- struct device_node *child = NULL;
-
- irqs = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
-
- if (!irqs)
- return NULL;
-
- for (i = 0; i < PHY_MAX_ADDR; i++)
- irqs[i] = PHY_POLL;
-
- while ((child = of_get_next_child(np, child)) != NULL) {
- int irq = irq_of_parse_and_map(child, 0);
- const u32 *id;
-
- if (irq == NO_IRQ)
- continue;
-
- id = of_get_property(child, "reg", NULL);
-
- if (!id)
- continue;
-
- if (*id < PHY_MAX_ADDR && *id >= 0)
- irqs[*id] = irq;
- else
- printk(KERN_WARNING "%s: "
- "%d is not a valid PHY address\n",
- np->full_name, *id);
- }
-
- return irqs;
-}
-
void fsl_pq_mdio_bus_name(char *name, struct device_node *np)
{
const u32 *addr;
@@ -315,7 +278,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
new_bus->priv = (void __force *)regs;
- new_bus->irq = create_irq_map(np);
+ new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
if (NULL == new_bus->irq) {
err = -ENOMEM;
@@ -338,13 +301,17 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
of_device_is_compatible(np, "ucc_geth_phy")) {
#ifdef CONFIG_UCC_GETH
u32 id;
+ static u32 mii_mng_master;
tbipa = &regs->utbipar;
if ((err = get_ucc_id_for_range(addr, addr + size, &id)))
goto err_free_irqs;
- ucc_set_qe_mux_mii_mng(id - 1);
+ if (!mii_mng_master) {
+ mii_mng_master = id;
+ ucc_set_qe_mux_mii_mng(id - 1);
+ }
#else
err = -ENODEV;
goto err_free_irqs;
@@ -384,15 +351,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
out_be32(tbipa, tbiaddr);
- /*
- * The TBIPHY-only buses will find PHYs at every address,
- * so we mask them all but the TBI
- */
- if (of_device_is_compatible(np, "fsl,gianfar-tbi"))
- new_bus->phy_mask = ~(1 << tbiaddr);
-
- err = mdiobus_register(new_bus);
-
+ err = of_mdiobus_register(new_bus, np);
if (err) {
printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
new_bus->name);
@@ -460,10 +419,10 @@ int __init fsl_pq_mdio_init(void)
{
return of_register_platform_driver(&fsl_pq_mdio_driver);
}
+module_init(fsl_pq_mdio_init);
void fsl_pq_mdio_exit(void)
{
of_unregister_platform_driver(&fsl_pq_mdio_driver);
}
-subsys_initcall_sync(fsl_pq_mdio_init);
module_exit(fsl_pq_mdio_exit);
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index a0519184e54..4ae1d259fce 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -75,6 +75,7 @@
#include <linux/if_vlan.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <linux/ip.h>
#include <linux/tcp.h>
@@ -168,17 +169,13 @@ static inline int gfar_uses_fcb(struct gfar_private *priv)
static int gfar_of_init(struct net_device *dev)
{
- struct device_node *phy, *mdio;
- const unsigned int *id;
const char *model;
const char *ctype;
const void *mac_addr;
- const phandle *ph;
u64 addr, size;
int err = 0;
struct gfar_private *priv = netdev_priv(dev);
struct device_node *np = priv->node;
- char bus_name[MII_BUS_ID_SIZE];
const u32 *stash;
const u32 *stash_len;
const u32 *stash_idx;
@@ -264,8 +261,8 @@ static int gfar_of_init(struct net_device *dev)
if (of_get_property(np, "fsl,magic-packet", NULL))
priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET;
- ph = of_get_property(np, "phy-handle", NULL);
- if (ph == NULL) {
+ priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
+ if (!priv->phy_node) {
u32 *fixed_link;
fixed_link = (u32 *)of_get_property(np, "fixed-link", NULL);
@@ -273,57 +270,10 @@ static int gfar_of_init(struct net_device *dev)
err = -ENODEV;
goto err_out;
}
-
- snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id),
- PHY_ID_FMT, "0", fixed_link[0]);
- } else {
- phy = of_find_node_by_phandle(*ph);
-
- if (phy == NULL) {
- err = -ENODEV;
- goto err_out;
- }
-
- mdio = of_get_parent(phy);
-
- id = of_get_property(phy, "reg", NULL);
-
- of_node_put(phy);
-
- fsl_pq_mdio_bus_name(bus_name, mdio);
- of_node_put(mdio);
- snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x",
- bus_name, *id);
}
/* Find the TBI PHY. If it's not there, we don't support SGMII */
- ph = of_get_property(np, "tbi-handle", NULL);
- if (ph) {
- struct device_node *tbi = of_find_node_by_phandle(*ph);
- struct of_device *ofdev;
- struct mii_bus *bus;
-
- if (!tbi)
- return 0;
-
- mdio = of_get_parent(tbi);
- if (!mdio)
- return 0;
-
- ofdev = of_find_device_by_node(mdio);
-
- of_node_put(mdio);
-
- id = of_get_property(tbi, "reg", NULL);
- if (!id)
- return 0;
-
- of_node_put(tbi);
-
- bus = dev_get_drvdata(&ofdev->dev);
-
- priv->tbiphy = bus->phy_map[*id];
- }
+ priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
return 0;
@@ -529,6 +479,10 @@ static int gfar_probe(struct of_device *ofdev,
register_fail:
iounmap(priv->regs);
regs_fail:
+ if (priv->phy_node)
+ of_node_put(priv->phy_node);
+ if (priv->tbi_node)
+ of_node_put(priv->tbi_node);
free_netdev(dev);
return err;
}
@@ -537,6 +491,11 @@ static int gfar_remove(struct of_device *ofdev)
{
struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
+ if (priv->phy_node)
+ of_node_put(priv->phy_node);
+ if (priv->tbi_node)
+ of_node_put(priv->tbi_node);
+
dev_set_drvdata(&ofdev->dev, NULL);
iounmap(priv->regs);
@@ -690,7 +649,6 @@ static int init_phy(struct net_device *dev)
uint gigabit_support =
priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
SUPPORTED_1000baseT_Full : 0;
- struct phy_device *phydev;
phy_interface_t interface;
priv->oldlink = 0;
@@ -699,21 +657,21 @@ static int init_phy(struct net_device *dev)
interface = gfar_get_interface(dev);
- phydev = phy_connect(dev, priv->phy_bus_id, &adjust_link, 0, interface);
+ if (priv->phy_node) {
+ priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link,
+ 0, interface);
+ if (!priv->phydev) {
+ dev_err(&dev->dev, "error: Could not attach to PHY\n");
+ return -ENODEV;
+ }
+ }
if (interface == PHY_INTERFACE_MODE_SGMII)
gfar_configure_serdes(dev);
- if (IS_ERR(phydev)) {
- printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
- return PTR_ERR(phydev);
- }
-
/* Remove any features not supported by the controller */
- phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
- phydev->advertising = phydev->supported;
-
- priv->phydev = phydev;
+ priv->phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
+ priv->phydev->advertising = priv->phydev->supported;
return 0;
}
@@ -730,10 +688,17 @@ static int init_phy(struct net_device *dev)
static void gfar_configure_serdes(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
+ struct phy_device *tbiphy;
- if (!priv->tbiphy) {
- printk(KERN_WARNING "SGMII mode requires that the device "
- "tree specify a tbi-handle\n");
+ if (!priv->tbi_node) {
+ dev_warn(&dev->dev, "error: SGMII mode requires that the "
+ "device tree specify a tbi-handle\n");
+ return;
+ }
+
+ tbiphy = of_phy_find_device(priv->tbi_node);
+ if (!tbiphy) {
+ dev_err(&dev->dev, "error: Could not get TBI device\n");
return;
}
@@ -743,17 +708,17 @@ static void gfar_configure_serdes(struct net_device *dev)
* everything for us? Resetting it takes the link down and requires
* several seconds for it to come back.
*/
- if (phy_read(priv->tbiphy, MII_BMSR) & BMSR_LSTATUS)
+ if (phy_read(tbiphy, MII_BMSR) & BMSR_LSTATUS)
return;
/* Single clk mode, mii mode off(for serdes communication) */
- phy_write(priv->tbiphy, MII_TBICON, TBICON_CLK_SELECT);
+ phy_write(tbiphy, MII_TBICON, TBICON_CLK_SELECT);
- phy_write(priv->tbiphy, MII_ADVERTISE,
+ phy_write(tbiphy, MII_ADVERTISE,
ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE |
ADVERTISE_1000XPSE_ASYM);
- phy_write(priv->tbiphy, MII_BMCR, BMCR_ANENABLE |
+ phy_write(tbiphy, MII_BMCR, BMCR_ANENABLE |
BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000);
}
@@ -1242,7 +1207,8 @@ static int gfar_enet_open(struct net_device *dev)
static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb)
{
struct txfcb *fcb = (struct txfcb *)skb_push(skb, GMAC_FCB_LEN);
- cacheable_memzero(fcb, GMAC_FCB_LEN);
+
+ memset(fcb, 0, GMAC_FCB_LEN);
return fcb;
}
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index cf352961ae9..2cd94338b5d 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -779,7 +779,8 @@ struct gfar_private {
spinlock_t bflock;
phy_interface_t interface;
- char phy_bus_id[BUS_ID_SIZE];
+ struct device_node *phy_node;
+ struct device_node *tbi_node;
u32 device_flags;
unsigned char rx_csum_enable:1,
extended_hash:1,
@@ -793,7 +794,6 @@ struct gfar_private {
/* PHY stuff */
struct phy_device *phydev;
- struct phy_device *tbiphy;
struct mii_bus *mii_bus;
int oldspeed;
int oldduplex;
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 310ee035067..9d5b62cb30f 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -1163,7 +1163,7 @@ static void hamachi_tx_timeout(struct net_device *dev)
hmp->rx_ring[RX_RING_SIZE-1].status_n_length |= cpu_to_le32(DescEndRing);
/* Trigger an immediate transmit demand. */
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
hmp->stats.tx_errors++;
/* Restart the chip's Tx/Rx processes . */
@@ -1280,7 +1280,7 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
status=readw(hmp->base + TxStatus);
if( !(status & 0x0001) || (status & 0x0002))
writew(0x0001, hmp->base + TxCmd);
- return 1;
+ return NETDEV_TX_BUSY;
}
/* Caution: the write order is important here, set the field
@@ -1364,7 +1364,6 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
hmp->tx_full = 1;
netif_stop_queue(dev);
}
- dev->trans_start = jiffies;
if (hamachi_debug > 4) {
printk(KERN_DEBUG "%s: Hamachi transmit frame #%d queued in slot %d.\n",
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index bb78c11559c..5e4b7afd068 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -777,7 +777,7 @@ static int baycom_send_packet(struct sk_buff *skb, struct net_device *dev)
return 0;
}
if (bc->skb)
- return -1;
+ return NETDEV_TX_LOCKED;
/* strip KISS byte */
if (skb->len >= HDLCDRV_MAXFLEN+1 || skb->len < 3) {
dev_kfree_skb(skb);
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index d509b371a56..5105548ad50 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -274,7 +274,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
if ((newskb = skb_realloc_headroom(skb, AX25_BPQ_HEADER_LEN)) == NULL) {
printk(KERN_WARNING "bpqether: out of memory\n");
kfree_skb(skb);
- return -ENOMEM;
+ return NETDEV_TX_OK;
}
if (skb->sk != NULL)
@@ -294,7 +294,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
if ((dev = bpq_get_ether_dev(dev)) == NULL) {
dev->stats.tx_dropped++;
kfree_skb(skb);
- return -ENODEV;
+ return NETDEV_TX_OK;
}
skb->protocol = ax25_type_trans(skb, dev);
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index 61de56e45ee..d034f8ca63c 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -409,7 +409,7 @@ static int hdlcdrv_send_packet(struct sk_buff *skb, struct net_device *dev)
return 0;
}
if (sm->skb)
- return -1;
+ return NETDEV_TX_LOCKED;
netif_stop_queue(dev);
sm->skb = skb;
return 0;
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 032c0db4c41..fda2fc83e9a 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -531,7 +531,7 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
if (!netif_running(dev)) {
printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name);
- return 1;
+ return NETDEV_TX_BUSY;
}
if (netif_queue_stopped(dev)) {
@@ -541,7 +541,7 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
*/
if (time_before(jiffies, dev->trans_start + 20 * HZ)) {
/* 20 sec timeout not reached */
- return 1;
+ return NETDEV_TX_BUSY;
}
printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name,
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index de3f49f991a..8feda9fe829 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -2864,7 +2864,7 @@ static int __init hp100_eisa_probe (struct device *gendev)
printk("hp100: %s: EISA adapter found at 0x%x\n", dev->name,
dev->base_addr);
#endif
- gendev->driver_data = dev;
+ dev_set_drvdata(gendev, dev);
return 0;
out1:
free_netdev(dev);
@@ -2873,7 +2873,7 @@ static int __init hp100_eisa_probe (struct device *gendev)
static int __devexit hp100_eisa_remove (struct device *gendev)
{
- struct net_device *dev = gendev->driver_data;
+ struct net_device *dev = dev_get_drvdata(gendev);
cleanup_dev(dev);
return 0;
}
diff --git a/drivers/net/hplance.c b/drivers/net/hplance.c
index 2e802634d36..3e3528ade25 100644
--- a/drivers/net/hplance.c
+++ b/drivers/net/hplance.c
@@ -71,6 +71,19 @@ static struct dio_driver hplance_driver = {
.remove = __devexit_p(hplance_remove_one),
};
+static const struct net_device_ops hplance_netdev_ops = {
+ .ndo_open = hplance_open,
+ .ndo_stop = hplance_close,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_set_multicast_list = lance_set_multicast,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = lance_poll,
+#endif
+};
+
/* Find all the HP Lance boards and initialise them... */
static int __devinit hplance_init_one(struct dio_dev *d,
const struct dio_device_id *ent)
@@ -135,13 +148,7 @@ static void __init hplance_init(struct net_device *dev, struct dio_dev *d)
/* Fill the dev fields */
dev->base_addr = va;
- dev->open = &hplance_open;
- dev->stop = &hplance_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = lance_poll;
-#endif
- dev->hard_start_xmit = &lance_start_xmit;
- dev->set_multicast_list = &lance_set_multicast;
+ dev->netdev_ops = &hplance_netdev_ops;
dev->dma = 0;
for (i=0; i<6; i++) {
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 806533c831c..beb84213b67 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -1484,7 +1484,7 @@ static int emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev)
stop_queue:
netif_stop_queue(ndev);
DBG2(dev, "stopped TX queue" NL);
- return 1;
+ return NETDEV_TX_BUSY;
}
/* Tx lock BHs */
diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c
index c25bc0bc0b2..448098d3b39 100644
--- a/drivers/net/ibmlana.c
+++ b/drivers/net/ibmlana.c
@@ -815,7 +815,7 @@ static int ibmlana_close(struct net_device *dev)
static int ibmlana_tx(struct sk_buff *skb, struct net_device *dev)
{
ibmlana_priv *priv = netdev_priv(dev);
- int retval = 0, tmplen, addr;
+ int tmplen, addr;
unsigned long flags;
tda_t tda;
int baddr;
@@ -824,7 +824,6 @@ static int ibmlana_tx(struct sk_buff *skb, struct net_device *dev)
the upper layer is in deep desperation and we simply ignore the frame. */
if (priv->txusedcnt >= TXBUFCNT) {
- retval = -EIO;
dev->stats.tx_dropped++;
goto tx_done;
}
@@ -874,7 +873,7 @@ static int ibmlana_tx(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&priv->lock, flags);
tx_done:
dev_kfree_skb(skb);
- return retval;
+ return NETDEV_TX_OK;
}
/* switch receiver mode. */
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 5c6315df86b..0995c438f28 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -1203,6 +1203,20 @@ static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev)
return ret;
}
+static const struct net_device_ops ibmveth_netdev_ops = {
+ .ndo_open = ibmveth_open,
+ .ndo_stop = ibmveth_close,
+ .ndo_start_xmit = ibmveth_start_xmit,
+ .ndo_set_multicast_list = ibmveth_set_multicast_list,
+ .ndo_do_ioctl = ibmveth_ioctl,
+ .ndo_change_mtu = ibmveth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ibmveth_poll_controller,
+#endif
+};
+
static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
{
int rc, i;
@@ -1241,7 +1255,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
return -ENOMEM;
adapter = netdev_priv(netdev);
- dev->dev.driver_data = netdev;
+ dev_set_drvdata(&dev->dev, netdev);
adapter->vdev = dev;
adapter->netdev = netdev;
@@ -1265,21 +1279,13 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
memcpy(&adapter->mac_addr, mac_addr_p, 6);
netdev->irq = dev->irq;
- netdev->open = ibmveth_open;
- netdev->stop = ibmveth_close;
- netdev->hard_start_xmit = ibmveth_start_xmit;
- netdev->set_multicast_list = ibmveth_set_multicast_list;
- netdev->do_ioctl = ibmveth_ioctl;
- netdev->ethtool_ops = &netdev_ethtool_ops;
- netdev->change_mtu = ibmveth_change_mtu;
+ netdev->netdev_ops = &ibmveth_netdev_ops;
+ netdev->ethtool_ops = &netdev_ethtool_ops;
SET_NETDEV_DEV(netdev, &dev->dev);
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = ibmveth_poll_controller;
-#endif
netdev->features |= NETIF_F_LLTX;
spin_lock_init(&adapter->stats_lock);
- memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
+ memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
for(i = 0; i<IbmVethNumBufferPools; i++) {
struct kobject *kobj = &adapter->rx_buff_pool[i].kobj;
@@ -1335,7 +1341,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
static int __devexit ibmveth_remove(struct vio_dev *dev)
{
- struct net_device *netdev = dev->dev.driver_data;
+ struct net_device *netdev = dev_get_drvdata(&dev->dev);
struct ibmveth_adapter *adapter = netdev_priv(netdev);
int i;
@@ -1368,8 +1374,8 @@ static void ibmveth_proc_unregister_driver(void)
static int ibmveth_show(struct seq_file *seq, void *v)
{
struct ibmveth_adapter *adapter = seq->private;
- char *current_mac = ((char*) &adapter->netdev->dev_addr);
- char *firmware_mac = ((char*) &adapter->mac_addr) ;
+ char *current_mac = (char *) adapter->netdev->dev_addr;
+ char *firmware_mac = (char *) &adapter->mac_addr;
seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version);
@@ -1468,8 +1474,8 @@ const char * buf, size_t count)
struct ibmveth_buff_pool *pool = container_of(kobj,
struct ibmveth_buff_pool,
kobj);
- struct net_device *netdev =
- container_of(kobj->parent, struct device, kobj)->driver_data;
+ struct net_device *netdev = dev_get_drvdata(
+ container_of(kobj->parent, struct device, kobj));
struct ibmveth_adapter *adapter = netdev_priv(netdev);
long value = simple_strtol(buf, NULL, 10);
long rc;
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 60a26300193..96713ef0629 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -156,6 +156,7 @@ static void ifb_setup(struct net_device *dev)
dev->flags |= IFF_NOARP;
dev->flags &= ~IFF_MULTICAST;
+ dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
random_ether_addr(dev->dev_addr);
}
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index eaf97705036..0f16abab256 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -130,6 +130,7 @@ struct e1000_adv_tx_context_desc {
#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
+#define E1000_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 packet TYPE of SCTP */
/* IPSec Encrypt Enable for ESP */
#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index ad2d319d0f8..3bda3db73f1 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -289,8 +289,9 @@
#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400
/* Receive Checksum Control */
+#define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */
#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */
-#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
+#define E1000_RXCSUM_CRCOFL 0x00000800 /* CRC32 offload enable */
#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
/* Header split receive */
diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c
index 840782fb573..ed9058eca45 100644
--- a/drivers/net/igb/e1000_mbx.c
+++ b/drivers/net/igb/e1000_mbx.c
@@ -140,13 +140,13 @@ static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
struct e1000_mbx_info *mbx = &hw->mbx;
int countdown = mbx->timeout;
- if (!mbx->ops.check_for_msg)
+ if (!countdown || !mbx->ops.check_for_msg)
goto out;
while (mbx->ops.check_for_msg(hw, mbx_id)) {
+ countdown--;
if (!countdown)
break;
- countdown--;
udelay(mbx->usec_delay);
}
out:
@@ -165,13 +165,13 @@ static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
struct e1000_mbx_info *mbx = &hw->mbx;
int countdown = mbx->timeout;
- if (!mbx->ops.check_for_ack)
+ if (!countdown || !mbx->ops.check_for_ack)
goto out;
while (mbx->ops.check_for_ack(hw, mbx_id)) {
+ countdown--;
if (!countdown)
break;
- countdown--;
udelay(mbx->usec_delay);
}
out:
diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h
index 3228a862031..ebe4b616db8 100644
--- a/drivers/net/igb/e1000_phy.h
+++ b/drivers/net/igb/e1000_phy.h
@@ -80,7 +80,7 @@ s32 igb_phy_init_script_igp3(struct e1000_hw *hw);
#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
-#define IGP01E1000_PSSR_MDIX 0x0008
+#define IGP01E1000_PSSR_MDIX 0x0800
#define IGP01E1000_PSSR_SPEED_MASK 0xC000
#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
#define IGP02E1000_PHY_CHANNEL_NUM 4
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
index 0bd7728fe46..6e5924511e4 100644
--- a/drivers/net/igb/e1000_regs.h
+++ b/drivers/net/igb/e1000_regs.h
@@ -142,6 +142,7 @@ enum {
#define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */
#define E1000_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
+#define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40))
/* Split and Replication RX Control - RW */
/*
* Convenience macros
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 4e8464b9df2..b2c98dea9ee 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -137,11 +137,17 @@ struct igb_buffer {
};
};
-struct igb_queue_stats {
+struct igb_tx_queue_stats {
u64 packets;
u64 bytes;
};
+struct igb_rx_queue_stats {
+ u64 packets;
+ u64 bytes;
+ u64 drops;
+};
+
struct igb_ring {
struct igb_adapter *adapter; /* backlink */
void *desc; /* descriptor ring memory */
@@ -167,12 +173,13 @@ struct igb_ring {
union {
/* TX */
struct {
- struct igb_queue_stats tx_stats;
+ struct igb_tx_queue_stats tx_stats;
bool detect_tx_hung;
};
/* RX */
struct {
- struct igb_queue_stats rx_stats;
+ struct igb_rx_queue_stats rx_stats;
+ u64 rx_queue_drops;
struct napi_struct napi;
int set_itr;
struct igb_ring *buddy;
@@ -238,7 +245,6 @@ struct igb_adapter {
u64 hw_csum_err;
u64 hw_csum_good;
u32 alloc_rx_buff_failed;
- bool rx_csum;
u32 gorc;
u64 gorc_old;
u16 rx_ps_hdr_size;
@@ -286,6 +292,7 @@ struct igb_adapter {
#define IGB_FLAG_DCA_ENABLED (1 << 1)
#define IGB_FLAG_QUAD_PORT_A (1 << 2)
#define IGB_FLAG_NEED_CTX_IDX (1 << 3)
+#define IGB_FLAG_RX_CSUM_DISABLED (1 << 4)
enum e1000_state_t {
__IGB_TESTING,
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 27eae49e79c..9598ac09f4b 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -64,6 +64,7 @@ static const struct igb_stats igb_gstrings_stats[] = {
{ "rx_crc_errors", IGB_STAT(stats.crcerrs) },
{ "rx_frame_errors", IGB_STAT(net_stats.rx_frame_errors) },
{ "rx_no_buffer_count", IGB_STAT(stats.rnbc) },
+ { "rx_queue_drop_packet_count", IGB_STAT(net_stats.rx_fifo_errors) },
{ "rx_missed_errors", IGB_STAT(stats.mpc) },
{ "tx_aborted_errors", IGB_STAT(stats.ecol) },
{ "tx_carrier_errors", IGB_STAT(stats.tncrs) },
@@ -96,9 +97,10 @@ static const struct igb_stats igb_gstrings_stats[] = {
};
#define IGB_QUEUE_STATS_LEN \
- ((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues + \
- ((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues) * \
- (sizeof(struct igb_queue_stats) / sizeof(u64)))
+ (((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues)* \
+ (sizeof(struct igb_rx_queue_stats) / sizeof(u64))) + \
+ ((((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues) * \
+ (sizeof(struct igb_tx_queue_stats) / sizeof(u64))))
#define IGB_GLOBAL_STATS_LEN \
sizeof(igb_gstrings_stats) / sizeof(struct igb_stats)
#define IGB_STATS_LEN (IGB_GLOBAL_STATS_LEN + IGB_QUEUE_STATS_LEN)
@@ -275,13 +277,17 @@ static int igb_set_pauseparam(struct net_device *netdev,
static u32 igb_get_rx_csum(struct net_device *netdev)
{
struct igb_adapter *adapter = netdev_priv(netdev);
- return adapter->rx_csum;
+ return !(adapter->flags & IGB_FLAG_RX_CSUM_DISABLED);
}
static int igb_set_rx_csum(struct net_device *netdev, u32 data)
{
struct igb_adapter *adapter = netdev_priv(netdev);
- adapter->rx_csum = data;
+
+ if (data)
+ adapter->flags &= ~IGB_FLAG_RX_CSUM_DISABLED;
+ else
+ adapter->flags |= IGB_FLAG_RX_CSUM_DISABLED;
return 0;
}
@@ -293,10 +299,16 @@ static u32 igb_get_tx_csum(struct net_device *netdev)
static int igb_set_tx_csum(struct net_device *netdev, u32 data)
{
- if (data)
+ struct igb_adapter *adapter = netdev_priv(netdev);
+
+ if (data) {
netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
- else
- netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+ if (adapter->hw.mac.type == e1000_82576)
+ netdev->features |= NETIF_F_SCTP_CSUM;
+ } else {
+ netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_SCTP_CSUM);
+ }
return 0;
}
@@ -1950,7 +1962,8 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
{
struct igb_adapter *adapter = netdev_priv(netdev);
u64 *queue_stat;
- int stat_count = sizeof(struct igb_queue_stats) / sizeof(u64);
+ int stat_count_tx = sizeof(struct igb_tx_queue_stats) / sizeof(u64);
+ int stat_count_rx = sizeof(struct igb_rx_queue_stats) / sizeof(u64);
int j;
int i;
@@ -1963,14 +1976,14 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
for (j = 0; j < adapter->num_tx_queues; j++) {
int k;
queue_stat = (u64 *)&adapter->tx_ring[j].tx_stats;
- for (k = 0; k < stat_count; k++)
+ for (k = 0; k < stat_count_tx; k++)
data[i + k] = queue_stat[k];
i += k;
}
for (j = 0; j < adapter->num_rx_queues; j++) {
int k;
queue_stat = (u64 *)&adapter->rx_ring[j].rx_stats;
- for (k = 0; k < stat_count; k++)
+ for (k = 0; k < stat_count_rx; k++)
data[i + k] = queue_stat[k];
i += k;
}
@@ -2004,6 +2017,8 @@ static void igb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
p += ETH_GSTRING_LEN;
sprintf(p, "rx_queue_%u_bytes", i);
p += ETH_GSTRING_LEN;
+ sprintf(p, "rx_queue_%u_drops", i);
+ p += ETH_GSTRING_LEN;
}
/* BUG_ON(p - data != IGB_STATS_LEN * ETH_GSTRING_LEN); */
break;
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index e25343588fc..ea17319624a 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -942,6 +942,8 @@ int igb_up(struct igb_adapter *adapter)
rd32(E1000_ICR);
igb_irq_enable(adapter);
+ netif_tx_start_all_queues(adapter->netdev);
+
/* Fire a link change interrupt to start the watchdog. */
wr32(E1000_ICS, E1000_ICS_LSC);
return 0;
@@ -994,6 +996,11 @@ void igb_down(struct igb_adapter *adapter)
igb_reset(adapter);
igb_clean_all_tx_rings(adapter);
igb_clean_all_rx_rings(adapter);
+#ifdef CONFIG_IGB_DCA
+
+ /* since we reset the hardware DCA settings were cleared */
+ igb_setup_dca(adapter);
+#endif
}
void igb_reinit_locked(struct igb_adapter *adapter)
@@ -1343,6 +1350,9 @@ static int __devinit igb_probe(struct pci_dev *pdev,
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
+ if (adapter->hw.mac.type == e1000_82576)
+ netdev->features |= NETIF_F_SCTP_CSUM;
+
adapter->en_mng_pt = igb_enable_mng_pass_thru(&adapter->hw);
/* before reading the NVM, reset the controller to put the device in a
@@ -1390,8 +1400,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
igb_validate_mdi_setting(hw);
- adapter->rx_csum = 1;
-
/* Initial Wake on LAN setting If APM wake is enabled in the EEPROM,
* enable the ACPI Magic Packet filter
*/
@@ -1442,22 +1450,18 @@ static int __devinit igb_probe(struct pci_dev *pdev,
* driver. */
igb_get_hw_control(adapter);
- /* tell the stack to leave us alone until igb_open() is called */
- netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
-
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
if (err)
goto err_register;
+ /* carrier off reporting is important to ethtool even BEFORE open */
+ netif_carrier_off(netdev);
+
#ifdef CONFIG_IGB_DCA
if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IGB_FLAG_DCA_ENABLED;
dev_info(&pdev->dev, "DCA enabled\n");
- /* Always use CB2 mode, difference is masked
- * in the CB driver. */
- wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_CB2);
igb_setup_dca(adapter);
}
#endif
@@ -1699,6 +1703,8 @@ static int igb_open(struct net_device *netdev)
if (test_bit(__IGB_TESTING, &adapter->state))
return -EBUSY;
+ netif_carrier_off(netdev);
+
/* allocate transmit descriptors */
err = igb_setup_all_tx_resources(adapter);
if (err)
@@ -2231,29 +2237,24 @@ static void igb_configure_rx(struct igb_adapter *adapter)
mrqc |= (E1000_MRQC_RSS_FIELD_IPV6_UDP_EX |
E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
-
wr32(E1000_MRQC, mrqc);
-
- /* Multiqueue and raw packet checksumming are mutually
- * exclusive. Note that this not the same as TCP/IP
- * checksumming, which works fine. */
- rxcsum = rd32(E1000_RXCSUM);
- rxcsum |= E1000_RXCSUM_PCSD;
- wr32(E1000_RXCSUM, rxcsum);
- } else {
+ } else if (adapter->vfs_allocated_count) {
/* Enable multi-queue for sr-iov */
- if (adapter->vfs_allocated_count)
- wr32(E1000_MRQC, E1000_MRQC_ENABLE_VMDQ);
- /* Enable Receive Checksum Offload for TCP and UDP */
- rxcsum = rd32(E1000_RXCSUM);
- if (adapter->rx_csum)
- rxcsum |= E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPPCSE;
- else
- rxcsum &= ~(E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPPCSE);
-
- wr32(E1000_RXCSUM, rxcsum);
+ wr32(E1000_MRQC, E1000_MRQC_ENABLE_VMDQ);
}
+ /* Enable Receive Checksum Offload for TCP and UDP */
+ rxcsum = rd32(E1000_RXCSUM);
+ /* Disable raw packet checksumming */
+ rxcsum |= E1000_RXCSUM_PCSD;
+
+ if (adapter->hw.mac.type == e1000_82576)
+ /* Enable Receive Checksum Offload for SCTP */
+ rxcsum |= E1000_RXCSUM_CRCOFL;
+
+ /* Don't need to set TUOFL or IPOFL, they default to 1 */
+ wr32(E1000_RXCSUM, rxcsum);
+
/* Set the default pool for the PF's first queue */
igb_configure_vt_default_pool(adapter);
@@ -2661,7 +2662,6 @@ static void igb_watchdog_task(struct work_struct *work)
}
netif_carrier_on(netdev);
- netif_tx_wake_all_queues(netdev);
igb_ping_all_vfs(adapter);
@@ -2678,7 +2678,6 @@ static void igb_watchdog_task(struct work_struct *work)
printk(KERN_INFO "igb: %s NIC Link is Down\n",
netdev->name);
netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
igb_ping_all_vfs(adapter);
@@ -2712,6 +2711,8 @@ link_up:
* (Do the reset outside of interrupt context). */
adapter->tx_timeout_count++;
schedule_work(&adapter->reset_task);
+ /* return immediately since reset is imminent */
+ return;
}
}
@@ -2895,13 +2896,13 @@ static void igb_set_itr(struct igb_adapter *adapter)
switch (current_itr) {
/* counts and packets in update_itr are dependent on these numbers */
case lowest_latency:
- new_itr = 70000;
+ new_itr = 56; /* aka 70,000 ints/sec */
break;
case low_latency:
- new_itr = 20000; /* aka hwitr = ~200 */
+ new_itr = 196; /* aka 20,000 ints/sec */
break;
case bulk_latency:
- new_itr = 4000;
+ new_itr = 980; /* aka 4,000 ints/sec */
break;
default:
break;
@@ -2920,7 +2921,8 @@ set_itr_now:
* by adding intermediate steps when interrupt rate is
* increasing */
new_itr = new_itr > adapter->itr ?
- min(adapter->itr + (new_itr >> 2), new_itr) :
+ max((new_itr * adapter->itr) /
+ (new_itr + (adapter->itr >> 2)), new_itr) :
new_itr;
/* Don't write the value here; it resets the adapter's
* internal timer, and causes us to delay far longer than
@@ -2929,7 +2931,7 @@ set_itr_now:
* ends up being correct.
*/
adapter->itr = new_itr;
- adapter->rx_ring->itr_val = 1000000000 / (new_itr * 256);
+ adapter->rx_ring->itr_val = new_itr;
adapter->rx_ring->set_itr = 1;
}
@@ -3068,11 +3070,15 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+ else if (ip_hdr(skb)->protocol == IPPROTO_SCTP)
+ tu_cmd |= E1000_ADVTXD_TUCMD_L4T_SCTP;
break;
case cpu_to_be16(ETH_P_IPV6):
/* XXX what about other V6 headers?? */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+ else if (ipv6_hdr(skb)->nexthdr == IPPROTO_SCTP)
+ tu_cmd |= E1000_ADVTXD_TUCMD_L4T_SCTP;
break;
default:
if (unlikely(net_ratelimit()))
@@ -3133,8 +3139,7 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter,
/* set time_stamp *before* dma to help avoid a possible race */
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
- buffer_info->dma = map[count];
- count++;
+ buffer_info->dma = skb_shinfo(skb)->dma_head;
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
struct skb_frag_struct *frag;
@@ -3158,7 +3163,7 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter,
tx_ring->buffer_info[i].skb = skb;
tx_ring->buffer_info[first].next_to_watch = i;
- return count;
+ return count + 1;
}
static inline void igb_tx_queue_adv(struct igb_adapter *adapter,
@@ -3338,7 +3343,6 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
if (count) {
igb_tx_queue_adv(adapter, tx_ring, tx_flags, count,
skb->len, hdr_len);
- netdev->trans_start = jiffies;
/* Make sure there is space in the ring for the next send. */
igb_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 4);
} else {
@@ -3582,8 +3586,35 @@ void igb_update_stats(struct igb_adapter *adapter)
/* Rx Errors */
+ if (hw->mac.type != e1000_82575) {
+ u32 rqdpc_tmp;
+ u64 rqdpc_total = 0;
+ int i;
+ /* Read out drops stats per RX queue. Notice RQDPC (Receive
+ * Queue Drop Packet Count) stats only gets incremented, if
+ * the DROP_EN but it set (in the SRRCTL register for that
+ * queue). If DROP_EN bit is NOT set, then the some what
+ * equivalent count is stored in RNBC (not per queue basis).
+ * Also note the drop count is due to lack of available
+ * descriptors.
+ */
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ rqdpc_tmp = rd32(E1000_RQDPC(i)) & 0xFFF;
+ adapter->rx_ring[i].rx_stats.drops += rqdpc_tmp;
+ rqdpc_total += adapter->rx_ring[i].rx_stats.drops;
+ }
+ adapter->net_stats.rx_fifo_errors = rqdpc_total;
+ }
+
+ /* Note RNBC (Receive No Buffers Count) is an not an exact
+ * drop count as the hardware FIFO might save the day. Thats
+ * one of the reason for saving it in rx_fifo_errors, as its
+ * potentially not a true drop.
+ */
+ adapter->net_stats.rx_fifo_errors += adapter->stats.rnbc;
+
/* RLEC on some newer hardware can be incorrect so build
- * our own version based on RUC and ROC */
+ * our own version based on RUC and ROC */
adapter->net_stats.rx_errors = adapter->stats.rxerrc +
adapter->stats.crcerrs + adapter->stats.algnerrc +
adapter->stats.ruc + adapter->stats.roc +
@@ -3767,11 +3798,15 @@ static void igb_update_tx_dca(struct igb_ring *tx_ring)
static void igb_setup_dca(struct igb_adapter *adapter)
{
+ struct e1000_hw *hw = &adapter->hw;
int i;
if (!(adapter->flags & IGB_FLAG_DCA_ENABLED))
return;
+ /* Always use CB2 mode, difference is masked in the CB driver. */
+ wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_CB2);
+
for (i = 0; i < adapter->num_tx_queues; i++) {
adapter->tx_ring[i].cpu = -1;
igb_update_tx_dca(&adapter->tx_ring[i]);
@@ -4434,20 +4469,12 @@ static void igb_receive_skb(struct igb_ring *ring, u8 status,
bool vlan_extracted = (adapter->vlgrp && (status & E1000_RXD_STAT_VP));
skb_record_rx_queue(skb, ring->queue_index);
- if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
- if (vlan_extracted)
- vlan_gro_receive(&ring->napi, adapter->vlgrp,
- le16_to_cpu(rx_desc->wb.upper.vlan),
- skb);
- else
- napi_gro_receive(&ring->napi, skb);
- } else {
- if (vlan_extracted)
- vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
- le16_to_cpu(rx_desc->wb.upper.vlan));
- else
- netif_receive_skb(skb);
- }
+ if (vlan_extracted)
+ vlan_gro_receive(&ring->napi, adapter->vlgrp,
+ le16_to_cpu(rx_desc->wb.upper.vlan),
+ skb);
+ else
+ napi_gro_receive(&ring->napi, skb);
}
static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
@@ -4456,19 +4483,28 @@ static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
skb->ip_summed = CHECKSUM_NONE;
/* Ignore Checksum bit is set or checksum is disabled through ethtool */
- if ((status_err & E1000_RXD_STAT_IXSM) || !adapter->rx_csum)
+ if ((status_err & E1000_RXD_STAT_IXSM) ||
+ (adapter->flags & IGB_FLAG_RX_CSUM_DISABLED))
return;
/* TCP/UDP checksum error bit is set */
if (status_err &
(E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) {
+ /*
+ * work around errata with sctp packets where the TCPE aka
+ * L4E bit is set incorrectly on 64 byte (60 byte w/o crc)
+ * packets, (aka let the stack check the crc32c)
+ */
+ if (!((adapter->hw.mac.type == e1000_82576) &&
+ (skb->len == 60)))
+ adapter->hw_csum_err++;
/* let the stack verify checksum errors */
- adapter->hw_csum_err++;
return;
}
/* It must be a TCP or UDP packet with a valid checksum */
if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))
skb->ip_summed = CHECKSUM_UNNECESSARY;
+ dev_dbg(&adapter->pdev->dev, "cksum success: bits %08X\n", status_err);
adapter->hw_csum_good++;
}
diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c
index 1dcaa690531..ee17a097d1c 100644
--- a/drivers/net/igbvf/ethtool.c
+++ b/drivers/net/igbvf/ethtool.c
@@ -133,6 +133,24 @@ static int igbvf_set_pauseparam(struct net_device *netdev,
return -EOPNOTSUPP;
}
+static u32 igbvf_get_rx_csum(struct net_device *netdev)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ return !(adapter->flags & IGBVF_FLAG_RX_CSUM_DISABLED);
+}
+
+static int igbvf_set_rx_csum(struct net_device *netdev, u32 data)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+ if (data)
+ adapter->flags &= ~IGBVF_FLAG_RX_CSUM_DISABLED;
+ else
+ adapter->flags |= IGBVF_FLAG_RX_CSUM_DISABLED;
+
+ return 0;
+}
+
static u32 igbvf_get_tx_csum(struct net_device *netdev)
{
return ((netdev->features & NETIF_F_IP_CSUM) != 0);
@@ -150,8 +168,6 @@ static int igbvf_set_tx_csum(struct net_device *netdev, u32 data)
static int igbvf_set_tso(struct net_device *netdev, u32 data)
{
struct igbvf_adapter *adapter = netdev_priv(netdev);
- int i;
- struct net_device *v_netdev;
if (data) {
netdev->features |= NETIF_F_TSO;
@@ -159,24 +175,10 @@ static int igbvf_set_tso(struct net_device *netdev, u32 data)
} else {
netdev->features &= ~NETIF_F_TSO;
netdev->features &= ~NETIF_F_TSO6;
- /* disable TSO on all VLANs if they're present */
- if (!adapter->vlgrp)
- goto tso_out;
- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
- v_netdev = vlan_group_get_device(adapter->vlgrp, i);
- if (!v_netdev)
- continue;
-
- v_netdev->features &= ~NETIF_F_TSO;
- v_netdev->features &= ~NETIF_F_TSO6;
- vlan_group_set_device(adapter->vlgrp, i, v_netdev);
- }
}
-tso_out:
dev_info(&adapter->pdev->dev, "TSO is %s\n",
data ? "Enabled" : "Disabled");
- adapter->flags |= FLAG_TSO_FORCE;
return 0;
}
@@ -517,6 +519,8 @@ static const struct ethtool_ops igbvf_ethtool_ops = {
.set_ringparam = igbvf_set_ringparam,
.get_pauseparam = igbvf_get_pauseparam,
.set_pauseparam = igbvf_set_pauseparam,
+ .get_rx_csum = igbvf_get_rx_csum,
+ .set_rx_csum = igbvf_set_rx_csum,
.get_tx_csum = igbvf_get_tx_csum,
.set_tx_csum = igbvf_set_tx_csum,
.get_sg = ethtool_op_get_sg,
diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h
index d488733893a..8e9b67ebbf8 100644
--- a/drivers/net/igbvf/igbvf.h
+++ b/drivers/net/igbvf/igbvf.h
@@ -286,11 +286,7 @@ struct igbvf_info {
};
/* hardware capability, feature, and workaround flags */
-#define FLAG_HAS_HW_VLAN_FILTER (1 << 0)
-#define FLAG_HAS_JUMBO_FRAMES (1 << 1)
-#define FLAG_MSI_ENABLED (1 << 2)
-#define FLAG_RX_CSUM_ENABLED (1 << 3)
-#define FLAG_TSO_FORCE (1 << 4)
+#define IGBVF_FLAG_RX_CSUM_DISABLED (1 << 0)
#define IGBVF_RX_DESC_ADV(R, i) \
(&((((R).desc))[i].rx_desc))
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index b774666ad3c..22aadb7884f 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -58,8 +58,7 @@ static void igbvf_reset_interrupt_capability(struct igbvf_adapter *);
static struct igbvf_info igbvf_vf_info = {
.mac = e1000_vfadapt,
- .flags = FLAG_HAS_JUMBO_FRAMES
- | FLAG_RX_CSUM_ENABLED,
+ .flags = 0,
.pba = 10,
.init_ops = e1000_init_function_pointers_vf,
};
@@ -107,8 +106,10 @@ static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,
skb->ip_summed = CHECKSUM_NONE;
/* Ignore Checksum bit is set or checksum is disabled through ethtool */
- if ((status_err & E1000_RXD_STAT_IXSM))
+ if ((status_err & E1000_RXD_STAT_IXSM) ||
+ (adapter->flags & IGBVF_FLAG_RX_CSUM_DISABLED))
return;
+
/* TCP/UDP checksum error bit is set */
if (status_err &
(E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) {
@@ -116,6 +117,7 @@ static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,
adapter->hw_csum_err++;
return;
}
+
/* It must be a TCP or UDP packet with a valid checksum */
if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2117,8 +2119,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter,
/* set time_stamp *before* dma to help avoid a possible race */
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
- buffer_info->dma = map[count];
- count++;
+ buffer_info->dma = skb_shinfo(skb)->dma_head;
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
struct skb_frag_struct *frag;
@@ -2142,7 +2143,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter,
tx_ring->buffer_info[i].skb = skb;
tx_ring->buffer_info[first].next_to_watch = i;
- return count;
+ return count + 1;
}
static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter,
@@ -2268,7 +2269,6 @@ static int igbvf_xmit_frame_ring_adv(struct sk_buff *skb,
if (count) {
igbvf_tx_queue_adv(adapter, tx_ring, tx_flags, count,
skb->len, hdr_len);
- netdev->trans_start = jiffies;
/* Make sure there is space in the ring for the next send. */
igbvf_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 4);
} else {
@@ -2351,15 +2351,6 @@ static int igbvf_change_mtu(struct net_device *netdev, int new_mtu)
return -EINVAL;
}
- /* Jumbo frame size limits */
- if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
- if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
- dev_err(&adapter->pdev->dev,
- "Jumbo Frames not supported.\n");
- return -EINVAL;
- }
- }
-
#define MAX_STD_JUMBO_FRAME_SIZE 9234
if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
dev_err(&adapter->pdev->dev, "MTU > 9216 not supported.\n");
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index c5593f4665a..e3cfefab670 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -530,7 +530,7 @@ static void ioc3_tcpudp_checksum(struct sk_buff *skb, uint32_t hwsum, int len)
* case where the checksum is right the higher layers will still
* drop the packet as appropriate.
*/
- if (eh->h_proto != ntohs(ETH_P_IP))
+ if (eh->h_proto != htons(ETH_P_IP))
return;
ih = (struct iphdr *) ((char *)eh + ETH_HLEN);
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index e6317557a53..f7638422142 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -17,6 +17,51 @@ config IRTTY_SIR
If unsure, say Y.
+config BFIN_SIR
+ tristate "Blackfin SIR on UART"
+ depends on BLACKFIN && IRDA
+ default n
+ help
+ Say Y here if your want to enable SIR function on Blackfin UART
+ devices.
+
+ To activate this driver you can start irattach like:
+ "irattach irda0 -s"
+
+ Saying M, it will be built as a module named bfin_sir.
+
+ Note that you need to turn off one of the serial drivers for SIR
+ to use that UART.
+
+config BFIN_SIR0
+ bool "Blackfin SIR on UART0"
+ depends on BFIN_SIR && !SERIAL_BFIN_UART0
+
+config BFIN_SIR1
+ bool "Blackfin SIR on UART1"
+ depends on BFIN_SIR && !SERIAL_BFIN_UART1 && (!BF531 && !BF532 && !BF533 && !BF561)
+
+config BFIN_SIR2
+ bool "Blackfin SIR on UART2"
+ depends on BFIN_SIR && !SERIAL_BFIN_UART2 && (BF54x || BF538 || BF539)
+
+config BFIN_SIR3
+ bool "Blackfin SIR on UART3"
+ depends on BFIN_SIR && !SERIAL_BFIN_UART3 && (BF54x)
+
+choice
+ prompt "SIR Mode"
+ depends on BFIN_SIR
+ default SIR_BFIN_DMA
+
+config SIR_BFIN_DMA
+ bool "DMA mode"
+ depends on !DMA_UNCACHED_NONE
+
+config SIR_BFIN_PIO
+ bool "PIO mode"
+endchoice
+
comment "Dongle support"
config DONGLE
diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile
index 5d20fde32a2..d82e1e3bd8c 100644
--- a/drivers/net/irda/Makefile
+++ b/drivers/net/irda/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_MCS_FIR) += mcs7780.o
obj-$(CONFIG_AU1000_FIR) += au1k_ir.o
# SIR drivers
obj-$(CONFIG_IRTTY_SIR) += irtty-sir.o sir-dev.o
+obj-$(CONFIG_BFIN_SIR) += bfin_sir.o
# dongle drivers for SIR drivers
obj-$(CONFIG_ESI_DONGLE) += esi-sir.o
obj-$(CONFIG_TEKRAM_DONGLE) += tekram-sir.o
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c
index 941164076a2..c4361d46659 100644
--- a/drivers/net/irda/au1k_ir.c
+++ b/drivers/net/irda/au1k_ir.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <linux/slab.h>
#include <linux/rtnetlink.h>
#include <linux/interrupt.h>
@@ -198,6 +199,17 @@ static int au1k_irda_init_iobuf(iobuff_t *io, int size)
return io->head ? 0 : -ENOMEM;
}
+static const struct net_device_ops au1k_irda_netdev_ops = {
+ .ndo_open = au1k_irda_start,
+ .ndo_stop = au1k_irda_stop,
+ .ndo_start_xmit = au1k_irda_hard_xmit,
+ .ndo_tx_timeout = au1k_tx_timeout,
+ .ndo_do_ioctl = au1k_irda_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int au1k_irda_net_init(struct net_device *dev)
{
struct au1k_private *aup = netdev_priv(dev);
@@ -209,11 +221,7 @@ static int au1k_irda_net_init(struct net_device *dev)
if (err)
goto out1;
- dev->open = au1k_irda_start;
- dev->hard_start_xmit = au1k_irda_hard_xmit;
- dev->stop = au1k_irda_stop;
- dev->do_ioctl = au1k_irda_ioctl;
- dev->tx_timeout = au1k_tx_timeout;
+ dev->netdev_ops = &au1k_irda_netdev_ops;
irda_init_max_qos_capabilies(&aup->qos);
@@ -504,13 +512,13 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
printk(KERN_DEBUG "%s: tx_full\n", dev->name);
netif_stop_queue(dev);
aup->tx_full = 1;
- return 1;
+ return NETDEV_TX_BUSY;
}
else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) {
printk(KERN_DEBUG "%s: tx_full\n", dev->name);
netif_stop_queue(dev);
aup->tx_full = 1;
- return 1;
+ return NETDEV_TX_BUSY;
}
pDB = aup->tx_db_inuse[aup->tx_head];
diff --git a/drivers/net/irda/bfin_sir.c b/drivers/net/irda/bfin_sir.c
new file mode 100644
index 00000000000..f3eed6a8fba
--- /dev/null
+++ b/drivers/net/irda/bfin_sir.c
@@ -0,0 +1,820 @@
+/*
+ * Blackfin Infra-red Driver
+ *
+ * Copyright 2006-2009 Analog Devices Inc.
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ *
+ */
+#include "bfin_sir.h"
+
+#ifdef CONFIG_SIR_BFIN_DMA
+#define DMA_SIR_RX_XCNT 10
+#define DMA_SIR_RX_YCNT (PAGE_SIZE / DMA_SIR_RX_XCNT)
+#define DMA_SIR_RX_FLUSH_JIFS (HZ * 4 / 250)
+#endif
+
+#if ANOMALY_05000447
+static int max_rate = 57600;
+#else
+static int max_rate = 115200;
+#endif
+
+static void turnaround_delay(unsigned long last_jif, int mtt)
+{
+ long ticks;
+
+ mtt = mtt < 10000 ? 10000 : mtt;
+ ticks = 1 + mtt / (USEC_PER_SEC / HZ);
+ schedule_timeout_uninterruptible(ticks);
+}
+
+static void __devinit bfin_sir_init_ports(struct bfin_sir_port *sp, struct platform_device *pdev)
+{
+ int i;
+ struct resource *res;
+
+ for (i = 0; i < pdev->num_resources; i++) {
+ res = &pdev->resource[i];
+ switch (res->flags) {
+ case IORESOURCE_MEM:
+ sp->membase = (void __iomem *)res->start;
+ break;
+ case IORESOURCE_IRQ:
+ sp->irq = res->start;
+ break;
+ case IORESOURCE_DMA:
+ sp->rx_dma_channel = res->start;
+ sp->tx_dma_channel = res->end;
+ break;
+ default:
+ break;
+ }
+ }
+
+ sp->clk = get_sclk();
+#ifdef CONFIG_SIR_BFIN_DMA
+ sp->tx_done = 1;
+ init_timer(&(sp->rx_dma_timer));
+#endif
+}
+
+static void bfin_sir_stop_tx(struct bfin_sir_port *port)
+{
+#ifdef CONFIG_SIR_BFIN_DMA
+ disable_dma(port->tx_dma_channel);
+#endif
+
+ while (!(SIR_UART_GET_LSR(port) & THRE)) {
+ cpu_relax();
+ continue;
+ }
+
+ SIR_UART_STOP_TX(port);
+}
+
+static void bfin_sir_enable_tx(struct bfin_sir_port *port)
+{
+ SIR_UART_ENABLE_TX(port);
+}
+
+static void bfin_sir_stop_rx(struct bfin_sir_port *port)
+{
+ SIR_UART_STOP_RX(port);
+}
+
+static void bfin_sir_enable_rx(struct bfin_sir_port *port)
+{
+ SIR_UART_ENABLE_RX(port);
+}
+
+static int bfin_sir_set_speed(struct bfin_sir_port *port, int speed)
+{
+ int ret = -EINVAL;
+ unsigned int quot;
+ unsigned short val, lsr, lcr;
+ static int utime;
+ int count = 10;
+
+ lcr = WLS(8);
+
+ switch (speed) {
+ case 9600:
+ case 19200:
+ case 38400:
+ case 57600:
+ case 115200:
+
+ quot = (port->clk + (8 * speed)) / (16 * speed)\
+ - ANOMALY_05000230;
+
+ do {
+ udelay(utime);
+ lsr = SIR_UART_GET_LSR(port);
+ } while (!(lsr & TEMT) && count--);
+
+ /* The useconds for 1 bits to transmit */
+ utime = 1000000 / speed + 1;
+
+ /* Clear UCEN bit to reset the UART state machine
+ * and control registers
+ */
+ val = SIR_UART_GET_GCTL(port);
+ val &= ~UCEN;
+ SIR_UART_PUT_GCTL(port, val);
+
+ /* Set DLAB in LCR to Access THR RBR IER */
+ SIR_UART_SET_DLAB(port);
+ SSYNC();
+
+ SIR_UART_PUT_DLL(port, quot & 0xFF);
+ SIR_UART_PUT_DLH(port, (quot >> 8) & 0xFF);
+ SSYNC();
+
+ /* Clear DLAB in LCR */
+ SIR_UART_CLEAR_DLAB(port);
+ SSYNC();
+
+ SIR_UART_PUT_LCR(port, lcr);
+
+ val = SIR_UART_GET_GCTL(port);
+ val |= UCEN;
+ SIR_UART_PUT_GCTL(port, val);
+
+ ret = 0;
+ break;
+ default:
+ printk(KERN_WARNING "bfin_sir: Invalid speed %d\n", speed);
+ break;
+ }
+
+ val = SIR_UART_GET_GCTL(port);
+ /* If not add the 'RPOLC', we can't catch the receive interrupt.
+ * It's related with the HW layout and the IR transiver.
+ */
+ val |= IREN | RPOLC;
+ SIR_UART_PUT_GCTL(port, val);
+ return ret;
+}
+
+static int bfin_sir_is_receiving(struct net_device *dev)
+{
+ struct bfin_sir_self *self = netdev_priv(dev);
+ struct bfin_sir_port *port = self->sir_port;
+
+ if (!(SIR_UART_GET_IER(port) & ERBFI))
+ return 0;
+ return self->rx_buff.state != OUTSIDE_FRAME;
+}
+
+#ifdef CONFIG_SIR_BFIN_PIO
+static void bfin_sir_tx_chars(struct net_device *dev)
+{
+ unsigned int chr;
+ struct bfin_sir_self *self = netdev_priv(dev);
+ struct bfin_sir_port *port = self->sir_port;
+
+ if (self->tx_buff.len != 0) {
+ chr = *(self->tx_buff.data);
+ SIR_UART_PUT_CHAR(port, chr);
+ self->tx_buff.data++;
+ self->tx_buff.len--;
+ } else {
+ self->stats.tx_packets++;
+ self->stats.tx_bytes += self->tx_buff.data - self->tx_buff.head;
+ if (self->newspeed) {
+ bfin_sir_set_speed(port, self->newspeed);
+ self->speed = self->newspeed;
+ self->newspeed = 0;
+ }
+ bfin_sir_stop_tx(port);
+ bfin_sir_enable_rx(port);
+ /* I'm hungry! */
+ netif_wake_queue(dev);
+ }
+}
+
+static void bfin_sir_rx_chars(struct net_device *dev)
+{
+ struct bfin_sir_self *self = netdev_priv(dev);
+ struct bfin_sir_port *port = self->sir_port;
+ unsigned char ch;
+
+ SIR_UART_CLEAR_LSR(port);
+ ch = SIR_UART_GET_CHAR(port);
+ async_unwrap_char(dev, &self->stats, &self->rx_buff, ch);
+ dev->last_rx = jiffies;
+}
+
+static irqreturn_t bfin_sir_rx_int(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct bfin_sir_self *self = netdev_priv(dev);
+ struct bfin_sir_port *port = self->sir_port;
+
+ spin_lock(&self->lock);
+ while ((SIR_UART_GET_LSR(port) & DR))
+ bfin_sir_rx_chars(dev);
+ spin_unlock(&self->lock);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t bfin_sir_tx_int(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct bfin_sir_self *self = netdev_priv(dev);
+ struct bfin_sir_port *port = self->sir_port;
+
+ spin_lock(&self->lock);
+ if (SIR_UART_GET_LSR(port) & THRE)
+ bfin_sir_tx_chars(dev);
+ spin_unlock(&self->lock);
+
+ return IRQ_HANDLED;
+}
+#endif /* CONFIG_SIR_BFIN_PIO */
+
+#ifdef CONFIG_SIR_BFIN_DMA
+static void bfin_sir_dma_tx_chars(struct net_device *dev)
+{
+ struct bfin_sir_self *self = netdev_priv(dev);
+ struct bfin_sir_port *port = self->sir_port;
+
+ if (!port->tx_done)
+ return;
+ port->tx_done = 0;
+
+ if (self->tx_buff.len == 0) {
+ self->stats.tx_packets++;
+ if (self->newspeed) {
+ bfin_sir_set_speed(port, self->newspeed);
+ self->speed = self->newspeed;
+ self->newspeed = 0;
+ }
+ bfin_sir_enable_rx(port);
+ port->tx_done = 1;
+ netif_wake_queue(dev);
+ return;
+ }
+
+ blackfin_dcache_flush_range((unsigned long)(self->tx_buff.data),
+ (unsigned long)(self->tx_buff.data+self->tx_buff.len));
+ set_dma_config(port->tx_dma_channel,
+ set_bfin_dma_config(DIR_READ, DMA_FLOW_STOP,
+ INTR_ON_BUF, DIMENSION_LINEAR, DATA_SIZE_8,
+ DMA_SYNC_RESTART));
+ set_dma_start_addr(port->tx_dma_channel,
+ (unsigned long)(self->tx_buff.data));
+ set_dma_x_count(port->tx_dma_channel, self->tx_buff.len);
+ set_dma_x_modify(port->tx_dma_channel, 1);
+ enable_dma(port->tx_dma_channel);
+}
+
+static irqreturn_t bfin_sir_dma_tx_int(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct bfin_sir_self *self = netdev_priv(dev);
+ struct bfin_sir_port *port = self->sir_port;
+
+ spin_lock(&self->lock);
+ if (!(get_dma_curr_irqstat(port->tx_dma_channel) & DMA_RUN)) {
+ clear_dma_irqstat(port->tx_dma_channel);
+ bfin_sir_stop_tx(port);
+
+ self->stats.tx_packets++;
+ self->stats.tx_bytes += self->tx_buff.len;
+ self->tx_buff.len = 0;
+ if (self->newspeed) {
+ bfin_sir_set_speed(port, self->newspeed);
+ self->speed = self->newspeed;
+ self->newspeed = 0;
+ }
+ bfin_sir_enable_rx(port);
+ /* I'm hungry! */
+ netif_wake_queue(dev);
+ port->tx_done = 1;
+ }
+ spin_unlock(&self->lock);
+
+ return IRQ_HANDLED;
+}
+
+static void bfin_sir_dma_rx_chars(struct net_device *dev)
+{
+ struct bfin_sir_self *self = netdev_priv(dev);
+ struct bfin_sir_port *port = self->sir_port;
+ int i;
+
+ SIR_UART_CLEAR_LSR(port);
+
+ for (i = port->rx_dma_buf.head; i < port->rx_dma_buf.tail; i++)
+ async_unwrap_char(dev, &self->stats, &self->rx_buff, port->rx_dma_buf.buf[i]);
+}
+
+void bfin_sir_rx_dma_timeout(struct net_device *dev)
+{
+ struct bfin_sir_self *self = netdev_priv(dev);
+ struct bfin_sir_port *port = self->sir_port;
+ int x_pos, pos;
+ unsigned long flags;
+
+ spin_lock_irqsave(&self->lock, flags);
+ x_pos = DMA_SIR_RX_XCNT - get_dma_curr_xcount(port->rx_dma_channel);
+ if (x_pos == DMA_SIR_RX_XCNT)
+ x_pos = 0;
+
+ pos = port->rx_dma_nrows * DMA_SIR_RX_XCNT + x_pos;
+
+ if (pos > port->rx_dma_buf.tail) {
+ port->rx_dma_buf.tail = pos;
+ bfin_sir_dma_rx_chars(dev);
+ port->rx_dma_buf.head = port->rx_dma_buf.tail;
+ }
+ spin_unlock_irqrestore(&self->lock, flags);
+}
+
+static irqreturn_t bfin_sir_dma_rx_int(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct bfin_sir_self *self = netdev_priv(dev);
+ struct bfin_sir_port *port = self->sir_port;
+ unsigned short irqstat;
+
+ spin_lock(&self->lock);
+
+ port->rx_dma_nrows++;
+ port->rx_dma_buf.tail = DMA_SIR_RX_XCNT * port->rx_dma_nrows;
+ bfin_sir_dma_rx_chars(dev);
+ if (port->rx_dma_nrows >= DMA_SIR_RX_YCNT) {
+ port->rx_dma_nrows = 0;
+ port->rx_dma_buf.tail = 0;
+ }
+ port->rx_dma_buf.head = port->rx_dma_buf.tail;
+
+ irqstat = get_dma_curr_irqstat(port->rx_dma_channel);
+ clear_dma_irqstat(port->rx_dma_channel);
+ spin_unlock(&self->lock);
+
+ mod_timer(&port->rx_dma_timer, jiffies + DMA_SIR_RX_FLUSH_JIFS);
+ return IRQ_HANDLED;
+}
+#endif /* CONFIG_SIR_BFIN_DMA */
+
+static int bfin_sir_startup(struct bfin_sir_port *port, struct net_device *dev)
+{
+#ifdef CONFIG_SIR_BFIN_DMA
+ dma_addr_t dma_handle;
+#endif /* CONFIG_SIR_BFIN_DMA */
+
+ if (request_dma(port->rx_dma_channel, "BFIN_UART_RX") < 0) {
+ dev_warn(&dev->dev, "Unable to attach SIR RX DMA channel\n");
+ return -EBUSY;
+ }
+
+ if (request_dma(port->tx_dma_channel, "BFIN_UART_TX") < 0) {
+ dev_warn(&dev->dev, "Unable to attach SIR TX DMA channel\n");
+ free_dma(port->rx_dma_channel);
+ return -EBUSY;
+ }
+
+#ifdef CONFIG_SIR_BFIN_DMA
+
+ set_dma_callback(port->rx_dma_channel, bfin_sir_dma_rx_int, dev);
+ set_dma_callback(port->tx_dma_channel, bfin_sir_dma_tx_int, dev);
+
+ port->rx_dma_buf.buf = (unsigned char *)dma_alloc_coherent(NULL, PAGE_SIZE, &dma_handle, GFP_DMA);
+ port->rx_dma_buf.head = 0;
+ port->rx_dma_buf.tail = 0;
+ port->rx_dma_nrows = 0;
+
+ set_dma_config(port->rx_dma_channel,
+ set_bfin_dma_config(DIR_WRITE, DMA_FLOW_AUTO,
+ INTR_ON_ROW, DIMENSION_2D,
+ DATA_SIZE_8, DMA_SYNC_RESTART));
+ set_dma_x_count(port->rx_dma_channel, DMA_SIR_RX_XCNT);
+ set_dma_x_modify(port->rx_dma_channel, 1);
+ set_dma_y_count(port->rx_dma_channel, DMA_SIR_RX_YCNT);
+ set_dma_y_modify(port->rx_dma_channel, 1);
+ set_dma_start_addr(port->rx_dma_channel, (unsigned long)port->rx_dma_buf.buf);
+ enable_dma(port->rx_dma_channel);
+
+ port->rx_dma_timer.data = (unsigned long)(dev);
+ port->rx_dma_timer.function = (void *)bfin_sir_rx_dma_timeout;
+
+#else
+
+ if (request_irq(port->irq, bfin_sir_rx_int, IRQF_DISABLED, "BFIN_SIR_RX", dev)) {
+ dev_warn(&dev->dev, "Unable to attach SIR RX interrupt\n");
+ return -EBUSY;
+ }
+
+ if (request_irq(port->irq+1, bfin_sir_tx_int, IRQF_DISABLED, "BFIN_SIR_TX", dev)) {
+ dev_warn(&dev->dev, "Unable to attach SIR TX interrupt\n");
+ free_irq(port->irq, dev);
+ return -EBUSY;
+ }
+#endif
+
+ return 0;
+}
+
+static void bfin_sir_shutdown(struct bfin_sir_port *port, struct net_device *dev)
+{
+ unsigned short val;
+
+ bfin_sir_stop_rx(port);
+ SIR_UART_DISABLE_INTS(port);
+
+ val = SIR_UART_GET_GCTL(port);
+ val &= ~(UCEN | IREN | RPOLC);
+ SIR_UART_PUT_GCTL(port, val);
+
+#ifdef CONFIG_SIR_BFIN_DMA
+ disable_dma(port->tx_dma_channel);
+ disable_dma(port->rx_dma_channel);
+ del_timer(&(port->rx_dma_timer));
+ dma_free_coherent(NULL, PAGE_SIZE, port->rx_dma_buf.buf, 0);
+#else
+ free_irq(port->irq+1, dev);
+ free_irq(port->irq, dev);
+#endif
+ free_dma(port->tx_dma_channel);
+ free_dma(port->rx_dma_channel);
+}
+
+#ifdef CONFIG_PM
+static int bfin_sir_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct bfin_sir_port *sir_port;
+ struct net_device *dev;
+ struct bfin_sir_self *self;
+
+ sir_port = platform_get_drvdata(pdev);
+ if (!sir_port)
+ return 0;
+
+ dev = sir_port->dev;
+ self = netdev_priv(dev);
+ if (self->open) {
+ flush_work(&self->work);
+ bfin_sir_shutdown(self->sir_port, dev);
+ netif_device_detach(dev);
+ }
+
+ return 0;
+}
+static int bfin_sir_resume(struct platform_device *pdev)
+{
+ struct bfin_sir_port *sir_port;
+ struct net_device *dev;
+ struct bfin_sir_self *self;
+ struct bfin_sir_port *port;
+
+ sir_port = platform_get_drvdata(pdev);
+ if (!sir_port)
+ return 0;
+
+ dev = sir_port->dev;
+ self = netdev_priv(dev);
+ port = self->sir_port;
+ if (self->open) {
+ if (self->newspeed) {
+ self->speed = self->newspeed;
+ self->newspeed = 0;
+ }
+ bfin_sir_startup(port, dev);
+ bfin_sir_set_speed(port, 9600);
+ bfin_sir_enable_rx(port);
+ netif_device_attach(dev);
+ }
+ return 0;
+}
+#else
+#define bfin_sir_suspend NULL
+#define bfin_sir_resume NULL
+#endif
+
+static void bfin_sir_send_work(struct work_struct *work)
+{
+ struct bfin_sir_self *self = container_of(work, struct bfin_sir_self, work);
+ struct net_device *dev = self->sir_port->dev;
+ struct bfin_sir_port *port = self->sir_port;
+ unsigned short val;
+ int tx_cnt = 10;
+
+ while (bfin_sir_is_receiving(dev) && --tx_cnt)
+ turnaround_delay(dev->last_rx, self->mtt);
+
+ bfin_sir_stop_rx(port);
+
+ /* To avoid losting RX interrupt, we reset IR function before
+ * sending data. We also can set the speed, which will
+ * reset all the UART.
+ */
+ val = SIR_UART_GET_GCTL(port);
+ val &= ~(IREN | RPOLC);
+ SIR_UART_PUT_GCTL(port, val);
+ SSYNC();
+ val |= IREN | RPOLC;
+ SIR_UART_PUT_GCTL(port, val);
+ SSYNC();
+ /* bfin_sir_set_speed(port, self->speed); */
+
+#ifdef CONFIG_SIR_BFIN_DMA
+ bfin_sir_dma_tx_chars(dev);
+#endif
+ bfin_sir_enable_tx(port);
+ dev->trans_start = jiffies;
+}
+
+static int bfin_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct bfin_sir_self *self = netdev_priv(dev);
+ int speed = irda_get_next_speed(skb);
+
+ netif_stop_queue(dev);
+
+ self->mtt = irda_get_mtt(skb);
+
+ if (speed != self->speed && speed != -1)
+ self->newspeed = speed;
+
+ self->tx_buff.data = self->tx_buff.head;
+ if (skb->len == 0)
+ self->tx_buff.len = 0;
+ else
+ self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, self->tx_buff.truesize);
+
+ schedule_work(&self->work);
+ dev_kfree_skb(skb);
+
+ return 0;
+}
+
+static int bfin_sir_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
+{
+ struct if_irda_req *rq = (struct if_irda_req *)ifreq;
+ struct bfin_sir_self *self = netdev_priv(dev);
+ struct bfin_sir_port *port = self->sir_port;
+ int ret = 0;
+
+ switch (cmd) {
+ case SIOCSBANDWIDTH:
+ if (capable(CAP_NET_ADMIN)) {
+ if (self->open) {
+ ret = bfin_sir_set_speed(port, rq->ifr_baudrate);
+ bfin_sir_enable_rx(port);
+ } else {
+ dev_warn(&dev->dev, "SIOCSBANDWIDTH: !netif_running\n");
+ ret = 0;
+ }
+ }
+ break;
+
+ case SIOCSMEDIABUSY:
+ ret = -EPERM;
+ if (capable(CAP_NET_ADMIN)) {
+ irda_device_set_media_busy(dev, TRUE);
+ ret = 0;
+ }
+ break;
+
+ case SIOCGRECEIVING:
+ rq->ifr_receiving = bfin_sir_is_receiving(dev);
+ break;
+
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ return ret;
+}
+
+static struct net_device_stats *bfin_sir_stats(struct net_device *dev)
+{
+ struct bfin_sir_self *self = netdev_priv(dev);
+
+ return &self->stats;
+}
+
+static int bfin_sir_open(struct net_device *dev)
+{
+ struct bfin_sir_self *self = netdev_priv(dev);
+ struct bfin_sir_port *port = self->sir_port;
+ int err = -ENOMEM;
+
+ self->newspeed = 0;
+ self->speed = 9600;
+
+ spin_lock_init(&self->lock);
+
+ err = bfin_sir_startup(port, dev);
+ if (err)
+ goto err_startup;
+
+ bfin_sir_set_speed(port, 9600);
+
+ self->irlap = irlap_open(dev, &self->qos, DRIVER_NAME);
+ if (!self->irlap)
+ goto err_irlap;
+
+ INIT_WORK(&self->work, bfin_sir_send_work);
+
+ /*
+ * Now enable the interrupt then start the queue
+ */
+ self->open = 1;
+ bfin_sir_enable_rx(port);
+
+ netif_start_queue(dev);
+
+ return 0;
+
+err_irlap:
+ self->open = 0;
+ bfin_sir_shutdown(port, dev);
+err_startup:
+ return err;
+}
+
+static int bfin_sir_stop(struct net_device *dev)
+{
+ struct bfin_sir_self *self = netdev_priv(dev);
+
+ flush_work(&self->work);
+ bfin_sir_shutdown(self->sir_port, dev);
+
+ if (self->rxskb) {
+ dev_kfree_skb(self->rxskb);
+ self->rxskb = NULL;
+ }
+
+ /* Stop IrLAP */
+ if (self->irlap) {
+ irlap_close(self->irlap);
+ self->irlap = NULL;
+ }
+
+ netif_stop_queue(dev);
+ self->open = 0;
+
+ return 0;
+}
+
+static int bfin_sir_init_iobuf(iobuff_t *io, int size)
+{
+ io->head = kmalloc(size, GFP_KERNEL);
+ if (!io->head)
+ return -ENOMEM;
+ io->truesize = size;
+ io->in_frame = FALSE;
+ io->state = OUTSIDE_FRAME;
+ io->data = io->head;
+ return 0;
+}
+
+static int __devinit bfin_sir_probe(struct platform_device *pdev)
+{
+ struct net_device *dev;
+ struct bfin_sir_self *self;
+ unsigned int baudrate_mask;
+ struct bfin_sir_port *sir_port;
+ int err;
+
+ if (pdev->id >= 0 && pdev->id < ARRAY_SIZE(per) && \
+ per[pdev->id][3] == pdev->id) {
+ err = peripheral_request_list(per[pdev->id], DRIVER_NAME);
+ if (err)
+ return err;
+ } else {
+ dev_err(&pdev->dev, "Invalid pdev id, please check board file\n");
+ return -ENODEV;
+ }
+
+ err = -ENOMEM;
+ sir_port = kmalloc(sizeof(*sir_port), GFP_KERNEL);
+ if (!sir_port)
+ goto err_mem_0;
+
+ bfin_sir_init_ports(sir_port, pdev);
+
+ dev = alloc_irdadev(sizeof(*self));
+ if (!dev)
+ goto err_mem_1;
+
+ self = netdev_priv(dev);
+ self->dev = &pdev->dev;
+ self->sir_port = sir_port;
+ sir_port->dev = dev;
+
+ err = bfin_sir_init_iobuf(&self->rx_buff, IRDA_SKB_MAX_MTU);
+ if (err)
+ goto err_mem_2;
+ err = bfin_sir_init_iobuf(&self->tx_buff, IRDA_SIR_MAX_FRAME);
+ if (err)
+ goto err_mem_3;
+
+ dev->hard_start_xmit = bfin_sir_hard_xmit;
+ dev->open = bfin_sir_open;
+ dev->stop = bfin_sir_stop;
+ dev->do_ioctl = bfin_sir_ioctl;
+ dev->get_stats = bfin_sir_stats;
+ dev->irq = sir_port->irq;
+
+ irda_init_max_qos_capabilies(&self->qos);
+
+ baudrate_mask = IR_9600;
+
+ switch (max_rate) {
+ case 115200:
+ baudrate_mask |= IR_115200;
+ case 57600:
+ baudrate_mask |= IR_57600;
+ case 38400:
+ baudrate_mask |= IR_38400;
+ case 19200:
+ baudrate_mask |= IR_19200;
+ case 9600:
+ break;
+ default:
+ dev_warn(&pdev->dev, "Invalid maximum baud rate, using 9600\n");
+ }
+
+ self->qos.baud_rate.bits &= baudrate_mask;
+
+ self->qos.min_turn_time.bits = 1; /* 10 ms or more */
+
+ irda_qos_bits_to_value(&self->qos);
+
+ err = register_netdev(dev);
+
+ if (err) {
+ kfree(self->tx_buff.head);
+err_mem_3:
+ kfree(self->rx_buff.head);
+err_mem_2:
+ free_netdev(dev);
+err_mem_1:
+ kfree(sir_port);
+err_mem_0:
+ peripheral_free_list(per[pdev->id]);
+ } else
+ platform_set_drvdata(pdev, sir_port);
+
+ return err;
+}
+
+static int __devexit bfin_sir_remove(struct platform_device *pdev)
+{
+ struct bfin_sir_port *sir_port;
+ struct net_device *dev = NULL;
+ struct bfin_sir_self *self;
+
+ sir_port = platform_get_drvdata(pdev);
+ if (!sir_port)
+ return 0;
+ dev = sir_port->dev;
+ self = netdev_priv(dev);
+ unregister_netdev(dev);
+ kfree(self->tx_buff.head);
+ kfree(self->rx_buff.head);
+ free_netdev(dev);
+ kfree(sir_port);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver bfin_ir_driver = {
+ .probe = bfin_sir_probe,
+ .remove = __devexit_p(bfin_sir_remove),
+ .suspend = bfin_sir_suspend,
+ .resume = bfin_sir_resume,
+ .driver = {
+ .name = DRIVER_NAME,
+ },
+};
+
+static int __init bfin_sir_init(void)
+{
+ return platform_driver_register(&bfin_ir_driver);
+}
+
+static void __exit bfin_sir_exit(void)
+{
+ platform_driver_unregister(&bfin_ir_driver);
+}
+
+module_init(bfin_sir_init);
+module_exit(bfin_sir_exit);
+
+module_param(max_rate, int, 0);
+MODULE_PARM_DESC(max_rate, "Maximum baud rate (115200, 57600, 38400, 19200, 9600)");
+
+MODULE_AUTHOR("Graf Yang <graf.yang@analog.com>");
+MODULE_DESCRIPTION("Blackfin IrDA driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/irda/bfin_sir.h b/drivers/net/irda/bfin_sir.h
new file mode 100644
index 00000000000..dac71b1f4f9
--- /dev/null
+++ b/drivers/net/irda/bfin_sir.h
@@ -0,0 +1,148 @@
+/*
+ * Blackfin Infra-red Driver
+ *
+ * Copyright 2006-2009 Analog Devices Inc.
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ *
+ */
+
+#include <linux/serial.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/wrapper.h>
+#include <net/irda/irda_device.h>
+
+#include <asm/irq.h>
+#include <asm/cacheflush.h>
+#include <asm/dma.h>
+#include <asm/portmux.h>
+
+#ifdef CONFIG_SIR_BFIN_DMA
+struct dma_rx_buf {
+ char *buf;
+ int head;
+ int tail;
+};
+#endif
+
+struct bfin_sir_port {
+ unsigned char __iomem *membase;
+ unsigned int irq;
+ unsigned int lsr;
+ unsigned long clk;
+ struct net_device *dev;
+#ifdef CONFIG_SIR_BFIN_DMA
+ int tx_done;
+ struct dma_rx_buf rx_dma_buf;
+ struct timer_list rx_dma_timer;
+ int rx_dma_nrows;
+#endif
+ unsigned int tx_dma_channel;
+ unsigned int rx_dma_channel;
+};
+
+struct bfin_sir_port_res {
+ unsigned long base_addr;
+ int irq;
+ unsigned int rx_dma_channel;
+ unsigned int tx_dma_channel;
+};
+
+struct bfin_sir_self {
+ struct bfin_sir_port *sir_port;
+ spinlock_t lock;
+ unsigned int open;
+ int speed;
+ int newspeed;
+
+ struct sk_buff *txskb;
+ struct sk_buff *rxskb;
+ struct net_device_stats stats;
+ struct device *dev;
+ struct irlap_cb *irlap;
+ struct qos_info qos;
+
+ iobuff_t tx_buff;
+ iobuff_t rx_buff;
+
+ struct work_struct work;
+ int mtt;
+};
+
+#define DRIVER_NAME "bfin_sir"
+
+#define SIR_UART_GET_CHAR(port) bfin_read16((port)->membase + OFFSET_RBR)
+#define SIR_UART_GET_DLL(port) bfin_read16((port)->membase + OFFSET_DLL)
+#define SIR_UART_GET_DLH(port) bfin_read16((port)->membase + OFFSET_DLH)
+#define SIR_UART_GET_LCR(port) bfin_read16((port)->membase + OFFSET_LCR)
+#define SIR_UART_GET_GCTL(port) bfin_read16((port)->membase + OFFSET_GCTL)
+
+#define SIR_UART_PUT_CHAR(port, v) bfin_write16(((port)->membase + OFFSET_THR), v)
+#define SIR_UART_PUT_DLL(port, v) bfin_write16(((port)->membase + OFFSET_DLL), v)
+#define SIR_UART_PUT_DLH(port, v) bfin_write16(((port)->membase + OFFSET_DLH), v)
+#define SIR_UART_PUT_LCR(port, v) bfin_write16(((port)->membase + OFFSET_LCR), v)
+#define SIR_UART_PUT_GCTL(port, v) bfin_write16(((port)->membase + OFFSET_GCTL), v)
+
+#ifdef CONFIG_BF54x
+#define SIR_UART_GET_LSR(port) bfin_read16((port)->membase + OFFSET_LSR)
+#define SIR_UART_GET_IER(port) bfin_read16((port)->membase + OFFSET_IER_SET)
+#define SIR_UART_SET_IER(port, v) bfin_write16(((port)->membase + OFFSET_IER_SET), v)
+#define SIR_UART_CLEAR_IER(port, v) bfin_write16(((port)->membase + OFFSET_IER_CLEAR), v)
+#define SIR_UART_PUT_LSR(port, v) bfin_write16(((port)->membase + OFFSET_LSR), v)
+#define SIR_UART_CLEAR_LSR(port) bfin_write16(((port)->membase + OFFSET_LSR), -1)
+
+#define SIR_UART_SET_DLAB(port)
+#define SIR_UART_CLEAR_DLAB(port)
+
+#define SIR_UART_ENABLE_INTS(port, v) SIR_UART_SET_IER(port, v)
+#define SIR_UART_DISABLE_INTS(port) SIR_UART_CLEAR_IER(port, 0xF)
+#define SIR_UART_STOP_TX(port) do { SIR_UART_PUT_LSR(port, TFI); SIR_UART_CLEAR_IER(port, ETBEI); } while (0)
+#define SIR_UART_ENABLE_TX(port) do { SIR_UART_SET_IER(port, ETBEI); } while (0)
+#define SIR_UART_STOP_RX(port) do { SIR_UART_CLEAR_IER(port, ERBFI); } while (0)
+#define SIR_UART_ENABLE_RX(port) do { SIR_UART_SET_IER(port, ERBFI); } while (0)
+#else
+
+#define SIR_UART_GET_IIR(port) bfin_read16((port)->membase + OFFSET_IIR)
+#define SIR_UART_GET_IER(port) bfin_read16((port)->membase + OFFSET_IER)
+#define SIR_UART_PUT_IER(port, v) bfin_write16(((port)->membase + OFFSET_IER), v)
+
+#define SIR_UART_SET_DLAB(port) do { SIR_UART_PUT_LCR(port, SIR_UART_GET_LCR(port) | DLAB); } while (0)
+#define SIR_UART_CLEAR_DLAB(port) do { SIR_UART_PUT_LCR(port, SIR_UART_GET_LCR(port) & ~DLAB); } while (0)
+
+#define SIR_UART_ENABLE_INTS(port, v) SIR_UART_PUT_IER(port, v)
+#define SIR_UART_DISABLE_INTS(port) SIR_UART_PUT_IER(port, 0)
+#define SIR_UART_STOP_TX(port) do { SIR_UART_PUT_IER(port, SIR_UART_GET_IER(port) & ~ETBEI); } while (0)
+#define SIR_UART_ENABLE_TX(port) do { SIR_UART_PUT_IER(port, SIR_UART_GET_IER(port) | ETBEI); } while (0)
+#define SIR_UART_STOP_RX(port) do { SIR_UART_PUT_IER(port, SIR_UART_GET_IER(port) & ~ERBFI); } while (0)
+#define SIR_UART_ENABLE_RX(port) do { SIR_UART_PUT_IER(port, SIR_UART_GET_IER(port) | ERBFI); } while (0)
+
+static inline unsigned int SIR_UART_GET_LSR(struct bfin_sir_port *port)
+{
+ unsigned int lsr = bfin_read16(port->membase + OFFSET_LSR);
+ port->lsr |= (lsr & (BI|FE|PE|OE));
+ return lsr | port->lsr;
+}
+
+static inline void SIR_UART_CLEAR_LSR(struct bfin_sir_port *port)
+{
+ port->lsr = 0;
+ bfin_read16(port->membase + OFFSET_LSR);
+}
+#endif
+
+static const unsigned short per[][4] = {
+ /* rx pin tx pin NULL uart_number */
+ {P_UART0_RX, P_UART0_TX, 0, 0},
+ {P_UART1_RX, P_UART1_TX, 0, 1},
+ {P_UART2_RX, P_UART2_TX, 0, 2},
+ {P_UART3_RX, P_UART3_TX, 0, 3},
+};
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 6b6548b9fda..9a0346e751a 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -994,11 +994,11 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
/* change speed pending, wait for its execution */
if (self->new_speed)
- return -EBUSY;
+ return NETDEV_TX_BUSY;
/* device stopped (apm) wait for restart */
if (self->stopped)
- return -EBUSY;
+ return NETDEV_TX_BUSY;
toshoboe_checkstuck (self);
@@ -1049,7 +1049,7 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
if (self->txpending)
{
spin_unlock_irqrestore(&self->spinlock, flags);
- return -EBUSY;
+ return NETDEV_TX_BUSY;
}
/* If in SIR mode we need to generate a string of XBOFs */
@@ -1105,7 +1105,7 @@ dumpbufs(skb->data,skb->len,'>');
,skb->len, self->ring->tx[self->txs].control, self->txpending);
toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
spin_unlock_irqrestore(&self->spinlock, flags);
- return -EBUSY;
+ return NETDEV_TX_BUSY;
}
if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_SIRON)
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 006ba23110d..0c0831c03f6 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -389,7 +389,6 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
s32 speed;
s16 xbofs;
int res, mtt;
- int err = 1; /* Failed */
IRDA_DEBUG(4, "%s() on %s\n", __func__, netdev->name);
@@ -430,7 +429,6 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
irda_usb_change_speed_xbofs(self);
netdev->trans_start = jiffies;
/* Will netif_wake_queue() in callback */
- err = 0; /* No error */
goto drop;
}
}
@@ -542,7 +540,7 @@ drop:
/* Drop silently the skb and exit */
dev_kfree_skb(skb);
spin_unlock_irqrestore(&self->lock, flags);
- return err; /* Usually 1 */
+ return NETDEV_TX_OK;
}
/*------------------------------------------------------------------*/
@@ -1859,6 +1857,42 @@ static void irda_usb_disconnect(struct usb_interface *intf)
IRDA_DEBUG(0, "%s(), USB IrDA Disconnected\n", __func__);
}
+#ifdef CONFIG_PM
+/* USB suspend, so power off the transmitter/receiver */
+static int irda_usb_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct irda_usb_cb *self = usb_get_intfdata(intf);
+ int i;
+
+ netif_device_detach(self->netdev);
+
+ if (self->tx_urb != NULL)
+ usb_kill_urb(self->tx_urb);
+ if (self->speed_urb != NULL)
+ usb_kill_urb(self->speed_urb);
+ for (i = 0; i < self->max_rx_urb; i++) {
+ if (self->rx_urb[i] != NULL)
+ usb_kill_urb(self->rx_urb[i]);
+ }
+ return 0;
+}
+
+/* Coming out of suspend, so reset hardware */
+static int irda_usb_resume(struct usb_interface *intf)
+{
+ struct irda_usb_cb *self = usb_get_intfdata(intf);
+ int i;
+
+ for (i = 0; i < self->max_rx_urb; i++) {
+ if (self->rx_urb[i] != NULL)
+ usb_submit_urb(self->rx_urb[i], GFP_KERNEL);
+ }
+
+ netif_device_attach(self->netdev);
+ return 0;
+}
+#endif
+
/*------------------------------------------------------------------*/
/*
* USB device callbacks
@@ -1868,6 +1902,10 @@ static struct usb_driver irda_driver = {
.probe = irda_usb_probe,
.disconnect = irda_usb_disconnect,
.id_table = dongles,
+#ifdef CONFIG_PM
+ .suspend = irda_usb_suspend,
+ .resume = irda_usb_resume,
+#endif
};
/************************* MODULE CALLBACKS *************************/
diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c
index 9d813bc4502..c3e4e2c435b 100644
--- a/drivers/net/irda/kingsun-sir.c
+++ b/drivers/net/irda/kingsun-sir.c
@@ -156,9 +156,6 @@ static int kingsun_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
int wraplen;
int ret = 0;
- if (skb == NULL || netdev == NULL)
- return -EINVAL;
-
netif_stop_queue(netdev);
/* the IRDA wrapping routines don't deal with non linear skb */
@@ -197,7 +194,7 @@ static int kingsun_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
dev_kfree_skb(skb);
spin_unlock(&kingsun->lock);
- return ret;
+ return NETDEV_TX_OK;
}
/* Receive callback function */
diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c
index b6ffe9715b6..d73b8b64fcb 100644
--- a/drivers/net/irda/ks959-sir.c
+++ b/drivers/net/irda/ks959-sir.c
@@ -391,9 +391,6 @@ static int ks959_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
unsigned int wraplen;
int ret = 0;
- if (skb == NULL || netdev == NULL)
- return -EINVAL;
-
netif_stop_queue(netdev);
/* the IRDA wrapping routines don't deal with non linear skb */
@@ -428,7 +425,7 @@ static int ks959_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
dev_kfree_skb(skb);
spin_unlock(&kingsun->lock);
- return ret;
+ return NETDEV_TX_OK;
}
/* Receive callback function */
diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/net/irda/ksdazzle-sir.c
index 64df27f2bfd..1ef45ec7442 100644
--- a/drivers/net/irda/ksdazzle-sir.c
+++ b/drivers/net/irda/ksdazzle-sir.c
@@ -304,9 +304,6 @@ static int ksdazzle_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
unsigned int wraplen;
int ret = 0;
- if (skb == NULL || netdev == NULL)
- return -EINVAL;
-
netif_stop_queue(netdev);
/* the IRDA wrapping routines don't deal with non linear skb */
@@ -341,7 +338,7 @@ static int ksdazzle_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
dev_kfree_skb(skb);
spin_unlock(&kingsun->lock);
- return ret;
+ return NETDEV_TX_OK;
}
/* Receive callback function */
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index fac504d0cfd..f4df1001983 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -824,10 +824,6 @@ static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
int wraplen;
int ret = 0;
-
- if (skb == NULL || ndev == NULL)
- return -EINVAL;
-
netif_stop_queue(ndev);
mcs = netdev_priv(ndev);
@@ -870,7 +866,7 @@ static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
dev_kfree_skb(skb);
spin_unlock_irqrestore(&mcs->lock, flags);
- return ret;
+ return NETDEV_TX_OK;
}
static const struct net_device_ops mcs_netdev_ops = {
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index e775338b525..3376a4f39e0 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -14,6 +14,7 @@
*/
#include <linux/module.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
@@ -797,6 +798,16 @@ static int pxa_irda_init_iobuf(iobuff_t *io, int size)
return io->head ? 0 : -ENOMEM;
}
+static const struct net_device_ops pxa_irda_netdev_ops = {
+ .ndo_open = pxa_irda_start,
+ .ndo_stop = pxa_irda_stop,
+ .ndo_start_xmit = pxa_irda_hard_xmit,
+ .ndo_do_ioctl = pxa_irda_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int pxa_irda_probe(struct platform_device *pdev)
{
struct net_device *dev;
@@ -845,10 +856,7 @@ static int pxa_irda_probe(struct platform_device *pdev)
if (err)
goto err_startup;
- dev->hard_start_xmit = pxa_irda_hard_xmit;
- dev->open = pxa_irda_start;
- dev->stop = pxa_irda_stop;
- dev->do_ioctl = pxa_irda_ioctl;
+ dev->netdev_ops = &pxa_irda_netdev_ops;
irda_init_max_qos_capabilies(&si->qos);
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 7a2b003954c..2aeb2e6aec1 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <linux/slab.h>
#include <linux/rtnetlink.h>
#include <linux/interrupt.h>
@@ -875,6 +876,16 @@ static int sa1100_irda_init_iobuf(iobuff_t *io, int size)
return io->head ? 0 : -ENOMEM;
}
+static const struct net_device_ops sa1100_irda_netdev_ops = {
+ .ndo_open = sa1100_irda_start,
+ .ndo_stop = sa1100_irda_stop,
+ .ndo_start_xmit = sa1100_irda_hard_xmit,
+ .ndo_do_ioctl = sa1100_irda_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int sa1100_irda_probe(struct platform_device *pdev)
{
struct net_device *dev;
@@ -913,11 +924,8 @@ static int sa1100_irda_probe(struct platform_device *pdev)
if (err)
goto err_mem_5;
- dev->hard_start_xmit = sa1100_irda_hard_xmit;
- dev->open = sa1100_irda_start;
- dev->stop = sa1100_irda_stop;
- dev->do_ioctl = sa1100_irda_ioctl;
- dev->irq = IRQ_Ser2ICP;
+ dev->netdev_ops = &sa1100_irda_netdev_ops;
+ dev->irq = IRQ_Ser2ICP;
irda_init_max_qos_capabilies(&si->qos);
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index d940809762e..fd0796c3db3 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -607,7 +607,7 @@ static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
* stopped so the network layer will retry after the
* fsm completes and wakes the queue.
*/
- return 1;
+ return NETDEV_TX_BUSY;
}
else if (unlikely(err)) {
/* other fatal error - forget the speed change and
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 59d79807b4d..d0797adb5f8 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -2124,7 +2124,7 @@ static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self)
while (count-- > 0 && !(inb(iobase + UART_LSR) & UART_LSR_TEMT))
udelay(1);
- if (count == 0)
+ if (count < 0)
IRDA_DEBUG(0, "%s(): stuck transmitter\n", __func__);
}
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index cb793c2bade..e44215cb188 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -1021,6 +1021,16 @@ static const struct ethtool_ops ops = {
.get_link = veth_get_link,
};
+static const struct net_device_ops veth_netdev_ops = {
+ .ndo_open = veth_open,
+ .ndo_stop = veth_close,
+ .ndo_start_xmit = veth_start_xmit,
+ .ndo_change_mtu = veth_change_mtu,
+ .ndo_set_multicast_list = veth_set_multicast_list,
+ .ndo_set_mac_address = NULL,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static struct net_device *veth_probe_one(int vlan,
struct vio_dev *vio_dev)
{
@@ -1067,12 +1077,7 @@ static struct net_device *veth_probe_one(int vlan,
memcpy(&port->mac_addr, mac_addr, ETH_ALEN);
- dev->open = veth_open;
- dev->hard_start_xmit = veth_start_xmit;
- dev->stop = veth_close;
- dev->change_mtu = veth_change_mtu;
- dev->set_mac_address = NULL;
- dev->set_multicast_list = veth_set_multicast_list;
+ dev->netdev_ops = &veth_netdev_ops;
SET_ETHTOOL_OPS(dev, &ops);
SET_NETDEV_DEV(dev, vdev);
diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c
index 11dcda0f453..ff67a84e680 100644
--- a/drivers/net/ixgb/ixgb_hw.c
+++ b/drivers/net/ixgb/ixgb_hw.c
@@ -192,7 +192,7 @@ ixgb_identify_xpak_vendor(struct ixgb_hw *hw)
vendor_name[i] = ixgb_read_phy_reg(hw,
MDIO_PMA_PMD_XPAK_VENDOR_NAME
+ i, IXGB_PHY_ADDRESS,
- MDIO_PMA_PMD_DID);
+ MDIO_MMD_PMAPMD);
}
/* Determine the actual vendor */
@@ -1225,15 +1225,15 @@ ixgb_optics_reset(struct ixgb_hw *hw)
u16 mdio_reg;
ixgb_write_phy_reg(hw,
- MDIO_PMA_PMD_CR1,
- IXGB_PHY_ADDRESS,
- MDIO_PMA_PMD_DID,
- MDIO_PMA_PMD_CR1_RESET);
-
- mdio_reg = ixgb_read_phy_reg( hw,
- MDIO_PMA_PMD_CR1,
- IXGB_PHY_ADDRESS,
- MDIO_PMA_PMD_DID);
+ MDIO_CTRL1,
+ IXGB_PHY_ADDRESS,
+ MDIO_MMD_PMAPMD,
+ MDIO_CTRL1_RESET);
+
+ mdio_reg = ixgb_read_phy_reg(hw,
+ MDIO_CTRL1,
+ IXGB_PHY_ADDRESS,
+ MDIO_MMD_PMAPMD);
}
return;
diff --git a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h
index 831fe0c58b2..af6ca3aab5a 100644
--- a/drivers/net/ixgb/ixgb_hw.h
+++ b/drivers/net/ixgb/ixgb_hw.h
@@ -29,6 +29,8 @@
#ifndef _IXGB_HW_H_
#define _IXGB_HW_H_
+#include <linux/mdio.h>
+
#include "ixgb_osdep.h"
/* Enums */
@@ -507,18 +509,6 @@ typedef enum {
/* Definitions for the optics devices on the MDIO bus. */
#define IXGB_PHY_ADDRESS 0x0 /* Single PHY, multiple "Devices" */
-/* Standard five-bit Device IDs. See IEEE 802.3ae, clause 45 */
-#define MDIO_PMA_PMD_DID 0x01
-#define MDIO_WIS_DID 0x02
-#define MDIO_PCS_DID 0x03
-#define MDIO_XGXS_DID 0x04
-
-/* Standard PMA/PMD registers and bit definitions. */
-/* Note: This is a very limited set of definitions, */
-/* only implemented features are defined. */
-#define MDIO_PMA_PMD_CR1 0x0000
-#define MDIO_PMA_PMD_CR1_RESET 0x8000
-
#define MDIO_PMA_PMD_XPAK_VENDOR_NAME 0x803A /* XPAK/XENPAK devices only */
/* Vendor-specific MDIO registers */
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 4a0826b8f6f..9c897cf86b9 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -266,6 +266,8 @@ ixgb_up(struct ixgb_adapter *adapter)
napi_enable(&adapter->napi);
ixgb_irq_enable(adapter);
+ netif_wake_queue(netdev);
+
mod_timer(&adapter->watchdog_timer, jiffies);
return 0;
@@ -471,10 +473,8 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
goto err_register;
- /* we're going to reset, so assume we have no link for now */
-
+ /* carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
DPRINTK(PROBE, INFO, "Intel(R) PRO/10GbE Network Connection\n");
ixgb_check_options(adapter);
@@ -592,6 +592,8 @@ ixgb_open(struct net_device *netdev)
if (err)
goto err_setup_tx;
+ netif_carrier_off(netdev);
+
/* allocate receive descriptors */
err = ixgb_setup_rx_resources(adapter);
@@ -602,6 +604,8 @@ ixgb_open(struct net_device *netdev)
if (err)
goto err_up;
+ netif_start_queue(netdev);
+
return 0;
err_up:
@@ -1116,7 +1120,6 @@ ixgb_watchdog(unsigned long data)
adapter->link_speed = 10000;
adapter->link_duplex = FULL_DUPLEX;
netif_carrier_on(netdev);
- netif_wake_queue(netdev);
}
} else {
if (netif_carrier_ok(netdev)) {
@@ -1125,8 +1128,6 @@ ixgb_watchdog(unsigned long data)
printk(KERN_INFO "ixgb: %s NIC Link is Down\n",
netdev->name);
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-
}
}
@@ -1139,6 +1140,8 @@ ixgb_watchdog(unsigned long data)
* to get done, so reset controller to flush Tx.
* (Do the reset outside of interrupt context). */
schedule_work(&adapter->tx_timeout_task);
+ /* return immediately since reset is imminent */
+ return;
}
}
@@ -1297,7 +1300,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
buffer_info->length = size;
WARN_ON(buffer_info->dma != 0);
buffer_info->time_stamp = jiffies;
- buffer_info->dma = map[0] + offset;
+ buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
pci_map_single(adapter->pdev,
skb->data + offset,
size,
@@ -1337,7 +1340,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
buffer_info->length = size;
buffer_info->time_stamp = jiffies;
- buffer_info->dma = map[f + 1] + offset;
+ buffer_info->dma = map[f] + offset;
buffer_info->next_to_watch = 0;
len -= size;
@@ -1485,7 +1488,6 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (count) {
ixgb_tx_queue(adapter, count, vlan_id, tx_flags);
- netdev->trans_start = jiffies;
/* Make sure there is space in the ring for the next send. */
ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED);
diff --git a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h
index d92e72bd627..371a6be4d96 100644
--- a/drivers/net/ixgb/ixgb_osdep.h
+++ b/drivers/net/ixgb/ixgb_osdep.h
@@ -40,7 +40,7 @@
#include <linux/sched.h>
#undef ASSERT
-#define ASSERT(x) if (!(x)) BUG()
+#define ASSERT(x) BUG_ON(!(x))
#define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B)
#ifdef DBG
diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
index b3f8208ec7b..21b41f42b61 100644
--- a/drivers/net/ixgbe/Makefile
+++ b/drivers/net/ixgbe/Makefile
@@ -37,3 +37,5 @@ ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \
ixgbe_dcb_82599.o ixgbe_dcb_nl.o
+
+ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index c26433d1460..cd22323cfd2 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -36,6 +36,10 @@
#include "ixgbe_type.h"
#include "ixgbe_common.h"
#include "ixgbe_dcb.h"
+#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+#define IXGBE_FCOE
+#include "ixgbe_fcoe.h"
+#endif /* CONFIG_FCOE or CONFIG_FCOE_MODULE */
#ifdef CONFIG_IXGBE_DCA
#include <linux/dca.h>
#endif
@@ -71,6 +75,8 @@
#define IXGBE_RXBUFFER_128 128 /* Used for packet split */
#define IXGBE_RXBUFFER_256 256 /* Used for packet split */
#define IXGBE_RXBUFFER_2048 2048
+#define IXGBE_RXBUFFER_4096 4096
+#define IXGBE_RXBUFFER_8192 8192
#define IXGBE_MAX_RXBUFFER 16384 /* largest size for a single descriptor */
#define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_256
@@ -84,6 +90,8 @@
#define IXGBE_TX_FLAGS_VLAN (u32)(1 << 1)
#define IXGBE_TX_FLAGS_TSO (u32)(1 << 2)
#define IXGBE_TX_FLAGS_IPV4 (u32)(1 << 3)
+#define IXGBE_TX_FLAGS_FCOE (u32)(1 << 4)
+#define IXGBE_TX_FLAGS_FSO (u32)(1 << 5)
#define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000
#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0x0000e000
#define IXGBE_TX_FLAGS_VLAN_SHIFT 16
@@ -113,17 +121,18 @@ struct ixgbe_queue_stats {
struct ixgbe_ring {
void *desc; /* descriptor ring memory */
- dma_addr_t dma; /* phys. address of descriptor ring */
- unsigned int size; /* length in bytes */
- unsigned int count; /* amount of descriptors */
- unsigned int next_to_use;
- unsigned int next_to_clean;
-
- int queue_index; /* needed for multiqueue queue management */
union {
struct ixgbe_tx_buffer *tx_buffer_info;
struct ixgbe_rx_buffer *rx_buffer_info;
};
+ u8 atr_sample_rate;
+ u8 atr_count;
+ u16 count; /* amount of descriptors */
+ u16 rx_buf_len;
+ u16 next_to_use;
+ u16 next_to_clean;
+
+ u8 queue_index; /* needed for multiqueue queue management */
u16 head;
u16 tail;
@@ -131,22 +140,24 @@ struct ixgbe_ring {
unsigned int total_bytes;
unsigned int total_packets;
- u16 reg_idx; /* holds the special value that gets the hardware register
- * offset associated with this ring, which is different
- * for DCB and RSS modes */
-
#ifdef CONFIG_IXGBE_DCA
/* cpu for tx queue */
int cpu;
#endif
- struct ixgbe_queue_stats stats;
- u64 v_idx; /* maps directly to the index for this ring in the hardware
- * vector array, can also be used for finding the bit in EICR
- * and friends that represents the vector for this ring */
+ u16 work_limit; /* max work per interrupt */
+ u16 reg_idx; /* holds the special value that gets
+ * the hardware register offset
+ * associated with this ring, which is
+ * different for DCB and RSS modes
+ */
- u16 work_limit; /* max work per interrupt */
- u16 rx_buf_len;
+ struct ixgbe_queue_stats stats;
+ unsigned long reinit_state;
+ u64 rsc_count; /* stat for coalesced packets */
+
+ unsigned int size; /* length in bytes */
+ dma_addr_t dma; /* phys. address of descriptor ring */
};
enum ixgbe_ring_f_enum {
@@ -154,6 +165,10 @@ enum ixgbe_ring_f_enum {
RING_F_DCB,
RING_F_VMDQ,
RING_F_RSS,
+ RING_F_FDIR,
+#ifdef IXGBE_FCOE
+ RING_F_FCOE,
+#endif /* IXGBE_FCOE */
RING_F_ARRAY_SIZE /* must be last in enum set */
};
@@ -161,6 +176,10 @@ enum ixgbe_ring_f_enum {
#define IXGBE_MAX_DCB_INDICES 8
#define IXGBE_MAX_RSS_INDICES 16
#define IXGBE_MAX_VMDQ_INDICES 16
+#define IXGBE_MAX_FDIR_INDICES 64
+#ifdef IXGBE_FCOE
+#define IXGBE_MAX_FCOE_INDICES 8
+#endif /* IXGBE_FCOE */
struct ixgbe_ring_feature {
int indices;
int mask;
@@ -178,6 +197,9 @@ struct ixgbe_ring_feature {
*/
struct ixgbe_q_vector {
struct ixgbe_adapter *adapter;
+ unsigned int v_idx; /* index of q_vector within array, also used for
+ * finding the bit in EICR and friends that
+ * represents the vector for this ring */
struct napi_struct napi;
DECLARE_BITMAP(rxr_idx, MAX_RX_QUEUES); /* Rx ring indices */
DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */
@@ -207,7 +229,15 @@ struct ixgbe_q_vector {
#define IXGBE_TX_CTXTDESC_ADV(R, i) \
(&(((struct ixgbe_adv_tx_context_desc *)((R).desc))[i]))
+#define IXGBE_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
+#define IXGBE_TX_DESC(R, i) IXGBE_GET_DESC(R, i, ixgbe_legacy_tx_desc)
+#define IXGBE_RX_DESC(R, i) IXGBE_GET_DESC(R, i, ixgbe_legacy_rx_desc)
+
#define IXGBE_MAX_JUMBO_FRAME_SIZE 16128
+#ifdef IXGBE_FCOE
+/* Use 3K as the baby jumbo frame size for FCoE */
+#define IXGBE_FCOE_JUMBO_FRAME_SIZE 3072
+#endif /* IXGBE_FCOE */
#define OTHER_VECTOR 1
#define NON_Q_VECTORS (OTHER_VECTOR)
@@ -229,11 +259,12 @@ struct ixgbe_adapter {
struct vlan_group *vlgrp;
u16 bd_number;
struct work_struct reset_task;
- struct ixgbe_q_vector q_vector[MAX_MSIX_Q_VECTORS];
+ struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
char name[MAX_MSIX_COUNT][IFNAMSIZ + 9];
struct ixgbe_dcb_config dcb_cfg;
struct ixgbe_dcb_config temp_dcb_cfg;
u8 dcb_set_bitmap;
+ enum ixgbe_fc_mode last_lfc_mode;
/* Interrupt Throttle Rate */
u32 itr_setting;
@@ -294,7 +325,13 @@ struct ixgbe_adapter {
#define IXGBE_FLAG_IN_WATCHDOG_TASK (u32)(1 << 23)
#define IXGBE_FLAG_IN_SFP_LINK_TASK (u32)(1 << 24)
#define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 25)
+#define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 26)
+#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 27)
+#define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 29)
+ u32 flags2;
+#define IXGBE_FLAG2_RSC_CAPABLE (u32)(1)
+#define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1)
/* default to trying for four seconds */
#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
@@ -303,6 +340,10 @@ struct ixgbe_adapter {
struct pci_dev *pdev;
struct net_device_stats net_stats;
+ u32 test_icr;
+ struct ixgbe_ring test_tx_ring;
+ struct ixgbe_ring test_rx_ring;
+
/* structs defined in ixgbe_hw.h */
struct ixgbe_hw hw;
u16 msg_enable;
@@ -325,6 +366,14 @@ struct ixgbe_adapter {
struct timer_list sfp_timer;
struct work_struct multispeed_fiber_task;
struct work_struct sfp_config_module_task;
+ u32 fdir_pballoc;
+ u32 atr_sample_rate;
+ spinlock_t fdir_perfect_lock;
+ struct work_struct fdir_reinit_task;
+#ifdef IXGBE_FCOE
+ struct ixgbe_fcoe fcoe;
+#endif /* IXGBE_FCOE */
+ u64 rsc_count;
u32 wol;
u16 eeprom_version;
};
@@ -333,6 +382,7 @@ enum ixbge_state_t {
__IXGBE_TESTING,
__IXGBE_RESETTING,
__IXGBE_DOWN,
+ __IXGBE_FDIR_INIT_DONE,
__IXGBE_SFP_MODULE_NOT_FOUND
};
@@ -363,10 +413,77 @@ extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *)
extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
-extern void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter);
extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
-void ixgbe_napi_add_all(struct ixgbe_adapter *adapter);
-void ixgbe_napi_del_all(struct ixgbe_adapter *adapter);
-extern void ixgbe_write_eitr(struct ixgbe_adapter *, int, u32);
+extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
+extern void ixgbe_write_eitr(struct ixgbe_q_vector *);
+extern int ethtool_ioctl(struct ifreq *ifr);
+extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw);
+extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc);
+extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc);
+extern s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_atr_input *input,
+ u8 queue);
+extern s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_atr_input *input,
+ u16 soft_id,
+ u8 queue);
+extern u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *input, u32 key);
+extern s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input,
+ u16 vlan_id);
+extern s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input,
+ u32 src_addr);
+extern s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input,
+ u32 dst_addr);
+extern s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input,
+ u32 src_addr_1, u32 src_addr_2,
+ u32 src_addr_3, u32 src_addr_4);
+extern s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input,
+ u32 dst_addr_1, u32 dst_addr_2,
+ u32 dst_addr_3, u32 dst_addr_4);
+extern s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input,
+ u16 src_port);
+extern s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input,
+ u16 dst_port);
+extern s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input,
+ u16 flex_byte);
+extern s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input,
+ u8 vm_pool);
+extern s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input,
+ u8 l4type);
+extern s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input,
+ u16 *vlan_id);
+extern s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input,
+ u32 *src_addr);
+extern s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input,
+ u32 *dst_addr);
+extern s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input,
+ u32 *src_addr_1, u32 *src_addr_2,
+ u32 *src_addr_3, u32 *src_addr_4);
+extern s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input,
+ u32 *dst_addr_1, u32 *dst_addr_2,
+ u32 *dst_addr_3, u32 *dst_addr_4);
+extern s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input,
+ u16 *src_port);
+extern s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input,
+ u16 *dst_port);
+extern s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input,
+ u16 *flex_byte);
+extern s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input,
+ u8 *vm_pool);
+extern s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input,
+ u8 *l4type);
+#ifdef IXGBE_FCOE
+extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter);
+extern int ixgbe_fso(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *tx_ring, struct sk_buff *skb,
+ u32 tx_flags, u8 *hdr_len);
+extern void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter);
+extern int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
+ union ixgbe_adv_rx_desc *rx_desc,
+ struct sk_buff *skb);
+extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
+ struct scatterlist *sgl, unsigned int sgc);
+extern int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid);
+#endif /* IXGBE_FCOE */
#endif /* _IXGBE_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 4791238c3f6..b9923047ce1 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -75,18 +75,49 @@ static u16 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw)
static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
{
struct ixgbe_mac_info *mac = &hw->mac;
+
+ /* Call PHY identify routine to get the phy type */
+ ixgbe_identify_phy_generic(hw);
+
+ mac->mcft_size = IXGBE_82598_MC_TBL_SIZE;
+ mac->vft_size = IXGBE_82598_VFT_TBL_SIZE;
+ mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
+ mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
+ mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
+ mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_init_phy_ops_82598 - PHY/SFP specific init
+ * @hw: pointer to hardware structure
+ *
+ * Initialize any function pointers that were not able to be
+ * set during get_invariants because the PHY/SFP type was
+ * not known. Perform the SFP init if necessary.
+ *
+ **/
+s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
+{
+ struct ixgbe_mac_info *mac = &hw->mac;
struct ixgbe_phy_info *phy = &hw->phy;
s32 ret_val = 0;
u16 list_offset, data_offset;
- /* Set the bus information prior to PHY identification */
- mac->ops.get_bus_info(hw);
+ /* Identify the PHY */
+ phy->ops.identify(hw);
- /* Call PHY identify routine to get the phy type */
- ixgbe_identify_phy_generic(hw);
+ /* Overwrite the link function pointers if copper PHY */
+ if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
+ mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
+ mac->ops.setup_link_speed =
+ &ixgbe_setup_copper_link_speed_82598;
+ mac->ops.get_link_capabilities =
+ &ixgbe_get_copper_link_capabilities_82598;
+ }
- /* PHY Init */
- switch (phy->type) {
+ switch (hw->phy.type) {
case ixgbe_phy_tn:
phy->ops.check_link = &ixgbe_check_phy_link_tnx;
phy->ops.get_firmware_version =
@@ -106,8 +137,8 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
/* Check to see if SFP+ module is supported */
ret_val = ixgbe_get_sfp_init_sequence_offsets(hw,
- &list_offset,
- &data_offset);
+ &list_offset,
+ &data_offset);
if (ret_val != 0) {
ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
goto out;
@@ -117,21 +148,6 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
break;
}
- if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
- mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
- mac->ops.setup_link_speed =
- &ixgbe_setup_copper_link_speed_82598;
- mac->ops.get_link_capabilities =
- &ixgbe_get_copper_link_capabilities_82598;
- }
-
- mac->mcft_size = IXGBE_82598_MC_TBL_SIZE;
- mac->vft_size = IXGBE_82598_VFT_TBL_SIZE;
- mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
- mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
- mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
- mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw);
-
out:
return ret_val;
}
@@ -149,12 +165,19 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
bool *autoneg)
{
s32 status = 0;
+ u32 autoc = 0;
/*
* Determine link capabilities based on the stored value of AUTOC,
- * which represents EEPROM defaults.
+ * which represents EEPROM defaults. If AUTOC value has not been
+ * stored, use the current register value.
*/
- switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) {
+ if (hw->mac.orig_link_settings_stored)
+ autoc = hw->mac.orig_autoc;
+ else
+ autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+
+ switch (autoc & IXGBE_AUTOC_LMS_MASK) {
case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
*speed = IXGBE_LINK_SPEED_1GB_FULL;
*autoneg = false;
@@ -173,9 +196,9 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
case IXGBE_AUTOC_LMS_KX4_AN:
case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
*speed = IXGBE_LINK_SPEED_UNKNOWN;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+ if (autoc & IXGBE_AUTOC_KX4_SUPP)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+ if (autoc & IXGBE_AUTOC_KX_SUPP)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
*autoneg = true;
break;
@@ -206,14 +229,13 @@ static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
*speed = 0;
*autoneg = true;
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD,
&speed_ability);
if (status == 0) {
- if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
+ if (speed_ability & MDIO_SPEED_10G)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
+ if (speed_ability & MDIO_PMA_SPEED_1000)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
}
@@ -271,6 +293,17 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
u32 rmcs_reg;
u32 reg;
+#ifdef CONFIG_DCB
+ if (hw->fc.requested_mode == ixgbe_fc_pfc)
+ goto out;
+
+#endif /* CONFIG_DCB */
+ /* Negotiate the fc mode to use */
+ ret_val = ixgbe_fc_autoneg(hw);
+ if (ret_val)
+ goto out;
+
+ /* Disable any previous flow control settings */
fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
@@ -282,14 +315,20 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
* 0: Flow control is completely disabled
* 1: Rx flow control is enabled (we can receive pause frames,
* but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames but
+ * 2: Tx flow control is enabled (we can send pause frames but
* we do not support receiving pause frames).
* 3: Both Rx and Tx flow control (symmetric) are enabled.
* other: Invalid.
+#ifdef CONFIG_DCB
+ * 4: Priority Flow Control is enabled.
+#endif
*/
switch (hw->fc.current_mode) {
case ixgbe_fc_none:
- /* Flow control completely disabled by software override. */
+ /*
+ * Flow control is disabled by software override or autoneg.
+ * The code below will actually disable it in the HW.
+ */
break;
case ixgbe_fc_rx_pause:
/*
@@ -314,6 +353,11 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
fctrl_reg |= IXGBE_FCTRL_RFCE;
rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
break;
+#ifdef CONFIG_DCB
+ case ixgbe_fc_pfc:
+ goto out;
+ break;
+#endif /* CONFIG_DCB */
default:
hw_dbg(hw, "Flow control param set incorrectly\n");
ret_val = -IXGBE_ERR_CONFIG;
@@ -321,7 +365,8 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
break;
}
- /* Enable 802.3x based flow control settings. */
+ /* Set 802.3x based flow control settings. */
+ fctrl_reg |= IXGBE_FCTRL_DPF;
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
@@ -340,7 +385,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
}
/* Configure pause time (2 TCs per register) */
- reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num));
+ reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2));
if ((packetbuf_num & 1) == 0)
reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
else
@@ -354,77 +399,6 @@ out:
}
/**
- * ixgbe_setup_fc_82598 - Configure flow control settings
- * @hw: pointer to hardware structure
- * @packetbuf_num: packet buffer number (0-7)
- *
- * Configures the flow control settings based on SW configuration. This
- * function is used for 802.3x flow control configuration only.
- **/
-static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
-{
- s32 ret_val = 0;
- ixgbe_link_speed speed;
- bool link_up;
-
- /* Validate the packetbuf configuration */
- if (packetbuf_num < 0 || packetbuf_num > 7) {
- hw_dbg(hw, "Invalid packet buffer number [%d], expected range is"
- " 0-7\n", packetbuf_num);
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
- }
-
- /*
- * Validate the water mark configuration. Zero water marks are invalid
- * because it causes the controller to just blast out fc packets.
- */
- if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
- hw_dbg(hw, "Invalid water mark configuration\n");
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
- }
-
- /*
- * Validate the requested mode. Strict IEEE mode does not allow
- * ixgbe_fc_rx_pause because it will cause testing anomalies.
- */
- if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
- hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
- }
-
- /*
- * 10gig parts do not have a word in the EEPROM to determine the
- * default flow control setting, so we explicitly set it to full.
- */
- if (hw->fc.requested_mode == ixgbe_fc_default)
- hw->fc.requested_mode = ixgbe_fc_full;
-
- /*
- * Save off the requested flow control mode for use later. Depending
- * on the link partner's capabilities, we may or may not use this mode.
- */
-
- hw->fc.current_mode = hw->fc.requested_mode;
-
- /* Decide whether to use autoneg or not. */
- hw->mac.ops.check_link(hw, &speed, &link_up, false);
- if (!hw->fc.disable_fc_autoneg && hw->phy.multispeed_fiber &&
- (speed == IXGBE_LINK_SPEED_1GB_FULL))
- ret_val = ixgbe_fc_autoneg(hw);
-
- if (ret_val)
- goto out;
-
- ret_val = ixgbe_fc_enable_82598(hw, packetbuf_num);
-
-out:
- return ret_val;
-}
-
-/**
* ixgbe_setup_mac_link_82598 - Configures MAC link settings
* @hw: pointer to hardware structure
*
@@ -463,13 +437,6 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
}
}
- /*
- * We want to save off the original Flow Control configuration just in
- * case we get disconnected and then reconnected into a different hub
- * or switch with different Flow Control capabilities.
- */
- ixgbe_setup_fc_82598(hw, 0);
-
/* Add delay to filter out noises during initial link setup */
msleep(50);
@@ -500,9 +467,9 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
* clear indicates active; set indicates inactive.
*/
if (hw->phy.type == ixgbe_phy_nl) {
- hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
- hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
- hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV,
+ hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg);
+ hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg);
+ hw->phy.ops.read_reg(hw, 0xC00C, MDIO_MMD_PMAPMD,
&adapt_comp_reg);
if (link_up_wait_to_complete) {
for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
@@ -515,10 +482,10 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
}
msleep(100);
hw->phy.ops.read_reg(hw, 0xC79F,
- IXGBE_TWINAX_DEV,
+ MDIO_MMD_PMAPMD,
&link_reg);
hw->phy.ops.read_reg(hw, 0xC00C,
- IXGBE_TWINAX_DEV,
+ MDIO_MMD_PMAPMD,
&adapt_comp_reg);
}
} else {
@@ -556,6 +523,11 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
else
*speed = IXGBE_LINK_SPEED_1GB_FULL;
+ /* if link is down, zero out the current_mode */
+ if (*link_up == false) {
+ hw->fc.current_mode = ixgbe_fc_none;
+ hw->fc.fc_was_autonegged = false;
+ }
out:
return 0;
}
@@ -673,6 +645,7 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
{
s32 status = 0;
+ s32 phy_status = 0;
u32 ctrl;
u32 gheccr;
u32 i;
@@ -716,14 +689,27 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
}
/* Reset PHY */
- if (hw->phy.reset_disable == false)
+ if (hw->phy.reset_disable == false) {
+ /* PHY ops must be identified and initialized prior to reset */
+
+ /* Init PHY and function pointers, perform SFP setup */
+ phy_status = hw->phy.ops.init(hw);
+ if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ goto reset_hw_out;
+ else if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT)
+ goto no_phy_reset;
+
+
hw->phy.ops.reset(hw);
+ }
+no_phy_reset:
/*
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
* access and verify no pending requests before reset
*/
- if (ixgbe_disable_pcie_master(hw) != 0) {
+ status = ixgbe_disable_pcie_master(hw);
+ if (status != 0) {
status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
}
@@ -767,9 +753,19 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
}
+ /*
+ * Store MAC address from RAR0, clear receive address registers, and
+ * clear the multicast table
+ */
+ hw->mac.ops.init_rx_addrs(hw);
+
/* Store the permanent mac address */
hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
+reset_hw_out:
+ if (phy_status)
+ status = phy_status;
+
return status;
}
@@ -954,14 +950,14 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
hw->phy.ops.write_reg(hw,
IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ MDIO_MMD_PMAPMD,
sfp_addr);
/* Poll status */
for (i = 0; i < 100; i++) {
hw->phy.ops.read_reg(hw,
IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ MDIO_MMD_PMAPMD,
&sfp_stat);
sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
@@ -977,7 +973,7 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
/* Read data */
hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data);
+ MDIO_MMD_PMAPMD, &sfp_data);
*eeprom_data = (u8)(sfp_data >> 8);
} else {
@@ -998,35 +994,56 @@ out:
static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
{
u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
+ u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+ u16 ext_ability = 0;
+
+ hw->phy.ops.identify(hw);
+
+ /* Copper PHY must be checked before AUTOC LMS to determine correct
+ * physical layer because 10GBase-T PHYs use LMS = KX4/KX */
+ if (hw->phy.type == ixgbe_phy_tn ||
+ hw->phy.type == ixgbe_phy_cu_unknown) {
+ hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD,
+ &ext_ability);
+ if (ext_ability & MDIO_PMA_EXTABLE_10GBT)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
+ if (ext_ability & MDIO_PMA_EXTABLE_1000BT)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
+ if (ext_ability & MDIO_PMA_EXTABLE_100BTX)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
+ goto out;
+ }
- switch (hw->device_id) {
- case IXGBE_DEV_ID_82598:
- /* Default device ID is mezzanine card KX/KX4 */
- physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
- IXGBE_PHYSICAL_LAYER_1000BASE_KX);
- break;
- case IXGBE_DEV_ID_82598_BX:
- physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
- case IXGBE_DEV_ID_82598EB_CX4:
- case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
- break;
- case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
- physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+ switch (autoc & IXGBE_AUTOC_LMS_MASK) {
+ case IXGBE_AUTOC_LMS_1G_AN:
+ case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
+ if (pma_pmd_1g == IXGBE_AUTOC_1G_KX)
+ physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+ else
+ physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
break;
- case IXGBE_DEV_ID_82598AF_DUAL_PORT:
- case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
- case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+ case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
+ if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4)
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
+ else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4)
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+ else /* XAUI */
+ physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
break;
- case IXGBE_DEV_ID_82598EB_XF_LR:
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+ case IXGBE_AUTOC_LMS_KX4_AN:
+ case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
+ if (autoc & IXGBE_AUTOC_KX_SUPP)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+ if (autoc & IXGBE_AUTOC_KX4_SUPP)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
break;
- case IXGBE_DEV_ID_82598AT:
- physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_T |
- IXGBE_PHYSICAL_LAYER_1000BASE_T);
+ default:
break;
- case IXGBE_DEV_ID_82598EB_SFP_LOM:
+ }
+
+ if (hw->phy.type == ixgbe_phy_nl) {
hw->phy.ops.identify_sfp(hw);
switch (hw->phy.sfp_type) {
@@ -1043,13 +1060,25 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
break;
}
- break;
+ }
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
+ physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+ break;
+ case IXGBE_DEV_ID_82598AF_DUAL_PORT:
+ case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
+ case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+ break;
+ case IXGBE_DEV_ID_82598EB_XF_LR:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+ break;
default:
- physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
break;
}
+out:
return physical_layer;
}
@@ -1086,7 +1115,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
.disable_mc = &ixgbe_disable_mc_generic,
.clear_vfta = &ixgbe_clear_vfta_82598,
.set_vfta = &ixgbe_set_vfta_82598,
- .setup_fc = &ixgbe_setup_fc_82598,
+ .fc_enable = &ixgbe_fc_enable_82598,
};
static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
@@ -1099,6 +1128,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
static struct ixgbe_phy_operations phy_ops_82598 = {
.identify = &ixgbe_identify_phy_generic,
.identify_sfp = &ixgbe_identify_sfp_module_generic,
+ .init = &ixgbe_init_phy_ops_82598,
.reset = &ixgbe_reset_phy_generic,
.read_reg = &ixgbe_read_phy_reg_generic,
.write_reg = &ixgbe_write_phy_reg_generic,
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 29771fbaa42..1984cab7d48 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -71,10 +71,10 @@ s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw);
s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw);
s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val);
s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val);
-s32 ixgbe_start_hw_rev_0_82599(struct ixgbe_hw *hw);
s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw);
s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw);
u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw);
+static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
{
@@ -100,22 +100,36 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
ixgbe_init_mac_link_ops_82599(hw);
+
+ hw->phy.ops.reset = NULL;
+
ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
&data_offset);
if (ret_val != 0)
goto setup_sfp_out;
+ /* PHY config will finish before releasing the semaphore */
+ ret_val = ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+ if (ret_val != 0) {
+ ret_val = IXGBE_ERR_SWFW_SYNC;
+ goto setup_sfp_out;
+ }
+
hw->eeprom.ops.read(hw, ++data_offset, &data_value);
while (data_value != 0xffff) {
IXGBE_WRITE_REG(hw, IXGBE_CORECTL, data_value);
IXGBE_WRITE_FLUSH(hw);
hw->eeprom.ops.read(hw, ++data_offset, &data_value);
}
- /* Now restart DSP */
- IXGBE_WRITE_REG(hw, IXGBE_CORECTL, 0x00000102);
- IXGBE_WRITE_REG(hw, IXGBE_CORECTL, 0x00000b1d);
- IXGBE_WRITE_FLUSH(hw);
+ /* Now restart DSP by setting Restart_AN */
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC,
+ (IXGBE_READ_REG(hw, IXGBE_AUTOC) | IXGBE_AUTOC_AN_RESTART));
+
+ /* Release the semaphore */
+ ixgbe_release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+ /* Delay obtaining semaphore again to allow FW access */
+ msleep(hw->eeprom.semaphore_delay);
}
setup_sfp_out:
@@ -146,51 +160,60 @@ u32 ixgbe_get_pcie_msix_count_82599(struct ixgbe_hw *hw)
static s32 ixgbe_get_invariants_82599(struct ixgbe_hw *hw)
{
struct ixgbe_mac_info *mac = &hw->mac;
- struct ixgbe_phy_info *phy = &hw->phy;
- s32 ret_val;
- /* Set the bus information prior to PHY identification */
- mac->ops.get_bus_info(hw);
+ ixgbe_init_mac_link_ops_82599(hw);
- /* Call PHY identify routine to get the Cu or SFI phy type */
- ret_val = phy->ops.identify(hw);
+ mac->mcft_size = IXGBE_82599_MC_TBL_SIZE;
+ mac->vft_size = IXGBE_82599_VFT_TBL_SIZE;
+ mac->num_rar_entries = IXGBE_82599_RAR_ENTRIES;
+ mac->max_rx_queues = IXGBE_82599_MAX_RX_QUEUES;
+ mac->max_tx_queues = IXGBE_82599_MAX_TX_QUEUES;
+ mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82599(hw);
- if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED)
- goto get_invariants_out;
+ return 0;
+}
- ixgbe_init_mac_link_ops_82599(hw);
+/**
+ * ixgbe_init_phy_ops_82599 - PHY/SFP specific init
+ * @hw: pointer to hardware structure
+ *
+ * Initialize any function pointers that were not able to be
+ * set during get_invariants because the PHY/SFP type was
+ * not known. Perform the SFP init if necessary.
+ *
+ **/
+s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
+{
+ struct ixgbe_mac_info *mac = &hw->mac;
+ struct ixgbe_phy_info *phy = &hw->phy;
+ s32 ret_val = 0;
- /* Setup SFP module if there is one present. */
- ret_val = mac->ops.setup_sfp(hw);
+ /* Identify the PHY or SFP module */
+ ret_val = phy->ops.identify(hw);
+
+ /* Setup function pointers based on detected SFP module and speeds */
+ ixgbe_init_mac_link_ops_82599(hw);
/* If copper media, overwrite with copper function pointers */
if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
mac->ops.setup_link = &ixgbe_setup_copper_link_82599;
mac->ops.setup_link_speed =
- &ixgbe_setup_copper_link_speed_82599;
+ &ixgbe_setup_copper_link_speed_82599;
mac->ops.get_link_capabilities =
&ixgbe_get_copper_link_capabilities_82599;
}
- /* PHY Init */
+ /* Set necessary function pointers based on phy type */
switch (hw->phy.type) {
case ixgbe_phy_tn:
phy->ops.check_link = &ixgbe_check_phy_link_tnx;
phy->ops.get_firmware_version =
- &ixgbe_get_phy_firmware_version_tnx;
+ &ixgbe_get_phy_firmware_version_tnx;
break;
default:
break;
}
- mac->mcft_size = IXGBE_82599_MC_TBL_SIZE;
- mac->vft_size = IXGBE_82599_VFT_TBL_SIZE;
- mac->num_rar_entries = IXGBE_82599_RAR_ENTRIES;
- mac->max_rx_queues = IXGBE_82599_MAX_RX_QUEUES;
- mac->max_tx_queues = IXGBE_82599_MAX_TX_QUEUES;
- mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82599(hw);
-
-get_invariants_out:
return ret_val;
}
@@ -207,8 +230,19 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
bool *negotiation)
{
s32 status = 0;
+ u32 autoc = 0;
+
+ /*
+ * Determine link capabilities based on the stored value of AUTOC,
+ * which represents EEPROM defaults. If AUTOC value has not been
+ * stored, use the current register value.
+ */
+ if (hw->mac.orig_link_settings_stored)
+ autoc = hw->mac.orig_autoc;
+ else
+ autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) {
+ switch (autoc & IXGBE_AUTOC_LMS_MASK) {
case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
*speed = IXGBE_LINK_SPEED_1GB_FULL;
*negotiation = false;
@@ -232,22 +266,22 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
case IXGBE_AUTOC_LMS_KX4_KX_KR:
case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
*speed = IXGBE_LINK_SPEED_UNKNOWN;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+ if (autoc & IXGBE_AUTOC_KR_SUPP)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+ if (autoc & IXGBE_AUTOC_KX4_SUPP)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+ if (autoc & IXGBE_AUTOC_KX_SUPP)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
*negotiation = true;
break;
case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:
*speed = IXGBE_LINK_SPEED_100_FULL;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+ if (autoc & IXGBE_AUTOC_KR_SUPP)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+ if (autoc & IXGBE_AUTOC_KX4_SUPP)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+ if (autoc & IXGBE_AUTOC_KX_SUPP)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
*negotiation = true;
break;
@@ -291,14 +325,13 @@ static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw,
*speed = 0;
*autoneg = true;
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD,
&speed_ability);
if (status == 0) {
- if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
+ if (speed_ability & MDIO_SPEED_10G)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
+ if (speed_ability & MDIO_PMA_SPEED_1000)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
}
@@ -323,8 +356,8 @@ enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
}
switch (hw->device_id) {
- case IXGBE_DEV_ID_82599:
case IXGBE_DEV_ID_82599_KX4:
+ case IXGBE_DEV_ID_82599_XAUI_LOM:
/* Default device ID is mezzanine card KX/KX4 */
media_type = ixgbe_media_type_backplane;
break;
@@ -380,9 +413,6 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw)
}
}
- /* Set up flow control */
- status = ixgbe_setup_fc_generic(hw, 0);
-
/* Add delay to filter out noises during initial link setup */
msleep(50);
@@ -428,11 +458,31 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
bool link_up = false;
bool negotiation;
+ int i;
/* Mask off requested but non-supported speeds */
hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation);
speed &= phy_link_speed;
+ /* Set autoneg_advertised value based on input link speed */
+ hw->phy.autoneg_advertised = 0;
+
+ if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+ hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
+
+ if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+ hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
+
+ /*
+ * When the driver changes the link speeds that it can support,
+ * it sets autotry_restart to true to indicate that we need to
+ * initiate a new autotry session with the link partner. To do
+ * so, we set the speed then disable and re-enable the tx laser, to
+ * alert the link partner that it also needs to restart autotry on its
+ * end. This is consistent with true clause 37 autoneg, which also
+ * involves a loss of signal.
+ */
+
/*
* Try each speed one by one, highest priority first. We do this in
* software because 10gb fiber doesn't support speed autonegotiation.
@@ -441,21 +491,52 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
speedcnt++;
highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
- /* Set hardware SDP's */
+ /* If we already have link at this speed, just jump out */
+ hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
+
+ if ((phy_link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
+ goto out;
+
+ /* Set the module link speed */
esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
- ixgbe_setup_mac_link_speed_82599(hw,
- IXGBE_LINK_SPEED_10GB_FULL,
- autoneg,
- autoneg_wait_to_complete);
+ /* Allow module to change analog characteristics (1G->10G) */
+ msleep(40);
- msleep(50);
-
- /* If we have link, just jump out */
- hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
- if (link_up)
+ status = ixgbe_setup_mac_link_speed_82599(hw,
+ IXGBE_LINK_SPEED_10GB_FULL,
+ autoneg,
+ autoneg_wait_to_complete);
+ if (status != 0)
goto out;
+
+ /* Flap the tx laser if it has not already been done */
+ if (hw->mac.autotry_restart) {
+ /* Disable tx laser; allow 100us to go dark per spec */
+ esdp_reg |= IXGBE_ESDP_SDP3;
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+ udelay(100);
+
+ /* Enable tx laser; allow 2ms to light up per spec */
+ esdp_reg &= ~IXGBE_ESDP_SDP3;
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+ msleep(2);
+
+ hw->mac.autotry_restart = false;
+ }
+
+ /* The controller may take up to 500ms at 10g to acquire link */
+ for (i = 0; i < 5; i++) {
+ /* Wait for the link partner to also set speed */
+ msleep(100);
+
+ /* If we have link, just jump out */
+ hw->mac.ops.check_link(hw, &phy_link_speed,
+ &link_up, false);
+ if (link_up)
+ goto out;
+ }
}
if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
@@ -463,16 +544,44 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
- /* Set hardware SDP's */
+ /* If we already have link at this speed, just jump out */
+ hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
+
+ if ((phy_link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
+ goto out;
+
+ /* Set the module link speed */
esdp_reg &= ~IXGBE_ESDP_SDP5;
esdp_reg |= IXGBE_ESDP_SDP5_DIR;
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
- ixgbe_setup_mac_link_speed_82599(
- hw, IXGBE_LINK_SPEED_1GB_FULL, autoneg,
- autoneg_wait_to_complete);
+ /* Allow module to change analog characteristics (10G->1G) */
+ msleep(40);
- msleep(50);
+ status = ixgbe_setup_mac_link_speed_82599(hw,
+ IXGBE_LINK_SPEED_1GB_FULL,
+ autoneg,
+ autoneg_wait_to_complete);
+ if (status != 0)
+ goto out;
+
+ /* Flap the tx laser if it has not already been done */
+ if (hw->mac.autotry_restart) {
+ /* Disable tx laser; allow 100us to go dark per spec */
+ esdp_reg |= IXGBE_ESDP_SDP3;
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+ udelay(100);
+
+ /* Enable tx laser; allow 2ms to light up per spec */
+ esdp_reg &= ~IXGBE_ESDP_SDP3;
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+ msleep(2);
+
+ hw->mac.autotry_restart = false;
+ }
+
+ /* Wait for the link partner to also set speed */
+ msleep(100);
/* If we have link, just jump out */
hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
@@ -538,6 +647,11 @@ s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
else
*speed = IXGBE_LINK_SPEED_100_FULL;
+ /* if link is down, zero out the current_mode */
+ if (*link_up == false) {
+ hw->fc.current_mode = ixgbe_fc_none;
+ hw->fc.fc_was_autonegged = false;
+ }
return 0;
}
@@ -558,6 +672,8 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
s32 status = 0;
u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+ u32 start_autoc = autoc;
+ u32 orig_autoc = 0;
u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
@@ -571,15 +687,25 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
status = IXGBE_ERR_LINK_SETUP;
- } else if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
- link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
- link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
+ goto out;
+ }
+
+ /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
+ if (hw->mac.orig_link_settings_stored)
+ orig_autoc = hw->mac.orig_autoc;
+ else
+ orig_autoc = autoc;
+
+
+ if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
+ link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
+ link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
/* Set KX4/KX/KR support according to speed requested */
autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP);
if (speed & IXGBE_LINK_SPEED_10GB_FULL)
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+ if (orig_autoc & IXGBE_AUTOC_KX4_SUPP)
autoc |= IXGBE_AUTOC_KX4_SUPP;
- if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+ if (orig_autoc & IXGBE_AUTOC_KR_SUPP)
autoc |= IXGBE_AUTOC_KR_SUPP;
if (speed & IXGBE_LINK_SPEED_1GB_FULL)
autoc |= IXGBE_AUTOC_KX_SUPP;
@@ -605,7 +731,7 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
}
}
- if (status == 0) {
+ if (autoc != start_autoc) {
/* Restart link */
autoc |= IXGBE_AUTOC_AN_RESTART;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
@@ -632,13 +758,11 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
}
}
- /* Set up flow control */
- status = ixgbe_setup_fc_generic(hw, 0);
-
/* Add delay to filter out noises during initial link setup */
msleep(50);
}
+out:
return status;
}
@@ -705,14 +829,30 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
/* Call adapter stop to disable tx/rx and clear interrupts */
hw->mac.ops.stop_adapter(hw);
+ /* PHY ops must be identified and initialized prior to reset */
+
+ /* Init PHY and function pointers, perform SFP setup */
+ status = hw->phy.ops.init(hw);
+
+ if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ goto reset_hw_out;
+
+ /* Setup SFP module if there is one present. */
+ if (hw->phy.sfp_setup_needed) {
+ status = hw->mac.ops.setup_sfp(hw);
+ hw->phy.sfp_setup_needed = false;
+ }
+
/* Reset PHY */
- hw->phy.ops.reset(hw);
+ if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL)
+ hw->phy.ops.reset(hw);
/*
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
* access and verify no pending requests before reset
*/
- if (ixgbe_disable_pcie_master(hw) != 0) {
+ status = ixgbe_disable_pcie_master(hw);
+ if (status != 0) {
status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
}
@@ -770,9 +910,30 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
}
}
+ /*
+ * Store MAC address from RAR0, clear receive address registers, and
+ * clear the multicast table. Also reset num_rar_entries to 128,
+ * since we modify this value when programming the SAN MAC address.
+ */
+ hw->mac.num_rar_entries = 128;
+ hw->mac.ops.init_rx_addrs(hw);
+
/* Store the permanent mac address */
hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
+ /* Store the permanent SAN mac address */
+ hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr);
+
+ /* Add the SAN MAC address to the RAR only if it's a valid address */
+ if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) {
+ hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
+ hw->mac.san_addr, 0, IXGBE_RAH_AV);
+
+ /* Reserve the last RAR for the SAN MAC address */
+ hw->mac.num_rar_entries--;
+ }
+
+reset_hw_out:
return status;
}
@@ -1004,6 +1165,931 @@ s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables.
+ * @hw: pointer to hardware structure
+ **/
+s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)
+{
+ int i;
+ u32 fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);
+ fdirctrl &= ~IXGBE_FDIRCTRL_INIT_DONE;
+
+ /*
+ * Before starting reinitialization process,
+ * FDIRCMD.CMD must be zero.
+ */
+ for (i = 0; i < IXGBE_FDIRCMD_CMD_POLL; i++) {
+ if (!(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) &
+ IXGBE_FDIRCMD_CMD_MASK))
+ break;
+ udelay(10);
+ }
+ if (i >= IXGBE_FDIRCMD_CMD_POLL) {
+ hw_dbg(hw ,"Flow Director previous command isn't complete, "
+ "aborting table re-initialization. \n");
+ return IXGBE_ERR_FDIR_REINIT_FAILED;
+ }
+
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRFREE, 0);
+ IXGBE_WRITE_FLUSH(hw);
+ /*
+ * 82599 adapters flow director init flow cannot be restarted,
+ * Workaround 82599 silicon errata by performing the following steps
+ * before re-writing the FDIRCTRL control register with the same value.
+ * - write 1 to bit 8 of FDIRCMD register &
+ * - write 0 to bit 8 of FDIRCMD register
+ */
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
+ (IXGBE_READ_REG(hw, IXGBE_FDIRCMD) |
+ IXGBE_FDIRCMD_CLEARHT));
+ IXGBE_WRITE_FLUSH(hw);
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
+ (IXGBE_READ_REG(hw, IXGBE_FDIRCMD) &
+ ~IXGBE_FDIRCMD_CLEARHT));
+ IXGBE_WRITE_FLUSH(hw);
+ /*
+ * Clear FDIR Hash register to clear any leftover hashes
+ * waiting to be programmed.
+ */
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, 0x00);
+ IXGBE_WRITE_FLUSH(hw);
+
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
+ IXGBE_WRITE_FLUSH(hw);
+
+ /* Poll init-done after we write FDIRCTRL register */
+ for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
+ if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
+ IXGBE_FDIRCTRL_INIT_DONE)
+ break;
+ udelay(10);
+ }
+ if (i >= IXGBE_FDIR_INIT_DONE_POLL) {
+ hw_dbg(hw, "Flow Director Signature poll time exceeded!\n");
+ return IXGBE_ERR_FDIR_REINIT_FAILED;
+ }
+
+ /* Clear FDIR statistics registers (read to clear) */
+ IXGBE_READ_REG(hw, IXGBE_FDIRUSTAT);
+ IXGBE_READ_REG(hw, IXGBE_FDIRFSTAT);
+ IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
+ IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
+ IXGBE_READ_REG(hw, IXGBE_FDIRLEN);
+
+ return 0;
+}
+
+/**
+ * ixgbe_init_fdir_signature_82599 - Initialize Flow Director signature filters
+ * @hw: pointer to hardware structure
+ * @pballoc: which mode to allocate filters with
+ **/
+s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc)
+{
+ u32 fdirctrl = 0;
+ u32 pbsize;
+ int i;
+
+ /*
+ * Before enabling Flow Director, the Rx Packet Buffer size
+ * must be reduced. The new value is the current size minus
+ * flow director memory usage size.
+ */
+ pbsize = (1 << (IXGBE_FDIR_PBALLOC_SIZE_SHIFT + pballoc));
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0),
+ (IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize));
+
+ /*
+ * The defaults in the HW for RX PB 1-7 are not zero and so should be
+ * intialized to zero for non DCB mode otherwise actual total RX PB
+ * would be bigger than programmed and filter space would run into
+ * the PB 0 region.
+ */
+ for (i = 1; i < 8; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
+
+ /* Send interrupt when 64 filters are left */
+ fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT;
+
+ /* Set the maximum length per hash bucket to 0xA filters */
+ fdirctrl |= 0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT;
+
+ switch (pballoc) {
+ case IXGBE_FDIR_PBALLOC_64K:
+ /* 8k - 1 signature filters */
+ fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K;
+ break;
+ case IXGBE_FDIR_PBALLOC_128K:
+ /* 16k - 1 signature filters */
+ fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K;
+ break;
+ case IXGBE_FDIR_PBALLOC_256K:
+ /* 32k - 1 signature filters */
+ fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K;
+ break;
+ default:
+ /* bad value */
+ return IXGBE_ERR_CONFIG;
+ };
+
+ /* Move the flexible bytes to use the ethertype - shift 6 words */
+ fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT);
+
+ fdirctrl |= IXGBE_FDIRCTRL_REPORT_STATUS;
+
+ /* Prime the keys for hashing */
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY,
+ htonl(IXGBE_ATR_BUCKET_HASH_KEY));
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY,
+ htonl(IXGBE_ATR_SIGNATURE_HASH_KEY));
+
+ /*
+ * Poll init-done after we write the register. Estimated times:
+ * 10G: PBALLOC = 11b, timing is 60us
+ * 1G: PBALLOC = 11b, timing is 600us
+ * 100M: PBALLOC = 11b, timing is 6ms
+ *
+ * Multiple these timings by 4 if under full Rx load
+ *
+ * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for
+ * 1 msec per poll time. If we're at line rate and drop to 100M, then
+ * this might not finish in our poll time, but we can live with that
+ * for now.
+ */
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
+ IXGBE_WRITE_FLUSH(hw);
+ for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
+ if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
+ IXGBE_FDIRCTRL_INIT_DONE)
+ break;
+ msleep(1);
+ }
+ if (i >= IXGBE_FDIR_INIT_DONE_POLL)
+ hw_dbg(hw, "Flow Director Signature poll time exceeded!\n");
+
+ return 0;
+}
+
+/**
+ * ixgbe_init_fdir_perfect_82599 - Initialize Flow Director perfect filters
+ * @hw: pointer to hardware structure
+ * @pballoc: which mode to allocate filters with
+ **/
+s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc)
+{
+ u32 fdirctrl = 0;
+ u32 pbsize;
+ int i;
+
+ /*
+ * Before enabling Flow Director, the Rx Packet Buffer size
+ * must be reduced. The new value is the current size minus
+ * flow director memory usage size.
+ */
+ pbsize = (1 << (IXGBE_FDIR_PBALLOC_SIZE_SHIFT + pballoc));
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0),
+ (IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize));
+
+ /*
+ * The defaults in the HW for RX PB 1-7 are not zero and so should be
+ * intialized to zero for non DCB mode otherwise actual total RX PB
+ * would be bigger than programmed and filter space would run into
+ * the PB 0 region.
+ */
+ for (i = 1; i < 8; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
+
+ /* Send interrupt when 64 filters are left */
+ fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT;
+
+ switch (pballoc) {
+ case IXGBE_FDIR_PBALLOC_64K:
+ /* 2k - 1 perfect filters */
+ fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K;
+ break;
+ case IXGBE_FDIR_PBALLOC_128K:
+ /* 4k - 1 perfect filters */
+ fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K;
+ break;
+ case IXGBE_FDIR_PBALLOC_256K:
+ /* 8k - 1 perfect filters */
+ fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K;
+ break;
+ default:
+ /* bad value */
+ return IXGBE_ERR_CONFIG;
+ };
+
+ /* Turn perfect match filtering on */
+ fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH;
+ fdirctrl |= IXGBE_FDIRCTRL_REPORT_STATUS;
+
+ /* Move the flexible bytes to use the ethertype - shift 6 words */
+ fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT);
+
+ /* Prime the keys for hashing */
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY,
+ htonl(IXGBE_ATR_BUCKET_HASH_KEY));
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY,
+ htonl(IXGBE_ATR_SIGNATURE_HASH_KEY));
+
+ /*
+ * Poll init-done after we write the register. Estimated times:
+ * 10G: PBALLOC = 11b, timing is 60us
+ * 1G: PBALLOC = 11b, timing is 600us
+ * 100M: PBALLOC = 11b, timing is 6ms
+ *
+ * Multiple these timings by 4 if under full Rx load
+ *
+ * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for
+ * 1 msec per poll time. If we're at line rate and drop to 100M, then
+ * this might not finish in our poll time, but we can live with that
+ * for now.
+ */
+
+ /* Set the maximum length per hash bucket to 0xA filters */
+ fdirctrl |= (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT);
+
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
+ IXGBE_WRITE_FLUSH(hw);
+ for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
+ if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
+ IXGBE_FDIRCTRL_INIT_DONE)
+ break;
+ msleep(1);
+ }
+ if (i >= IXGBE_FDIR_INIT_DONE_POLL)
+ hw_dbg(hw, "Flow Director Perfect poll time exceeded!\n");
+
+ return 0;
+}
+
+
+/**
+ * ixgbe_atr_compute_hash_82599 - Compute the hashes for SW ATR
+ * @stream: input bitstream to compute the hash on
+ * @key: 32-bit hash key
+ **/
+u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *atr_input, u32 key)
+{
+ /*
+ * The algorithm is as follows:
+ * Hash[15:0] = Sum { S[n] x K[n+16] }, n = 0...350
+ * where Sum {A[n]}, n = 0...n is bitwise XOR of A[0], A[1]...A[n]
+ * and A[n] x B[n] is bitwise AND between same length strings
+ *
+ * K[n] is 16 bits, defined as:
+ * for n modulo 32 >= 15, K[n] = K[n % 32 : (n % 32) - 15]
+ * for n modulo 32 < 15, K[n] =
+ * K[(n % 32:0) | (31:31 - (14 - (n % 32)))]
+ *
+ * S[n] is 16 bits, defined as:
+ * for n >= 15, S[n] = S[n:n - 15]
+ * for n < 15, S[n] = S[(n:0) | (350:350 - (14 - n))]
+ *
+ * To simplify for programming, the algorithm is implemented
+ * in software this way:
+ *
+ * Key[31:0], Stream[335:0]
+ *
+ * tmp_key[11 * 32 - 1:0] = 11{Key[31:0] = key concatenated 11 times
+ * int_key[350:0] = tmp_key[351:1]
+ * int_stream[365:0] = Stream[14:0] | Stream[335:0] | Stream[335:321]
+ *
+ * hash[15:0] = 0;
+ * for (i = 0; i < 351; i++) {
+ * if (int_key[i])
+ * hash ^= int_stream[(i + 15):i];
+ * }
+ */
+
+ union {
+ u64 fill[6];
+ u32 key[11];
+ u8 key_stream[44];
+ } tmp_key;
+
+ u8 *stream = (u8 *)atr_input;
+ u8 int_key[44]; /* upper-most bit unused */
+ u8 hash_str[46]; /* upper-most 2 bits unused */
+ u16 hash_result = 0;
+ int i, j, k, h;
+
+ /*
+ * Initialize the fill member to prevent warnings
+ * on some compilers
+ */
+ tmp_key.fill[0] = 0;
+
+ /* First load the temporary key stream */
+ for (i = 0; i < 6; i++) {
+ u64 fillkey = ((u64)key << 32) | key;
+ tmp_key.fill[i] = fillkey;
+ }
+
+ /*
+ * Set the interim key for the hashing. Bit 352 is unused, so we must
+ * shift and compensate when building the key.
+ */
+
+ int_key[0] = tmp_key.key_stream[0] >> 1;
+ for (i = 1, j = 0; i < 44; i++) {
+ unsigned int this_key = tmp_key.key_stream[j] << 7;
+ j++;
+ int_key[i] = (u8)(this_key | (tmp_key.key_stream[j] >> 1));
+ }
+
+ /*
+ * Set the interim bit string for the hashing. Bits 368 and 367 are
+ * unused, so shift and compensate when building the string.
+ */
+ hash_str[0] = (stream[40] & 0x7f) >> 1;
+ for (i = 1, j = 40; i < 46; i++) {
+ unsigned int this_str = stream[j] << 7;
+ j++;
+ if (j > 41)
+ j = 0;
+ hash_str[i] = (u8)(this_str | (stream[j] >> 1));
+ }
+
+ /*
+ * Now compute the hash. i is the index into hash_str, j is into our
+ * key stream, k is counting the number of bits, and h interates within
+ * each byte.
+ */
+ for (i = 45, j = 43, k = 0; k < 351 && i >= 2 && j >= 0; i--, j--) {
+ for (h = 0; h < 8 && k < 351; h++, k++) {
+ if (int_key[j] & (1 << h)) {
+ /*
+ * Key bit is set, XOR in the current 16-bit
+ * string. Example of processing:
+ * h = 0,
+ * tmp = (hash_str[i - 2] & 0 << 16) |
+ * (hash_str[i - 1] & 0xff << 8) |
+ * (hash_str[i] & 0xff >> 0)
+ * So tmp = hash_str[15 + k:k], since the
+ * i + 2 clause rolls off the 16-bit value
+ * h = 7,
+ * tmp = (hash_str[i - 2] & 0x7f << 9) |
+ * (hash_str[i - 1] & 0xff << 1) |
+ * (hash_str[i] & 0x80 >> 7)
+ */
+ int tmp = (hash_str[i] >> h);
+ tmp |= (hash_str[i - 1] << (8 - h));
+ tmp |= (int)(hash_str[i - 2] & ((1 << h) - 1))
+ << (16 - h);
+ hash_result ^= (u16)tmp;
+ }
+ }
+ }
+
+ return hash_result;
+}
+
+/**
+ * ixgbe_atr_set_vlan_id_82599 - Sets the VLAN id in the ATR input stream
+ * @input: input stream to modify
+ * @vlan: the VLAN id to load
+ **/
+s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan)
+{
+ input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] = vlan >> 8;
+ input->byte_stream[IXGBE_ATR_VLAN_OFFSET] = vlan & 0xff;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_set_src_ipv4_82599 - Sets the source IPv4 address
+ * @input: input stream to modify
+ * @src_addr: the IP address to load
+ **/
+s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr)
+{
+ input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 3] = src_addr >> 24;
+ input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 2] =
+ (src_addr >> 16) & 0xff;
+ input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 1] =
+ (src_addr >> 8) & 0xff;
+ input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET] = src_addr & 0xff;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_set_dst_ipv4_82599 - Sets the destination IPv4 address
+ * @input: input stream to modify
+ * @dst_addr: the IP address to load
+ **/
+s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr)
+{
+ input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 3] = dst_addr >> 24;
+ input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 2] =
+ (dst_addr >> 16) & 0xff;
+ input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 1] =
+ (dst_addr >> 8) & 0xff;
+ input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET] = dst_addr & 0xff;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_set_src_ipv6_82599 - Sets the source IPv6 address
+ * @input: input stream to modify
+ * @src_addr_1: the first 4 bytes of the IP address to load
+ * @src_addr_2: the second 4 bytes of the IP address to load
+ * @src_addr_3: the third 4 bytes of the IP address to load
+ * @src_addr_4: the fourth 4 bytes of the IP address to load
+ **/
+s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input,
+ u32 src_addr_1, u32 src_addr_2,
+ u32 src_addr_3, u32 src_addr_4)
+{
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET] = src_addr_4 & 0xff;
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] =
+ (src_addr_4 >> 8) & 0xff;
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 2] =
+ (src_addr_4 >> 16) & 0xff;
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 3] = src_addr_4 >> 24;
+
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 4] = src_addr_3 & 0xff;
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 5] =
+ (src_addr_3 >> 8) & 0xff;
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 6] =
+ (src_addr_3 >> 16) & 0xff;
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 7] = src_addr_3 >> 24;
+
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 8] = src_addr_2 & 0xff;
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 9] =
+ (src_addr_2 >> 8) & 0xff;
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 10] =
+ (src_addr_2 >> 16) & 0xff;
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 11] = src_addr_2 >> 24;
+
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12] = src_addr_1 & 0xff;
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] =
+ (src_addr_1 >> 8) & 0xff;
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 14] =
+ (src_addr_1 >> 16) & 0xff;
+ input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 15] = src_addr_1 >> 24;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_set_dst_ipv6_82599 - Sets the destination IPv6 address
+ * @input: input stream to modify
+ * @dst_addr_1: the first 4 bytes of the IP address to load
+ * @dst_addr_2: the second 4 bytes of the IP address to load
+ * @dst_addr_3: the third 4 bytes of the IP address to load
+ * @dst_addr_4: the fourth 4 bytes of the IP address to load
+ **/
+s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input,
+ u32 dst_addr_1, u32 dst_addr_2,
+ u32 dst_addr_3, u32 dst_addr_4)
+{
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET] = dst_addr_4 & 0xff;
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] =
+ (dst_addr_4 >> 8) & 0xff;
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] =
+ (dst_addr_4 >> 16) & 0xff;
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] = dst_addr_4 >> 24;
+
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4] = dst_addr_3 & 0xff;
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] =
+ (dst_addr_3 >> 8) & 0xff;
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] =
+ (dst_addr_3 >> 16) & 0xff;
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] = dst_addr_3 >> 24;
+
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8] = dst_addr_2 & 0xff;
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] =
+ (dst_addr_2 >> 8) & 0xff;
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] =
+ (dst_addr_2 >> 16) & 0xff;
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] = dst_addr_2 >> 24;
+
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12] = dst_addr_1 & 0xff;
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] =
+ (dst_addr_1 >> 8) & 0xff;
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] =
+ (dst_addr_1 >> 16) & 0xff;
+ input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] = dst_addr_1 >> 24;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_set_src_port_82599 - Sets the source port
+ * @input: input stream to modify
+ * @src_port: the source port to load
+ **/
+s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port)
+{
+ input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET + 1] = src_port >> 8;
+ input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET] = src_port & 0xff;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_set_dst_port_82599 - Sets the destination port
+ * @input: input stream to modify
+ * @dst_port: the destination port to load
+ **/
+s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, u16 dst_port)
+{
+ input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET + 1] = dst_port >> 8;
+ input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET] = dst_port & 0xff;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_set_flex_byte_82599 - Sets the flexible bytes
+ * @input: input stream to modify
+ * @flex_bytes: the flexible bytes to load
+ **/
+s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte)
+{
+ input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET + 1] = flex_byte >> 8;
+ input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET] = flex_byte & 0xff;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_set_vm_pool_82599 - Sets the Virtual Machine pool
+ * @input: input stream to modify
+ * @vm_pool: the Virtual Machine pool to load
+ **/
+s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, u8 vm_pool)
+{
+ input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET] = vm_pool;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_set_l4type_82599 - Sets the layer 4 packet type
+ * @input: input stream to modify
+ * @l4type: the layer 4 type value to load
+ **/
+s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, u8 l4type)
+{
+ input->byte_stream[IXGBE_ATR_L4TYPE_OFFSET] = l4type;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_get_vlan_id_82599 - Gets the VLAN id from the ATR input stream
+ * @input: input stream to search
+ * @vlan: the VLAN id to load
+ **/
+s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, u16 *vlan)
+{
+ *vlan = input->byte_stream[IXGBE_ATR_VLAN_OFFSET];
+ *vlan |= input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] << 8;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_get_src_ipv4_82599 - Gets the source IPv4 address
+ * @input: input stream to search
+ * @src_addr: the IP address to load
+ **/
+s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input, u32 *src_addr)
+{
+ *src_addr = input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET];
+ *src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 1] << 8;
+ *src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 2] << 16;
+ *src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 3] << 24;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_get_dst_ipv4_82599 - Gets the destination IPv4 address
+ * @input: input stream to search
+ * @dst_addr: the IP address to load
+ **/
+s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 *dst_addr)
+{
+ *dst_addr = input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET];
+ *dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 1] << 8;
+ *dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 2] << 16;
+ *dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 3] << 24;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_get_src_ipv6_82599 - Gets the source IPv6 address
+ * @input: input stream to search
+ * @src_addr_1: the first 4 bytes of the IP address to load
+ * @src_addr_2: the second 4 bytes of the IP address to load
+ * @src_addr_3: the third 4 bytes of the IP address to load
+ * @src_addr_4: the fourth 4 bytes of the IP address to load
+ **/
+s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input,
+ u32 *src_addr_1, u32 *src_addr_2,
+ u32 *src_addr_3, u32 *src_addr_4)
+{
+ *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12];
+ *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] << 8;
+ *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 14] << 16;
+ *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 15] << 24;
+
+ *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 8];
+ *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 9] << 8;
+ *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 10] << 16;
+ *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 11] << 24;
+
+ *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 4];
+ *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 5] << 8;
+ *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 6] << 16;
+ *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 7] << 24;
+
+ *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET];
+ *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] << 8;
+ *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 2] << 16;
+ *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 3] << 24;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_get_dst_ipv6_82599 - Gets the destination IPv6 address
+ * @input: input stream to search
+ * @dst_addr_1: the first 4 bytes of the IP address to load
+ * @dst_addr_2: the second 4 bytes of the IP address to load
+ * @dst_addr_3: the third 4 bytes of the IP address to load
+ * @dst_addr_4: the fourth 4 bytes of the IP address to load
+ **/
+s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input,
+ u32 *dst_addr_1, u32 *dst_addr_2,
+ u32 *dst_addr_3, u32 *dst_addr_4)
+{
+ *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12];
+ *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] << 8;
+ *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] << 16;
+ *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] << 24;
+
+ *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8];
+ *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] << 8;
+ *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] << 16;
+ *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] << 24;
+
+ *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4];
+ *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] << 8;
+ *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] << 16;
+ *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] << 24;
+
+ *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET];
+ *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] << 8;
+ *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] << 16;
+ *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] << 24;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_get_src_port_82599 - Gets the source port
+ * @input: input stream to modify
+ * @src_port: the source port to load
+ *
+ * Even though the input is given in big-endian, the FDIRPORT registers
+ * expect the ports to be programmed in little-endian. Hence the need to swap
+ * endianness when retrieving the data. This can be confusing since the
+ * internal hash engine expects it to be big-endian.
+ **/
+s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input, u16 *src_port)
+{
+ *src_port = input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET] << 8;
+ *src_port |= input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET + 1];
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_get_dst_port_82599 - Gets the destination port
+ * @input: input stream to modify
+ * @dst_port: the destination port to load
+ *
+ * Even though the input is given in big-endian, the FDIRPORT registers
+ * expect the ports to be programmed in little-endian. Hence the need to swap
+ * endianness when retrieving the data. This can be confusing since the
+ * internal hash engine expects it to be big-endian.
+ **/
+s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input, u16 *dst_port)
+{
+ *dst_port = input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET] << 8;
+ *dst_port |= input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET + 1];
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_get_flex_byte_82599 - Gets the flexible bytes
+ * @input: input stream to modify
+ * @flex_bytes: the flexible bytes to load
+ **/
+s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input, u16 *flex_byte)
+{
+ *flex_byte = input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET];
+ *flex_byte |= input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET + 1] << 8;
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_get_vm_pool_82599 - Gets the Virtual Machine pool
+ * @input: input stream to modify
+ * @vm_pool: the Virtual Machine pool to load
+ **/
+s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, u8 *vm_pool)
+{
+ *vm_pool = input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET];
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_get_l4type_82599 - Gets the layer 4 packet type
+ * @input: input stream to modify
+ * @l4type: the layer 4 type value to load
+ **/
+s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input, u8 *l4type)
+{
+ *l4type = input->byte_stream[IXGBE_ATR_L4TYPE_OFFSET];
+
+ return 0;
+}
+
+/**
+ * ixgbe_atr_add_signature_filter_82599 - Adds a signature hash filter
+ * @hw: pointer to hardware structure
+ * @stream: input bitstream
+ * @queue: queue index to direct traffic to
+ **/
+s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_atr_input *input,
+ u8 queue)
+{
+ u64 fdirhashcmd;
+ u64 fdircmd;
+ u32 fdirhash;
+ u16 bucket_hash, sig_hash;
+ u8 l4type;
+
+ bucket_hash = ixgbe_atr_compute_hash_82599(input,
+ IXGBE_ATR_BUCKET_HASH_KEY);
+
+ /* bucket_hash is only 15 bits */
+ bucket_hash &= IXGBE_ATR_HASH_MASK;
+
+ sig_hash = ixgbe_atr_compute_hash_82599(input,
+ IXGBE_ATR_SIGNATURE_HASH_KEY);
+
+ /* Get the l4type in order to program FDIRCMD properly */
+ /* lowest 2 bits are FDIRCMD.L4TYPE, third lowest bit is FDIRCMD.IPV6 */
+ ixgbe_atr_get_l4type_82599(input, &l4type);
+
+ /*
+ * The lower 32-bits of fdirhashcmd is for FDIRHASH, the upper 32-bits
+ * is for FDIRCMD. Then do a 64-bit register write from FDIRHASH.
+ */
+ fdirhash = sig_hash << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT | bucket_hash;
+
+ fdircmd = (IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE |
+ IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN);
+
+ switch (l4type & IXGBE_ATR_L4TYPE_MASK) {
+ case IXGBE_ATR_L4TYPE_TCP:
+ fdircmd |= IXGBE_FDIRCMD_L4TYPE_TCP;
+ break;
+ case IXGBE_ATR_L4TYPE_UDP:
+ fdircmd |= IXGBE_FDIRCMD_L4TYPE_UDP;
+ break;
+ case IXGBE_ATR_L4TYPE_SCTP:
+ fdircmd |= IXGBE_FDIRCMD_L4TYPE_SCTP;
+ break;
+ default:
+ hw_dbg(hw, "Error on l4type input\n");
+ return IXGBE_ERR_CONFIG;
+ }
+
+ if (l4type & IXGBE_ATR_L4TYPE_IPV6_MASK)
+ fdircmd |= IXGBE_FDIRCMD_IPV6;
+
+ fdircmd |= ((u64)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT);
+ fdirhashcmd = ((fdircmd << 32) | fdirhash);
+
+ IXGBE_WRITE_REG64(hw, IXGBE_FDIRHASH, fdirhashcmd);
+
+ return 0;
+}
+
+/**
+ * ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter
+ * @hw: pointer to hardware structure
+ * @input: input bitstream
+ * @queue: queue index to direct traffic to
+ *
+ * Note that the caller to this function must lock before calling, since the
+ * hardware writes must be protected from one another.
+ **/
+s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_atr_input *input,
+ u16 soft_id,
+ u8 queue)
+{
+ u32 fdircmd = 0;
+ u32 fdirhash;
+ u32 src_ipv4, dst_ipv4;
+ u32 src_ipv6_1, src_ipv6_2, src_ipv6_3, src_ipv6_4;
+ u16 src_port, dst_port, vlan_id, flex_bytes;
+ u16 bucket_hash;
+ u8 l4type;
+
+ /* Get our input values */
+ ixgbe_atr_get_l4type_82599(input, &l4type);
+
+ /*
+ * Check l4type formatting, and bail out before we touch the hardware
+ * if there's a configuration issue
+ */
+ switch (l4type & IXGBE_ATR_L4TYPE_MASK) {
+ case IXGBE_ATR_L4TYPE_TCP:
+ fdircmd |= IXGBE_FDIRCMD_L4TYPE_TCP;
+ break;
+ case IXGBE_ATR_L4TYPE_UDP:
+ fdircmd |= IXGBE_FDIRCMD_L4TYPE_UDP;
+ break;
+ case IXGBE_ATR_L4TYPE_SCTP:
+ fdircmd |= IXGBE_FDIRCMD_L4TYPE_SCTP;
+ break;
+ default:
+ hw_dbg(hw, "Error on l4type input\n");
+ return IXGBE_ERR_CONFIG;
+ }
+
+ bucket_hash = ixgbe_atr_compute_hash_82599(input,
+ IXGBE_ATR_BUCKET_HASH_KEY);
+
+ /* bucket_hash is only 15 bits */
+ bucket_hash &= IXGBE_ATR_HASH_MASK;
+
+ ixgbe_atr_get_vlan_id_82599(input, &vlan_id);
+ ixgbe_atr_get_src_port_82599(input, &src_port);
+ ixgbe_atr_get_dst_port_82599(input, &dst_port);
+ ixgbe_atr_get_flex_byte_82599(input, &flex_bytes);
+
+ fdirhash = soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT | bucket_hash;
+
+ /* Now figure out if we're IPv4 or IPv6 */
+ if (l4type & IXGBE_ATR_L4TYPE_IPV6_MASK) {
+ /* IPv6 */
+ ixgbe_atr_get_src_ipv6_82599(input, &src_ipv6_1, &src_ipv6_2,
+ &src_ipv6_3, &src_ipv6_4);
+
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(0), src_ipv6_1);
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(1), src_ipv6_2);
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(2), src_ipv6_3);
+ /* The last 4 bytes is the same register as IPv4 */
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv6_4);
+
+ fdircmd |= IXGBE_FDIRCMD_IPV6;
+ fdircmd |= IXGBE_FDIRCMD_IPv6DMATCH;
+ } else {
+ /* IPv4 */
+ ixgbe_atr_get_src_ipv4_82599(input, &src_ipv4);
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv4);
+
+ }
+
+ ixgbe_atr_get_dst_ipv4_82599(input, &dst_ipv4);
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRIPDA, dst_ipv4);
+
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, (vlan_id |
+ (flex_bytes << IXGBE_FDIRVLAN_FLEX_SHIFT)));
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, (src_port |
+ (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT)));
+
+ fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW;
+ fdircmd |= IXGBE_FDIRCMD_FILTER_UPDATE;
+ fdircmd |= IXGBE_FDIRCMD_LAST;
+ fdircmd |= IXGBE_FDIRCMD_QUEUE_EN;
+ fdircmd |= queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT;
+
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd);
+
+ return 0;
+}
+/**
* ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register
* @hw: pointer to hardware structure
* @reg: analog register to read
@@ -1056,8 +2142,9 @@ s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val)
s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
{
u32 q_num;
+ s32 ret_val;
- ixgbe_start_hw_generic(hw);
+ ret_val = ixgbe_start_hw_generic(hw);
/* Clear the rate limiters */
for (q_num = 0; q_num < hw->mac.max_tx_queues; q_num++) {
@@ -1066,7 +2153,13 @@ s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
}
IXGBE_WRITE_FLUSH(hw);
- return 0;
+ /* We need to run link autotry after the driver loads */
+ hw->mac.autotry_restart = true;
+
+ if (ret_val == 0)
+ ret_val = ixgbe_verify_fw_version_82599(hw);
+
+ return ret_val;
}
/**
@@ -1093,53 +2186,100 @@ s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
{
u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+ u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
+ u32 pma_pmd_10g_parallel = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
+ u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+ u16 ext_ability = 0;
u8 comp_codes_10g = 0;
- switch (hw->device_id) {
- case IXGBE_DEV_ID_82599:
- case IXGBE_DEV_ID_82599_KX4:
- /* Default device ID is mezzanine card KX/KX4 */
- physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
- IXGBE_PHYSICAL_LAYER_1000BASE_KX);
+ hw->phy.ops.identify(hw);
+
+ if (hw->phy.type == ixgbe_phy_tn ||
+ hw->phy.type == ixgbe_phy_cu_unknown) {
+ hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD,
+ &ext_ability);
+ if (ext_ability & MDIO_PMA_EXTABLE_10GBT)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
+ if (ext_ability & MDIO_PMA_EXTABLE_1000BT)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
+ if (ext_ability & MDIO_PMA_EXTABLE_100BTX)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
+ goto out;
+ }
+
+ switch (autoc & IXGBE_AUTOC_LMS_MASK) {
+ case IXGBE_AUTOC_LMS_1G_AN:
+ case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
+ if (pma_pmd_1g == IXGBE_AUTOC_1G_KX_BX) {
+ physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX |
+ IXGBE_PHYSICAL_LAYER_1000BASE_BX;
+ goto out;
+ } else
+ /* SFI mode so read SFP module */
+ goto sfp_check;
break;
- case IXGBE_DEV_ID_82599_SFP:
- hw->phy.ops.identify_sfp(hw);
+ case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
+ if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_CX4)
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
+ else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_KX4)
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+ else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_XAUI)
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_XAUI;
+ goto out;
+ break;
+ case IXGBE_AUTOC_LMS_10G_SERIAL:
+ if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_KR) {
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR;
+ goto out;
+ } else if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)
+ goto sfp_check;
+ break;
+ case IXGBE_AUTOC_LMS_KX4_KX_KR:
+ case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
+ if (autoc & IXGBE_AUTOC_KX_SUPP)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+ if (autoc & IXGBE_AUTOC_KX4_SUPP)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+ if (autoc & IXGBE_AUTOC_KR_SUPP)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KR;
+ goto out;
+ break;
+ default:
+ goto out;
+ break;
+ }
- switch (hw->phy.sfp_type) {
- case ixgbe_sfp_type_da_cu:
- case ixgbe_sfp_type_da_cu_core0:
- case ixgbe_sfp_type_da_cu_core1:
- physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
- break;
- case ixgbe_sfp_type_sr:
+sfp_check:
+ /* SFP check must be done last since DA modules are sometimes used to
+ * test KR mode - we need to id KR mode correctly before SFP module.
+ * Call identify_sfp because the pluggable module may have changed */
+ hw->phy.ops.identify_sfp(hw);
+ if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
+ goto out;
+
+ switch (hw->phy.type) {
+ case ixgbe_phy_tw_tyco:
+ case ixgbe_phy_tw_unknown:
+ physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+ break;
+ case ixgbe_phy_sfp_avago:
+ case ixgbe_phy_sfp_ftl:
+ case ixgbe_phy_sfp_intel:
+ case ixgbe_phy_sfp_unknown:
+ hw->phy.ops.read_i2c_eeprom(hw,
+ IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g);
+ if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
- break;
- case ixgbe_sfp_type_lr:
+ else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
- break;
- case ixgbe_sfp_type_srlr_core0:
- case ixgbe_sfp_type_srlr_core1:
- hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_10GBE_COMP_CODES,
- &comp_codes_10g);
- if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
- physical_layer =
- IXGBE_PHYSICAL_LAYER_10GBASE_SR;
- else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
- physical_layer =
- IXGBE_PHYSICAL_LAYER_10GBASE_LR;
- else
- physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
- default:
- physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
- break;
- }
break;
default:
- physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
break;
}
+out:
return physical_layer;
}
@@ -1187,6 +2327,138 @@ s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
return 0;
}
+/**
+ * ixgbe_get_device_caps_82599 - Get additional device capabilities
+ * @hw: pointer to hardware structure
+ * @device_caps: the EEPROM word with the extra device capabilities
+ *
+ * This function will read the EEPROM location for the device capabilities,
+ * and return the word through device_caps.
+ **/
+s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps)
+{
+ hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
+
+ return 0;
+}
+
+/**
+ * ixgbe_get_san_mac_addr_offset_82599 - SAN MAC address offset for 82599
+ * @hw: pointer to hardware structure
+ * @san_mac_offset: SAN MAC address offset
+ *
+ * This function will read the EEPROM location for the SAN MAC address
+ * pointer, and returns the value at that location. This is used in both
+ * get and set mac_addr routines.
+ **/
+s32 ixgbe_get_san_mac_addr_offset_82599(struct ixgbe_hw *hw,
+ u16 *san_mac_offset)
+{
+ /*
+ * First read the EEPROM pointer to see if the MAC addresses are
+ * available.
+ */
+ hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, san_mac_offset);
+
+ return 0;
+}
+
+/**
+ * ixgbe_get_san_mac_addr_82599 - SAN MAC address retrieval for 82599
+ * @hw: pointer to hardware structure
+ * @san_mac_addr: SAN MAC address
+ *
+ * Reads the SAN MAC address from the EEPROM, if it's available. This is
+ * per-port, so set_lan_id() must be called before reading the addresses.
+ * set_lan_id() is called by identify_sfp(), but this cannot be relied
+ * upon for non-SFP connections, so we must call it here.
+ **/
+s32 ixgbe_get_san_mac_addr_82599(struct ixgbe_hw *hw, u8 *san_mac_addr)
+{
+ u16 san_mac_data, san_mac_offset;
+ u8 i;
+
+ /*
+ * First read the EEPROM pointer to see if the MAC addresses are
+ * available. If they're not, no point in calling set_lan_id() here.
+ */
+ ixgbe_get_san_mac_addr_offset_82599(hw, &san_mac_offset);
+
+ if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) {
+ /*
+ * No addresses available in this EEPROM. It's not an
+ * error though, so just wipe the local address and return.
+ */
+ for (i = 0; i < 6; i++)
+ san_mac_addr[i] = 0xFF;
+
+ goto san_mac_addr_out;
+ }
+
+ /* make sure we know which port we need to program */
+ hw->mac.ops.set_lan_id(hw);
+ /* apply the port offset to the address offset */
+ (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) :
+ (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
+ for (i = 0; i < 3; i++) {
+ hw->eeprom.ops.read(hw, san_mac_offset, &san_mac_data);
+ san_mac_addr[i * 2] = (u8)(san_mac_data);
+ san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8);
+ san_mac_offset++;
+ }
+
+san_mac_addr_out:
+ return 0;
+}
+
+/**
+ * ixgbe_verify_fw_version_82599 - verify fw version for 82599
+ * @hw: pointer to hardware structure
+ *
+ * Verifies that installed the firmware version is 0.6 or higher
+ * for SFI devices. All 82599 SFI devices should have version 0.6 or higher.
+ *
+ * Returns IXGBE_ERR_EEPROM_VERSION if the FW is not present or
+ * if the FW version is not supported.
+ **/
+static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
+{
+ s32 status = IXGBE_ERR_EEPROM_VERSION;
+ u16 fw_offset, fw_ptp_cfg_offset;
+ u16 fw_version = 0;
+
+ /* firmware check is only necessary for SFI devices */
+ if (hw->phy.media_type != ixgbe_media_type_fiber) {
+ status = 0;
+ goto fw_version_out;
+ }
+
+ /* get the offset to the Firmware Module block */
+ hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset);
+
+ if ((fw_offset == 0) || (fw_offset == 0xFFFF))
+ goto fw_version_out;
+
+ /* get the offset to the Pass Through Patch Configuration block */
+ hw->eeprom.ops.read(hw, (fw_offset +
+ IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR),
+ &fw_ptp_cfg_offset);
+
+ if ((fw_ptp_cfg_offset == 0) || (fw_ptp_cfg_offset == 0xFFFF))
+ goto fw_version_out;
+
+ /* get the firmware version */
+ hw->eeprom.ops.read(hw, (fw_ptp_cfg_offset +
+ IXGBE_FW_PATCH_VERSION_4),
+ &fw_version);
+
+ if (fw_version > 0x5)
+ status = 0;
+
+fw_version_out:
+ return status;
+}
+
static struct ixgbe_mac_operations mac_ops_82599 = {
.init_hw = &ixgbe_init_hw_generic,
.reset_hw = &ixgbe_reset_hw_82599,
@@ -1196,6 +2468,8 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
.get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82599,
.enable_rx_dma = &ixgbe_enable_rx_dma_82599,
.get_mac_addr = &ixgbe_get_mac_addr_generic,
+ .get_san_mac_addr = &ixgbe_get_san_mac_addr_82599,
+ .get_device_caps = &ixgbe_get_device_caps_82599,
.stop_adapter = &ixgbe_stop_adapter_generic,
.get_bus_info = &ixgbe_get_bus_info_generic,
.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie,
@@ -1220,7 +2494,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
.disable_mc = &ixgbe_disable_mc_generic,
.clear_vfta = &ixgbe_clear_vfta_82599,
.set_vfta = &ixgbe_set_vfta_82599,
- .setup_fc = &ixgbe_setup_fc_generic,
+ .fc_enable = &ixgbe_fc_enable_generic,
.init_uta_tables = &ixgbe_init_uta_tables_82599,
.setup_sfp = &ixgbe_setup_sfp_modules_82599,
};
@@ -1236,6 +2510,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
static struct ixgbe_phy_operations phy_ops_82599 = {
.identify = &ixgbe_identify_phy_82599,
.identify_sfp = &ixgbe_identify_sfp_module_generic,
+ .init = &ixgbe_init_phy_ops_82599,
.reset = &ixgbe_reset_phy_generic,
.read_reg = &ixgbe_read_phy_reg_generic,
.write_reg = &ixgbe_write_phy_reg_generic,
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 186a65069b3..96a18595377 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -28,6 +28,8 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
#include "ixgbe.h"
#include "ixgbe_common.h"
@@ -71,12 +73,6 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
/* Identify the PHY */
hw->phy.ops.identify(hw);
- /*
- * Store MAC address from RAR0, clear receive address registers, and
- * clear the multicast table
- */
- hw->mac.ops.init_rx_addrs(hw);
-
/* Clear the VLAN filter table */
hw->mac.ops.clear_vfta(hw);
@@ -89,6 +85,9 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
IXGBE_WRITE_FLUSH(hw);
+ /* Setup flow control */
+ ixgbe_setup_fc(hw, 0);
+
/* Clear adapter stopped flag */
hw->adapter_stopped = false;
@@ -107,13 +106,17 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
**/
s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw)
{
+ s32 status;
+
/* Reset the hardware */
- hw->mac.ops.reset_hw(hw);
+ status = hw->mac.ops.reset_hw(hw);
- /* Start the HW */
- hw->mac.ops.start_hw(hw);
+ if (status == 0) {
+ /* Start the HW */
+ status = hw->mac.ops.start_hw(hw);
+ }
- return 0;
+ return status;
}
/**
@@ -1362,15 +1365,14 @@ static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
* Drivers using secondary unicast addresses must set user_set_promisc when
* manually putting the device into promiscuous mode.
**/
-s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
- u32 addr_count, ixgbe_mc_addr_itr next)
+s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw,
+ struct list_head *uc_list)
{
- u8 *addr;
u32 i;
u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc;
u32 uc_addr_in_use;
u32 fctrl;
- u32 vmdq;
+ struct netdev_hw_addr *ha;
/*
* Clear accounting of old secondary address list,
@@ -1388,10 +1390,9 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
}
/* Add the new addresses */
- for (i = 0; i < addr_count; i++) {
+ list_for_each_entry(ha, uc_list, list) {
hw_dbg(hw, " Adding the secondary addresses:\n");
- addr = next(hw, &addr_list, &vmdq);
- ixgbe_add_uc_addr(hw, addr, vmdq);
+ ixgbe_add_uc_addr(hw, ha->addr, 0);
}
if (hw->addr_ctrl.overflow_promisc) {
@@ -1583,19 +1584,30 @@ s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
}
/**
- * ixgbe_fc_enable - Enable flow control
+ * ixgbe_fc_enable_generic - Enable flow control
* @hw: pointer to hardware structure
* @packetbuf_num: packet buffer number (0-7)
*
* Enable flow control according to the current settings.
**/
-s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num)
+s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
{
s32 ret_val = 0;
- u32 mflcn_reg;
- u32 fccfg_reg;
+ u32 mflcn_reg, fccfg_reg;
u32 reg;
+ u32 rx_pba_size;
+#ifdef CONFIG_DCB
+ if (hw->fc.requested_mode == ixgbe_fc_pfc)
+ goto out;
+
+#endif /* CONFIG_DCB */
+ /* Negotiate the fc mode to use */
+ ret_val = ixgbe_fc_autoneg(hw);
+ if (ret_val)
+ goto out;
+
+ /* Disable any previous flow control settings */
mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE);
@@ -1615,7 +1627,10 @@ s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num)
*/
switch (hw->fc.current_mode) {
case ixgbe_fc_none:
- /* Flow control completely disabled by software override. */
+ /*
+ * Flow control is disabled by software override or autoneg.
+ * The code below will actually disable it in the HW.
+ */
break;
case ixgbe_fc_rx_pause:
/*
@@ -1644,7 +1659,7 @@ s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num)
case ixgbe_fc_pfc:
goto out;
break;
-#endif
+#endif /* CONFIG_DCB */
default:
hw_dbg(hw, "Flow control param set incorrectly\n");
ret_val = -IXGBE_ERR_CONFIG;
@@ -1652,25 +1667,48 @@ s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num)
break;
}
- /* Enable 802.3x based flow control settings. */
+ /* Set 802.3x based flow control settings. */
+ mflcn_reg |= IXGBE_MFLCN_DPF;
IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
- /* Set up and enable Rx high/low water mark thresholds, enable XON. */
- if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
- if (hw->fc.send_xon)
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num),
- (hw->fc.low_water | IXGBE_FCRTL_XONE));
- else
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num),
- hw->fc.low_water);
+ reg = IXGBE_READ_REG(hw, IXGBE_MTQC);
+ /* Thresholds are different for link flow control when in DCB mode */
+ if (reg & IXGBE_MTQC_RT_ENA) {
+ rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num));
+
+ /* Always disable XON for LFC when in DCB mode */
+ reg = (rx_pba_size >> 5) & 0xFFE0;
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), reg);
+
+ reg = (rx_pba_size >> 2) & 0xFFE0;
+ if (hw->fc.current_mode & ixgbe_fc_tx_pause)
+ reg |= IXGBE_FCRTH_FCEN;
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), reg);
+ } else {
+ /*
+ * Set up and enable Rx high/low water mark thresholds,
+ * enable XON.
+ */
+ if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
+ if (hw->fc.send_xon) {
+ IXGBE_WRITE_REG(hw,
+ IXGBE_FCRTL_82599(packetbuf_num),
+ (hw->fc.low_water |
+ IXGBE_FCRTL_XONE));
+ } else {
+ IXGBE_WRITE_REG(hw,
+ IXGBE_FCRTL_82599(packetbuf_num),
+ hw->fc.low_water);
+ }
- IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num),
- (hw->fc.high_water | IXGBE_FCRTH_FCEN));
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num),
+ (hw->fc.high_water | IXGBE_FCRTH_FCEN));
+ }
}
/* Configure pause time (2 TCs per register) */
- reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num));
+ reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2));
if ((packetbuf_num & 1) == 0)
reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
else
@@ -1687,100 +1725,41 @@ out:
* ixgbe_fc_autoneg - Configure flow control
* @hw: pointer to hardware structure
*
- * Negotiates flow control capabilities with link partner using autoneg and
- * applies the results.
+ * Compares our advertised flow control capabilities to those advertised by
+ * our link partner, and determines the proper flow control mode to use.
**/
s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
{
s32 ret_val = 0;
- u32 i, reg, pcs_anadv_reg, pcs_lpab_reg;
-
- reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
+ ixgbe_link_speed speed;
+ u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
+ bool link_up;
/*
- * The possible values of fc.current_mode are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames,
- * but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames but
- * we do not support receiving pause frames).
- * 3: Both Rx and Tx flow control (symmetric) are enabled.
- * 4: Priority Flow Control is enabled.
- * other: Invalid.
+ * AN should have completed when the cable was plugged in.
+ * Look for reasons to bail out. Bail out if:
+ * - FC autoneg is disabled, or if
+ * - we don't have multispeed fiber, or if
+ * - we're not running at 1G, or if
+ * - link is not up, or if
+ * - link is up but AN did not complete, or if
+ * - link is up and AN completed but timed out
+ *
+ * Since we're being called from an LSC, link is already know to be up.
+ * So use link_up_wait_to_complete=false.
*/
- switch (hw->fc.current_mode) {
- case ixgbe_fc_none:
- /* Flow control completely disabled by software override. */
- reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
- break;
- case ixgbe_fc_rx_pause:
- /*
- * Rx Flow control is enabled and Tx Flow control is
- * disabled by software override. Since there really
- * isn't a way to advertise that we are capable of RX
- * Pause ONLY, we will advertise that we support both
- * symmetric and asymmetric Rx PAUSE. Later, we will
- * disable the adapter's ability to send PAUSE frames.
- */
- reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
- break;
- case ixgbe_fc_tx_pause:
- /*
- * Tx Flow control is enabled, and Rx Flow control is
- * disabled by software override.
- */
- reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
- reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
- break;
- case ixgbe_fc_full:
- /* Flow control (both Rx and Tx) is enabled by SW override. */
- reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
- break;
-#ifdef CONFIG_DCB
- case ixgbe_fc_pfc:
- goto out;
- break;
-#endif
- default:
- hw_dbg(hw, "Flow control param set incorrectly\n");
- ret_val = -IXGBE_ERR_CONFIG;
- goto out;
- break;
- }
-
- IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
- reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
-
- /* Set PCS register for autoneg */
- /* Enable and restart autoneg */
- reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART;
-
- /* Disable AN timeout */
- if (hw->fc.strict_ieee)
- reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
-
- hw_dbg(hw, "Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg);
- IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
-
- /* See if autonegotiation has succeeded */
- hw->mac.autoneg_succeeded = 0;
- for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
- msleep(10);
- reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
- if ((reg & (IXGBE_PCS1GLSTA_LINK_OK |
- IXGBE_PCS1GLSTA_AN_COMPLETE)) ==
- (IXGBE_PCS1GLSTA_LINK_OK |
- IXGBE_PCS1GLSTA_AN_COMPLETE)) {
- if (!(reg & IXGBE_PCS1GLSTA_AN_TIMED_OUT))
- hw->mac.autoneg_succeeded = 1;
- break;
- }
- }
-
- if (!hw->mac.autoneg_succeeded) {
- /* Autoneg failed to achieve a link, so we turn fc off */
- hw->fc.current_mode = ixgbe_fc_none;
- hw_dbg(hw, "Flow Control = NONE.\n");
+ hw->mac.ops.check_link(hw, &speed, &link_up, false);
+ linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
+
+ if (hw->fc.disable_fc_autoneg ||
+ !hw->phy.multispeed_fiber ||
+ (speed != IXGBE_LINK_SPEED_1GB_FULL) ||
+ !link_up ||
+ ((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
+ ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
+ hw->fc.fc_was_autonegged = false;
+ hw->fc.current_mode = hw->fc.requested_mode;
+ hw_dbg(hw, "Autoneg FC was skipped.\n");
goto out;
}
@@ -1823,21 +1802,23 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
hw_dbg(hw, "Flow Control = NONE.\n");
}
+ /* Record that current_mode is the result of a successful autoneg */
+ hw->fc.fc_was_autonegged = true;
+
out:
return ret_val;
}
/**
- * ixgbe_setup_fc_generic - Set up flow control
+ * ixgbe_setup_fc - Set up flow control
* @hw: pointer to hardware structure
*
- * Sets up flow control.
+ * Called at init time to set up flow control.
**/
-s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
+s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
{
s32 ret_val = 0;
- ixgbe_link_speed speed;
- bool link_up;
+ u32 reg;
#ifdef CONFIG_DCB
if (hw->fc.requested_mode == ixgbe_fc_pfc) {
@@ -1866,7 +1847,7 @@ s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
/*
* Validate the requested mode. Strict IEEE mode does not allow
- * ixgbe_fc_rx_pause because it will cause testing anomalies.
+ * ixgbe_fc_rx_pause because it will cause us to fail at UNH.
*/
if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict "
@@ -1883,21 +1864,77 @@ s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
hw->fc.requested_mode = ixgbe_fc_full;
/*
- * Save off the requested flow control mode for use later. Depending
- * on the link partner's capabilities, we may or may not use this mode.
+ * Set up the 1G flow control advertisement registers so the HW will be
+ * able to do fc autoneg once the cable is plugged in. If we end up
+ * using 10g instead, this is harmless.
*/
- hw->fc.current_mode = hw->fc.requested_mode;
-
- /* Decide whether to use autoneg or not. */
- hw->mac.ops.check_link(hw, &speed, &link_up, false);
- if (!hw->fc.disable_fc_autoneg && hw->phy.multispeed_fiber &&
- (speed == IXGBE_LINK_SPEED_1GB_FULL))
- ret_val = ixgbe_fc_autoneg(hw);
+ reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
- if (ret_val)
+ /*
+ * The possible values of fc.requested_mode are:
+ * 0: Flow control is completely disabled
+ * 1: Rx flow control is enabled (we can receive pause frames,
+ * but not send pause frames).
+ * 2: Tx flow control is enabled (we can send pause frames but
+ * we do not support receiving pause frames).
+ * 3: Both Rx and Tx flow control (symmetric) are enabled.
+#ifdef CONFIG_DCB
+ * 4: Priority Flow Control is enabled.
+#endif
+ * other: Invalid.
+ */
+ switch (hw->fc.requested_mode) {
+ case ixgbe_fc_none:
+ /* Flow control completely disabled by software override. */
+ reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+ break;
+ case ixgbe_fc_rx_pause:
+ /*
+ * Rx Flow control is enabled and Tx Flow control is
+ * disabled by software override. Since there really
+ * isn't a way to advertise that we are capable of RX
+ * Pause ONLY, we will advertise that we support both
+ * symmetric and asymmetric Rx PAUSE. Later, we will
+ * disable the adapter's ability to send PAUSE frames.
+ */
+ reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+ break;
+ case ixgbe_fc_tx_pause:
+ /*
+ * Tx Flow control is enabled, and Rx Flow control is
+ * disabled by software override.
+ */
+ reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
+ reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
+ break;
+ case ixgbe_fc_full:
+ /* Flow control (both Rx and Tx) is enabled by SW override. */
+ reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+ break;
+#ifdef CONFIG_DCB
+ case ixgbe_fc_pfc:
+ goto out;
+ break;
+#endif /* CONFIG_DCB */
+ default:
+ hw_dbg(hw, "Flow control param set incorrectly\n");
+ ret_val = -IXGBE_ERR_CONFIG;
goto out;
+ break;
+ }
- ret_val = ixgbe_fc_enable(hw, packetbuf_num);
+ IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
+ reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
+
+ /* Enable and restart autoneg to inform the link partner */
+ reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART;
+
+ /* Disable AN timeout */
+ if (hw->fc.strict_ieee)
+ reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
+
+ IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
+ hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg);
out:
return ret_val;
@@ -2044,6 +2081,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
hw->mac.ops.check_link(hw, &speed, &link_up, false);
if (!link_up) {
+ autoc_reg |= IXGBE_AUTOC_AN_RESTART;
autoc_reg |= IXGBE_AUTOC_FLU;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
msleep(10);
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index dd260890ad0..0d34d4d8244 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -59,13 +59,13 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw);
s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
u32 mc_addr_count,
ixgbe_mc_addr_itr func);
-s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
- u32 addr_count, ixgbe_mc_addr_itr func);
+s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw,
+ struct list_head *uc_list);
s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval);
-s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num);
-s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packtetbuf_num);
+s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
+s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packtetbuf_num);
s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw);
s32 ixgbe_validate_mac_addr(u8 *mac_addr);
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c
index 62206273d88..f30263898eb 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82598.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c
@@ -294,6 +294,9 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw,
u32 reg, rx_pba_size;
u8 i;
+ if (!dcb_config->pfc_mode_enable)
+ goto out;
+
/* Enable Transmit Priority Flow Control */
reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
reg &= ~IXGBE_RMCS_TFCE_802_3X;
@@ -341,6 +344,7 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw,
/* Configure flow control refresh threshold value */
IXGBE_WRITE_REG(hw, IXGBE_FCRTV, 0x3400);
+out:
return 0;
}
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c
index f4417fc3b0f..589f62c7062 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c
@@ -295,7 +295,7 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
/* If PFC is disabled globally then fall back to LFC. */
if (!dcb_config->pfc_mode_enable) {
for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
- hw->mac.ops.setup_fc(hw, i);
+ hw->mac.ops.fc_enable(hw, i);
goto out;
}
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index bd0a0c27695..d56890f5c9d 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -28,15 +28,22 @@
#include "ixgbe.h"
#include <linux/dcbnl.h>
+#include "ixgbe_dcb_82598.h"
+#include "ixgbe_dcb_82599.h"
/* Callbacks for DCB netlink in the kernel */
#define BIT_DCB_MODE 0x01
#define BIT_PFC 0x02
#define BIT_PG_RX 0x04
#define BIT_PG_TX 0x08
-#define BIT_BCN 0x10
+#define BIT_RESETLINK 0x40
#define BIT_LINKSPEED 0x80
+/* Responses for the DCB_C_SET_ALL command */
+#define DCB_HW_CHG_RST 0 /* DCB configuration changed with reset */
+#define DCB_NO_HW_CHG 1 /* DCB configuration did not change */
+#define DCB_HW_CHG 2 /* DCB configuration changed, no reset */
+
int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
struct ixgbe_dcb_config *dst_dcb_cfg, int tc_max)
{
@@ -124,15 +131,12 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
if (netif_running(netdev))
netdev->netdev_ops->ndo_stop(netdev);
- ixgbe_reset_interrupt_capability(adapter);
- ixgbe_napi_del_all(adapter);
- INIT_LIST_HEAD(&netdev->napi_list);
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
- adapter->tx_ring = NULL;
- adapter->rx_ring = NULL;
+ ixgbe_clear_interrupt_scheme(adapter);
- adapter->hw.fc.requested_mode = ixgbe_fc_pfc;
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ adapter->last_lfc_mode = adapter->hw.fc.current_mode;
+ adapter->hw.fc.requested_mode = ixgbe_fc_none;
+ }
adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
ixgbe_init_interrupt_scheme(adapter);
@@ -141,17 +145,13 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
} else {
/* Turn off DCB */
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- adapter->hw.fc.requested_mode = ixgbe_fc_default;
if (netif_running(netdev))
netdev->netdev_ops->ndo_stop(netdev);
- ixgbe_reset_interrupt_capability(adapter);
- ixgbe_napi_del_all(adapter);
- INIT_LIST_HEAD(&netdev->napi_list);
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
- adapter->tx_ring = NULL;
- adapter->rx_ring = NULL;
+ ixgbe_clear_interrupt_scheme(adapter);
+ adapter->hw.fc.requested_mode = adapter->last_lfc_mode;
+ adapter->temp_dcb_cfg.pfc_mode_enable = false;
+ adapter->dcb_cfg.pfc_mode_enable = false;
adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
ixgbe_init_interrupt_scheme(adapter);
@@ -167,10 +167,15 @@ static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev,
u8 *perm_addr)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- int i;
+ int i, j;
for (i = 0; i < netdev->addr_len; i++)
perm_addr[i] = adapter->hw.mac.perm_addr[i];
+
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ for (j = 0; j < netdev->addr_len; j++, i++)
+ perm_addr[i] = adapter->hw.mac.san_addr[j];
+ }
}
static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
@@ -197,8 +202,10 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
(adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent !=
adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent) ||
(adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap !=
- adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap))
+ adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap)) {
adapter->dcb_set_bitmap |= BIT_PG_TX;
+ adapter->dcb_set_bitmap |= BIT_RESETLINK;
+ }
}
static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
@@ -209,8 +216,10 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct;
if (adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] !=
- adapter->dcb_cfg.bw_percentage[0][bwg_id])
+ adapter->dcb_cfg.bw_percentage[0][bwg_id]) {
adapter->dcb_set_bitmap |= BIT_PG_RX;
+ adapter->dcb_set_bitmap |= BIT_RESETLINK;
+ }
}
static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
@@ -237,8 +246,10 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
(adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent !=
adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent) ||
(adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap !=
- adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap))
+ adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap)) {
adapter->dcb_set_bitmap |= BIT_PG_RX;
+ adapter->dcb_set_bitmap |= BIT_RESETLINK;
+ }
}
static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
@@ -249,8 +260,10 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct;
if (adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] !=
- adapter->dcb_cfg.bw_percentage[1][bwg_id])
+ adapter->dcb_cfg.bw_percentage[1][bwg_id]) {
adapter->dcb_set_bitmap |= BIT_PG_RX;
+ adapter->dcb_set_bitmap |= BIT_RESETLINK;
+ }
}
static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc,
@@ -319,28 +332,60 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
struct ixgbe_adapter *adapter = netdev_priv(netdev);
int ret;
- adapter->dcb_set_bitmap &= ~BIT_BCN; /* no set for BCN */
if (!adapter->dcb_set_bitmap)
- return 1;
+ return DCB_NO_HW_CHG;
- while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
- msleep(1);
+ /*
+ * Only take down the adapter if the configuration change
+ * requires a reset.
+ */
+ if (adapter->dcb_set_bitmap & BIT_RESETLINK) {
+ while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
+ msleep(1);
- if (netif_running(netdev))
- ixgbe_down(adapter);
+ if (netif_running(netdev))
+ ixgbe_down(adapter);
+ }
ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
adapter->ring_feature[RING_F_DCB].indices);
if (ret) {
- clear_bit(__IXGBE_RESETTING, &adapter->state);
- return ret;
+ if (adapter->dcb_set_bitmap & BIT_RESETLINK)
+ clear_bit(__IXGBE_RESETTING, &adapter->state);
+ return DCB_NO_HW_CHG;
+ }
+
+ if (adapter->dcb_cfg.pfc_mode_enable) {
+ if ((adapter->hw.mac.type != ixgbe_mac_82598EB) &&
+ (adapter->hw.fc.current_mode != ixgbe_fc_pfc))
+ adapter->last_lfc_mode = adapter->hw.fc.current_mode;
+ adapter->hw.fc.requested_mode = ixgbe_fc_pfc;
+ } else {
+ if (adapter->hw.mac.type != ixgbe_mac_82598EB)
+ adapter->hw.fc.requested_mode = adapter->last_lfc_mode;
+ else
+ adapter->hw.fc.requested_mode = ixgbe_fc_none;
}
- if (netif_running(netdev))
- ixgbe_up(adapter);
+ if (adapter->dcb_set_bitmap & BIT_RESETLINK) {
+ if (netif_running(netdev))
+ ixgbe_up(adapter);
+ ret = DCB_HW_CHG_RST;
+ } else if (adapter->dcb_set_bitmap & BIT_PFC) {
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ ixgbe_dcb_config_pfc_82598(&adapter->hw,
+ &adapter->dcb_cfg);
+ else if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ ixgbe_dcb_config_pfc_82599(&adapter->hw,
+ &adapter->dcb_cfg);
+ ret = DCB_HW_CHG;
+ }
+ if (adapter->dcb_cfg.pfc_mode_enable)
+ adapter->hw.fc.current_mode = ixgbe_fc_pfc;
+ if (adapter->dcb_set_bitmap & BIT_RESETLINK)
+ clear_bit(__IXGBE_RESETTING, &adapter->state);
adapter->dcb_set_bitmap = 0x00;
- clear_bit(__IXGBE_RESETTING, &adapter->state);
return ret;
}
@@ -416,11 +461,17 @@ static u8 ixgbe_dcbnl_getpfcstate(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED);
+ return adapter->dcb_cfg.pfc_mode_enable;
}
static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ adapter->temp_dcb_cfg.pfc_mode_enable = state;
+ if (adapter->temp_dcb_cfg.pfc_mode_enable !=
+ adapter->dcb_cfg.pfc_mode_enable)
+ adapter->dcb_set_bitmap |= BIT_PFC;
return;
}
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index f0a20facc65..86f4f3e36f2 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -67,6 +67,9 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"rx_over_errors", IXGBE_STAT(net_stats.rx_over_errors)},
{"rx_crc_errors", IXGBE_STAT(net_stats.rx_crc_errors)},
{"rx_frame_errors", IXGBE_STAT(net_stats.rx_frame_errors)},
+ {"hw_rsc_count", IXGBE_STAT(rsc_count)},
+ {"fdir_match", IXGBE_STAT(stats.fdirmatch)},
+ {"fdir_miss", IXGBE_STAT(stats.fdirmiss)},
{"rx_fifo_errors", IXGBE_STAT(net_stats.rx_fifo_errors)},
{"rx_missed_errors", IXGBE_STAT(net_stats.rx_missed_errors)},
{"tx_aborted_errors", IXGBE_STAT(net_stats.tx_aborted_errors)},
@@ -90,6 +93,14 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)},
{"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)},
{"rx_no_dma_resources", IXGBE_STAT(hw_rx_no_dma_resources)},
+#ifdef IXGBE_FCOE
+ {"fcoe_bad_fccrc", IXGBE_STAT(stats.fccrc)},
+ {"rx_fcoe_dropped", IXGBE_STAT(stats.fcoerpdc)},
+ {"rx_fcoe_packets", IXGBE_STAT(stats.fcoeprc)},
+ {"rx_fcoe_dwords", IXGBE_STAT(stats.fcoedwrc)},
+ {"tx_fcoe_packets", IXGBE_STAT(stats.fcoeptc)},
+ {"tx_fcoe_dwords", IXGBE_STAT(stats.fcoedwtc)},
+#endif /* IXGBE_FCOE */
};
#define IXGBE_QUEUE_STATS_LEN \
@@ -109,6 +120,13 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
IXGBE_PB_STATS_LEN + \
IXGBE_QUEUE_STATS_LEN)
+static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = {
+ "Register test (offline)", "Eeprom test (offline)",
+ "Interrupt test (offline)", "Loopback test (offline)",
+ "Link test (on/offline)"
+};
+#define IXGBE_TEST_LEN sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN
+
static int ixgbe_get_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
@@ -120,11 +138,12 @@ static int ixgbe_get_settings(struct net_device *netdev,
ecmd->supported = SUPPORTED_10000baseT_Full;
ecmd->autoneg = AUTONEG_ENABLE;
ecmd->transceiver = XCVR_EXTERNAL;
- if (hw->phy.media_type == ixgbe_media_type_copper) {
+ if ((hw->phy.media_type == ixgbe_media_type_copper) ||
+ (hw->mac.type == ixgbe_mac_82599EB)) {
ecmd->supported |= (SUPPORTED_1000baseT_Full |
- SUPPORTED_TP | SUPPORTED_Autoneg);
+ SUPPORTED_Autoneg);
- ecmd->advertising = (ADVERTISED_TP | ADVERTISED_Autoneg);
+ ecmd->advertising = ADVERTISED_Autoneg;
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
ecmd->advertising |= ADVERTISED_10000baseT_Full;
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
@@ -139,7 +158,15 @@ static int ixgbe_get_settings(struct net_device *netdev,
ecmd->advertising |= (ADVERTISED_10000baseT_Full |
ADVERTISED_1000baseT_Full);
- ecmd->port = PORT_TP;
+ if (hw->phy.media_type == ixgbe_media_type_copper) {
+ ecmd->supported |= SUPPORTED_TP;
+ ecmd->advertising |= ADVERTISED_TP;
+ ecmd->port = PORT_TP;
+ } else {
+ ecmd->supported |= SUPPORTED_FIBRE;
+ ecmd->advertising |= ADVERTISED_FIBRE;
+ ecmd->port = PORT_FIBRE;
+ }
} else if (hw->phy.media_type == ixgbe_media_type_backplane) {
/* Set as FIBRE until SERDES defined in kernel */
switch (hw->device_id) {
@@ -187,16 +214,10 @@ static int ixgbe_set_settings(struct net_device *netdev,
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
u32 advertised, old;
- s32 err;
+ s32 err = 0;
- switch (hw->phy.media_type) {
- case ixgbe_media_type_fiber:
- if ((ecmd->autoneg == AUTONEG_ENABLE) ||
- (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
- return -EINVAL;
- /* in this case we currently only support 10Gb/FULL */
- break;
- case ixgbe_media_type_copper:
+ if ((hw->phy.media_type == ixgbe_media_type_copper) ||
+ (hw->mac.type == ixgbe_mac_82599EB)) {
/* 10000/copper and 1000/copper must autoneg
* this function does not support any duplex forcing, but can
* limit the advertising of the adapter to only 10000 or 1000 */
@@ -212,20 +233,23 @@ static int ixgbe_set_settings(struct net_device *netdev,
advertised |= IXGBE_LINK_SPEED_1GB_FULL;
if (old == advertised)
- break;
+ return err;
/* this sets the link speed and restarts auto-neg */
+ hw->mac.autotry_restart = true;
err = hw->mac.ops.setup_link_speed(hw, advertised, true, true);
if (err) {
DPRINTK(PROBE, INFO,
"setup link failed with code %d\n", err);
hw->mac.ops.setup_link_speed(hw, old, true, true);
}
- break;
- default:
- break;
+ } else {
+ /* in this case we currently only support 10Gb/FULL */
+ if ((ecmd->autoneg == AUTONEG_ENABLE) ||
+ (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
+ return -EINVAL;
}
- return 0;
+ return err;
}
static void ixgbe_get_pauseparam(struct net_device *netdev,
@@ -245,6 +269,13 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
else
pause->autoneg = 1;
+#ifdef CONFIG_DCB
+ if (hw->fc.current_mode == ixgbe_fc_pfc) {
+ pause->rx_pause = 0;
+ pause->tx_pause = 0;
+ }
+
+#endif
if (hw->fc.current_mode == ixgbe_fc_rx_pause) {
pause->rx_pause = 1;
} else if (hw->fc.current_mode == ixgbe_fc_tx_pause) {
@@ -260,24 +291,46 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
+ struct ixgbe_fc_info fc;
+
+#ifdef CONFIG_DCB
+ if (adapter->dcb_cfg.pfc_mode_enable ||
+ ((hw->mac.type == ixgbe_mac_82598EB) &&
+ (adapter->flags & IXGBE_FLAG_DCB_ENABLED)))
+ return -EINVAL;
+
+#endif
+
+ fc = hw->fc;
if (pause->autoneg != AUTONEG_ENABLE)
- hw->fc.disable_fc_autoneg = true;
+ fc.disable_fc_autoneg = true;
else
- hw->fc.disable_fc_autoneg = false;
+ fc.disable_fc_autoneg = false;
if (pause->rx_pause && pause->tx_pause)
- hw->fc.requested_mode = ixgbe_fc_full;
+ fc.requested_mode = ixgbe_fc_full;
else if (pause->rx_pause && !pause->tx_pause)
- hw->fc.requested_mode = ixgbe_fc_rx_pause;
+ fc.requested_mode = ixgbe_fc_rx_pause;
else if (!pause->rx_pause && pause->tx_pause)
- hw->fc.requested_mode = ixgbe_fc_tx_pause;
+ fc.requested_mode = ixgbe_fc_tx_pause;
else if (!pause->rx_pause && !pause->tx_pause)
- hw->fc.requested_mode = ixgbe_fc_none;
+ fc.requested_mode = ixgbe_fc_none;
else
return -EINVAL;
- hw->mac.ops.setup_fc(hw, 0);
+#ifdef CONFIG_DCB
+ adapter->last_lfc_mode = fc.requested_mode;
+#endif
+
+ /* if the thing changed then we'll update and use new autoneg */
+ if (memcmp(&fc, &hw->fc, sizeof(struct ixgbe_fc_info))) {
+ hw->fc = fc;
+ if (netif_running(netdev))
+ ixgbe_reinit_locked(adapter);
+ else
+ ixgbe_reset(adapter);
+ }
return 0;
}
@@ -311,10 +364,17 @@ static u32 ixgbe_get_tx_csum(struct net_device *netdev)
static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
{
- if (data)
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ if (data) {
netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
- else
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ netdev->features |= NETIF_F_SCTP_CSUM;
+ } else {
netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ netdev->features &= ~NETIF_F_SCTP_CSUM;
+ }
return 0;
}
@@ -710,6 +770,7 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
strncpy(drvinfo->fw_version, firmware_version, 32);
strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
drvinfo->n_stats = IXGBE_STATS_LEN;
+ drvinfo->testinfo_len = IXGBE_TEST_LEN;
drvinfo->regdump_len = ixgbe_get_regs_len(netdev);
}
@@ -781,7 +842,6 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
}
goto err_setup;
}
- temp_tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
}
need_update = true;
}
@@ -811,7 +871,6 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
}
goto err_setup;
}
- temp_rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
}
need_update = true;
}
@@ -851,6 +910,8 @@ err_setup:
static int ixgbe_get_sset_count(struct net_device *netdev, int sset)
{
switch (sset) {
+ case ETH_SS_TEST:
+ return IXGBE_TEST_LEN;
case ETH_SS_STATS:
return IXGBE_STATS_LEN;
default:
@@ -905,6 +966,10 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
int i;
switch (stringset) {
+ case ETH_SS_TEST:
+ memcpy(data, *ixgbe_gstrings_test,
+ IXGBE_TEST_LEN * ETH_GSTRING_LEN);
+ break;
case ETH_SS_STATS:
for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
memcpy(p, ixgbe_gstrings_stats[i].stat_string,
@@ -942,6 +1007,815 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
}
}
+static int ixgbe_link_test(struct ixgbe_adapter *adapter, u64 *data)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ bool link_up;
+ u32 link_speed = 0;
+ *data = 0;
+
+ hw->mac.ops.check_link(hw, &link_speed, &link_up, true);
+ if (link_up)
+ return *data;
+ else
+ *data = 1;
+ return *data;
+}
+
+/* ethtool register test data */
+struct ixgbe_reg_test {
+ u16 reg;
+ u8 array_len;
+ u8 test_type;
+ u32 mask;
+ u32 write;
+};
+
+/* In the hardware, registers are laid out either singly, in arrays
+ * spaced 0x40 bytes apart, or in contiguous tables. We assume
+ * most tests take place on arrays or single registers (handled
+ * as a single-element array) and special-case the tables.
+ * Table tests are always pattern tests.
+ *
+ * We also make provision for some required setup steps by specifying
+ * registers to be written without any read-back testing.
+ */
+
+#define PATTERN_TEST 1
+#define SET_READ_TEST 2
+#define WRITE_NO_TEST 3
+#define TABLE32_TEST 4
+#define TABLE64_TEST_LO 5
+#define TABLE64_TEST_HI 6
+
+/* default 82599 register test */
+static struct ixgbe_reg_test reg_test_82599[] = {
+ { IXGBE_FCRTL_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
+ { IXGBE_FCRTH_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
+ { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { IXGBE_VLNCTRL, 1, PATTERN_TEST, 0x00000000, 0x00000000 },
+ { IXGBE_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 },
+ { IXGBE_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { IXGBE_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
+ { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE },
+ { IXGBE_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+ { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 },
+ { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
+ { IXGBE_FCTTV(0), 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { IXGBE_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { IXGBE_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { IXGBE_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFF80 },
+ { IXGBE_RXCTRL, 1, SET_READ_TEST, 0x00000001, 0x00000001 },
+ { IXGBE_RAL(0), 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
+ { IXGBE_RAL(0), 16, TABLE64_TEST_HI, 0x8001FFFF, 0x800CFFFF },
+ { IXGBE_MTA(0), 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { 0, 0, 0, 0 }
+};
+
+/* default 82598 register test */
+static struct ixgbe_reg_test reg_test_82598[] = {
+ { IXGBE_FCRTL(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
+ { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
+ { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { IXGBE_VLNCTRL, 1, PATTERN_TEST, 0x00000000, 0x00000000 },
+ { IXGBE_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { IXGBE_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { IXGBE_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
+ /* Enable all four RX queues before testing. */
+ { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE },
+ /* RDH is read-only for 82598, only test RDT. */
+ { IXGBE_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+ { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 },
+ { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
+ { IXGBE_FCTTV(0), 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { IXGBE_TIPG, 1, PATTERN_TEST, 0x000000FF, 0x000000FF },
+ { IXGBE_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { IXGBE_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { IXGBE_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
+ { IXGBE_RXCTRL, 1, SET_READ_TEST, 0x00000003, 0x00000003 },
+ { IXGBE_DTXCTL, 1, SET_READ_TEST, 0x00000005, 0x00000005 },
+ { IXGBE_RAL(0), 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
+ { IXGBE_RAL(0), 16, TABLE64_TEST_HI, 0x800CFFFF, 0x800CFFFF },
+ { IXGBE_MTA(0), 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { 0, 0, 0, 0 }
+};
+
+#define REG_PATTERN_TEST(R, M, W) \
+{ \
+ u32 pat, val, before; \
+ const u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \
+ for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { \
+ before = readl(adapter->hw.hw_addr + R); \
+ writel((_test[pat] & W), (adapter->hw.hw_addr + R)); \
+ val = readl(adapter->hw.hw_addr + R); \
+ if (val != (_test[pat] & W & M)) { \
+ DPRINTK(DRV, ERR, "pattern test reg %04X failed: got "\
+ "0x%08X expected 0x%08X\n", \
+ R, val, (_test[pat] & W & M)); \
+ *data = R; \
+ writel(before, adapter->hw.hw_addr + R); \
+ return 1; \
+ } \
+ writel(before, adapter->hw.hw_addr + R); \
+ } \
+}
+
+#define REG_SET_AND_CHECK(R, M, W) \
+{ \
+ u32 val, before; \
+ before = readl(adapter->hw.hw_addr + R); \
+ writel((W & M), (adapter->hw.hw_addr + R)); \
+ val = readl(adapter->hw.hw_addr + R); \
+ if ((W & M) != (val & M)) { \
+ DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\
+ "expected 0x%08X\n", R, (val & M), (W & M)); \
+ *data = R; \
+ writel(before, (adapter->hw.hw_addr + R)); \
+ return 1; \
+ } \
+ writel(before, (adapter->hw.hw_addr + R)); \
+}
+
+static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
+{
+ struct ixgbe_reg_test *test;
+ u32 value, before, after;
+ u32 i, toggle;
+
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ toggle = 0x7FFFF30F;
+ test = reg_test_82599;
+ } else {
+ toggle = 0x7FFFF3FF;
+ test = reg_test_82598;
+ }
+
+ /*
+ * Because the status register is such a special case,
+ * we handle it separately from the rest of the register
+ * tests. Some bits are read-only, some toggle, and some
+ * are writeable on newer MACs.
+ */
+ before = IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS);
+ value = (IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS) & toggle);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_STATUS, toggle);
+ after = IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS) & toggle;
+ if (value != after) {
+ DPRINTK(DRV, ERR, "failed STATUS register test got: "
+ "0x%08X expected: 0x%08X\n", after, value);
+ *data = 1;
+ return 1;
+ }
+ /* restore previous status */
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_STATUS, before);
+
+ /*
+ * Perform the remainder of the register test, looping through
+ * the test table until we either fail or reach the null entry.
+ */
+ while (test->reg) {
+ for (i = 0; i < test->array_len; i++) {
+ switch (test->test_type) {
+ case PATTERN_TEST:
+ REG_PATTERN_TEST(test->reg + (i * 0x40),
+ test->mask,
+ test->write);
+ break;
+ case SET_READ_TEST:
+ REG_SET_AND_CHECK(test->reg + (i * 0x40),
+ test->mask,
+ test->write);
+ break;
+ case WRITE_NO_TEST:
+ writel(test->write,
+ (adapter->hw.hw_addr + test->reg)
+ + (i * 0x40));
+ break;
+ case TABLE32_TEST:
+ REG_PATTERN_TEST(test->reg + (i * 4),
+ test->mask,
+ test->write);
+ break;
+ case TABLE64_TEST_LO:
+ REG_PATTERN_TEST(test->reg + (i * 8),
+ test->mask,
+ test->write);
+ break;
+ case TABLE64_TEST_HI:
+ REG_PATTERN_TEST((test->reg + 4) + (i * 8),
+ test->mask,
+ test->write);
+ break;
+ }
+ }
+ test++;
+ }
+
+ *data = 0;
+ return 0;
+}
+
+static int ixgbe_eeprom_test(struct ixgbe_adapter *adapter, u64 *data)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ if (hw->eeprom.ops.validate_checksum(hw, NULL))
+ *data = 1;
+ else
+ *data = 0;
+ return *data;
+}
+
+static irqreturn_t ixgbe_test_intr(int irq, void *data)
+{
+ struct net_device *netdev = (struct net_device *) data;
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ adapter->test_icr |= IXGBE_READ_REG(&adapter->hw, IXGBE_EICR);
+
+ return IRQ_HANDLED;
+}
+
+static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)
+{
+ struct net_device *netdev = adapter->netdev;
+ u32 mask, i = 0, shared_int = true;
+ u32 irq = adapter->pdev->irq;
+
+ *data = 0;
+
+ /* Hook up test interrupt handler just for this test */
+ if (adapter->msix_entries) {
+ /* NOTE: we don't test MSI-X interrupts here, yet */
+ return 0;
+ } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
+ shared_int = false;
+ if (request_irq(irq, &ixgbe_test_intr, 0, netdev->name,
+ netdev)) {
+ *data = 1;
+ return -1;
+ }
+ } else if (!request_irq(irq, &ixgbe_test_intr, IRQF_PROBE_SHARED,
+ netdev->name, netdev)) {
+ shared_int = false;
+ } else if (request_irq(irq, &ixgbe_test_intr, IRQF_SHARED,
+ netdev->name, netdev)) {
+ *data = 1;
+ return -1;
+ }
+ DPRINTK(HW, INFO, "testing %s interrupt\n",
+ (shared_int ? "shared" : "unshared"));
+
+ /* Disable all the interrupts */
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF);
+ msleep(10);
+
+ /* Test each interrupt */
+ for (; i < 10; i++) {
+ /* Interrupt to test */
+ mask = 1 << i;
+
+ if (!shared_int) {
+ /*
+ * Disable the interrupts to be reported in
+ * the cause register and then force the same
+ * interrupt and see if one gets posted. If
+ * an interrupt was posted to the bus, the
+ * test failed.
+ */
+ adapter->test_icr = 0;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC,
+ ~mask & 0x00007FFF);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
+ ~mask & 0x00007FFF);
+ msleep(10);
+
+ if (adapter->test_icr & mask) {
+ *data = 3;
+ break;
+ }
+ }
+
+ /*
+ * Enable the interrupt to be reported in the cause
+ * register and then force the same interrupt and see
+ * if one gets posted. If an interrupt was not posted
+ * to the bus, the test failed.
+ */
+ adapter->test_icr = 0;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask);
+ msleep(10);
+
+ if (!(adapter->test_icr &mask)) {
+ *data = 4;
+ break;
+ }
+
+ if (!shared_int) {
+ /*
+ * Disable the other interrupts to be reported in
+ * the cause register and then force the other
+ * interrupts and see if any get posted. If
+ * an interrupt was posted to the bus, the
+ * test failed.
+ */
+ adapter->test_icr = 0;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC,
+ ~mask & 0x00007FFF);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
+ ~mask & 0x00007FFF);
+ msleep(10);
+
+ if (adapter->test_icr) {
+ *data = 5;
+ break;
+ }
+ }
+ }
+
+ /* Disable all the interrupts */
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF);
+ msleep(10);
+
+ /* Unhook test interrupt handler */
+ free_irq(irq, netdev);
+
+ return *data;
+}
+
+static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_ring *tx_ring = &adapter->test_tx_ring;
+ struct ixgbe_ring *rx_ring = &adapter->test_rx_ring;
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct pci_dev *pdev = adapter->pdev;
+ u32 reg_ctl;
+ int i;
+
+ /* shut down the DMA engines now so they can be reinitialized later */
+
+ /* first Rx */
+ reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+ reg_ctl &= ~IXGBE_RXCTRL_RXEN;
+ IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_ctl);
+ reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(0));
+ reg_ctl &= ~IXGBE_RXDCTL_ENABLE;
+ IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(0), reg_ctl);
+
+ /* now Tx */
+ reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(0));
+ reg_ctl &= ~IXGBE_TXDCTL_ENABLE;
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(0), reg_ctl);
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
+ reg_ctl &= ~IXGBE_DMATXCTL_TE;
+ IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl);
+ }
+
+ ixgbe_reset(adapter);
+
+ if (tx_ring->desc && tx_ring->tx_buffer_info) {
+ for (i = 0; i < tx_ring->count; i++) {
+ struct ixgbe_tx_buffer *buf =
+ &(tx_ring->tx_buffer_info[i]);
+ if (buf->dma)
+ pci_unmap_single(pdev, buf->dma, buf->length,
+ PCI_DMA_TODEVICE);
+ if (buf->skb)
+ dev_kfree_skb(buf->skb);
+ }
+ }
+
+ if (rx_ring->desc && rx_ring->rx_buffer_info) {
+ for (i = 0; i < rx_ring->count; i++) {
+ struct ixgbe_rx_buffer *buf =
+ &(rx_ring->rx_buffer_info[i]);
+ if (buf->dma)
+ pci_unmap_single(pdev, buf->dma,
+ IXGBE_RXBUFFER_2048,
+ PCI_DMA_FROMDEVICE);
+ if (buf->skb)
+ dev_kfree_skb(buf->skb);
+ }
+ }
+
+ if (tx_ring->desc) {
+ pci_free_consistent(pdev, tx_ring->size, tx_ring->desc,
+ tx_ring->dma);
+ tx_ring->desc = NULL;
+ }
+ if (rx_ring->desc) {
+ pci_free_consistent(pdev, rx_ring->size, rx_ring->desc,
+ rx_ring->dma);
+ rx_ring->desc = NULL;
+ }
+
+ kfree(tx_ring->tx_buffer_info);
+ tx_ring->tx_buffer_info = NULL;
+ kfree(rx_ring->rx_buffer_info);
+ rx_ring->rx_buffer_info = NULL;
+
+ return;
+}
+
+static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_ring *tx_ring = &adapter->test_tx_ring;
+ struct ixgbe_ring *rx_ring = &adapter->test_rx_ring;
+ struct pci_dev *pdev = adapter->pdev;
+ u32 rctl, reg_data;
+ int i, ret_val;
+
+ /* Setup Tx descriptor ring and Tx buffers */
+
+ if (!tx_ring->count)
+ tx_ring->count = IXGBE_DEFAULT_TXD;
+
+ tx_ring->tx_buffer_info = kcalloc(tx_ring->count,
+ sizeof(struct ixgbe_tx_buffer),
+ GFP_KERNEL);
+ if (!(tx_ring->tx_buffer_info)) {
+ ret_val = 1;
+ goto err_nomem;
+ }
+
+ tx_ring->size = tx_ring->count * sizeof(struct ixgbe_legacy_tx_desc);
+ tx_ring->size = ALIGN(tx_ring->size, 4096);
+ if (!(tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
+ &tx_ring->dma))) {
+ ret_val = 2;
+ goto err_nomem;
+ }
+ tx_ring->next_to_use = tx_ring->next_to_clean = 0;
+
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAL(0),
+ ((u64) tx_ring->dma & 0x00000000FFFFFFFF));
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAH(0),
+ ((u64) tx_ring->dma >> 32));
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDLEN(0),
+ tx_ring->count * sizeof(struct ixgbe_legacy_tx_desc));
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDH(0), 0);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), 0);
+
+ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
+ reg_data |= IXGBE_HLREG0_TXPADEN;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
+
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL);
+ reg_data |= IXGBE_DMATXCTL_TE;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data);
+ }
+ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_TXDCTL(0));
+ reg_data |= IXGBE_TXDCTL_ENABLE;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_TXDCTL(0), reg_data);
+
+ for (i = 0; i < tx_ring->count; i++) {
+ struct ixgbe_legacy_tx_desc *desc = IXGBE_TX_DESC(*tx_ring, i);
+ struct sk_buff *skb;
+ unsigned int size = 1024;
+
+ skb = alloc_skb(size, GFP_KERNEL);
+ if (!skb) {
+ ret_val = 3;
+ goto err_nomem;
+ }
+ skb_put(skb, size);
+ tx_ring->tx_buffer_info[i].skb = skb;
+ tx_ring->tx_buffer_info[i].length = skb->len;
+ tx_ring->tx_buffer_info[i].dma =
+ pci_map_single(pdev, skb->data, skb->len,
+ PCI_DMA_TODEVICE);
+ desc->buffer_addr = cpu_to_le64(tx_ring->tx_buffer_info[i].dma);
+ desc->lower.data = cpu_to_le32(skb->len);
+ desc->lower.data |= cpu_to_le32(IXGBE_TXD_CMD_EOP |
+ IXGBE_TXD_CMD_IFCS |
+ IXGBE_TXD_CMD_RS);
+ desc->upper.data = 0;
+ }
+
+ /* Setup Rx Descriptor ring and Rx buffers */
+
+ if (!rx_ring->count)
+ rx_ring->count = IXGBE_DEFAULT_RXD;
+
+ rx_ring->rx_buffer_info = kcalloc(rx_ring->count,
+ sizeof(struct ixgbe_rx_buffer),
+ GFP_KERNEL);
+ if (!(rx_ring->rx_buffer_info)) {
+ ret_val = 4;
+ goto err_nomem;
+ }
+
+ rx_ring->size = rx_ring->count * sizeof(struct ixgbe_legacy_rx_desc);
+ rx_ring->size = ALIGN(rx_ring->size, 4096);
+ if (!(rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size,
+ &rx_ring->dma))) {
+ ret_val = 5;
+ goto err_nomem;
+ }
+ rx_ring->next_to_use = rx_ring->next_to_clean = 0;
+
+ rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl & ~IXGBE_RXCTRL_RXEN);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAL(0),
+ ((u64)rx_ring->dma & 0xFFFFFFFF));
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAH(0),
+ ((u64) rx_ring->dma >> 32));
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDLEN(0), rx_ring->size);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDH(0), 0);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), 0);
+
+ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
+ reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_data);
+
+ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
+ reg_data &= ~IXGBE_HLREG0_LPBK;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
+
+ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RDRXCTL);
+#define IXGBE_RDRXCTL_RDMTS_MASK 0x00000003 /* Receive Descriptor Minimum
+ Threshold Size mask */
+ reg_data &= ~IXGBE_RDRXCTL_RDMTS_MASK;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDRXCTL, reg_data);
+
+ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_MCSTCTRL);
+#define IXGBE_MCSTCTRL_MO_MASK 0x00000003 /* Multicast Offset mask */
+ reg_data &= ~IXGBE_MCSTCTRL_MO_MASK;
+ reg_data |= adapter->hw.mac.mc_filter_type;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_MCSTCTRL, reg_data);
+
+ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(0));
+ reg_data |= IXGBE_RXDCTL_ENABLE;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(0), reg_data);
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ int j = adapter->rx_ring[0].reg_idx;
+ u32 k;
+ for (k = 0; k < 10; k++) {
+ if (IXGBE_READ_REG(&adapter->hw,
+ IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE)
+ break;
+ else
+ msleep(1);
+ }
+ }
+
+ rctl |= IXGBE_RXCTRL_RXEN | IXGBE_RXCTRL_DMBYPS;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl);
+
+ for (i = 0; i < rx_ring->count; i++) {
+ struct ixgbe_legacy_rx_desc *rx_desc =
+ IXGBE_RX_DESC(*rx_ring, i);
+ struct sk_buff *skb;
+
+ skb = alloc_skb(IXGBE_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL);
+ if (!skb) {
+ ret_val = 6;
+ goto err_nomem;
+ }
+ skb_reserve(skb, NET_IP_ALIGN);
+ rx_ring->rx_buffer_info[i].skb = skb;
+ rx_ring->rx_buffer_info[i].dma =
+ pci_map_single(pdev, skb->data, IXGBE_RXBUFFER_2048,
+ PCI_DMA_FROMDEVICE);
+ rx_desc->buffer_addr =
+ cpu_to_le64(rx_ring->rx_buffer_info[i].dma);
+ memset(skb->data, 0x00, skb->len);
+ }
+
+ return 0;
+
+err_nomem:
+ ixgbe_free_desc_rings(adapter);
+ return ret_val;
+}
+
+static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 reg_data;
+
+ /* right now we only support MAC loopback in the driver */
+
+ /* Setup MAC loopback */
+ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
+ reg_data |= IXGBE_HLREG0_LPBK;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
+
+ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_AUTOC);
+ reg_data &= ~IXGBE_AUTOC_LMS_MASK;
+ reg_data |= IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_AUTOC, reg_data);
+
+ /* Disable Atlas Tx lanes; re-enabled in reset path */
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ u8 atlas;
+
+ hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &atlas);
+ atlas |= IXGBE_ATLAS_PDN_TX_REG_EN;
+ hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, atlas);
+
+ hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, &atlas);
+ atlas |= IXGBE_ATLAS_PDN_TX_10G_QL_ALL;
+ hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, atlas);
+
+ hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, &atlas);
+ atlas |= IXGBE_ATLAS_PDN_TX_1G_QL_ALL;
+ hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, atlas);
+
+ hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, &atlas);
+ atlas |= IXGBE_ATLAS_PDN_TX_AN_QL_ALL;
+ hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, atlas);
+ }
+
+ return 0;
+}
+
+static void ixgbe_loopback_cleanup(struct ixgbe_adapter *adapter)
+{
+ u32 reg_data;
+
+ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
+ reg_data &= ~IXGBE_HLREG0_LPBK;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
+}
+
+static void ixgbe_create_lbtest_frame(struct sk_buff *skb,
+ unsigned int frame_size)
+{
+ memset(skb->data, 0xFF, frame_size);
+ frame_size &= ~1;
+ memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
+ memset(&skb->data[frame_size / 2 + 10], 0xBE, 1);
+ memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
+}
+
+static int ixgbe_check_lbtest_frame(struct sk_buff *skb,
+ unsigned int frame_size)
+{
+ frame_size &= ~1;
+ if (*(skb->data + 3) == 0xFF) {
+ if ((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
+ (*(skb->data + frame_size / 2 + 12) == 0xAF)) {
+ return 0;
+ }
+ }
+ return 13;
+}
+
+static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_ring *tx_ring = &adapter->test_tx_ring;
+ struct ixgbe_ring *rx_ring = &adapter->test_rx_ring;
+ struct pci_dev *pdev = adapter->pdev;
+ int i, j, k, l, lc, good_cnt, ret_val = 0;
+ unsigned long time;
+
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), rx_ring->count - 1);
+
+ /*
+ * Calculate the loop count based on the largest descriptor ring
+ * The idea is to wrap the largest ring a number of times using 64
+ * send/receive pairs during each loop
+ */
+
+ if (rx_ring->count <= tx_ring->count)
+ lc = ((tx_ring->count / 64) * 2) + 1;
+ else
+ lc = ((rx_ring->count / 64) * 2) + 1;
+
+ k = l = 0;
+ for (j = 0; j <= lc; j++) {
+ for (i = 0; i < 64; i++) {
+ ixgbe_create_lbtest_frame(
+ tx_ring->tx_buffer_info[k].skb,
+ 1024);
+ pci_dma_sync_single_for_device(pdev,
+ tx_ring->tx_buffer_info[k].dma,
+ tx_ring->tx_buffer_info[k].length,
+ PCI_DMA_TODEVICE);
+ if (unlikely(++k == tx_ring->count))
+ k = 0;
+ }
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), k);
+ msleep(200);
+ /* set the start time for the receive */
+ time = jiffies;
+ good_cnt = 0;
+ do {
+ /* receive the sent packets */
+ pci_dma_sync_single_for_cpu(pdev,
+ rx_ring->rx_buffer_info[l].dma,
+ IXGBE_RXBUFFER_2048,
+ PCI_DMA_FROMDEVICE);
+ ret_val = ixgbe_check_lbtest_frame(
+ rx_ring->rx_buffer_info[l].skb, 1024);
+ if (!ret_val)
+ good_cnt++;
+ if (++l == rx_ring->count)
+ l = 0;
+ /*
+ * time + 20 msecs (200 msecs on 2.4) is more than
+ * enough time to complete the receives, if it's
+ * exceeded, break and error off
+ */
+ } while (good_cnt < 64 && jiffies < (time + 20));
+ if (good_cnt != 64) {
+ /* ret_val is the same as mis-compare */
+ ret_val = 13;
+ break;
+ }
+ if (jiffies >= (time + 20)) {
+ /* Error code for time out error */
+ ret_val = 14;
+ break;
+ }
+ }
+
+ return ret_val;
+}
+
+static int ixgbe_loopback_test(struct ixgbe_adapter *adapter, u64 *data)
+{
+ *data = ixgbe_setup_desc_rings(adapter);
+ if (*data)
+ goto out;
+ *data = ixgbe_setup_loopback_test(adapter);
+ if (*data)
+ goto err_loopback;
+ *data = ixgbe_run_loopback_test(adapter);
+ ixgbe_loopback_cleanup(adapter);
+
+err_loopback:
+ ixgbe_free_desc_rings(adapter);
+out:
+ return *data;
+}
+
+static void ixgbe_diag_test(struct net_device *netdev,
+ struct ethtool_test *eth_test, u64 *data)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ bool if_running = netif_running(netdev);
+
+ set_bit(__IXGBE_TESTING, &adapter->state);
+ if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
+ /* Offline tests */
+
+ DPRINTK(HW, INFO, "offline testing starting\n");
+
+ /* Link test performed before hardware reset so autoneg doesn't
+ * interfere with test result */
+ if (ixgbe_link_test(adapter, &data[4]))
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+
+ if (if_running)
+ /* indicate we're in test mode */
+ dev_close(netdev);
+ else
+ ixgbe_reset(adapter);
+
+ DPRINTK(HW, INFO, "register testing starting\n");
+ if (ixgbe_reg_test(adapter, &data[0]))
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+
+ ixgbe_reset(adapter);
+ DPRINTK(HW, INFO, "eeprom testing starting\n");
+ if (ixgbe_eeprom_test(adapter, &data[1]))
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+
+ ixgbe_reset(adapter);
+ DPRINTK(HW, INFO, "interrupt testing starting\n");
+ if (ixgbe_intr_test(adapter, &data[2]))
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+
+ ixgbe_reset(adapter);
+ DPRINTK(HW, INFO, "loopback testing starting\n");
+ if (ixgbe_loopback_test(adapter, &data[3]))
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+
+ ixgbe_reset(adapter);
+
+ clear_bit(__IXGBE_TESTING, &adapter->state);
+ if (if_running)
+ dev_open(netdev);
+ } else {
+ DPRINTK(HW, INFO, "online testing starting\n");
+ /* Online tests */
+ if (ixgbe_link_test(adapter, &data[4]))
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+
+ /* Online tests aren't run; pass by default */
+ data[0] = 0;
+ data[1] = 0;
+ data[2] = 0;
+ data[3] = 0;
+
+ clear_bit(__IXGBE_TESTING, &adapter->state);
+ }
+ msleep_interruptible(4 * 1000);
+}
static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter,
struct ethtool_wolinfo *wol)
@@ -1106,20 +1980,40 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
}
for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
- struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
+ struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
if (q_vector->txr_count && !q_vector->rxr_count)
/* tx vector gets half the rate */
q_vector->eitr = (adapter->eitr_param >> 1);
else
/* rx only or mixed */
q_vector->eitr = adapter->eitr_param;
- ixgbe_write_eitr(adapter, i,
- EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
+ ixgbe_write_eitr(q_vector);
}
return 0;
}
+static int ixgbe_set_flags(struct net_device *netdev, u32 data)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ ethtool_op_set_flags(netdev, data);
+
+ if (!(adapter->flags & IXGBE_FLAG2_RSC_CAPABLE))
+ return 0;
+
+ /* if state changes we need to update adapter->flags and reset */
+ if ((!!(data & ETH_FLAG_LRO)) !=
+ (!!(adapter->flags & IXGBE_FLAG2_RSC_ENABLED))) {
+ adapter->flags ^= IXGBE_FLAG2_RSC_ENABLED;
+ if (netif_running(netdev))
+ ixgbe_reinit_locked(adapter);
+ else
+ ixgbe_reset(adapter);
+ }
+ return 0;
+
+}
static const struct ethtool_ops ixgbe_ethtool_ops = {
.get_settings = ixgbe_get_settings,
@@ -1147,6 +2041,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
.set_msglevel = ixgbe_set_msglevel,
.get_tso = ethtool_op_get_tso,
.set_tso = ixgbe_set_tso,
+ .self_test = ixgbe_diag_test,
.get_strings = ixgbe_get_strings,
.phys_id = ixgbe_phys_id,
.get_sset_count = ixgbe_get_sset_count,
@@ -1154,7 +2049,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
.get_coalesce = ixgbe_get_coalesce,
.set_coalesce = ixgbe_set_coalesce,
.get_flags = ethtool_op_get_flags,
- .set_flags = ethtool_op_set_flags,
+ .set_flags = ixgbe_set_flags,
};
void ixgbe_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c
new file mode 100644
index 00000000000..3c3bf1f07b8
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_fcoe.c
@@ -0,0 +1,556 @@
+/*******************************************************************************
+
+ Intel 10 Gigabit PCI Express Linux driver
+ Copyright(c) 1999 - 2009 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+
+#include "ixgbe.h"
+#include <linux/if_ether.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/fc/fc_fs.h>
+#include <scsi/fc/fc_fcoe.h>
+#include <scsi/libfc.h>
+#include <scsi/libfcoe.h>
+
+/**
+ * ixgbe_rx_is_fcoe - check the rx desc for incoming pkt type
+ * @rx_desc: advanced rx descriptor
+ *
+ * Returns : true if it is FCoE pkt
+ */
+static inline bool ixgbe_rx_is_fcoe(union ixgbe_adv_rx_desc *rx_desc)
+{
+ u16 p;
+
+ p = le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.pkt_info);
+ if (p & IXGBE_RXDADV_PKTTYPE_ETQF) {
+ p &= IXGBE_RXDADV_PKTTYPE_ETQF_MASK;
+ p >>= IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT;
+ return p == IXGBE_ETQF_FILTER_FCOE;
+ }
+ return false;
+}
+
+/**
+ * ixgbe_fcoe_clear_ddp - clear the given ddp context
+ * @ddp - ptr to the ixgbe_fcoe_ddp
+ *
+ * Returns : none
+ *
+ */
+static inline void ixgbe_fcoe_clear_ddp(struct ixgbe_fcoe_ddp *ddp)
+{
+ ddp->len = 0;
+ ddp->err = 0;
+ ddp->udl = NULL;
+ ddp->udp = 0UL;
+ ddp->sgl = NULL;
+ ddp->sgc = 0;
+}
+
+/**
+ * ixgbe_fcoe_ddp_put - free the ddp context for a given xid
+ * @netdev: the corresponding net_device
+ * @xid: the xid that corresponding ddp will be freed
+ *
+ * This is the implementation of net_device_ops.ndo_fcoe_ddp_done
+ * and it is expected to be called by ULD, i.e., FCP layer of libfc
+ * to release the corresponding ddp context when the I/O is done.
+ *
+ * Returns : data length already ddp-ed in bytes
+ */
+int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid)
+{
+ int len = 0;
+ struct ixgbe_fcoe *fcoe;
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_fcoe_ddp *ddp;
+
+ if (!netdev)
+ goto out_ddp_put;
+
+ if (xid >= IXGBE_FCOE_DDP_MAX)
+ goto out_ddp_put;
+
+ adapter = netdev_priv(netdev);
+ fcoe = &adapter->fcoe;
+ ddp = &fcoe->ddp[xid];
+ if (!ddp->udl)
+ goto out_ddp_put;
+
+ len = ddp->len;
+ /* if there an error, force to invalidate ddp context */
+ if (ddp->err) {
+ spin_lock_bh(&fcoe->lock);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCFLT, 0);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCFLTRW,
+ (xid | IXGBE_FCFLTRW_WE));
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCBUFF, 0);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCDMARW,
+ (xid | IXGBE_FCDMARW_WE));
+ spin_unlock_bh(&fcoe->lock);
+ }
+ if (ddp->sgl)
+ pci_unmap_sg(adapter->pdev, ddp->sgl, ddp->sgc,
+ DMA_FROM_DEVICE);
+ pci_pool_free(fcoe->pool, ddp->udl, ddp->udp);
+ ixgbe_fcoe_clear_ddp(ddp);
+
+out_ddp_put:
+ return len;
+}
+
+/**
+ * ixgbe_fcoe_ddp_get - called to set up ddp context
+ * @netdev: the corresponding net_device
+ * @xid: the exchange id requesting ddp
+ * @sgl: the scatter-gather list for this request
+ * @sgc: the number of scatter-gather items
+ *
+ * This is the implementation of net_device_ops.ndo_fcoe_ddp_setup
+ * and is expected to be called from ULD, e.g., FCP layer of libfc
+ * to set up ddp for the corresponding xid of the given sglist for
+ * the corresponding I/O.
+ *
+ * Returns : 1 for success and 0 for no ddp
+ */
+int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
+ struct scatterlist *sgl, unsigned int sgc)
+{
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_hw *hw;
+ struct ixgbe_fcoe *fcoe;
+ struct ixgbe_fcoe_ddp *ddp;
+ struct scatterlist *sg;
+ unsigned int i, j, dmacount;
+ unsigned int len;
+ static const unsigned int bufflen = 4096;
+ unsigned int firstoff = 0;
+ unsigned int lastsize;
+ unsigned int thisoff = 0;
+ unsigned int thislen = 0;
+ u32 fcbuff, fcdmarw, fcfltrw;
+ dma_addr_t addr;
+
+ if (!netdev || !sgl)
+ return 0;
+
+ adapter = netdev_priv(netdev);
+ if (xid >= IXGBE_FCOE_DDP_MAX) {
+ DPRINTK(DRV, WARNING, "xid=0x%x out-of-range\n", xid);
+ return 0;
+ }
+
+ fcoe = &adapter->fcoe;
+ if (!fcoe->pool) {
+ DPRINTK(DRV, WARNING, "xid=0x%x no ddp pool for fcoe\n", xid);
+ return 0;
+ }
+
+ ddp = &fcoe->ddp[xid];
+ if (ddp->sgl) {
+ DPRINTK(DRV, ERR, "xid 0x%x w/ non-null sgl=%p nents=%d\n",
+ xid, ddp->sgl, ddp->sgc);
+ return 0;
+ }
+ ixgbe_fcoe_clear_ddp(ddp);
+
+ /* setup dma from scsi command sgl */
+ dmacount = pci_map_sg(adapter->pdev, sgl, sgc, DMA_FROM_DEVICE);
+ if (dmacount == 0) {
+ DPRINTK(DRV, ERR, "xid 0x%x DMA map error\n", xid);
+ return 0;
+ }
+
+ /* alloc the udl from our ddp pool */
+ ddp->udl = pci_pool_alloc(fcoe->pool, GFP_KERNEL, &ddp->udp);
+ if (!ddp->udl) {
+ DPRINTK(DRV, ERR, "failed allocated ddp context\n");
+ goto out_noddp_unmap;
+ }
+ ddp->sgl = sgl;
+ ddp->sgc = sgc;
+
+ j = 0;
+ for_each_sg(sgl, sg, dmacount, i) {
+ addr = sg_dma_address(sg);
+ len = sg_dma_len(sg);
+ while (len) {
+ /* get the offset of length of current buffer */
+ thisoff = addr & ((dma_addr_t)bufflen - 1);
+ thislen = min((bufflen - thisoff), len);
+ /*
+ * all but the 1st buffer (j == 0)
+ * must be aligned on bufflen
+ */
+ if ((j != 0) && (thisoff))
+ goto out_noddp_free;
+ /*
+ * all but the last buffer
+ * ((i == (dmacount - 1)) && (thislen == len))
+ * must end at bufflen
+ */
+ if (((i != (dmacount - 1)) || (thislen != len))
+ && ((thislen + thisoff) != bufflen))
+ goto out_noddp_free;
+
+ ddp->udl[j] = (u64)(addr - thisoff);
+ /* only the first buffer may have none-zero offset */
+ if (j == 0)
+ firstoff = thisoff;
+ len -= thislen;
+ addr += thislen;
+ j++;
+ /* max number of buffers allowed in one DDP context */
+ if (j > IXGBE_BUFFCNT_MAX) {
+ DPRINTK(DRV, ERR, "xid=%x:%d,%d,%d:addr=%llx "
+ "not enough descriptors\n",
+ xid, i, j, dmacount, (u64)addr);
+ goto out_noddp_free;
+ }
+ }
+ }
+ /* only the last buffer may have non-full bufflen */
+ lastsize = thisoff + thislen;
+
+ fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT);
+ fcbuff |= (j << IXGBE_FCBUFF_BUFFCNT_SHIFT);
+ fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT);
+ fcbuff |= (IXGBE_FCBUFF_VALID);
+
+ fcdmarw = xid;
+ fcdmarw |= IXGBE_FCDMARW_WE;
+ fcdmarw |= (lastsize << IXGBE_FCDMARW_LASTSIZE_SHIFT);
+
+ fcfltrw = xid;
+ fcfltrw |= IXGBE_FCFLTRW_WE;
+
+ /* program DMA context */
+ hw = &adapter->hw;
+ spin_lock_bh(&fcoe->lock);
+ IXGBE_WRITE_REG(hw, IXGBE_FCPTRL, ddp->udp & DMA_32BIT_MASK);
+ IXGBE_WRITE_REG(hw, IXGBE_FCPTRH, (u64)ddp->udp >> 32);
+ IXGBE_WRITE_REG(hw, IXGBE_FCBUFF, fcbuff);
+ IXGBE_WRITE_REG(hw, IXGBE_FCDMARW, fcdmarw);
+ /* program filter context */
+ IXGBE_WRITE_REG(hw, IXGBE_FCPARAM, 0);
+ IXGBE_WRITE_REG(hw, IXGBE_FCFLT, IXGBE_FCFLT_VALID);
+ IXGBE_WRITE_REG(hw, IXGBE_FCFLTRW, fcfltrw);
+ spin_unlock_bh(&fcoe->lock);
+
+ return 1;
+
+out_noddp_free:
+ pci_pool_free(fcoe->pool, ddp->udl, ddp->udp);
+ ixgbe_fcoe_clear_ddp(ddp);
+
+out_noddp_unmap:
+ pci_unmap_sg(adapter->pdev, sgl, sgc, DMA_FROM_DEVICE);
+ return 0;
+}
+
+/**
+ * ixgbe_fcoe_ddp - check ddp status and mark it done
+ * @adapter: ixgbe adapter
+ * @rx_desc: advanced rx descriptor
+ * @skb: the skb holding the received data
+ *
+ * This checks ddp status.
+ *
+ * Returns : < 0 indicates an error or not a FCiE ddp, 0 indicates
+ * not passing the skb to ULD, > 0 indicates is the length of data
+ * being ddped.
+ */
+int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
+ union ixgbe_adv_rx_desc *rx_desc,
+ struct sk_buff *skb)
+{
+ u16 xid;
+ u32 sterr, fceofe, fcerr, fcstat;
+ int rc = -EINVAL;
+ struct ixgbe_fcoe *fcoe;
+ struct ixgbe_fcoe_ddp *ddp;
+ struct fc_frame_header *fh;
+
+ if (!ixgbe_rx_is_fcoe(rx_desc))
+ goto ddp_out;
+
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ sterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+ fcerr = (sterr & IXGBE_RXDADV_ERR_FCERR);
+ fceofe = (sterr & IXGBE_RXDADV_ERR_FCEOFE);
+ if (fcerr == IXGBE_FCERR_BADCRC)
+ skb->ip_summed = CHECKSUM_NONE;
+
+ skb_reset_network_header(skb);
+ skb_set_transport_header(skb, skb_network_offset(skb) +
+ sizeof(struct fcoe_hdr));
+ fh = (struct fc_frame_header *)skb_transport_header(skb);
+ xid = be16_to_cpu(fh->fh_ox_id);
+ if (xid >= IXGBE_FCOE_DDP_MAX)
+ goto ddp_out;
+
+ fcoe = &adapter->fcoe;
+ ddp = &fcoe->ddp[xid];
+ if (!ddp->udl)
+ goto ddp_out;
+
+ ddp->err = (fcerr | fceofe);
+ if (ddp->err)
+ goto ddp_out;
+
+ fcstat = (sterr & IXGBE_RXDADV_STAT_FCSTAT);
+ if (fcstat) {
+ /* update length of DDPed data */
+ ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
+ /* unmap the sg list when FCP_RSP is received */
+ if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_FCPRSP) {
+ pci_unmap_sg(adapter->pdev, ddp->sgl,
+ ddp->sgc, DMA_FROM_DEVICE);
+ ddp->sgl = NULL;
+ ddp->sgc = 0;
+ }
+ /* return 0 to bypass going to ULD for DDPed data */
+ if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_DDP)
+ rc = 0;
+ else
+ rc = ddp->len;
+ }
+
+ddp_out:
+ return rc;
+}
+
+/**
+ * ixgbe_fso - ixgbe FCoE Sequence Offload (FSO)
+ * @adapter: ixgbe adapter
+ * @tx_ring: tx desc ring
+ * @skb: associated skb
+ * @tx_flags: tx flags
+ * @hdr_len: hdr_len to be returned
+ *
+ * This sets up large send offload for FCoE
+ *
+ * Returns : 0 indicates no FSO, > 0 for FSO, < 0 for error
+ */
+int ixgbe_fso(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *tx_ring, struct sk_buff *skb,
+ u32 tx_flags, u8 *hdr_len)
+{
+ u8 sof, eof;
+ u32 vlan_macip_lens;
+ u32 fcoe_sof_eof;
+ u32 type_tucmd;
+ u32 mss_l4len_idx;
+ int mss = 0;
+ unsigned int i;
+ struct ixgbe_tx_buffer *tx_buffer_info;
+ struct ixgbe_adv_tx_context_desc *context_desc;
+ struct fc_frame_header *fh;
+
+ if (skb_is_gso(skb) && (skb_shinfo(skb)->gso_type != SKB_GSO_FCOE)) {
+ DPRINTK(DRV, ERR, "Wrong gso type %d:expecting SKB_GSO_FCOE\n",
+ skb_shinfo(skb)->gso_type);
+ return -EINVAL;
+ }
+
+ /* resets the header to point fcoe/fc */
+ skb_set_network_header(skb, skb->mac_len);
+ skb_set_transport_header(skb, skb->mac_len +
+ sizeof(struct fcoe_hdr));
+
+ /* sets up SOF and ORIS */
+ fcoe_sof_eof = 0;
+ sof = ((struct fcoe_hdr *)skb_network_header(skb))->fcoe_sof;
+ switch (sof) {
+ case FC_SOF_I2:
+ fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIS;
+ break;
+ case FC_SOF_I3:
+ fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_SOF;
+ fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIS;
+ break;
+ case FC_SOF_N2:
+ break;
+ case FC_SOF_N3:
+ fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_SOF;
+ break;
+ default:
+ DPRINTK(DRV, WARNING, "unknown sof = 0x%x\n", sof);
+ return -EINVAL;
+ }
+
+ /* the first byte of the last dword is EOF */
+ skb_copy_bits(skb, skb->len - 4, &eof, 1);
+ /* sets up EOF and ORIE */
+ switch (eof) {
+ case FC_EOF_N:
+ fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_N;
+ break;
+ case FC_EOF_T:
+ /* lso needs ORIE */
+ if (skb_is_gso(skb)) {
+ fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_N;
+ fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIE;
+ } else {
+ fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_T;
+ }
+ break;
+ case FC_EOF_NI:
+ fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_NI;
+ break;
+ case FC_EOF_A:
+ fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_A;
+ break;
+ default:
+ DPRINTK(DRV, WARNING, "unknown eof = 0x%x\n", eof);
+ return -EINVAL;
+ }
+
+ /* sets up PARINC indicating data offset */
+ fh = (struct fc_frame_header *)skb_transport_header(skb);
+ if (fh->fh_f_ctl[2] & FC_FC_REL_OFF)
+ fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_PARINC;
+
+ /* hdr_len includes fc_hdr if FCoE lso is enabled */
+ *hdr_len = sizeof(struct fcoe_crc_eof);
+ if (skb_is_gso(skb))
+ *hdr_len += (skb_transport_offset(skb) +
+ sizeof(struct fc_frame_header));
+ /* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */
+ vlan_macip_lens = (skb_transport_offset(skb) +
+ sizeof(struct fc_frame_header));
+ vlan_macip_lens |= ((skb_transport_offset(skb) - 4)
+ << IXGBE_ADVTXD_MACLEN_SHIFT);
+ vlan_macip_lens |= (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
+
+ /* type_tycmd and mss: set TUCMD.FCoE to enable offload */
+ type_tucmd = IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT |
+ IXGBE_ADVTXT_TUCMD_FCOE;
+ if (skb_is_gso(skb))
+ mss = skb_shinfo(skb)->gso_size;
+ /* mss_l4len_id: use 1 for FSO as TSO, no need for L4LEN */
+ mss_l4len_idx = (mss << IXGBE_ADVTXD_MSS_SHIFT) |
+ (1 << IXGBE_ADVTXD_IDX_SHIFT);
+
+ /* write context desc */
+ i = tx_ring->next_to_use;
+ context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i);
+ context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
+ context_desc->seqnum_seed = cpu_to_le32(fcoe_sof_eof);
+ context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd);
+ context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
+
+ tx_buffer_info = &tx_ring->tx_buffer_info[i];
+ tx_buffer_info->time_stamp = jiffies;
+ tx_buffer_info->next_to_watch = i;
+
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+ tx_ring->next_to_use = i;
+
+ return skb_is_gso(skb);
+}
+
+/**
+ * ixgbe_configure_fcoe - configures registers for fcoe at start
+ * @adapter: ptr to ixgbe adapter
+ *
+ * This sets up FCoE related registers
+ *
+ * Returns : none
+ */
+void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
+{
+ int i, fcoe_q, fcoe_i;
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct ixgbe_fcoe *fcoe = &adapter->fcoe;
+ struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE];
+
+ /* create the pool for ddp if not created yet */
+ if (!fcoe->pool) {
+ /* allocate ddp pool */
+ fcoe->pool = pci_pool_create("ixgbe_fcoe_ddp",
+ adapter->pdev, IXGBE_FCPTR_MAX,
+ IXGBE_FCPTR_ALIGN, PAGE_SIZE);
+ if (!fcoe->pool)
+ DPRINTK(DRV, ERR,
+ "failed to allocated FCoE DDP pool\n");
+
+ spin_lock_init(&fcoe->lock);
+ }
+
+ /* Enable L2 eth type filter for FCoE */
+ IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE),
+ (ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN));
+ if (adapter->ring_feature[RING_F_FCOE].indices) {
+ /* Use multiple rx queues for FCoE by redirection table */
+ for (i = 0; i < IXGBE_FCRETA_SIZE; i++) {
+ fcoe_i = f->mask + i % f->indices;
+ fcoe_i &= IXGBE_FCRETA_ENTRY_MASK;
+ fcoe_q = adapter->rx_ring[fcoe_i].reg_idx;
+ IXGBE_WRITE_REG(hw, IXGBE_FCRETA(i), fcoe_q);
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, IXGBE_FCRECTL_ENA);
+ IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0);
+ } else {
+ /* Use single rx queue for FCoE */
+ fcoe_i = f->mask;
+ fcoe_q = adapter->rx_ring[fcoe_i].reg_idx;
+ IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, 0);
+ IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE),
+ IXGBE_ETQS_QUEUE_EN |
+ (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
+ }
+
+ IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL,
+ IXGBE_FCRXCTRL_FCOELLI |
+ IXGBE_FCRXCTRL_FCCRCBO |
+ (FC_FCOE_VER << IXGBE_FCRXCTRL_FCOEVER_SHIFT));
+}
+
+/**
+ * ixgbe_cleanup_fcoe - release all fcoe ddp context resources
+ * @adapter : ixgbe adapter
+ *
+ * Cleans up outstanding ddp context resources
+ *
+ * Returns : none
+ */
+void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter)
+{
+ int i;
+ struct ixgbe_fcoe *fcoe = &adapter->fcoe;
+
+ /* release ddp resource */
+ if (fcoe->pool) {
+ for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++)
+ ixgbe_fcoe_ddp_put(adapter->netdev, i);
+ pci_pool_destroy(fcoe->pool);
+ fcoe->pool = NULL;
+ }
+}
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h
new file mode 100644
index 00000000000..c5b50026a89
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_fcoe.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+
+ Intel 10 Gigabit PCI Express Linux driver
+ Copyright(c) 1999 - 2009 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _IXGBE_FCOE_H
+#define _IXGBE_FCOE_H
+
+#include <scsi/fc/fc_fs.h>
+#include <scsi/fc/fc_fcoe.h>
+
+/* shift bits within STAT fo FCSTAT */
+#define IXGBE_RXDADV_FCSTAT_SHIFT 4
+
+/* ddp user buffer */
+#define IXGBE_BUFFCNT_MAX 256 /* 8 bits bufcnt */
+#define IXGBE_FCPTR_ALIGN 16
+#define IXGBE_FCPTR_MAX (IXGBE_BUFFCNT_MAX * sizeof(dma_addr_t))
+#define IXGBE_FCBUFF_4KB 0x0
+#define IXGBE_FCBUFF_8KB 0x1
+#define IXGBE_FCBUFF_16KB 0x2
+#define IXGBE_FCBUFF_64KB 0x3
+#define IXGBE_FCBUFF_MAX 65536 /* 64KB max */
+#define IXGBE_FCBUFF_MIN 4096 /* 4KB min */
+#define IXGBE_FCOE_DDP_MAX 512 /* 9 bits xid */
+
+/* fcerr */
+#define IXGBE_FCERR_BADCRC 0x00100000
+
+struct ixgbe_fcoe_ddp {
+ int len;
+ u32 err;
+ unsigned int sgc;
+ struct scatterlist *sgl;
+ dma_addr_t udp;
+ u64 *udl;
+};
+
+struct ixgbe_fcoe {
+ spinlock_t lock;
+ struct pci_pool *pool;
+ struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX];
+};
+
+#endif /* _IXGBE_FCOE_H */
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 07e778d3e5d..a551a96ce67 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -39,6 +39,7 @@
#include <net/ip6_checksum.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
+#include <scsi/fc/fc_fcoe.h>
#include "ixgbe.h"
#include "ixgbe_common.h"
@@ -47,7 +48,7 @@ char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
"Intel(R) 10 Gigabit PCI Express Network Driver";
-#define DRV_VERSION "2.0.8-k2"
+#define DRV_VERSION "2.0.34-k2"
const char ixgbe_driver_version[] = DRV_VERSION;
static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
@@ -89,6 +90,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4),
board_82599 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_XAUI_LOM),
+ board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP),
board_82599 },
@@ -183,6 +186,22 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction,
}
}
+static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter,
+ u64 qmask)
+{
+ u32 mask;
+
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask);
+ } else {
+ mask = (qmask & 0xFFFFFFFF);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), mask);
+ mask = (qmask >> 32);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(1), mask);
+ }
+}
+
static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
struct ixgbe_tx_buffer
*tx_buffer_info)
@@ -245,14 +264,13 @@ static void ixgbe_tx_timeout(struct net_device *netdev);
/**
* ixgbe_clean_tx_irq - Reclaim resources after transmit completes
- * @adapter: board private structure
+ * @q_vector: structure containing interrupt and ring information
* @tx_ring: tx ring to clean
- *
- * returns true if transmit work is done
**/
-static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
+static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
struct ixgbe_ring *tx_ring)
{
+ struct ixgbe_adapter *adapter = q_vector->adapter;
struct net_device *netdev = adapter->netdev;
union ixgbe_adv_tx_desc *tx_desc, *eop_desc;
struct ixgbe_tx_buffer *tx_buffer_info;
@@ -275,12 +293,24 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
if (cleaned && skb) {
unsigned int segs, bytecount;
+ unsigned int hlen = skb_headlen(skb);
/* gso_segs is currently only valid for tcp */
segs = skb_shinfo(skb)->gso_segs ?: 1;
+#ifdef IXGBE_FCOE
+ /* adjust for FCoE Sequence Offload */
+ if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
+ && (skb->protocol == htons(ETH_P_FCOE)) &&
+ skb_is_gso(skb)) {
+ hlen = skb_transport_offset(skb) +
+ sizeof(struct fc_frame_header) +
+ sizeof(struct fcoe_crc_eof);
+ segs = DIV_ROUND_UP(skb->len - hlen,
+ skb_shinfo(skb)->gso_size);
+ }
+#endif /* IXGBE_FCOE */
/* multiply data chunks by size of headers */
- bytecount = ((segs - 1) * skb_headlen(skb)) +
- skb->len;
+ bytecount = ((segs - 1) * hlen) + skb->len;
total_packets += segs;
total_bytes += bytecount;
}
@@ -327,7 +357,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
/* re-arm the interrupt */
if (count >= tx_ring->work_limit)
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->v_idx);
+ ixgbe_irq_rearm_queues(adapter, ((u64)1 << q_vector->v_idx));
tx_ring->total_bytes += total_bytes;
tx_ring->total_packets += total_packets;
@@ -398,6 +428,9 @@ static void ixgbe_setup_dca(struct ixgbe_adapter *adapter)
if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED))
return;
+ /* always use CB2 mode, difference is masked in the CB driver */
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
+
for (i = 0; i < adapter->num_tx_queues; i++) {
adapter->tx_ring[i].cpu = -1;
ixgbe_update_tx_dca(adapter, &adapter->tx_ring[i]);
@@ -419,9 +452,6 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
/* if we're already enabled, don't do it again */
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
break;
- /* Always use CB2 mode, difference is masked
- * in the CB driver. */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
if (dca_add_requester(dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
ixgbe_setup_dca(adapter);
@@ -451,6 +481,7 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
**/
static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
struct sk_buff *skb, u8 status,
+ struct ixgbe_ring *ring,
union ixgbe_adv_rx_desc *rx_desc)
{
struct ixgbe_adapter *adapter = q_vector->adapter;
@@ -458,24 +489,17 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
bool is_vlan = (status & IXGBE_RXD_STAT_VP);
u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
- skb_record_rx_queue(skb, q_vector - &adapter->q_vector[0]);
- if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
+ skb_record_rx_queue(skb, ring->queue_index);
+ if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
if (adapter->vlgrp && is_vlan && (tag != 0))
vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
else
napi_gro_receive(napi, skb);
} else {
- if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
- if (adapter->vlgrp && is_vlan && (tag != 0))
- vlan_hwaccel_receive_skb(skb, adapter->vlgrp, tag);
- else
- netif_receive_skb(skb);
- } else {
- if (adapter->vlgrp && is_vlan && (tag != 0))
- vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
- else
- netif_rx(skb);
- }
+ if (adapter->vlgrp && is_vlan && (tag != 0))
+ vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
+ else
+ netif_rx(skb);
}
}
@@ -622,6 +646,40 @@ static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc)
return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
}
+static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc)
+{
+ return (le32_to_cpu(rx_desc->wb.lower.lo_dword.data) &
+ IXGBE_RXDADV_RSCCNT_MASK) >>
+ IXGBE_RXDADV_RSCCNT_SHIFT;
+}
+
+/**
+ * ixgbe_transform_rsc_queue - change rsc queue into a full packet
+ * @skb: pointer to the last skb in the rsc queue
+ *
+ * This function changes a queue full of hw rsc buffers into a completed
+ * packet. It uses the ->prev pointers to find the first packet and then
+ * turns it into the frag list owner.
+ **/
+static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb)
+{
+ unsigned int frag_list_size = 0;
+
+ while (skb->prev) {
+ struct sk_buff *prev = skb->prev;
+ frag_list_size += skb->len;
+ skb->prev = NULL;
+ skb = prev;
+ }
+
+ skb_shinfo(skb)->frag_list = skb->next;
+ skb->next = NULL;
+ skb->len += frag_list_size;
+ skb->data_len += frag_list_size;
+ skb->truesize += frag_list_size;
+ return skb;
+}
+
static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
struct ixgbe_ring *rx_ring,
int *work_done, int work_to_do)
@@ -631,12 +689,15 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
struct sk_buff *skb;
- unsigned int i;
+ unsigned int i, rsc_count = 0;
u32 len, staterr;
u16 hdr_info;
bool cleaned = false;
int cleaned_count = 0;
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
+#ifdef IXGBE_FCOE
+ int ddp_bytes = 0;
+#endif /* IXGBE_FCOE */
i = rx_ring->next_to_clean;
rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
@@ -667,7 +728,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
prefetch(skb->data - NET_IP_ALIGN);
rx_buffer_info->skb = NULL;
- if (len && !skb_shinfo(skb)->nr_frags) {
+ if (rx_buffer_info->dma) {
pci_unmap_single(pdev, rx_buffer_info->dma,
rx_ring->rx_buf_len,
PCI_DMA_FROMDEVICE);
@@ -697,20 +758,38 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
i++;
if (i == rx_ring->count)
i = 0;
- next_buffer = &rx_ring->rx_buffer_info[i];
next_rxd = IXGBE_RX_DESC_ADV(*rx_ring, i);
prefetch(next_rxd);
-
cleaned_count++;
+
+ if (adapter->flags & IXGBE_FLAG2_RSC_CAPABLE)
+ rsc_count = ixgbe_get_rsc_count(rx_desc);
+
+ if (rsc_count) {
+ u32 nextp = (staterr & IXGBE_RXDADV_NEXTP_MASK) >>
+ IXGBE_RXDADV_NEXTP_SHIFT;
+ next_buffer = &rx_ring->rx_buffer_info[nextp];
+ rx_ring->rsc_count += (rsc_count - 1);
+ } else {
+ next_buffer = &rx_ring->rx_buffer_info[i];
+ }
+
if (staterr & IXGBE_RXD_STAT_EOP) {
+ if (skb->prev)
+ skb = ixgbe_transform_rsc_queue(skb);
rx_ring->stats.packets++;
rx_ring->stats.bytes += skb->len;
} else {
- rx_buffer_info->skb = next_buffer->skb;
- rx_buffer_info->dma = next_buffer->dma;
- next_buffer->skb = skb;
- next_buffer->dma = 0;
+ if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+ rx_buffer_info->skb = next_buffer->skb;
+ rx_buffer_info->dma = next_buffer->dma;
+ next_buffer->skb = skb;
+ next_buffer->dma = 0;
+ } else {
+ skb->next = next_buffer->skb;
+ skb->next->prev = skb;
+ }
adapter->non_eop_descs++;
goto next_desc;
}
@@ -727,7 +806,15 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
total_rx_packets++;
skb->protocol = eth_type_trans(skb, adapter->netdev);
- ixgbe_receive_skb(q_vector, skb, staterr, rx_desc);
+#ifdef IXGBE_FCOE
+ /* if ddp, not passing to ULD unless for FCP_RSP or error */
+ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
+ ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb);
+ if (!ddp_bytes)
+ goto next_desc;
+ }
+#endif /* IXGBE_FCOE */
+ ixgbe_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc);
next_desc:
rx_desc->wb.upper.status_error = 0;
@@ -740,7 +827,7 @@ next_desc:
/* use prefetched values */
rx_desc = next_rxd;
- rx_buffer_info = next_buffer;
+ rx_buffer_info = &rx_ring->rx_buffer_info[i];
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
}
@@ -751,6 +838,21 @@ next_desc:
if (cleaned_count)
ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count);
+#ifdef IXGBE_FCOE
+ /* include DDPed FCoE data */
+ if (ddp_bytes > 0) {
+ unsigned int mss;
+
+ mss = adapter->netdev->mtu - sizeof(struct fcoe_hdr) -
+ sizeof(struct fc_frame_header) -
+ sizeof(struct fcoe_crc_eof);
+ if (mss > 512)
+ mss &= ~511;
+ total_rx_bytes += ddp_bytes;
+ total_rx_packets += DIV_ROUND_UP(ddp_bytes, mss);
+ }
+#endif /* IXGBE_FCOE */
+
rx_ring->total_packets += total_rx_packets;
rx_ring->total_bytes += total_rx_bytes;
adapter->net_stats.rx_bytes += total_rx_bytes;
@@ -780,7 +882,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
* corresponding register.
*/
for (v_idx = 0; v_idx < q_vectors; v_idx++) {
- q_vector = &adapter->q_vector[v_idx];
+ q_vector = adapter->q_vector[v_idx];
/* XXX for_each_bit(...) */
r_idx = find_first_bit(q_vector->rxr_idx,
adapter->num_rx_queues);
@@ -810,12 +912,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
/* rx only */
q_vector->eitr = adapter->eitr_param;
- /*
- * since this is initial set up don't need to call
- * ixgbe_write_eitr helper
- */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx),
- EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
+ ixgbe_write_eitr(q_vector);
}
if (adapter->hw.mac.type == ixgbe_mac_82598EB)
@@ -900,17 +997,19 @@ update_itr_done:
/**
* ixgbe_write_eitr - write EITR register in hardware specific way
- * @adapter: pointer to adapter struct
- * @v_idx: vector index into q_vector array
- * @itr_reg: new value to be written in *register* format, not ints/s
+ * @q_vector: structure containing interrupt and ring information
*
* This function is made to be called by ethtool and by the driver
* when it needs to update EITR registers at runtime. Hardware
* specific quirks/differences are taken care of here.
*/
-void ixgbe_write_eitr(struct ixgbe_adapter *adapter, int v_idx, u32 itr_reg)
+void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector)
{
+ struct ixgbe_adapter *adapter = q_vector->adapter;
struct ixgbe_hw *hw = &adapter->hw;
+ int v_idx = q_vector->v_idx;
+ u32 itr_reg = EITR_INTS_PER_SEC_TO_REG(q_vector->eitr);
+
if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
/* must write high and low 16 bits to reset counter */
itr_reg |= (itr_reg << 16);
@@ -929,8 +1028,7 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
struct ixgbe_adapter *adapter = q_vector->adapter;
u32 new_itr;
u8 current_itr, ret_itr;
- int i, r_idx, v_idx = ((void *)q_vector - (void *)(adapter->q_vector)) /
- sizeof(struct ixgbe_q_vector);
+ int i, r_idx;
struct ixgbe_ring *rx_ring, *tx_ring;
r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
@@ -980,14 +1078,13 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
}
if (new_itr != q_vector->eitr) {
- u32 itr_reg;
+ /* do an exponential smoothing */
+ new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
/* save the algorithm value here, not the smoothed one */
q_vector->eitr = new_itr;
- /* do an exponential smoothing */
- new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
- itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
- ixgbe_write_eitr(adapter, v_idx, itr_reg);
+
+ ixgbe_write_eitr(q_vector);
}
return;
@@ -1058,14 +1155,64 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
if (hw->mac.type == ixgbe_mac_82598EB)
ixgbe_check_fan_failure(adapter, eicr);
- if (hw->mac.type == ixgbe_mac_82599EB)
+ if (hw->mac.type == ixgbe_mac_82599EB) {
ixgbe_check_sfp_event(adapter, eicr);
+
+ /* Handle Flow Director Full threshold interrupt */
+ if (eicr & IXGBE_EICR_FLOW_DIR) {
+ int i;
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_FLOW_DIR);
+ /* Disable transmits before FDIR Re-initialization */
+ netif_tx_stop_all_queues(netdev);
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ struct ixgbe_ring *tx_ring =
+ &adapter->tx_ring[i];
+ if (test_and_clear_bit(__IXGBE_FDIR_INIT_DONE,
+ &tx_ring->reinit_state))
+ schedule_work(&adapter->fdir_reinit_task);
+ }
+ }
+ }
if (!test_bit(__IXGBE_DOWN, &adapter->state))
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
return IRQ_HANDLED;
}
+static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter,
+ u64 qmask)
+{
+ u32 mask;
+
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
+ } else {
+ mask = (qmask & 0xFFFFFFFF);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(0), mask);
+ mask = (qmask >> 32);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask);
+ }
+ /* skip the flush */
+}
+
+static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter,
+ u64 qmask)
+{
+ u32 mask;
+
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, mask);
+ } else {
+ mask = (qmask & 0xFFFFFFFF);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), mask);
+ mask = (qmask >> 32);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), mask);
+ }
+ /* skip the flush */
+}
+
static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
{
struct ixgbe_q_vector *q_vector = data;
@@ -1079,17 +1226,16 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
for (i = 0; i < q_vector->txr_count; i++) {
tx_ring = &(adapter->tx_ring[r_idx]);
-#ifdef CONFIG_IXGBE_DCA
- if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
- ixgbe_update_tx_dca(adapter, tx_ring);
-#endif
tx_ring->total_bytes = 0;
tx_ring->total_packets = 0;
- ixgbe_clean_tx_irq(adapter, tx_ring);
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
r_idx + 1);
}
+ /* disable interrupts on this vector only */
+ ixgbe_irq_disable_queues(adapter, ((u64)1 << q_vector->v_idx));
+ napi_schedule(&q_vector->napi);
+
return IRQ_HANDLED;
}
@@ -1121,7 +1267,7 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
rx_ring = &(adapter->rx_ring[r_idx]);
/* disable interrupts on this vector only */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx);
+ ixgbe_irq_disable_queues(adapter, ((u64)1 << q_vector->v_idx));
napi_schedule(&q_vector->napi);
return IRQ_HANDLED;
@@ -1129,8 +1275,36 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
{
- ixgbe_msix_clean_rx(irq, data);
- ixgbe_msix_clean_tx(irq, data);
+ struct ixgbe_q_vector *q_vector = data;
+ struct ixgbe_adapter *adapter = q_vector->adapter;
+ struct ixgbe_ring *ring;
+ int r_idx;
+ int i;
+
+ if (!q_vector->txr_count && !q_vector->rxr_count)
+ return IRQ_HANDLED;
+
+ r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
+ for (i = 0; i < q_vector->txr_count; i++) {
+ ring = &(adapter->tx_ring[r_idx]);
+ ring->total_bytes = 0;
+ ring->total_packets = 0;
+ r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
+ r_idx + 1);
+ }
+
+ r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+ for (i = 0; i < q_vector->rxr_count; i++) {
+ ring = &(adapter->rx_ring[r_idx]);
+ ring->total_bytes = 0;
+ ring->total_packets = 0;
+ r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
+ r_idx + 1);
+ }
+
+ /* disable interrupts on this vector only */
+ ixgbe_irq_disable_queues(adapter, ((u64)1 << q_vector->v_idx));
+ napi_schedule(&q_vector->napi);
return IRQ_HANDLED;
}
@@ -1167,29 +1341,42 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
if (adapter->itr_setting & 1)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rx_ring->v_idx);
+ ixgbe_irq_enable_queues(adapter,
+ ((u64)1 << q_vector->v_idx));
}
return work_done;
}
/**
- * ixgbe_clean_rxonly_many - msix (aka one shot) rx clean routine
+ * ixgbe_clean_rxtx_many - msix (aka one shot) rx clean routine
* @napi: napi struct with our devices info in it
* @budget: amount of work driver is allowed to do this pass, in packets
*
* This function will clean more than one rx queue associated with a
* q_vector.
**/
-static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
+static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
{
struct ixgbe_q_vector *q_vector =
container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
- struct ixgbe_ring *rx_ring = NULL;
+ struct ixgbe_ring *ring = NULL;
int work_done = 0, i;
long r_idx;
- u16 enable_mask = 0;
+ bool tx_clean_complete = true;
+
+ r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
+ for (i = 0; i < q_vector->txr_count; i++) {
+ ring = &(adapter->tx_ring[r_idx]);
+#ifdef CONFIG_IXGBE_DCA
+ if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+ ixgbe_update_tx_dca(adapter, ring);
+#endif
+ tx_clean_complete &= ixgbe_clean_tx_irq(q_vector, ring);
+ r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
+ r_idx + 1);
+ }
/* attempt to distribute budget to each queue fairly, but don't allow
* the budget to go below 1 because we'll exit polling */
@@ -1197,47 +1384,87 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
budget = max(budget, 1);
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
for (i = 0; i < q_vector->rxr_count; i++) {
- rx_ring = &(adapter->rx_ring[r_idx]);
+ ring = &(adapter->rx_ring[r_idx]);
#ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
- ixgbe_update_rx_dca(adapter, rx_ring);
+ ixgbe_update_rx_dca(adapter, ring);
#endif
- ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
- enable_mask |= rx_ring->v_idx;
+ ixgbe_clean_rx_irq(q_vector, ring, &work_done, budget);
r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
r_idx + 1);
}
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
- rx_ring = &(adapter->rx_ring[r_idx]);
+ ring = &(adapter->rx_ring[r_idx]);
/* If all Rx work done, exit the polling mode */
if (work_done < budget) {
napi_complete(napi);
if (adapter->itr_setting & 1)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, enable_mask);
+ ixgbe_irq_enable_queues(adapter,
+ ((u64)1 << q_vector->v_idx));
return 0;
}
return work_done;
}
+
+/**
+ * ixgbe_clean_txonly - msix (aka one shot) tx clean routine
+ * @napi: napi struct with our devices info in it
+ * @budget: amount of work driver is allowed to do this pass, in packets
+ *
+ * This function is optimized for cleaning one queue only on a single
+ * q_vector!!!
+ **/
+static int ixgbe_clean_txonly(struct napi_struct *napi, int budget)
+{
+ struct ixgbe_q_vector *q_vector =
+ container_of(napi, struct ixgbe_q_vector, napi);
+ struct ixgbe_adapter *adapter = q_vector->adapter;
+ struct ixgbe_ring *tx_ring = NULL;
+ int work_done = 0;
+ long r_idx;
+
+ r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
+ tx_ring = &(adapter->tx_ring[r_idx]);
+#ifdef CONFIG_IXGBE_DCA
+ if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+ ixgbe_update_tx_dca(adapter, tx_ring);
+#endif
+
+ if (!ixgbe_clean_tx_irq(q_vector, tx_ring))
+ work_done = budget;
+
+ /* If all Rx work done, exit the polling mode */
+ if (work_done < budget) {
+ napi_complete(napi);
+ if (adapter->itr_setting & 1)
+ ixgbe_set_itr_msix(q_vector);
+ if (!test_bit(__IXGBE_DOWN, &adapter->state))
+ ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx));
+ }
+
+ return work_done;
+}
+
static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
int r_idx)
{
- a->q_vector[v_idx].adapter = a;
- set_bit(r_idx, a->q_vector[v_idx].rxr_idx);
- a->q_vector[v_idx].rxr_count++;
- a->rx_ring[r_idx].v_idx = 1 << v_idx;
+ struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
+
+ set_bit(r_idx, q_vector->rxr_idx);
+ q_vector->rxr_count++;
}
static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
- int r_idx)
+ int t_idx)
{
- a->q_vector[v_idx].adapter = a;
- set_bit(r_idx, a->q_vector[v_idx].txr_idx);
- a->q_vector[v_idx].txr_count++;
- a->tx_ring[r_idx].v_idx = 1 << v_idx;
+ struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
+
+ set_bit(t_idx, q_vector->txr_idx);
+ q_vector->txr_count++;
}
/**
@@ -1333,7 +1560,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
(!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
&ixgbe_msix_clean_many)
for (vector = 0; vector < q_vectors; vector++) {
- handler = SET_HANDLER(&adapter->q_vector[vector]);
+ handler = SET_HANDLER(adapter->q_vector[vector]);
if(handler == &ixgbe_msix_clean_rx) {
sprintf(adapter->name[vector], "%s-%s-%d",
@@ -1349,7 +1576,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
err = request_irq(adapter->msix_entries[vector].vector,
handler, 0, adapter->name[vector],
- &(adapter->q_vector[vector]));
+ adapter->q_vector[vector]);
if (err) {
DPRINTK(PROBE, ERR,
"request_irq failed for MSIX interrupt "
@@ -1372,7 +1599,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
free_queue_irqs:
for (i = vector - 1; i >= 0; i--)
free_irq(adapter->msix_entries[--vector].vector,
- &(adapter->q_vector[i]));
+ adapter->q_vector[i]);
adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
pci_disable_msix(adapter->pdev);
kfree(adapter->msix_entries);
@@ -1383,7 +1610,7 @@ out:
static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
{
- struct ixgbe_q_vector *q_vector = adapter->q_vector;
+ struct ixgbe_q_vector *q_vector = adapter->q_vector[0];
u8 current_itr;
u32 new_itr = q_vector->eitr;
struct ixgbe_ring *rx_ring = &adapter->rx_ring[0];
@@ -1416,14 +1643,13 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
}
if (new_itr != q_vector->eitr) {
- u32 itr_reg;
+ /* do an exponential smoothing */
+ new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
/* save the algorithm value here, not the smoothed one */
q_vector->eitr = new_itr;
- /* do an exponential smoothing */
- new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
- itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
- ixgbe_write_eitr(adapter, 0, itr_reg);
+
+ ixgbe_write_eitr(q_vector);
}
return;
@@ -1436,7 +1662,8 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
{
u32 mask;
- mask = IXGBE_EIMS_ENABLE_MASK;
+
+ mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
mask |= IXGBE_EIMS_GPI_SDP1;
if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
@@ -1444,16 +1671,12 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
mask |= IXGBE_EIMS_GPI_SDP1;
mask |= IXGBE_EIMS_GPI_SDP2;
}
+ if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
+ adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
+ mask |= IXGBE_EIMS_FLOW_DIR;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- /* enable the rest of the queue vectors */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1),
- (IXGBE_EIMS_RTX_QUEUE << 16));
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(2),
- ((IXGBE_EIMS_RTX_QUEUE << 16) |
- IXGBE_EIMS_RTX_QUEUE));
- }
+ ixgbe_irq_enable_queues(adapter, ~0);
IXGBE_WRITE_FLUSH(&adapter->hw);
}
@@ -1467,6 +1690,7 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
struct net_device *netdev = data;
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
+ struct ixgbe_q_vector *q_vector = adapter->q_vector[0];
u32 eicr;
/*
@@ -1494,13 +1718,13 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
ixgbe_check_fan_failure(adapter, eicr);
- if (napi_schedule_prep(&adapter->q_vector[0].napi)) {
+ if (napi_schedule_prep(&(q_vector->napi))) {
adapter->tx_ring[0].total_packets = 0;
adapter->tx_ring[0].total_bytes = 0;
adapter->rx_ring[0].total_packets = 0;
adapter->rx_ring[0].total_bytes = 0;
/* would disable interrupts here but EIAM disabled it */
- __napi_schedule(&adapter->q_vector[0].napi);
+ __napi_schedule(&(q_vector->napi));
}
return IRQ_HANDLED;
@@ -1511,7 +1735,7 @@ static inline void ixgbe_reset_q_vectors(struct ixgbe_adapter *adapter)
int i, q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
for (i = 0; i < q_vectors; i++) {
- struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
+ struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
bitmap_zero(q_vector->rxr_idx, MAX_RX_QUEUES);
bitmap_zero(q_vector->txr_idx, MAX_TX_QUEUES);
q_vector->rxr_count = 0;
@@ -1562,7 +1786,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
i--;
for (; i >= 0; i--) {
free_irq(adapter->msix_entries[i].vector,
- &(adapter->q_vector[i]));
+ adapter->q_vector[i]);
}
ixgbe_reset_q_vectors(adapter);
@@ -1577,10 +1801,12 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
**/
static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
{
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
+ } else {
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFF0000);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(2), ~0);
}
IXGBE_WRITE_FLUSH(&adapter->hw);
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
@@ -1592,18 +1818,6 @@ static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
}
}
-static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter)
-{
- u32 mask = IXGBE_EIMS_RTX_QUEUE;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask << 16);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(2),
- (mask << 16 | mask));
- }
- /* skip the flush */
-}
-
/**
* ixgbe_configure_msi_and_legacy - Initialize PIN (INTA...) and MSI interrupts
*
@@ -1673,11 +1887,34 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
u32 srrctl;
int queue0 = 0;
unsigned long mask;
+ struct ixgbe_ring_feature *feature = adapter->ring_feature;
if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- queue0 = index;
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ int dcb_i = feature[RING_F_DCB].indices;
+ if (dcb_i == 8)
+ queue0 = index >> 4;
+ else if (dcb_i == 4)
+ queue0 = index >> 5;
+ else
+ dev_err(&adapter->pdev->dev, "Invalid DCB "
+ "configuration\n");
+#ifdef IXGBE_FCOE
+ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
+ struct ixgbe_ring_feature *f;
+
+ rx_ring = &adapter->rx_ring[queue0];
+ f = &adapter->ring_feature[RING_F_FCOE];
+ if ((queue0 == 0) && (index > rx_ring->reg_idx))
+ queue0 = f->mask + index -
+ rx_ring->reg_idx - 1;
+ }
+#endif /* IXGBE_FCOE */
+ } else {
+ queue0 = index;
+ }
} else {
- mask = (unsigned long) adapter->ring_feature[RING_F_RSS].mask;
+ mask = (unsigned long) feature[RING_F_RSS].mask;
queue0 = index & mask;
index = index & mask;
}
@@ -1689,33 +1926,55 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
+ srrctl |= (IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
+ IXGBE_SRRCTL_BSIZEHDR_MASK;
+
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
- u16 bufsz = IXGBE_RXBUFFER_2048;
- /* grow the amount we can receive on large page machines */
- if (bufsz < (PAGE_SIZE / 2))
- bufsz = (PAGE_SIZE / 2);
- /* cap the bufsz at our largest descriptor size */
- bufsz = min((u16)IXGBE_MAX_RXBUFFER, bufsz);
-
- srrctl |= bufsz >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+#if (PAGE_SIZE / 2) > IXGBE_MAX_RXBUFFER
+ srrctl |= IXGBE_MAX_RXBUFFER >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+#else
+ srrctl |= (PAGE_SIZE / 2) >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+#endif
srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
- srrctl |= ((IXGBE_RX_HDR_SIZE <<
- IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
- IXGBE_SRRCTL_BSIZEHDR_MASK);
} else {
+ srrctl |= ALIGN(rx_ring->rx_buf_len, 1024) >>
+ IXGBE_SRRCTL_BSIZEPKT_SHIFT;
srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
-
- if (rx_ring->rx_buf_len == MAXIMUM_ETHERNET_VLAN_SIZE)
- srrctl |= IXGBE_RXBUFFER_2048 >>
- IXGBE_SRRCTL_BSIZEPKT_SHIFT;
- else
- srrctl |= rx_ring->rx_buf_len >>
- IXGBE_SRRCTL_BSIZEPKT_SHIFT;
}
IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
}
+static u32 ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
+{
+ u32 mrqc = 0;
+ int mask;
+
+ if (!(adapter->hw.mac.type == ixgbe_mac_82599EB))
+ return mrqc;
+
+ mask = adapter->flags & (IXGBE_FLAG_RSS_ENABLED
+#ifdef CONFIG_IXGBE_DCB
+ | IXGBE_FLAG_DCB_ENABLED
+#endif
+ );
+
+ switch (mask) {
+ case (IXGBE_FLAG_RSS_ENABLED):
+ mrqc = IXGBE_MRQC_RSSEN;
+ break;
+#ifdef CONFIG_IXGBE_DCB
+ case (IXGBE_FLAG_DCB_ENABLED):
+ mrqc = IXGBE_MRQC_RT8TCEN;
+ break;
+#endif /* CONFIG_IXGBE_DCB */
+ default:
+ break;
+ }
+
+ return mrqc;
+}
+
/**
* ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
* @adapter: board private structure
@@ -1736,11 +1995,17 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
u32 fctrl, hlreg0;
u32 reta = 0, mrqc = 0;
u32 rdrxctl;
+ u32 rscctrl;
int rx_buf_len;
/* Decide whether to use packet split mode or not */
adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
+#ifdef IXGBE_FCOE
+ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
+ adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
+#endif /* IXGBE_FCOE */
+
/* Set the RX buffer length according to the mode */
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
rx_buf_len = IXGBE_RX_HDR_SIZE;
@@ -1749,11 +2014,13 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
IXGBE_PSRTYPE_UDPHDR |
IXGBE_PSRTYPE_IPV4HDR |
- IXGBE_PSRTYPE_IPV6HDR;
+ IXGBE_PSRTYPE_IPV6HDR |
+ IXGBE_PSRTYPE_L2HDR;
IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype);
}
} else {
- if (netdev->mtu <= ETH_DATA_LEN)
+ if (!(adapter->flags & IXGBE_FLAG2_RSC_ENABLED) &&
+ (netdev->mtu <= ETH_DATA_LEN))
rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
else
rx_buf_len = ALIGN(max_frame, 1024);
@@ -1770,6 +2037,10 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
hlreg0 &= ~IXGBE_HLREG0_JUMBOEN;
else
hlreg0 |= IXGBE_HLREG0_JUMBOEN;
+#ifdef IXGBE_FCOE
+ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
+ hlreg0 |= IXGBE_HLREG0_JUMBOEN;
+#endif
IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
rdlen = adapter->rx_ring[0].count * sizeof(union ixgbe_adv_rx_desc);
@@ -1777,8 +2048,10 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
- /* Setup the HW Rx Head and Tail Descriptor Pointers and
- * the Base and Length of the Rx Descriptor Ring */
+ /*
+ * Setup the HW Rx Head and Tail Descriptor Pointers and
+ * the Base and Length of the Rx Descriptor Ring
+ */
for (i = 0; i < adapter->num_rx_queues; i++) {
rdba = adapter->rx_ring[i].dma;
j = adapter->rx_ring[i].reg_idx;
@@ -1791,6 +2064,17 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
adapter->rx_ring[i].tail = IXGBE_RDT(j);
adapter->rx_ring[i].rx_buf_len = rx_buf_len;
+#ifdef IXGBE_FCOE
+ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
+ struct ixgbe_ring_feature *f;
+ f = &adapter->ring_feature[RING_F_FCOE];
+ if ((rx_buf_len < IXGBE_FCOE_JUMBO_FRAME_SIZE) &&
+ (i >= f->mask) && (i < f->mask + f->indices))
+ adapter->rx_ring[i].rx_buf_len =
+ IXGBE_FCOE_JUMBO_FRAME_SIZE;
+ }
+
+#endif /* IXGBE_FCOE */
ixgbe_configure_srrctl(adapter, j);
}
@@ -1811,23 +2095,8 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
}
/* Program MRQC for the distribution of queues */
- if (hw->mac.type == ixgbe_mac_82599EB) {
- int mask = adapter->flags & (
- IXGBE_FLAG_RSS_ENABLED
- | IXGBE_FLAG_DCB_ENABLED
- );
+ mrqc = ixgbe_setup_mrqc(adapter);
- switch (mask) {
- case (IXGBE_FLAG_RSS_ENABLED):
- mrqc = IXGBE_MRQC_RSSEN;
- break;
- case (IXGBE_FLAG_DCB_ENABLED):
- mrqc = IXGBE_MRQC_RT8TCEN;
- break;
- default:
- break;
- }
- }
if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
/* Fill out redirection table */
for (i = 0, j = 0; i < 128; i++, j++) {
@@ -1875,8 +2144,45 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
if (hw->mac.type == ixgbe_mac_82599EB) {
rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP;
+ rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE;
IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
}
+
+ if (adapter->flags & IXGBE_FLAG2_RSC_ENABLED) {
+ /* Enable 82599 HW-RSC */
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ j = adapter->rx_ring[i].reg_idx;
+ rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(j));
+ rscctrl |= IXGBE_RSCCTL_RSCEN;
+ /*
+ * we must limit the number of descriptors so that the
+ * total size of max desc * buf_len is not greater
+ * than 65535
+ */
+ if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+#if (MAX_SKB_FRAGS > 16)
+ rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
+#elif (MAX_SKB_FRAGS > 8)
+ rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
+#elif (MAX_SKB_FRAGS > 4)
+ rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
+#else
+ rscctrl |= IXGBE_RSCCTL_MAXDESC_1;
+#endif
+ } else {
+ if (rx_buf_len < IXGBE_RXBUFFER_4096)
+ rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
+ else if (rx_buf_len < IXGBE_RXBUFFER_8192)
+ rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
+ else
+ rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(j), rscctrl);
+ }
+ /* Disable RSC for ACK packets */
+ IXGBE_WRITE_REG(hw, IXGBE_RSCDBU,
+ (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU)));
+ }
}
static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
@@ -2015,11 +2321,7 @@ static void ixgbe_set_rx_mode(struct net_device *netdev)
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
/* reprogram secondary unicast list */
- addr_count = netdev->uc_count;
- if (addr_count)
- addr_list = netdev->uc_list->dmi_addr;
- hw->mac.ops.update_uc_addr_list(hw, addr_list, addr_count,
- ixgbe_addr_list_itr);
+ hw->mac.ops.update_uc_addr_list(hw, &netdev->uc_list);
/* reprogram multicast list */
addr_count = netdev->mc_count;
@@ -2041,13 +2343,16 @@ static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
for (q_idx = 0; q_idx < q_vectors; q_idx++) {
struct napi_struct *napi;
- q_vector = &adapter->q_vector[q_idx];
- if (!q_vector->rxr_count)
- continue;
+ q_vector = adapter->q_vector[q_idx];
napi = &q_vector->napi;
- if ((adapter->flags & IXGBE_FLAG_MSIX_ENABLED) &&
- (q_vector->rxr_count > 1))
- napi->poll = &ixgbe_clean_rxonly_many;
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ if (!q_vector->rxr_count || !q_vector->txr_count) {
+ if (q_vector->txr_count == 1)
+ napi->poll = &ixgbe_clean_txonly;
+ else if (q_vector->rxr_count == 1)
+ napi->poll = &ixgbe_clean_rxonly;
+ }
+ }
napi_enable(napi);
}
@@ -2064,9 +2369,7 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
q_vectors = 1;
for (q_idx = 0; q_idx < q_vectors; q_idx++) {
- q_vector = &adapter->q_vector[q_idx];
- if (!q_vector->rxr_count)
- continue;
+ q_vector = adapter->q_vector[q_idx];
napi_disable(&q_vector->napi);
}
}
@@ -2124,6 +2427,7 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
static void ixgbe_configure(struct ixgbe_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
+ struct ixgbe_hw *hw = &adapter->hw;
int i;
ixgbe_set_rx_mode(netdev);
@@ -2140,6 +2444,20 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
netif_set_gso_max_size(netdev, 65536);
#endif
+#ifdef IXGBE_FCOE
+ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
+ ixgbe_configure_fcoe(adapter);
+
+#endif /* IXGBE_FCOE */
+ if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) {
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ adapter->tx_ring[i].atr_sample_rate =
+ adapter->atr_sample_rate;
+ ixgbe_init_fdir_signature_82599(hw, adapter->fdir_pballoc);
+ } else if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) {
+ ixgbe_init_fdir_perfect_82599(hw, adapter->fdir_pballoc);
+ }
+
ixgbe_configure_tx(adapter);
ixgbe_configure_rx(adapter);
for (i = 0; i < adapter->num_rx_queues; i++)
@@ -2294,6 +2612,13 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
}
+#ifdef IXGBE_FCOE
+ /* adjust max frame to be able to do baby jumbo for FCoE */
+ if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
+ (max_frame < IXGBE_FCOE_JUMBO_FRAME_SIZE))
+ max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE;
+
+#endif /* IXGBE_FCOE */
mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) {
mhadd &= ~IXGBE_MHADD_MFS_MASK;
@@ -2357,6 +2682,17 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
ixgbe_irq_enable(adapter);
/*
+ * If this adapter has a fan, check to see if we had a failure
+ * before we enabled the interrupt.
+ */
+ if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) {
+ u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+ if (esdp & IXGBE_ESDP_SDP1)
+ DPRINTK(DRV, CRIT,
+ "Fan has stopped, replace the adapter\n");
+ }
+
+ /*
* For hot-pluggable SFP+ devices, a new SFP+ module may have
* arrived before interrupts were enabled. We need to kick off
* the SFP+ module setup first, then try to bring up link.
@@ -2378,6 +2714,10 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
DPRINTK(PROBE, ERR, "link_config FAILED %d\n", err);
}
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ set_bit(__IXGBE_FDIR_INIT_DONE,
+ &(adapter->tx_ring[i].reinit_state));
+
/* enable transmits */
netif_tx_start_all_queues(netdev);
@@ -2404,20 +2744,37 @@ int ixgbe_up(struct ixgbe_adapter *adapter)
/* hardware has been reset, we need to reload some things */
ixgbe_configure(adapter);
- ixgbe_napi_add_all(adapter);
-
return ixgbe_up_complete(adapter);
}
void ixgbe_reset(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
- if (hw->mac.ops.init_hw(hw))
- dev_err(&adapter->pdev->dev, "Hardware Error\n");
+ int err;
+
+ err = hw->mac.ops.init_hw(hw);
+ switch (err) {
+ case 0:
+ case IXGBE_ERR_SFP_NOT_PRESENT:
+ break;
+ case IXGBE_ERR_MASTER_REQUESTS_PENDING:
+ dev_err(&adapter->pdev->dev, "master disable timed out\n");
+ break;
+ case IXGBE_ERR_EEPROM_VERSION:
+ /* We are running on a pre-production device, log a warning */
+ dev_warn(&adapter->pdev->dev, "This device is a pre-production "
+ "adapter/LOM. Please be aware there may be issues "
+ "associated with your hardware. If you are "
+ "experiencing problems please contact your Intel or "
+ "hardware representative who provided you with this "
+ "hardware.\n");
+ break;
+ default:
+ dev_err(&adapter->pdev->dev, "Hardware Error: %d\n", err);
+ }
/* reprogram the RAR[0] in case user changed it. */
hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
-
}
/**
@@ -2445,8 +2802,13 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
rx_buffer_info->dma = 0;
}
if (rx_buffer_info->skb) {
- dev_kfree_skb(rx_buffer_info->skb);
+ struct sk_buff *skb = rx_buffer_info->skb;
rx_buffer_info->skb = NULL;
+ do {
+ struct sk_buff *this = skb;
+ skb = skb->prev;
+ dev_kfree_skb(this);
+ } while (skb);
}
if (!rx_buffer_info->page)
continue;
@@ -2560,6 +2922,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
del_timer_sync(&adapter->watchdog_timer);
cancel_work_sync(&adapter->watchdog_task);
+ if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
+ adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
+ cancel_work_sync(&adapter->fdir_reinit_task);
+
/* disable transmits in the hardware now that interrupts are off */
for (i = 0; i < adapter->num_tx_queues; i++) {
j = adapter->tx_ring[i].reg_idx;
@@ -2575,13 +2941,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
netif_carrier_off(netdev);
-#ifdef CONFIG_IXGBE_DCA
- if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
- adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
- dca_remove_requester(&adapter->pdev->dev);
- }
-
-#endif
if (!pci_channel_offline(adapter->pdev))
ixgbe_reset(adapter);
ixgbe_clean_all_tx_rings(adapter);
@@ -2589,13 +2948,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
#ifdef CONFIG_IXGBE_DCA
/* since we reset the hardware DCA settings were cleared */
- if (dca_add_requester(&adapter->pdev->dev) == 0) {
- adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
- /* always use CB2 mode, difference is masked
- * in the CB driver */
- IXGBE_WRITE_REG(hw, IXGBE_DCA_CTRL, 2);
- ixgbe_setup_dca(adapter);
- }
+ ixgbe_setup_dca(adapter);
#endif
}
@@ -2620,7 +2973,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
}
#endif
- tx_clean_complete = ixgbe_clean_tx_irq(adapter, adapter->tx_ring);
+ tx_clean_complete = ixgbe_clean_tx_irq(q_vector, adapter->tx_ring);
ixgbe_clean_rx_irq(q_vector, adapter->rx_ring, &work_done, budget);
if (!tx_clean_complete)
@@ -2632,7 +2985,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
if (adapter->itr_setting & 1)
ixgbe_set_itr(adapter);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_enable_queues(adapter);
+ ixgbe_irq_enable_queues(adapter, IXGBE_EIMS_RTX_QUEUE);
}
return work_done;
}
@@ -2668,17 +3021,15 @@ static void ixgbe_reset_task(struct work_struct *work)
static inline bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter)
{
bool ret = false;
+ struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_DCB];
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- adapter->ring_feature[RING_F_DCB].mask = 0x7 << 3;
- adapter->num_rx_queues =
- adapter->ring_feature[RING_F_DCB].indices;
- adapter->num_tx_queues =
- adapter->ring_feature[RING_F_DCB].indices;
- ret = true;
- } else {
- ret = false;
- }
+ if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
+ return ret;
+
+ f->mask = 0x7 << 3;
+ adapter->num_rx_queues = f->indices;
+ adapter->num_tx_queues = f->indices;
+ ret = true;
return ret;
}
@@ -2695,13 +3046,12 @@ static inline bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter)
static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
{
bool ret = false;
+ struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_RSS];
if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
- adapter->ring_feature[RING_F_RSS].mask = 0xF;
- adapter->num_rx_queues =
- adapter->ring_feature[RING_F_RSS].indices;
- adapter->num_tx_queues =
- adapter->ring_feature[RING_F_RSS].indices;
+ f->mask = 0xF;
+ adapter->num_rx_queues = f->indices;
+ adapter->num_tx_queues = f->indices;
ret = true;
} else {
ret = false;
@@ -2710,6 +3060,79 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
return ret;
}
+/**
+ * ixgbe_set_fdir_queues: Allocate queues for Flow Director
+ * @adapter: board private structure to initialize
+ *
+ * Flow Director is an advanced Rx filter, attempting to get Rx flows back
+ * to the original CPU that initiated the Tx session. This runs in addition
+ * to RSS, so if a packet doesn't match an FDIR filter, we can still spread the
+ * Rx load across CPUs using RSS.
+ *
+ **/
+static bool inline ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter)
+{
+ bool ret = false;
+ struct ixgbe_ring_feature *f_fdir = &adapter->ring_feature[RING_F_FDIR];
+
+ f_fdir->indices = min((int)num_online_cpus(), f_fdir->indices);
+ f_fdir->mask = 0;
+
+ /* Flow Director must have RSS enabled */
+ if (adapter->flags & IXGBE_FLAG_RSS_ENABLED &&
+ ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
+ (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)))) {
+ adapter->num_tx_queues = f_fdir->indices;
+ adapter->num_rx_queues = f_fdir->indices;
+ ret = true;
+ } else {
+ adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
+ adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
+ }
+ return ret;
+}
+
+#ifdef IXGBE_FCOE
+/**
+ * ixgbe_set_fcoe_queues: Allocate queues for Fiber Channel over Ethernet (FCoE)
+ * @adapter: board private structure to initialize
+ *
+ * FCoE RX FCRETA can use up to 8 rx queues for up to 8 different exchanges.
+ * The ring feature mask is not used as a mask for FCoE, as it can take any 8
+ * rx queues out of the max number of rx queues, instead, it is used as the
+ * index of the first rx queue used by FCoE.
+ *
+ **/
+static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter)
+{
+ bool ret = false;
+ struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE];
+
+ f->indices = min((int)num_online_cpus(), f->indices);
+ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
+#ifdef CONFIG_IXGBE_DCB
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ DPRINTK(PROBE, INFO, "FCOE enabled with DCB \n");
+ ixgbe_set_dcb_queues(adapter);
+ }
+#endif
+ if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
+ DPRINTK(PROBE, INFO, "FCOE enabled with RSS \n");
+ ixgbe_set_rss_queues(adapter);
+ }
+ /* adding FCoE rx rings to the end */
+ f->mask = adapter->num_rx_queues;
+ adapter->num_rx_queues += f->indices;
+ if (adapter->num_tx_queues == 0)
+ adapter->num_tx_queues = f->indices;
+
+ ret = true;
+ }
+
+ return ret;
+}
+
+#endif /* IXGBE_FCOE */
/*
* ixgbe_set_num_queues: Allocate queues for device, feature dependant
* @adapter: board private structure to initialize
@@ -2723,11 +3146,19 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
**/
static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
{
+#ifdef IXGBE_FCOE
+ if (ixgbe_set_fcoe_queues(adapter))
+ goto done;
+
+#endif /* IXGBE_FCOE */
#ifdef CONFIG_IXGBE_DCB
if (ixgbe_set_dcb_queues(adapter))
goto done;
#endif
+ if (ixgbe_set_fdir_queues(adapter))
+ goto done;
+
if (ixgbe_set_rss_queues(adapter))
goto done;
@@ -2778,9 +3209,6 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
kfree(adapter->msix_entries);
adapter->msix_entries = NULL;
- adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
- adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
- ixgbe_set_num_queues(adapter);
} else {
adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */
/*
@@ -2902,6 +3330,64 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter)
#endif
/**
+ * ixgbe_cache_ring_fdir - Descriptor ring to register mapping for Flow Director
+ * @adapter: board private structure to initialize
+ *
+ * Cache the descriptor ring offsets for Flow Director to the assigned rings.
+ *
+ **/
+static bool inline ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter)
+{
+ int i;
+ bool ret = false;
+
+ if (adapter->flags & IXGBE_FLAG_RSS_ENABLED &&
+ ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) ||
+ (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))) {
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ adapter->rx_ring[i].reg_idx = i;
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ adapter->tx_ring[i].reg_idx = i;
+ ret = true;
+ }
+
+ return ret;
+}
+
+#ifdef IXGBE_FCOE
+/**
+ * ixgbe_cache_ring_fcoe - Descriptor ring to register mapping for the FCoE
+ * @adapter: board private structure to initialize
+ *
+ * Cache the descriptor ring offsets for FCoE mode to the assigned rings.
+ *
+ */
+static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter)
+{
+ int i, fcoe_i = 0;
+ bool ret = false;
+ struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE];
+
+ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
+#ifdef CONFIG_IXGBE_DCB
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ ixgbe_cache_ring_dcb(adapter);
+ fcoe_i = adapter->rx_ring[0].reg_idx + 1;
+ }
+#endif /* CONFIG_IXGBE_DCB */
+ if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
+ ixgbe_cache_ring_rss(adapter);
+ fcoe_i = f->mask;
+ }
+ for (i = 0; i < f->indices; i++, fcoe_i++)
+ adapter->rx_ring[f->mask + i].reg_idx = fcoe_i;
+ ret = true;
+ }
+ return ret;
+}
+
+#endif /* IXGBE_FCOE */
+/**
* ixgbe_cache_ring_register - Descriptor ring to register mapping
* @adapter: board private structure to initialize
*
@@ -2918,11 +3404,19 @@ static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
adapter->rx_ring[0].reg_idx = 0;
adapter->tx_ring[0].reg_idx = 0;
+#ifdef IXGBE_FCOE
+ if (ixgbe_cache_ring_fcoe(adapter))
+ return;
+
+#endif /* IXGBE_FCOE */
#ifdef CONFIG_IXGBE_DCB
if (ixgbe_cache_ring_dcb(adapter))
return;
#endif
+ if (ixgbe_cache_ring_fdir(adapter))
+ return;
+
if (ixgbe_cache_ring_rss(adapter))
return;
}
@@ -3004,31 +3498,23 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
* mean we disable MSI-X capabilities of the adapter. */
adapter->msix_entries = kcalloc(v_budget,
sizeof(struct msix_entry), GFP_KERNEL);
- if (!adapter->msix_entries) {
- adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
- adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
- ixgbe_set_num_queues(adapter);
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
- err = ixgbe_alloc_queues(adapter);
- if (err) {
- DPRINTK(PROBE, ERR, "Unable to allocate memory "
- "for queues\n");
- goto out;
- }
+ if (adapter->msix_entries) {
+ for (vector = 0; vector < v_budget; vector++)
+ adapter->msix_entries[vector].entry = vector;
- goto try_msi;
- }
+ ixgbe_acquire_msix_vectors(adapter, v_budget);
- for (vector = 0; vector < v_budget; vector++)
- adapter->msix_entries[vector].entry = vector;
-
- ixgbe_acquire_msix_vectors(adapter, v_budget);
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
+ goto out;
+ }
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
- goto out;
+ adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
+ adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
+ adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
+ adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
+ adapter->atr_sample_rate = 0;
+ ixgbe_set_num_queues(adapter);
-try_msi:
err = pci_enable_msi(adapter->pdev);
if (!err) {
adapter->flags |= IXGBE_FLAG_MSI_ENABLED;
@@ -3043,6 +3529,79 @@ out:
return err;
}
+/**
+ * ixgbe_alloc_q_vectors - Allocate memory for interrupt vectors
+ * @adapter: board private structure to initialize
+ *
+ * We allocate one q_vector per queue interrupt. If allocation fails we
+ * return -ENOMEM.
+ **/
+static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter)
+{
+ int q_idx, num_q_vectors;
+ struct ixgbe_q_vector *q_vector;
+ int napi_vectors;
+ int (*poll)(struct napi_struct *, int);
+
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+ napi_vectors = adapter->num_rx_queues;
+ poll = &ixgbe_clean_rxtx_many;
+ } else {
+ num_q_vectors = 1;
+ napi_vectors = 1;
+ poll = &ixgbe_poll;
+ }
+
+ for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
+ q_vector = kzalloc(sizeof(struct ixgbe_q_vector), GFP_KERNEL);
+ if (!q_vector)
+ goto err_out;
+ q_vector->adapter = adapter;
+ q_vector->eitr = adapter->eitr_param;
+ q_vector->v_idx = q_idx;
+ netif_napi_add(adapter->netdev, &q_vector->napi, (*poll), 64);
+ adapter->q_vector[q_idx] = q_vector;
+ }
+
+ return 0;
+
+err_out:
+ while (q_idx) {
+ q_idx--;
+ q_vector = adapter->q_vector[q_idx];
+ netif_napi_del(&q_vector->napi);
+ kfree(q_vector);
+ adapter->q_vector[q_idx] = NULL;
+ }
+ return -ENOMEM;
+}
+
+/**
+ * ixgbe_free_q_vectors - Free memory allocated for interrupt vectors
+ * @adapter: board private structure to initialize
+ *
+ * This function frees the memory allocated to the q_vectors. In addition if
+ * NAPI is enabled it will delete any references to the NAPI struct prior
+ * to freeing the q_vector.
+ **/
+static void ixgbe_free_q_vectors(struct ixgbe_adapter *adapter)
+{
+ int q_idx, num_q_vectors;
+
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
+ num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+ else
+ num_q_vectors = 1;
+
+ for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
+ struct ixgbe_q_vector *q_vector = adapter->q_vector[q_idx];
+ adapter->q_vector[q_idx] = NULL;
+ netif_napi_del(&q_vector->napi);
+ kfree(q_vector);
+ }
+}
+
void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter)
{
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
@@ -3074,18 +3633,25 @@ int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
/* Number of supported queues */
ixgbe_set_num_queues(adapter);
- err = ixgbe_alloc_queues(adapter);
- if (err) {
- DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
- goto err_alloc_queues;
- }
-
err = ixgbe_set_interrupt_capability(adapter);
if (err) {
DPRINTK(PROBE, ERR, "Unable to setup interrupt capabilities\n");
goto err_set_interrupt;
}
+ err = ixgbe_alloc_q_vectors(adapter);
+ if (err) {
+ DPRINTK(PROBE, ERR, "Unable to allocate memory for queue "
+ "vectors\n");
+ goto err_alloc_q_vectors;
+ }
+
+ err = ixgbe_alloc_queues(adapter);
+ if (err) {
+ DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
+ goto err_alloc_queues;
+ }
+
DPRINTK(DRV, INFO, "Multiqueue %s: Rx Queue count = %u, "
"Tx Queue count = %u\n",
(adapter->num_rx_queues > 1) ? "Enabled" :
@@ -3095,11 +3661,30 @@ int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
return 0;
+err_alloc_queues:
+ ixgbe_free_q_vectors(adapter);
+err_alloc_q_vectors:
+ ixgbe_reset_interrupt_capability(adapter);
err_set_interrupt:
+ return err;
+}
+
+/**
+ * ixgbe_clear_interrupt_scheme - Clear the current interrupt scheme settings
+ * @adapter: board private structure to clear interrupt scheme on
+ *
+ * We go through and clear interrupt specific resources and reset the structure
+ * to pre-load conditions
+ **/
+void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
+{
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
-err_alloc_queues:
- return err;
+ adapter->tx_ring = NULL;
+ adapter->rx_ring = NULL;
+
+ ixgbe_free_q_vectors(adapter);
+ ixgbe_reset_interrupt_capability(adapter);
}
/**
@@ -3185,10 +3770,24 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->ring_feature[RING_F_RSS].indices = rss;
adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
adapter->ring_feature[RING_F_DCB].indices = IXGBE_MAX_DCB_INDICES;
- if (hw->mac.type == ixgbe_mac_82598EB)
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ if (hw->device_id == IXGBE_DEV_ID_82598AT)
+ adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE;
adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598;
- else if (hw->mac.type == ixgbe_mac_82599EB)
+ } else if (hw->mac.type == ixgbe_mac_82599EB) {
adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599;
+ adapter->flags |= IXGBE_FLAG2_RSC_CAPABLE;
+ adapter->flags |= IXGBE_FLAG2_RSC_ENABLED;
+ adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
+ adapter->ring_feature[RING_F_FDIR].indices =
+ IXGBE_MAX_FDIR_INDICES;
+ adapter->atr_sample_rate = 20;
+ adapter->fdir_pballoc = 0;
+#ifdef IXGBE_FCOE
+ adapter->flags |= IXGBE_FLAG_FCOE_ENABLED;
+ adapter->ring_feature[RING_F_FCOE].indices = IXGBE_FCRETA_SIZE;
+#endif /* IXGBE_FCOE */
+ }
#ifdef CONFIG_IXGBE_DCB
/* Configure DCB traffic classes */
@@ -3203,6 +3802,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->dcb_cfg.bw_percentage[DCB_TX_CONFIG][0] = 100;
adapter->dcb_cfg.bw_percentage[DCB_RX_CONFIG][0] = 100;
adapter->dcb_cfg.rx_pba_cfg = pba_equal;
+ adapter->dcb_cfg.pfc_mode_enable = false;
adapter->dcb_cfg.round_robin_enable = false;
adapter->dcb_set_bitmap = 0x00;
ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg,
@@ -3213,6 +3813,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
/* default flow control settings */
hw->fc.requested_mode = ixgbe_fc_full;
hw->fc.current_mode = ixgbe_fc_full; /* init for ethtool output */
+#ifdef CONFIG_DCB
+ adapter->last_lfc_mode = hw->fc.current_mode;
+#endif
hw->fc.high_water = IXGBE_DEFAULT_FCRTH;
hw->fc.low_water = IXGBE_DEFAULT_FCRTL;
hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
@@ -3503,6 +4106,8 @@ static int ixgbe_open(struct net_device *netdev)
if (test_bit(__IXGBE_TESTING, &adapter->state))
return -EBUSY;
+ netif_carrier_off(netdev);
+
/* allocate transmit descriptors */
err = ixgbe_setup_all_tx_resources(adapter);
if (err)
@@ -3515,8 +4120,6 @@ static int ixgbe_open(struct net_device *netdev)
ixgbe_configure(adapter);
- ixgbe_napi_add_all(adapter);
-
err = ixgbe_request_irq(adapter);
if (err)
goto err_req_irq;
@@ -3568,55 +4171,6 @@ static int ixgbe_close(struct net_device *netdev)
return 0;
}
-/**
- * ixgbe_napi_add_all - prep napi structs for use
- * @adapter: private struct
- *
- * helper function to napi_add each possible q_vector->napi
- */
-void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
-{
- int q_idx, q_vectors;
- struct net_device *netdev = adapter->netdev;
- int (*poll)(struct napi_struct *, int);
-
- /* check if we already have our netdev->napi_list populated */
- if (&netdev->napi_list != netdev->napi_list.next)
- return;
-
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- poll = &ixgbe_clean_rxonly;
- /* Only enable as many vectors as we have rx queues. */
- q_vectors = adapter->num_rx_queues;
- } else {
- poll = &ixgbe_poll;
- /* only one q_vector for legacy modes */
- q_vectors = 1;
- }
-
- for (q_idx = 0; q_idx < q_vectors; q_idx++) {
- struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
- netif_napi_add(adapter->netdev, &q_vector->napi, (*poll), 64);
- }
-}
-
-void ixgbe_napi_del_all(struct ixgbe_adapter *adapter)
-{
- int q_idx;
- int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
-
- /* legacy and MSI only use one vector */
- if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED))
- q_vectors = 1;
-
- for (q_idx = 0; q_idx < q_vectors; q_idx++) {
- struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
- if (!q_vector->rxr_count)
- continue;
- netif_napi_del(&q_vector->napi);
- }
-}
-
#ifdef CONFIG_PM
static int ixgbe_resume(struct pci_dev *pdev)
{
@@ -3626,7 +4180,8 @@ static int ixgbe_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
- err = pci_enable_device(pdev);
+
+ err = pci_enable_device_mem(pdev);
if (err) {
printk(KERN_ERR "ixgbe: Cannot enable PCI device from "
"suspend\n");
@@ -3634,8 +4189,7 @@ static int ixgbe_resume(struct pci_dev *pdev)
}
pci_set_master(pdev);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
+ pci_wake_from_d3(pdev, false);
err = ixgbe_init_interrupt_scheme(adapter);
if (err) {
@@ -3679,11 +4233,7 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
ixgbe_free_all_tx_resources(adapter);
ixgbe_free_all_rx_resources(adapter);
}
- ixgbe_reset_interrupt_capability(adapter);
- ixgbe_napi_del_all(adapter);
- INIT_LIST_HEAD(&netdev->napi_list);
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
+ ixgbe_clear_interrupt_scheme(adapter);
#ifdef CONFIG_PM
retval = pci_save_state(pdev);
@@ -3711,13 +4261,10 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0);
}
- if (wufc && hw->mac.type == ixgbe_mac_82599EB) {
- pci_enable_wake(pdev, PCI_D3hot, 1);
- pci_enable_wake(pdev, PCI_D3cold, 1);
- } else {
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
- }
+ if (wufc && hw->mac.type == ixgbe_mac_82599EB)
+ pci_wake_from_d3(pdev, true);
+ else
+ pci_wake_from_d3(pdev, false);
*enable_wake = !!wufc;
@@ -3772,9 +4319,13 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
if (hw->mac.type == ixgbe_mac_82599EB) {
+ u64 rsc_count = 0;
for (i = 0; i < 16; i++)
adapter->hw_rx_no_dma_resources +=
IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ rsc_count += adapter->rx_ring[i].rsc_count;
+ adapter->rsc_count = rsc_count;
}
adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
@@ -3821,6 +4372,16 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
+ adapter->stats.fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
+ adapter->stats.fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
+#ifdef IXGBE_FCOE
+ adapter->stats.fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC);
+ adapter->stats.fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC);
+ adapter->stats.fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC);
+ adapter->stats.fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC);
+ adapter->stats.fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC);
+ adapter->stats.fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC);
+#endif /* IXGBE_FCOE */
} else {
adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
@@ -3888,64 +4449,43 @@ static void ixgbe_watchdog(unsigned long data)
{
struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
struct ixgbe_hw *hw = &adapter->hw;
+ u64 eics = 0;
+ int i;
- /* Do the watchdog outside of interrupt context due to the lovely
- * delays that some of the newer hardware requires */
- if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
- u64 eics = 0;
- int i;
+ /*
+ * Do the watchdog outside of interrupt context due to the lovely
+ * delays that some of the newer hardware requires
+ */
- for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++)
- eics |= (1 << i);
+ if (test_bit(__IXGBE_DOWN, &adapter->state))
+ goto watchdog_short_circuit;
- /* Cause software interrupt to ensure rx rings are cleaned */
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- IXGBE_WRITE_REG(hw, IXGBE_EICS, (u32)eics);
- } else {
- /*
- * for legacy and MSI interrupts don't set any
- * bits that are enabled for EIAM, because this
- * operation would set *both* EIMS and EICS for
- * any bit in EIAM
- */
- IXGBE_WRITE_REG(hw, IXGBE_EICS,
- (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
- }
- break;
- case ixgbe_mac_82599EB:
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- /*
- * EICS(0..15) first 0-15 q vectors
- * EICS[1] (16..31) q vectors 16-31
- * EICS[2] (0..31) q vectors 32-63
- */
- IXGBE_WRITE_REG(hw, IXGBE_EICS,
- (u32)(eics & 0xFFFF));
- IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(1),
- (u32)(eics & 0xFFFF0000));
- IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(2),
- (u32)(eics >> 32));
- } else {
- /*
- * for legacy and MSI interrupts don't set any
- * bits that are enabled for EIAM, because this
- * operation would set *both* EIMS and EICS for
- * any bit in EIAM
- */
- IXGBE_WRITE_REG(hw, IXGBE_EICS,
- (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
- }
- break;
- default:
- break;
- }
- /* Reset the timer */
- mod_timer(&adapter->watchdog_timer,
- round_jiffies(jiffies + 2 * HZ));
+ if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) {
+ /*
+ * for legacy and MSI interrupts don't set any bits
+ * that are enabled for EIAM, because this operation
+ * would set *both* EIMS and EICS for any bit in EIAM
+ */
+ IXGBE_WRITE_REG(hw, IXGBE_EICS,
+ (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
+ goto watchdog_reschedule;
}
+ /* get one bit for every active tx/rx interrupt vector */
+ for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
+ struct ixgbe_q_vector *qv = adapter->q_vector[i];
+ if (qv->rxr_count || qv->txr_count)
+ eics |= ((u64)1 << i);
+ }
+
+ /* Cause software interrupt to ensure rx rings are cleaned */
+ ixgbe_irq_rearm_queues(adapter, eics);
+
+watchdog_reschedule:
+ /* Reset the timer */
+ mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
+
+watchdog_short_circuit:
schedule_work(&adapter->watchdog_task);
}
@@ -3999,6 +4539,30 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work)
}
/**
+ * ixgbe_fdir_reinit_task - worker thread to reinit FDIR filter table
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_fdir_reinit_task(struct work_struct *work)
+{
+ struct ixgbe_adapter *adapter = container_of(work,
+ struct ixgbe_adapter,
+ fdir_reinit_task);
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i;
+
+ if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ set_bit(__IXGBE_FDIR_INIT_DONE,
+ &(adapter->tx_ring[i].reinit_state));
+ } else {
+ DPRINTK(PROBE, ERR, "failed to finish FDIR re-initialization, "
+ "ignored adding FDIR ATR filters \n");
+ }
+ /* Done FDIR Re-initialization, enable transmits */
+ netif_tx_start_all_queues(adapter->netdev);
+}
+
+/**
* ixgbe_watchdog_task - worker thread to bring link up
* @work: pointer to work_struct containing our data
**/
@@ -4011,16 +4575,32 @@ static void ixgbe_watchdog_task(struct work_struct *work)
struct ixgbe_hw *hw = &adapter->hw;
u32 link_speed = adapter->link_speed;
bool link_up = adapter->link_up;
+ int i;
+ struct ixgbe_ring *tx_ring;
+ int some_tx_pending = 0;
adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK;
if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) {
hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
+ if (link_up) {
+#ifdef CONFIG_DCB
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+ hw->mac.ops.fc_enable(hw, i);
+ } else {
+ hw->mac.ops.fc_enable(hw, 0);
+ }
+#else
+ hw->mac.ops.fc_enable(hw, 0);
+#endif
+ }
+
if (link_up ||
time_after(jiffies, (adapter->link_check_timeout +
IXGBE_TRY_LINK_TIMEOUT))) {
- IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
+ IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
}
adapter->link_up = link_up;
adapter->link_speed = link_speed;
@@ -4068,6 +4648,25 @@ static void ixgbe_watchdog_task(struct work_struct *work)
}
}
+ if (!netif_carrier_ok(netdev)) {
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ tx_ring = &adapter->tx_ring[i];
+ if (tx_ring->next_to_use != tx_ring->next_to_clean) {
+ some_tx_pending = 1;
+ break;
+ }
+ }
+
+ if (some_tx_pending) {
+ /* We've lost link, so the controller stops DMA,
+ * but we've got queued Tx work that's never going
+ * to get done, so reset controller to flush Tx.
+ * (Do the reset outside of interrupt context).
+ */
+ schedule_work(&adapter->reset_task);
+ }
+ }
+
ixgbe_update_stats(adapter);
adapter->flags &= ~IXGBE_FLAG_IN_WATCHDOG_TASK;
}
@@ -4196,12 +4795,18 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
type_tucmd_mlhl |=
IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ else if (ip_hdr(skb)->protocol == IPPROTO_SCTP)
+ type_tucmd_mlhl |=
+ IXGBE_ADVTXD_TUCMD_L4T_SCTP;
break;
case cpu_to_be16(ETH_P_IPV6):
/* XXX what about other V6 headers?? */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
type_tucmd_mlhl |=
IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ else if (ipv6_hdr(skb)->nexthdr == IPPROTO_SCTP)
+ type_tucmd_mlhl |=
+ IXGBE_ADVTXD_TUCMD_L4T_SCTP;
break;
default:
if (unlikely(net_ratelimit())) {
@@ -4234,10 +4839,12 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
struct ixgbe_ring *tx_ring,
- struct sk_buff *skb, unsigned int first)
+ struct sk_buff *skb, u32 tx_flags,
+ unsigned int first)
{
struct ixgbe_tx_buffer *tx_buffer_info;
- unsigned int len = skb_headlen(skb);
+ unsigned int len;
+ unsigned int total = skb->len;
unsigned int offset = 0, size, count = 0, i;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int f;
@@ -4252,16 +4859,22 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
map = skb_shinfo(skb)->dma_maps;
+ if (tx_flags & IXGBE_TX_FLAGS_FCOE)
+ /* excluding fcoe_crc_eof for FCoE */
+ total -= sizeof(struct fcoe_crc_eof);
+
+ len = min(skb_headlen(skb), total);
while (len) {
tx_buffer_info = &tx_ring->tx_buffer_info[i];
size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
tx_buffer_info->length = size;
- tx_buffer_info->dma = map[0] + offset;
+ tx_buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
tx_buffer_info->time_stamp = jiffies;
tx_buffer_info->next_to_watch = i;
len -= size;
+ total -= size;
offset += size;
count++;
@@ -4276,7 +4889,7 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
struct skb_frag_struct *frag;
frag = &skb_shinfo(skb)->frags[f];
- len = frag->size;
+ len = min((unsigned int)frag->size, total);
offset = 0;
while (len) {
@@ -4288,14 +4901,17 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
tx_buffer_info->length = size;
- tx_buffer_info->dma = map[f + 1] + offset;
+ tx_buffer_info->dma = map[f] + offset;
tx_buffer_info->time_stamp = jiffies;
tx_buffer_info->next_to_watch = i;
len -= size;
+ total -= size;
offset += size;
count++;
}
+ if (total == 0)
+ break;
}
tx_ring->tx_buffer_info[i].skb = skb;
@@ -4337,6 +4953,13 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
IXGBE_ADVTXD_POPTS_SHIFT;
+ if (tx_flags & IXGBE_TX_FLAGS_FCOE) {
+ olinfo_status |= IXGBE_ADVTXD_CC;
+ olinfo_status |= (1 << IXGBE_ADVTXD_IDX_SHIFT);
+ if (tx_flags & IXGBE_TX_FLAGS_FSO)
+ cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
+ }
+
olinfo_status |= ((paylen - hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT);
i = tx_ring->next_to_use;
@@ -4366,6 +4989,58 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
writel(i, adapter->hw.hw_addr + tx_ring->tail);
}
+static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
+ int queue, u32 tx_flags)
+{
+ /* Right now, we support IPv4 only */
+ struct ixgbe_atr_input atr_input;
+ struct tcphdr *th;
+ struct udphdr *uh;
+ struct iphdr *iph = ip_hdr(skb);
+ struct ethhdr *eth = (struct ethhdr *)skb->data;
+ u16 vlan_id, src_port, dst_port, flex_bytes;
+ u32 src_ipv4_addr, dst_ipv4_addr;
+ u8 l4type = 0;
+
+ /* check if we're UDP or TCP */
+ if (iph->protocol == IPPROTO_TCP) {
+ th = tcp_hdr(skb);
+ src_port = th->source;
+ dst_port = th->dest;
+ l4type |= IXGBE_ATR_L4TYPE_TCP;
+ /* l4type IPv4 type is 0, no need to assign */
+ } else if(iph->protocol == IPPROTO_UDP) {
+ uh = udp_hdr(skb);
+ src_port = uh->source;
+ dst_port = uh->dest;
+ l4type |= IXGBE_ATR_L4TYPE_UDP;
+ /* l4type IPv4 type is 0, no need to assign */
+ } else {
+ /* Unsupported L4 header, just bail here */
+ return;
+ }
+
+ memset(&atr_input, 0, sizeof(struct ixgbe_atr_input));
+
+ vlan_id = (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK) >>
+ IXGBE_TX_FLAGS_VLAN_SHIFT;
+ src_ipv4_addr = iph->saddr;
+ dst_ipv4_addr = iph->daddr;
+ flex_bytes = eth->h_proto;
+
+ ixgbe_atr_set_vlan_id_82599(&atr_input, vlan_id);
+ ixgbe_atr_set_src_port_82599(&atr_input, dst_port);
+ ixgbe_atr_set_dst_port_82599(&atr_input, src_port);
+ ixgbe_atr_set_flex_byte_82599(&atr_input, flex_bytes);
+ ixgbe_atr_set_l4type_82599(&atr_input, l4type);
+ /* src and dst are inverted, think how the receiver sees them */
+ ixgbe_atr_set_src_ipv4_82599(&atr_input, dst_ipv4_addr);
+ ixgbe_atr_set_dst_ipv4_82599(&atr_input, src_ipv4_addr);
+
+ /* This assumes the Rx queue and Tx queue are bound to the same CPU */
+ ixgbe_fdir_add_signature_filter_82599(&adapter->hw, &atr_input, queue);
+}
+
static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
struct ixgbe_ring *tx_ring, int size)
{
@@ -4400,6 +5075,9 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
+ if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE)
+ return smp_processor_id();
+
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
return 0; /* All traffic should default to class 0 */
@@ -4433,10 +5111,16 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
tx_flags |= IXGBE_TX_FLAGS_VLAN;
}
- /* three things can cause us to need a context descriptor */
+
+ if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
+ (skb->protocol == htons(ETH_P_FCOE)))
+ tx_flags |= IXGBE_TX_FLAGS_FCOE;
+
+ /* four things can cause us to need a context descriptor */
if (skb_is_gso(skb) ||
(skb->ip_summed == CHECKSUM_PARTIAL) ||
- (tx_flags & IXGBE_TX_FLAGS_VLAN))
+ (tx_flags & IXGBE_TX_FLAGS_VLAN) ||
+ (tx_flags & IXGBE_TX_FLAGS_FCOE))
count++;
count += TXD_USE_COUNT(skb_headlen(skb));
@@ -4448,27 +5132,49 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_BUSY;
}
- if (skb->protocol == htons(ETH_P_IP))
- tx_flags |= IXGBE_TX_FLAGS_IPV4;
first = tx_ring->next_to_use;
- tso = ixgbe_tso(adapter, tx_ring, skb, tx_flags, &hdr_len);
- if (tso < 0) {
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
-
- if (tso)
- tx_flags |= IXGBE_TX_FLAGS_TSO;
- else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags) &&
- (skb->ip_summed == CHECKSUM_PARTIAL))
- tx_flags |= IXGBE_TX_FLAGS_CSUM;
+ if (tx_flags & IXGBE_TX_FLAGS_FCOE) {
+#ifdef IXGBE_FCOE
+ /* setup tx offload for FCoE */
+ tso = ixgbe_fso(adapter, tx_ring, skb, tx_flags, &hdr_len);
+ if (tso < 0) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+ if (tso)
+ tx_flags |= IXGBE_TX_FLAGS_FSO;
+#endif /* IXGBE_FCOE */
+ } else {
+ if (skb->protocol == htons(ETH_P_IP))
+ tx_flags |= IXGBE_TX_FLAGS_IPV4;
+ tso = ixgbe_tso(adapter, tx_ring, skb, tx_flags, &hdr_len);
+ if (tso < 0) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
- count = ixgbe_tx_map(adapter, tx_ring, skb, first);
+ if (tso)
+ tx_flags |= IXGBE_TX_FLAGS_TSO;
+ else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags) &&
+ (skb->ip_summed == CHECKSUM_PARTIAL))
+ tx_flags |= IXGBE_TX_FLAGS_CSUM;
+ }
+ count = ixgbe_tx_map(adapter, tx_ring, skb, tx_flags, first);
if (count) {
+ /* add the ATR filter if ATR is on */
+ if (tx_ring->atr_sample_rate) {
+ ++tx_ring->atr_count;
+ if ((tx_ring->atr_count >= tx_ring->atr_sample_rate) &&
+ test_bit(__IXGBE_FDIR_INIT_DONE,
+ &tx_ring->reinit_state)) {
+ ixgbe_atr(adapter, skb, tx_ring->queue_index,
+ tx_flags);
+ tx_ring->atr_count = 0;
+ }
+ }
ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len,
hdr_len);
- netdev->trans_start = jiffies;
ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
} else {
@@ -4519,6 +5225,82 @@ static int ixgbe_set_mac(struct net_device *netdev, void *p)
return 0;
}
+static int
+ixgbe_mdio_read(struct net_device *netdev, int prtad, int devad, u16 addr)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
+ u16 value;
+ int rc;
+
+ if (prtad != hw->phy.mdio.prtad)
+ return -EINVAL;
+ rc = hw->phy.ops.read_reg(hw, addr, devad, &value);
+ if (!rc)
+ rc = value;
+ return rc;
+}
+
+static int ixgbe_mdio_write(struct net_device *netdev, int prtad, int devad,
+ u16 addr, u16 value)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ if (prtad != hw->phy.mdio.prtad)
+ return -EINVAL;
+ return hw->phy.ops.write_reg(hw, addr, devad, value);
+}
+
+static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd);
+}
+
+/**
+ * ixgbe_add_sanmac_netdev - Add the SAN MAC address to the corresponding
+ * netdev->dev_addr_list
+ * @netdev: network interface device structure
+ *
+ * Returns non-zero on failure
+ **/
+static int ixgbe_add_sanmac_netdev(struct net_device *dev)
+{
+ int err = 0;
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+ struct ixgbe_mac_info *mac = &adapter->hw.mac;
+
+ if (is_valid_ether_addr(mac->san_addr)) {
+ rtnl_lock();
+ err = dev_addr_add(dev, mac->san_addr, NETDEV_HW_ADDR_T_SAN);
+ rtnl_unlock();
+ }
+ return err;
+}
+
+/**
+ * ixgbe_del_sanmac_netdev - Removes the SAN MAC address to the corresponding
+ * netdev->dev_addr_list
+ * @netdev: network interface device structure
+ *
+ * Returns non-zero on failure
+ **/
+static int ixgbe_del_sanmac_netdev(struct net_device *dev)
+{
+ int err = 0;
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+ struct ixgbe_mac_info *mac = &adapter->hw.mac;
+
+ if (is_valid_ether_addr(mac->san_addr)) {
+ rtnl_lock();
+ err = dev_addr_del(dev, mac->san_addr, NETDEV_HW_ADDR_T_SAN);
+ rtnl_unlock();
+ }
+ return err;
+}
+
#ifdef CONFIG_NET_POLL_CONTROLLER
/*
* Polling 'interrupt' - used by things like netconsole to send skbs
@@ -4552,9 +5334,14 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_vlan_rx_register = ixgbe_vlan_rx_register,
.ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid,
+ .ndo_do_ioctl = ixgbe_ioctl,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ixgbe_netpoll,
#endif
+#ifdef IXGBE_FCOE
+ .ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get,
+ .ndo_fcoe_ddp_done = ixgbe_fcoe_ddp_put,
+#endif /* IXGBE_FCOE */
};
/**
@@ -4577,9 +5364,12 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data];
static int cards_found;
int i, err, pci_using_dac;
+#ifdef IXGBE_FCOE
+ u16 device_caps;
+#endif
u32 part_num, eec;
- err = pci_enable_device(pdev);
+ err = pci_enable_device_mem(pdev);
if (err)
return err;
@@ -4599,9 +5389,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
pci_using_dac = 0;
}
- err = pci_request_regions(pdev, ixgbe_driver_name);
+ err = pci_request_selected_regions(pdev, pci_select_bars(pdev,
+ IORESOURCE_MEM), ixgbe_driver_name);
if (err) {
- dev_err(&pdev->dev, "pci_request_regions failed 0x%x\n", err);
+ dev_err(&pdev->dev,
+ "pci_request_selected_regions failed 0x%x\n", err);
goto err_pci_reg;
}
@@ -4665,6 +5457,13 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
/* PHY */
memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops));
hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+ /* ixgbe_identify_phy_generic will set prtad and mmds properly */
+ hw->phy.mdio.prtad = MDIO_PRTAD_NONE;
+ hw->phy.mdio.mmds = 0;
+ hw->phy.mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+ hw->phy.mdio.dev = netdev;
+ hw->phy.mdio.mdio_read = ixgbe_mdio_read;
+ hw->phy.mdio.mdio_write = ixgbe_mdio_write;
/* set up this timer and work struct before calling get_invariants
* which might start the timer
@@ -4682,29 +5481,42 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
INIT_WORK(&adapter->sfp_config_module_task,
ixgbe_sfp_config_module_task);
- err = ii->get_invariants(hw);
- if (err == IXGBE_ERR_SFP_NOT_PRESENT) {
- /* start a kernel thread to watch for a module to arrive */
- set_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
- mod_timer(&adapter->sfp_timer,
- round_jiffies(jiffies + (2 * HZ)));
- err = 0;
- } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
- DPRINTK(PROBE, ERR, "failed to load because an "
- "unsupported SFP+ module type was detected.\n");
- goto err_hw_init;
- } else if (err) {
- goto err_hw_init;
- }
+ ii->get_invariants(hw);
/* setup the private structure */
err = ixgbe_sw_init(adapter);
if (err)
goto err_sw_init;
+ /*
+ * If there is a fan on this device and it has failed log the
+ * failure.
+ */
+ if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) {
+ u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+ if (esdp & IXGBE_ESDP_SDP1)
+ DPRINTK(PROBE, CRIT,
+ "Fan has stopped, replace the adapter\n");
+ }
+
/* reset_hw fills in the perm_addr as well */
err = hw->mac.ops.reset_hw(hw);
- if (err) {
+ if (err == IXGBE_ERR_SFP_NOT_PRESENT &&
+ hw->mac.type == ixgbe_mac_82598EB) {
+ /*
+ * Start a kernel thread to watch for a module to arrive.
+ * Only do this for 82598, since 82599 will generate
+ * interrupts on module arrival.
+ */
+ set_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
+ mod_timer(&adapter->sfp_timer,
+ round_jiffies(jiffies + (2 * HZ)));
+ err = 0;
+ } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+ dev_err(&adapter->pdev->dev, "failed to load because an "
+ "unsupported SFP+ module type was detected.\n");
+ goto err_sw_init;
+ } else if (err) {
dev_err(&adapter->pdev->dev, "HW Init failed: %d\n", err);
goto err_sw_init;
}
@@ -4720,6 +5532,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_TSO6;
netdev->features |= NETIF_F_GRO;
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ netdev->features |= NETIF_F_SCTP_CSUM;
+
netdev->vlan_features |= NETIF_F_TSO;
netdev->vlan_features |= NETIF_F_TSO6;
netdev->vlan_features |= NETIF_F_IP_CSUM;
@@ -4732,9 +5547,32 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netdev->dcbnl_ops = &dcbnl_ops;
#endif
+#ifdef IXGBE_FCOE
+ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
+ if (hw->mac.ops.get_device_caps) {
+ hw->mac.ops.get_device_caps(hw, &device_caps);
+ if (!(device_caps & IXGBE_DEVICE_CAPS_FCOE_OFFLOADS)) {
+ netdev->features |= NETIF_F_FCOE_CRC;
+ netdev->features |= NETIF_F_FSO;
+ netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1;
+ DPRINTK(DRV, INFO, "FCoE enabled, "
+ "disabling Flow Director\n");
+ adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
+ adapter->flags &=
+ ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
+ adapter->atr_sample_rate = 0;
+ } else {
+ adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED;
+ }
+ }
+ }
+#endif /* IXGBE_FCOE */
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
+ if (adapter->flags & IXGBE_FLAG2_RSC_ENABLED)
+ netdev->features |= NETIF_F_LRO;
+
/* make sure the EEPROM is good */
if (hw->eeprom.ops.validate_checksum(hw, NULL) < 0) {
dev_err(&pdev->dev, "The EEPROM Checksum Is Not Valid\n");
@@ -4766,6 +5604,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
case IXGBE_DEV_ID_82599_KX4:
adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX |
IXGBE_WUFC_MC | IXGBE_WUFC_BC);
+ /* Enable ACPI wakeup in GRC */
+ IXGBE_WRITE_REG(hw, IXGBE_GRC,
+ (IXGBE_READ_REG(hw, IXGBE_GRC) & ~IXGBE_GRC_APME));
break;
default:
adapter->wol = 0;
@@ -4774,6 +5615,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
device_init_wakeup(&adapter->pdev->dev, true);
device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+ /* pick up the PCI bus settings for reporting later */
+ hw->mac.ops.get_bus_info(hw);
+
/* print bus type/speed/width info */
dev_info(&pdev->dev, "(PCI Express:%s:%s) %pM\n",
((hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0Gb/s":
@@ -4805,24 +5649,37 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
hw->eeprom.ops.read(hw, 0x29, &adapter->eeprom_version);
/* reset the hardware with the new settings */
- hw->mac.ops.start_hw(hw);
-
- netif_carrier_off(netdev);
+ err = hw->mac.ops.start_hw(hw);
+ if (err == IXGBE_ERR_EEPROM_VERSION) {
+ /* We are running on a pre-production device, log a warning */
+ dev_warn(&pdev->dev, "This device is a pre-production "
+ "adapter/LOM. Please be aware there may be issues "
+ "associated with your hardware. If you are "
+ "experiencing problems please contact your Intel or "
+ "hardware representative who provided you with this "
+ "hardware.\n");
+ }
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
if (err)
goto err_register;
+ /* carrier off reporting is important to ethtool even BEFORE open */
+ netif_carrier_off(netdev);
+
+ if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
+ adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
+ INIT_WORK(&adapter->fdir_reinit_task, ixgbe_fdir_reinit_task);
+
#ifdef CONFIG_IXGBE_DCA
if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
- /* always use CB2 mode, difference is masked
- * in the CB driver */
- IXGBE_WRITE_REG(hw, IXGBE_DCA_CTRL, 2);
ixgbe_setup_dca(adapter);
}
#endif
+ /* add san mac addr to netdev */
+ ixgbe_add_sanmac_netdev(netdev);
dev_info(&pdev->dev, "Intel(R) 10 Gigabit Network Connection\n");
cards_found++;
@@ -4830,9 +5687,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
err_register:
ixgbe_release_hw_control(adapter);
-err_hw_init:
+ ixgbe_clear_interrupt_scheme(adapter);
err_sw_init:
- ixgbe_reset_interrupt_capability(adapter);
err_eeprom:
clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
del_timer_sync(&adapter->sfp_timer);
@@ -4843,7 +5699,8 @@ err_eeprom:
err_ioremap:
free_netdev(netdev);
err_alloc_etherdev:
- pci_release_regions(pdev);
+ pci_release_selected_regions(pdev, pci_select_bars(pdev,
+ IORESOURCE_MEM));
err_pci_reg:
err_dma:
pci_disable_device(pdev);
@@ -4877,6 +5734,9 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
cancel_work_sync(&adapter->sfp_task);
cancel_work_sync(&adapter->multispeed_fiber_task);
cancel_work_sync(&adapter->sfp_config_module_task);
+ if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
+ adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
+ cancel_work_sync(&adapter->fdir_reinit_task);
flush_scheduled_work();
#ifdef CONFIG_IXGBE_DCA
@@ -4887,19 +5747,27 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
}
#endif
+#ifdef IXGBE_FCOE
+ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
+ ixgbe_cleanup_fcoe(adapter);
+
+#endif /* IXGBE_FCOE */
+
+ /* remove the added san mac */
+ ixgbe_del_sanmac_netdev(netdev);
+
if (netdev->reg_state == NETREG_REGISTERED)
unregister_netdev(netdev);
- ixgbe_reset_interrupt_capability(adapter);
+ ixgbe_clear_interrupt_scheme(adapter);
ixgbe_release_hw_control(adapter);
iounmap(adapter->hw.hw_addr);
- pci_release_regions(pdev);
+ pci_release_selected_regions(pdev, pci_select_bars(pdev,
+ IORESOURCE_MEM));
DPRINTK(PROBE, INFO, "complete\n");
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
free_netdev(netdev);
@@ -4927,6 +5795,9 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
netif_device_detach(netdev);
+ if (state == pci_channel_io_perm_failure)
+ return PCI_ERS_RESULT_DISCONNECT;
+
if (netif_running(netdev))
ixgbe_down(adapter);
pci_disable_device(pdev);
@@ -4948,7 +5819,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
pci_ers_result_t result;
int err;
- if (pci_enable_device(pdev)) {
+ if (pci_enable_device_mem(pdev)) {
DPRINTK(PROBE, ERR,
"Cannot re-enable PCI device after reset.\n");
result = PCI_ERS_RESULT_DISCONNECT;
@@ -4956,8 +5827,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
pci_set_master(pdev);
pci_restore_state(pdev);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
+ pci_wake_from_d3(pdev, false);
ixgbe_reset(adapter);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index 14e9606aa3b..453e966762f 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -44,7 +44,6 @@ static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
static bool ixgbe_get_i2c_data(u32 *i2cctl);
static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw);
-static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw);
@@ -61,8 +60,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
if (hw->phy.type == ixgbe_phy_unknown) {
for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
- if (ixgbe_validate_phy_addr(hw, phy_addr)) {
- hw->phy.addr = phy_addr;
+ if (mdio45_probe(&hw->phy.mdio, phy_addr) == 0) {
ixgbe_get_phy_id(hw);
hw->phy.type =
ixgbe_get_phy_type_from_id(hw->phy.id);
@@ -78,26 +76,6 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
}
/**
- * ixgbe_validate_phy_addr - Determines phy address is valid
- * @hw: pointer to hardware structure
- *
- **/
-static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr)
-{
- u16 phy_id = 0;
- bool valid = false;
-
- hw->phy.addr = phy_addr;
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id);
-
- if (phy_id != 0xFFFF && phy_id != 0x0)
- valid = true;
-
- return valid;
-}
-
-/**
* ixgbe_get_phy_id - Get the phy type
* @hw: pointer to hardware structure
*
@@ -108,14 +86,12 @@ static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw)
u16 phy_id_high = 0;
u16 phy_id_low = 0;
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ status = hw->phy.ops.read_reg(hw, MDIO_DEVID1, MDIO_MMD_PMAPMD,
&phy_id_high);
if (status == 0) {
hw->phy.id = (u32)(phy_id_high << 16);
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ status = hw->phy.ops.read_reg(hw, MDIO_DEVID2, MDIO_MMD_PMAPMD,
&phy_id_low);
hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK);
hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK);
@@ -160,9 +136,8 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
* Perform soft PHY reset to the PHY_XS.
* This will cause a soft reset to the PHY
*/
- return hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE,
- IXGBE_MDIO_PHY_XS_RESET);
+ return hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS,
+ MDIO_CTRL1_RESET);
}
/**
@@ -192,7 +167,7 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
/* Setup and write the address cycle command */
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
(device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
(IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -223,7 +198,8 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
*/
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
(device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (hw->phy.mdio.prtad <<
+ IXGBE_MSCA_PHY_ADDR_SHIFT) |
(IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -292,7 +268,7 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
/* Setup and write the address cycle command */
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
(device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
(IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -323,7 +299,8 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
*/
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
(device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (hw->phy.mdio.prtad <<
+ IXGBE_MSCA_PHY_ADDR_SHIFT) |
(IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -365,7 +342,7 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
s32 status = IXGBE_NOT_IMPLEMENTED;
u32 time_out;
u32 max_time_out = 10;
- u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
+ u16 autoneg_reg;
/*
* Set advertisement settings in PHY based on autoneg_advertised
@@ -373,36 +350,31 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
* tnx devices cannot be "forced" to a autoneg 10G and fail. But can
* for a 1G.
*/
- hw->phy.ops.read_reg(hw, IXGBE_MII_SPEED_SELECTION_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
+ hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, &autoneg_reg);
if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL)
- autoneg_reg &= 0xEFFF; /* 0 in bit 12 is 1G operation */
+ autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G;
else
- autoneg_reg |= 0x1000; /* 1 in bit 12 is 10G/1G operation */
+ autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G;
- hw->phy.ops.write_reg(hw, IXGBE_MII_SPEED_SELECTION_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
+ hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, autoneg_reg);
/* Restart PHY autonegotiation and wait for completion */
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
+ hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, &autoneg_reg);
- autoneg_reg |= IXGBE_MII_RESTART;
+ autoneg_reg |= MDIO_AN_CTRL1_RESTART;
- hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
+ hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, autoneg_reg);
/* Wait for autonegotiation to finish */
for (time_out = 0; time_out < max_time_out; time_out++) {
udelay(10);
/* Restart PHY autonegotiation and wait for completion */
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+ status = hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN,
&autoneg_reg);
- autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE;
- if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE) {
+ autoneg_reg &= MDIO_AN_STAT1_COMPLETE;
+ if (autoneg_reg == MDIO_AN_STAT1_COMPLETE) {
status = 0;
break;
}
@@ -457,23 +429,21 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
s32 ret_val = 0;
u32 i;
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data);
+ hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, &phy_data);
/* reset the PHY and poll for completion */
- hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE,
- (phy_data | IXGBE_MDIO_PHY_XS_RESET));
+ hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS,
+ (phy_data | MDIO_CTRL1_RESET));
for (i = 0; i < 100; i++) {
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data);
- if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) == 0)
+ hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS,
+ &phy_data);
+ if ((phy_data & MDIO_CTRL1_RESET) == 0)
break;
msleep(10);
}
- if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) != 0) {
+ if ((phy_data & MDIO_CTRL1_RESET) != 0) {
hw_dbg(hw, "PHY reset did not complete.\n");
ret_val = IXGBE_ERR_PHY;
goto out;
@@ -509,7 +479,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
for (i = 0; i < edata; i++) {
hw->eeprom.ops.read(hw, data_offset, &eword);
hw->phy.ops.write_reg(hw, phy_offset,
- IXGBE_TWINAX_DEV, eword);
+ MDIO_MMD_PMAPMD, eword);
hw_dbg(hw, "Wrote %4.4x to %4.4x\n", eword,
phy_offset);
data_offset++;
@@ -552,18 +522,30 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
{
s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
u32 vendor_oui = 0;
+ enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
u8 identifier = 0;
u8 comp_codes_1g = 0;
u8 comp_codes_10g = 0;
u8 oui_bytes[3] = {0, 0, 0};
- u8 transmission_media = 0;
+ u8 cable_tech = 0;
u16 enforce_sfp = 0;
+ if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) {
+ hw->phy.sfp_type = ixgbe_sfp_type_not_present;
+ status = IXGBE_ERR_SFP_NOT_PRESENT;
+ goto out;
+ }
+
status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER,
&identifier);
- if (status == IXGBE_ERR_SFP_NOT_PRESENT) {
+ if (status == IXGBE_ERR_SFP_NOT_PRESENT || status == IXGBE_ERR_I2C) {
+ status = IXGBE_ERR_SFP_NOT_PRESENT;
hw->phy.sfp_type = ixgbe_sfp_type_not_present;
+ if (hw->phy.type != ixgbe_phy_nl) {
+ hw->phy.id = 0;
+ hw->phy.type = ixgbe_phy_unknown;
+ }
goto out;
}
@@ -572,8 +554,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
&comp_codes_1g);
hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_10GBE_COMP_CODES,
&comp_codes_10g);
- hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_TRANSMISSION_MEDIA,
- &transmission_media);
+ hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_CABLE_TECHNOLOGY,
+ &cable_tech);
/* ID Module
* =========
@@ -586,7 +568,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
* 6 SFP_SR/LR_CORE1 - 82599-specific
*/
if (hw->mac.type == ixgbe_mac_82598EB) {
- if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
+ if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
hw->phy.sfp_type = ixgbe_sfp_type_sr;
@@ -595,7 +577,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
else
hw->phy.sfp_type = ixgbe_sfp_type_unknown;
} else if (hw->mac.type == ixgbe_mac_82599EB) {
- if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
+ if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
if (hw->bus.lan_id == 0)
hw->phy.sfp_type =
ixgbe_sfp_type_da_cu_core0;
@@ -620,8 +602,19 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
hw->phy.sfp_type = ixgbe_sfp_type_unknown;
}
+ if (hw->phy.sfp_type != stored_sfp_type)
+ hw->phy.sfp_setup_needed = true;
+
+ /* Determine if the SFP+ PHY is dual speed or not. */
+ hw->phy.multispeed_fiber = false;
+ if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
+ (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
+ ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
+ (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
+ hw->phy.multispeed_fiber = true;
+
/* Determine PHY vendor */
- if (hw->phy.type == ixgbe_phy_unknown) {
+ if (hw->phy.type != ixgbe_phy_nl) {
hw->phy.id = identifier;
hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_VENDOR_OUI_BYTE0,
@@ -640,8 +633,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
switch (vendor_oui) {
case IXGBE_SFF_VENDOR_OUI_TYCO:
- if (transmission_media &
- IXGBE_SFF_TWIN_AX_CAPABLE)
+ if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
hw->phy.type = ixgbe_phy_tw_tyco;
break;
case IXGBE_SFF_VENDOR_OUI_FTL:
@@ -654,31 +646,42 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
hw->phy.type = ixgbe_phy_sfp_intel;
break;
default:
- if (transmission_media &
- IXGBE_SFF_TWIN_AX_CAPABLE)
+ if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
hw->phy.type = ixgbe_phy_tw_unknown;
else
hw->phy.type = ixgbe_phy_sfp_unknown;
break;
}
}
- if (hw->mac.type == ixgbe_mac_82598EB ||
- (hw->phy.sfp_type != ixgbe_sfp_type_sr &&
- hw->phy.sfp_type != ixgbe_sfp_type_lr &&
- hw->phy.sfp_type != ixgbe_sfp_type_srlr_core0 &&
- hw->phy.sfp_type != ixgbe_sfp_type_srlr_core1)) {
+
+ /* All passive DA cables are supported */
+ if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) {
+ status = 0;
+ goto out;
+ }
+
+ /* 1G SFP modules are not supported */
+ if (comp_codes_10g == 0) {
+ hw->phy.type = ixgbe_phy_sfp_unsupported;
+ status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+ goto out;
+ }
+
+ /* Anything else 82598-based is supported */
+ if (hw->mac.type == ixgbe_mac_82598EB) {
status = 0;
goto out;
}
- hw->eeprom.ops.read(hw, IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET,
- &enforce_sfp);
- if (!(enforce_sfp & IXGBE_PHY_ALLOW_ANY_SFP)) {
+ /* This is guaranteed to be 82599, no need to check for NULL */
+ hw->mac.ops.get_device_caps(hw, &enforce_sfp);
+ if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
/* Make sure we're a supported PHY type */
if (hw->phy.type == ixgbe_phy_sfp_intel) {
status = 0;
} else {
hw_dbg(hw, "SFP+ module not supported\n");
+ hw->phy.type = ixgbe_phy_sfp_unsupported;
status = IXGBE_ERR_SFP_NOT_SUPPORTED;
}
} else {
@@ -1279,7 +1282,7 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
udelay(10);
status = hw->phy.ops.read_reg(hw,
IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ MDIO_MMD_VEND1,
&phy_data);
phy_link = phy_data &
IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
@@ -1307,8 +1310,7 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
{
s32 status = 0;
- status = hw->phy.ops.read_reg(hw, TNX_FW_REV,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ status = hw->phy.ops.read_reg(hw, TNX_FW_REV, MDIO_MMD_VEND1,
firmware_version);
return status;
diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h
index cc5f1b3287e..9b700f5bf1e 100644
--- a/drivers/net/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ixgbe/ixgbe_phy.h
@@ -39,11 +39,12 @@
#define IXGBE_SFF_VENDOR_OUI_BYTE2 0x27
#define IXGBE_SFF_1GBE_COMP_CODES 0x6
#define IXGBE_SFF_10GBE_COMP_CODES 0x3
-#define IXGBE_SFF_TRANSMISSION_MEDIA 0x9
+#define IXGBE_SFF_CABLE_TECHNOLOGY 0x8
/* Bitmasks */
-#define IXGBE_SFF_TWIN_AX_CAPABLE 0x80
+#define IXGBE_SFF_DA_PASSIVE_CABLE 0x4
#define IXGBE_SFF_1GBASESX_CAPABLE 0x1
+#define IXGBE_SFF_1GBASELX_CAPABLE 0x2
#define IXGBE_SFF_10GBASESR_CAPABLE 0x10
#define IXGBE_SFF_10GBASELR_CAPABLE 0x20
#define IXGBE_I2C_EEPROM_READ_MASK 0x100
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 030ff0a9ea6..fa87309dc08 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -29,6 +29,8 @@
#define _IXGBE_TYPE_H_
#include <linux/types.h>
+#include <linux/mdio.h>
+#include <linux/list.h>
/* Vendor ID */
#define IXGBE_INTEL_VENDOR_ID 0x8086
@@ -45,9 +47,9 @@
#define IXGBE_DEV_ID_82598_DA_DUAL_PORT 0x10F1
#define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM 0x10E1
#define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4
-#define IXGBE_DEV_ID_82599 0x10D8
#define IXGBE_DEV_ID_82599_KX4 0x10F7
#define IXGBE_DEV_ID_82599_SFP 0x10FB
+#define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC
/* General Registers */
#define IXGBE_CTRL 0x00000
@@ -229,6 +231,34 @@
#define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */
#define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */
+/* Flow Director registers */
+#define IXGBE_FDIRCTRL 0x0EE00
+#define IXGBE_FDIRHKEY 0x0EE68
+#define IXGBE_FDIRSKEY 0x0EE6C
+#define IXGBE_FDIRDIP4M 0x0EE3C
+#define IXGBE_FDIRSIP4M 0x0EE40
+#define IXGBE_FDIRTCPM 0x0EE44
+#define IXGBE_FDIRUDPM 0x0EE48
+#define IXGBE_FDIRIP6M 0x0EE74
+#define IXGBE_FDIRM 0x0EE70
+
+/* Flow Director Stats registers */
+#define IXGBE_FDIRFREE 0x0EE38
+#define IXGBE_FDIRLEN 0x0EE4C
+#define IXGBE_FDIRUSTAT 0x0EE50
+#define IXGBE_FDIRFSTAT 0x0EE54
+#define IXGBE_FDIRMATCH 0x0EE58
+#define IXGBE_FDIRMISS 0x0EE5C
+
+/* Flow Director Programming registers */
+#define IXGBE_FDIRSIPv6(_i) (0x0EE0C + ((_i) * 4)) /* 3 of these (0-2) */
+#define IXGBE_FDIRIPSA 0x0EE18
+#define IXGBE_FDIRIPDA 0x0EE1C
+#define IXGBE_FDIRPORT 0x0EE20
+#define IXGBE_FDIRVLAN 0x0EE24
+#define IXGBE_FDIRHASH 0x0EE28
+#define IXGBE_FDIRCMD 0x0EE2C
+
/* Transmit DMA registers */
#define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40)) /* 32 of these (0-31)*/
#define IXGBE_TDBAH(_i) (0x06004 + ((_i) * 0x40))
@@ -443,6 +473,21 @@
#define IXGBE_SECTXCTRL_STORE_FORWARD_ENABLE 0x4
+/* HW RSC registers */
+#define IXGBE_RSCCTL(_i) (((_i) < 64) ? (0x0102C + ((_i) * 0x40)) : \
+ (0x0D02C + ((_i - 64) * 0x40)))
+#define IXGBE_RSCDBU 0x03028
+#define IXGBE_RSCCTL_RSCEN 0x01
+#define IXGBE_RSCCTL_MAXDESC_1 0x00
+#define IXGBE_RSCCTL_MAXDESC_4 0x04
+#define IXGBE_RSCCTL_MAXDESC_8 0x08
+#define IXGBE_RSCCTL_MAXDESC_16 0x0C
+#define IXGBE_RXDADV_RSCCNT_SHIFT 17
+#define IXGBE_GPIE_RSC_DELAY_SHIFT 11
+#define IXGBE_RXDADV_RSCCNT_MASK 0x001E0000
+#define IXGBE_RSCDBU_RSCACKDIS 0x00000080
+#define IXGBE_RDRXCTL_RSCFRSTSIZE 0x003E0000
+
/* DCB registers */
#define IXGBE_RTRPCS 0x02430
#define IXGBE_RTTDCS 0x04900
@@ -462,6 +507,63 @@
#define IXGBE_RTTDTECC_NO_BCN 0x00000100
#define IXGBE_RTTBCNRC 0x04984
+/* FCoE registers */
+#define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */
+#define IXGBE_FCPTRH 0x02414 /* FC USer Desc. PTR High */
+#define IXGBE_FCBUFF 0x02418 /* FC Buffer Control */
+#define IXGBE_FCDMARW 0x02420 /* FC Receive DMA RW */
+#define IXGBE_FCINVST0 0x03FC0 /* FC Invalid DMA Context Status Reg 0 */
+#define IXGBE_FCINVST(_i) (IXGBE_FCINVST0 + ((_i) * 4))
+#define IXGBE_FCBUFF_VALID (1 << 0) /* DMA Context Valid */
+#define IXGBE_FCBUFF_BUFFSIZE (3 << 3) /* User Buffer Size */
+#define IXGBE_FCBUFF_WRCONTX (1 << 7) /* 0: Initiator, 1: Target */
+#define IXGBE_FCBUFF_BUFFCNT 0x0000ff00 /* Number of User Buffers */
+#define IXGBE_FCBUFF_OFFSET 0xffff0000 /* User Buffer Offset */
+#define IXGBE_FCBUFF_BUFFSIZE_SHIFT 3
+#define IXGBE_FCBUFF_BUFFCNT_SHIFT 8
+#define IXGBE_FCBUFF_OFFSET_SHIFT 16
+#define IXGBE_FCDMARW_WE (1 << 14) /* Write enable */
+#define IXGBE_FCDMARW_RE (1 << 15) /* Read enable */
+#define IXGBE_FCDMARW_FCOESEL 0x000001ff /* FC X_ID: 11 bits */
+#define IXGBE_FCDMARW_LASTSIZE 0xffff0000 /* Last User Buffer Size */
+#define IXGBE_FCDMARW_LASTSIZE_SHIFT 16
+
+/* FCoE SOF/EOF */
+#define IXGBE_TEOFF 0x04A94 /* Tx FC EOF */
+#define IXGBE_TSOFF 0x04A98 /* Tx FC SOF */
+#define IXGBE_REOFF 0x05158 /* Rx FC EOF */
+#define IXGBE_RSOFF 0x051F8 /* Rx FC SOF */
+/* FCoE Filter Context Registers */
+#define IXGBE_FCFLT 0x05108 /* FC FLT Context */
+#define IXGBE_FCFLTRW 0x05110 /* FC Filter RW Control */
+#define IXGBE_FCPARAM 0x051d8 /* FC Offset Parameter */
+#define IXGBE_FCFLT_VALID (1 << 0) /* Filter Context Valid */
+#define IXGBE_FCFLT_FIRST (1 << 1) /* Filter First */
+#define IXGBE_FCFLT_SEQID 0x00ff0000 /* Sequence ID */
+#define IXGBE_FCFLT_SEQCNT 0xff000000 /* Sequence Count */
+#define IXGBE_FCFLTRW_RVALDT (1 << 13) /* Fast Re-Validation */
+#define IXGBE_FCFLTRW_WE (1 << 14) /* Write Enable */
+#define IXGBE_FCFLTRW_RE (1 << 15) /* Read Enable */
+/* FCoE Receive Control */
+#define IXGBE_FCRXCTRL 0x05100 /* FC Receive Control */
+#define IXGBE_FCRXCTRL_FCOELLI (1 << 0) /* Low latency interrupt */
+#define IXGBE_FCRXCTRL_SAVBAD (1 << 1) /* Save Bad Frames */
+#define IXGBE_FCRXCTRL_FRSTRDH (1 << 2) /* EN 1st Read Header */
+#define IXGBE_FCRXCTRL_LASTSEQH (1 << 3) /* EN Last Header in Seq */
+#define IXGBE_FCRXCTRL_ALLH (1 << 4) /* EN All Headers */
+#define IXGBE_FCRXCTRL_FRSTSEQH (1 << 5) /* EN 1st Seq. Header */
+#define IXGBE_FCRXCTRL_ICRC (1 << 6) /* Ignore Bad FC CRC */
+#define IXGBE_FCRXCTRL_FCCRCBO (1 << 7) /* FC CRC Byte Ordering */
+#define IXGBE_FCRXCTRL_FCOEVER 0x00000f00 /* FCoE Version: 4 bits */
+#define IXGBE_FCRXCTRL_FCOEVER_SHIFT 8
+/* FCoE Redirection */
+#define IXGBE_FCRECTL 0x0ED00 /* FC Redirection Control */
+#define IXGBE_FCRETA0 0x0ED10 /* FC Redirection Table 0 */
+#define IXGBE_FCRETA(_i) (IXGBE_FCRETA0 + ((_i) * 4)) /* FCoE Redir */
+#define IXGBE_FCRECTL_ENA 0x1 /* FCoE Redir Table Enable */
+#define IXGBE_FCRETA_SIZE 8 /* Max entries in FCRETA */
+#define IXGBE_FCRETA_ENTRY_MASK 0x0000007f /* 7 bits for the queue index */
+
/* Stats registers */
#define IXGBE_CRCERRS 0x04000
#define IXGBE_ILLERRC 0x04004
@@ -533,6 +635,13 @@
#define IXGBE_QPRDC(_i) (0x01430 + ((_i) * 0x40)) /* 16 of these */
#define IXGBE_QBTC_L(_i) (0x08700 + ((_i) * 0x8)) /* 16 of these */
#define IXGBE_QBTC_H(_i) (0x08704 + ((_i) * 0x8)) /* 16 of these */
+#define IXGBE_FCCRC 0x05118 /* Count of Good Eth CRC w/ Bad FC CRC */
+#define IXGBE_FCOERPDC 0x0241C /* FCoE Rx Packets Dropped Count */
+#define IXGBE_FCLAST 0x02424 /* FCoE Last Error Count */
+#define IXGBE_FCOEPRC 0x02428 /* Number of FCoE Packets Received */
+#define IXGBE_FCOEDWRC 0x0242C /* Number of FCoE DWords Received */
+#define IXGBE_FCOEPTC 0x08784 /* Number of FCoE Packets Transmitted */
+#define IXGBE_FCOEDWTC 0x08788 /* Number of FCoE DWords Transmitted */
/* Management */
#define IXGBE_MAVTV(_i) (0x05010 + ((_i) * 4)) /* 8 of these (0-7) */
@@ -833,13 +942,7 @@
/* Omer bit masks */
#define IXGBE_CORECTL_WRITE_CMD 0x00010000
-/* Device Type definitions for new protocol MDIO commands */
-#define IXGBE_MDIO_PMA_PMD_DEV_TYPE 0x1
-#define IXGBE_MDIO_PCS_DEV_TYPE 0x3
-#define IXGBE_MDIO_PHY_XS_DEV_TYPE 0x4
-#define IXGBE_MDIO_AUTO_NEG_DEV_TYPE 0x7
-#define IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE 0x1E /* Device 30 */
-#define IXGBE_TWINAX_DEV 1
+/* MDIO definitions */
#define IXGBE_MDIO_COMMAND_TIMEOUT 100 /* PHY Timeout for 1 GB mode */
@@ -850,31 +953,10 @@
#define IXGBE_MDIO_VENDOR_SPECIFIC_1_10G_SPEED 0x0018
#define IXGBE_MDIO_VENDOR_SPECIFIC_1_1G_SPEED 0x0010
-#define IXGBE_MDIO_AUTO_NEG_CONTROL 0x0 /* AUTO_NEG Control Reg */
-#define IXGBE_MDIO_AUTO_NEG_STATUS 0x1 /* AUTO_NEG Status Reg */
-#define IXGBE_MDIO_PHY_XS_CONTROL 0x0 /* PHY_XS Control Reg */
-#define IXGBE_MDIO_PHY_XS_RESET 0x8000 /* PHY_XS Reset */
-#define IXGBE_MDIO_PHY_ID_HIGH 0x2 /* PHY ID High Reg*/
-#define IXGBE_MDIO_PHY_ID_LOW 0x3 /* PHY ID Low Reg*/
-#define IXGBE_MDIO_PHY_SPEED_ABILITY 0x4 /* Speed Ability Reg */
-#define IXGBE_MDIO_PHY_SPEED_10G 0x0001 /* 10G capable */
-#define IXGBE_MDIO_PHY_SPEED_1G 0x0010 /* 1G capable */
-#define IXGBE_MDIO_PHY_EXT_ABILITY 0xB /* Ext Ability Reg */
-#define IXGBE_MDIO_PHY_10GBASET_ABILITY 0x0004 /* 10GBaseT capable */
-#define IXGBE_MDIO_PHY_1000BASET_ABILITY 0x0020 /* 1000BaseT capable */
-
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Addr Reg */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT 0xC30C /* PHY_XS SDA/SCL Status Reg */
-/* MII clause 22/28 definitions */
-#define IXGBE_MDIO_PHY_LOW_POWER_MODE 0x0800
-
-#define IXGBE_MII_SPEED_SELECTION_REG 0x10
-#define IXGBE_MII_RESTART 0x200
-#define IXGBE_MII_AUTONEG_COMPLETE 0x20
-#define IXGBE_MII_AUTONEG_REG 0x0
-
#define IXGBE_PHY_REVISION_MASK 0xFFFFFFF0
#define IXGBE_MAX_PHY_ADDR 32
@@ -898,8 +980,6 @@
#define IXGBE_CONTROL_NL 0x000F
#define IXGBE_CONTROL_EOL_NL 0x0FFF
#define IXGBE_CONTROL_SOL_NL 0x0000
-#define IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET 0x002C
-#define IXGBE_PHY_ALLOW_ANY_SFP 0x1
/* General purpose Interrupt Enable */
#define IXGBE_SDP0_GPIEN 0x00000001 /* SDP0 */
@@ -958,6 +1038,8 @@
#define IXGBE_VT_CTL_DIS_DEFPL 0x20000000 /* disable default pool */
#define IXGBE_VT_CTL_REPLEN 0x40000000 /* replication enabled */
#define IXGBE_VT_CTL_VT_ENABLE 0x00000001 /* Enable VT Mode */
+#define IXGBE_VT_CTL_POOL_SHIFT 7
+#define IXGBE_VT_CTL_POOL_MASK (0x3F << IXGBE_VT_CTL_POOL_SHIFT)
/* VMOLR bitmasks */
#define IXGBE_VMOLR_AUPE 0x01000000 /* accept untagged packets */
@@ -1148,6 +1230,7 @@
/* Interrupt Vector Allocation Registers */
#define IXGBE_IVAR_REG_NUM 25
+#define IXGBE_IVAR_REG_NUM_82599 64
#define IXGBE_IVAR_TXRX_ENTRY 96
#define IXGBE_IVAR_RX_ENTRY 64
#define IXGBE_IVAR_RX_QUEUE(_i) (0 + (_i))
@@ -1163,6 +1246,7 @@
/* ETYPE Queue Filter/Select Bit Masks */
#define IXGBE_MAX_ETQF_FILTERS 8
+#define IXGBE_ETQF_FCOE 0x08000000 /* bit 27 */
#define IXGBE_ETQF_BCN 0x10000000 /* bit 28 */
#define IXGBE_ETQF_1588 0x40000000 /* bit 30 */
#define IXGBE_ETQF_FILTER_EN 0x80000000 /* bit 31 */
@@ -1185,6 +1269,7 @@
*/
#define IXGBE_ETQF_FILTER_EAPOL 0
#define IXGBE_ETQF_FILTER_BCN 1
+#define IXGBE_ETQF_FILTER_FCOE 2
#define IXGBE_ETQF_FILTER_1588 3
/* VLAN Control Bit Masks */
#define IXGBE_VLNCTRL_VET 0x0000FFFF /* bits 0-15 */
@@ -1208,8 +1293,10 @@
#define IXGBE_STATUS_LAN_ID_1 0x00000004 /* LAN ID 1 */
/* ESDP Bit Masks */
-#define IXGBE_ESDP_SDP0 0x00000001
-#define IXGBE_ESDP_SDP1 0x00000002
+#define IXGBE_ESDP_SDP0 0x00000001 /* SDP0 Data Value */
+#define IXGBE_ESDP_SDP1 0x00000002 /* SDP1 Data Value */
+#define IXGBE_ESDP_SDP2 0x00000004 /* SDP2 Data Value */
+#define IXGBE_ESDP_SDP3 0x00000008 /* SDP3 Data Value */
#define IXGBE_ESDP_SDP4 0x00000010 /* SDP4 Data Value */
#define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */
#define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */
@@ -1309,8 +1396,6 @@
#define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */
#define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */
-#define FIBER_LINK_UP_LIMIT 50
-
/* PCS1GLSTA Bit Masks */
#define IXGBE_PCS1GLSTA_LINK_OK 1
#define IXGBE_PCS1GLSTA_SYNK_OK 0x10
@@ -1382,6 +1467,8 @@
#define IXGBE_FW_PTR 0x0F
#define IXGBE_PBANUM0_PTR 0x15
#define IXGBE_PBANUM1_PTR 0x16
+#define IXGBE_DEVICE_CAPS 0x2C
+#define IXGBE_SAN_MAC_ADDR_PTR 0x28
#define IXGBE_PCIE_MSIX_82599_CAPS 0x72
#define IXGBE_PCIE_MSIX_82598_CAPS 0x62
@@ -1425,6 +1512,13 @@
#define IXGBE_EERD_ATTEMPTS 100000
#endif
+#define IXGBE_SAN_MAC_ADDR_PORT0_OFFSET 0x0
+#define IXGBE_SAN_MAC_ADDR_PORT1_OFFSET 0x3
+#define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1
+#define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS 0x2
+#define IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR 0x4
+#define IXGBE_FW_PATCH_VERSION_4 0x7
+
/* PCI Bus Info */
#define IXGBE_PCI_LINK_STATUS 0xB2
#define IXGBE_PCI_LINK_WIDTH 0x3F0
@@ -1553,7 +1647,8 @@
#define IXGBE_MTQC_RT_ENA 0x1 /* DCB Enable */
#define IXGBE_MTQC_VT_ENA 0x2 /* VMDQ2 Enable */
#define IXGBE_MTQC_64Q_1PB 0x0 /* 64 queues 1 pack buffer */
-#define IXGBE_MTQC_64VF 0x8 /* 2 TX Queues per pool w/64VF's */
+#define IXGBE_MTQC_32VF 0x8 /* 4 TX Queues per pool w/32VF's */
+#define IXGBE_MTQC_64VF 0x4 /* 2 TX Queues per pool w/64VF's */
#define IXGBE_MTQC_8TC_8TQ 0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */
/* Receive Descriptor bit definitions */
@@ -1585,6 +1680,11 @@
#define IXGBE_RXD_ERR_IPE 0x80 /* IP Checksum Error */
#define IXGBE_RXDADV_ERR_MASK 0xfff00000 /* RDESC.ERRORS mask */
#define IXGBE_RXDADV_ERR_SHIFT 20 /* RDESC.ERRORS shift */
+#define IXGBE_RXDADV_ERR_FCEOFE 0x80000000 /* FCoEFe/IPE */
+#define IXGBE_RXDADV_ERR_FCERR 0x00700000 /* FCERR/FDIRERR */
+#define IXGBE_RXDADV_ERR_FDIR_LEN 0x00100000 /* FDIR Length error */
+#define IXGBE_RXDADV_ERR_FDIR_DROP 0x00200000 /* FDIR Drop error */
+#define IXGBE_RXDADV_ERR_FDIR_COLL 0x00400000 /* FDIR Collision error */
#define IXGBE_RXDADV_ERR_HBO 0x00800000 /*Header Buffer Overflow */
#define IXGBE_RXDADV_ERR_CE 0x01000000 /* CRC Error */
#define IXGBE_RXDADV_ERR_LE 0x02000000 /* Length Error */
@@ -1604,12 +1704,19 @@
#define IXGBE_RXDADV_STAT_FLM IXGBE_RXD_STAT_FLM /* FDir Match */
#define IXGBE_RXDADV_STAT_VP IXGBE_RXD_STAT_VP /* IEEE VLAN Pkt */
#define IXGBE_RXDADV_STAT_MASK 0x000fffff /* Stat/NEXTP: bit 0-19 */
+#define IXGBE_RXDADV_STAT_FCEOFS 0x00000040 /* FCoE EOF/SOF Stat */
+#define IXGBE_RXDADV_STAT_FCSTAT 0x00000030 /* FCoE Pkt Stat */
+#define IXGBE_RXDADV_STAT_FCSTAT_NOMTCH 0x00000000 /* 00: No Ctxt Match */
+#define IXGBE_RXDADV_STAT_FCSTAT_NODDP 0x00000010 /* 01: Ctxt w/o DDP */
+#define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP 0x00000020 /* 10: Recv. FCP_RSP */
+#define IXGBE_RXDADV_STAT_FCSTAT_DDP 0x00000030 /* 11: Ctxt w/ DDP */
/* PSRTYPE bit definitions */
#define IXGBE_PSRTYPE_TCPHDR 0x00000010
#define IXGBE_PSRTYPE_UDPHDR 0x00000020
#define IXGBE_PSRTYPE_IPV4HDR 0x00000100
#define IXGBE_PSRTYPE_IPV6HDR 0x00000200
+#define IXGBE_PSRTYPE_L2HDR 0x00001000
/* SRRCTL bit definitions */
#define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */
@@ -1710,6 +1817,82 @@
#endif
+enum ixgbe_fdir_pballoc_type {
+ IXGBE_FDIR_PBALLOC_64K = 0,
+ IXGBE_FDIR_PBALLOC_128K,
+ IXGBE_FDIR_PBALLOC_256K,
+};
+#define IXGBE_FDIR_PBALLOC_SIZE_SHIFT 16
+
+/* Flow Director register values */
+#define IXGBE_FDIRCTRL_PBALLOC_64K 0x00000001
+#define IXGBE_FDIRCTRL_PBALLOC_128K 0x00000002
+#define IXGBE_FDIRCTRL_PBALLOC_256K 0x00000003
+#define IXGBE_FDIRCTRL_INIT_DONE 0x00000008
+#define IXGBE_FDIRCTRL_PERFECT_MATCH 0x00000010
+#define IXGBE_FDIRCTRL_REPORT_STATUS 0x00000020
+#define IXGBE_FDIRCTRL_REPORT_STATUS_ALWAYS 0x00000080
+#define IXGBE_FDIRCTRL_DROP_Q_SHIFT 8
+#define IXGBE_FDIRCTRL_FLEX_SHIFT 16
+#define IXGBE_FDIRCTRL_SEARCHLIM 0x00800000
+#define IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT 24
+#define IXGBE_FDIRCTRL_FULL_THRESH_MASK 0xF0000000
+#define IXGBE_FDIRCTRL_FULL_THRESH_SHIFT 28
+
+#define IXGBE_FDIRTCPM_DPORTM_SHIFT 16
+#define IXGBE_FDIRUDPM_DPORTM_SHIFT 16
+#define IXGBE_FDIRIP6M_DIPM_SHIFT 16
+#define IXGBE_FDIRM_VLANID 0x00000001
+#define IXGBE_FDIRM_VLANP 0x00000002
+#define IXGBE_FDIRM_POOL 0x00000004
+#define IXGBE_FDIRM_L3P 0x00000008
+#define IXGBE_FDIRM_L4P 0x00000010
+#define IXGBE_FDIRM_FLEX 0x00000020
+#define IXGBE_FDIRM_DIPv6 0x00000040
+
+#define IXGBE_FDIRFREE_FREE_MASK 0xFFFF
+#define IXGBE_FDIRFREE_FREE_SHIFT 0
+#define IXGBE_FDIRFREE_COLL_MASK 0x7FFF0000
+#define IXGBE_FDIRFREE_COLL_SHIFT 16
+#define IXGBE_FDIRLEN_MAXLEN_MASK 0x3F
+#define IXGBE_FDIRLEN_MAXLEN_SHIFT 0
+#define IXGBE_FDIRLEN_MAXHASH_MASK 0x7FFF0000
+#define IXGBE_FDIRLEN_MAXHASH_SHIFT 16
+#define IXGBE_FDIRUSTAT_ADD_MASK 0xFFFF
+#define IXGBE_FDIRUSTAT_ADD_SHIFT 0
+#define IXGBE_FDIRUSTAT_REMOVE_MASK 0xFFFF0000
+#define IXGBE_FDIRUSTAT_REMOVE_SHIFT 16
+#define IXGBE_FDIRFSTAT_FADD_MASK 0x00FF
+#define IXGBE_FDIRFSTAT_FADD_SHIFT 0
+#define IXGBE_FDIRFSTAT_FREMOVE_MASK 0xFF00
+#define IXGBE_FDIRFSTAT_FREMOVE_SHIFT 8
+#define IXGBE_FDIRPORT_DESTINATION_SHIFT 16
+#define IXGBE_FDIRVLAN_FLEX_SHIFT 16
+#define IXGBE_FDIRHASH_BUCKET_VALID_SHIFT 15
+#define IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT 16
+
+#define IXGBE_FDIRCMD_CMD_MASK 0x00000003
+#define IXGBE_FDIRCMD_CMD_ADD_FLOW 0x00000001
+#define IXGBE_FDIRCMD_CMD_REMOVE_FLOW 0x00000002
+#define IXGBE_FDIRCMD_CMD_QUERY_REM_FILT 0x00000003
+#define IXGBE_FDIRCMD_CMD_QUERY_REM_HASH 0x00000007
+#define IXGBE_FDIRCMD_FILTER_UPDATE 0x00000008
+#define IXGBE_FDIRCMD_IPv6DMATCH 0x00000010
+#define IXGBE_FDIRCMD_L4TYPE_UDP 0x00000020
+#define IXGBE_FDIRCMD_L4TYPE_TCP 0x00000040
+#define IXGBE_FDIRCMD_L4TYPE_SCTP 0x00000060
+#define IXGBE_FDIRCMD_IPV6 0x00000080
+#define IXGBE_FDIRCMD_CLEARHT 0x00000100
+#define IXGBE_FDIRCMD_DROP 0x00000200
+#define IXGBE_FDIRCMD_INT 0x00000400
+#define IXGBE_FDIRCMD_LAST 0x00000800
+#define IXGBE_FDIRCMD_COLLISION 0x00001000
+#define IXGBE_FDIRCMD_QUEUE_EN 0x00008000
+#define IXGBE_FDIRCMD_RX_QUEUE_SHIFT 16
+#define IXGBE_FDIRCMD_VT_POOL_SHIFT 24
+#define IXGBE_FDIR_INIT_DONE_POLL 10
+#define IXGBE_FDIRCMD_CMD_POLL 10
+
/* Transmit Descriptor - Legacy */
struct ixgbe_legacy_tx_desc {
u64 buffer_addr; /* Address of the descriptor's data buffer */
@@ -1836,6 +2019,16 @@ struct ixgbe_adv_tx_context_desc {
#define IXGBE_ADVTXD_POPTS_IPSEC 0x00000400 /* IPSec offload request */
#define IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
#define IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000/* ESP Encrypt Enable */
+#define IXGBE_ADVTXT_TUCMD_FCOE 0x00008000 /* FCoE Frame Type */
+#define IXGBE_ADVTXD_FCOEF_EOF_MASK (0x3 << 10) /* FC EOF index */
+#define IXGBE_ADVTXD_FCOEF_SOF ((1 << 2) << 10) /* FC SOF index */
+#define IXGBE_ADVTXD_FCOEF_PARINC ((1 << 3) << 10) /* Rel_Off in F_CTL */
+#define IXGBE_ADVTXD_FCOEF_ORIE ((1 << 4) << 10) /* Orientation: End */
+#define IXGBE_ADVTXD_FCOEF_ORIS ((1 << 5) << 10) /* Orientation: Start */
+#define IXGBE_ADVTXD_FCOEF_EOF_N (0x0 << 10) /* 00: EOFn */
+#define IXGBE_ADVTXD_FCOEF_EOF_T (0x1 << 10) /* 01: EOFt */
+#define IXGBE_ADVTXD_FCOEF_EOF_NI (0x2 << 10) /* 10: EOFni */
+#define IXGBE_ADVTXD_FCOEF_EOF_A (0x3 << 10) /* 11: EOFa */
#define IXGBE_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
#define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
@@ -1861,7 +2054,7 @@ typedef u32 ixgbe_physical_layer;
#define IXGBE_PHYSICAL_LAYER_UNKNOWN 0
#define IXGBE_PHYSICAL_LAYER_10GBASE_T 0x0001
#define IXGBE_PHYSICAL_LAYER_1000BASE_T 0x0002
-#define IXGBE_PHYSICAL_LAYER_100BASE_T 0x0004
+#define IXGBE_PHYSICAL_LAYER_100BASE_TX 0x0004
#define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU 0x0008
#define IXGBE_PHYSICAL_LAYER_10GBASE_LR 0x0010
#define IXGBE_PHYSICAL_LAYER_10GBASE_LRM 0x0020
@@ -1870,6 +2063,47 @@ typedef u32 ixgbe_physical_layer;
#define IXGBE_PHYSICAL_LAYER_10GBASE_CX4 0x0100
#define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x0200
#define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400
+#define IXGBE_PHYSICAL_LAYER_10GBASE_KR 0x0800
+#define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000
+
+/* Software ATR hash keys */
+#define IXGBE_ATR_BUCKET_HASH_KEY 0xE214AD3D
+#define IXGBE_ATR_SIGNATURE_HASH_KEY 0x14364D17
+
+/* Software ATR input stream offsets and masks */
+#define IXGBE_ATR_VLAN_OFFSET 0
+#define IXGBE_ATR_SRC_IPV6_OFFSET 2
+#define IXGBE_ATR_SRC_IPV4_OFFSET 14
+#define IXGBE_ATR_DST_IPV6_OFFSET 18
+#define IXGBE_ATR_DST_IPV4_OFFSET 30
+#define IXGBE_ATR_SRC_PORT_OFFSET 34
+#define IXGBE_ATR_DST_PORT_OFFSET 36
+#define IXGBE_ATR_FLEX_BYTE_OFFSET 38
+#define IXGBE_ATR_VM_POOL_OFFSET 40
+#define IXGBE_ATR_L4TYPE_OFFSET 41
+
+#define IXGBE_ATR_L4TYPE_MASK 0x3
+#define IXGBE_ATR_L4TYPE_IPV6_MASK 0x4
+#define IXGBE_ATR_L4TYPE_UDP 0x1
+#define IXGBE_ATR_L4TYPE_TCP 0x2
+#define IXGBE_ATR_L4TYPE_SCTP 0x3
+#define IXGBE_ATR_HASH_MASK 0x7fff
+
+/* Flow Director ATR input struct. */
+struct ixgbe_atr_input {
+ /* Byte layout in order, all values with MSB first:
+ *
+ * vlan_id - 2 bytes
+ * src_ip - 16 bytes
+ * dst_ip - 16 bytes
+ * src_port - 2 bytes
+ * dst_port - 2 bytes
+ * flex_bytes - 2 bytes
+ * vm_pool - 1 byte
+ * l4type - 1 byte
+ */
+ u8 byte_stream[42];
+};
enum ixgbe_eeprom_type {
ixgbe_eeprom_uninitialized = 0,
@@ -1897,6 +2131,7 @@ enum ixgbe_phy_type {
ixgbe_phy_sfp_ftl,
ixgbe_phy_sfp_unknown,
ixgbe_phy_sfp_intel,
+ ixgbe_phy_sfp_unsupported,
ixgbe_phy_generic
};
@@ -2005,7 +2240,8 @@ struct ixgbe_fc_info {
u16 pause_time; /* Flow Control Pause timer */
bool send_xon; /* Flow control send XON */
bool strict_ieee; /* Strict IEEE mode */
- bool disable_fc_autoneg; /* Turn off autoneg FC mode */
+ bool disable_fc_autoneg; /* Do not autonegotiate FC */
+ bool fc_was_autonegged; /* Is current_mode the result of autonegging? */
enum ixgbe_fc_mode current_mode; /* FC mode in effect */
enum ixgbe_fc_mode requested_mode; /* FC mode requested by caller */
};
@@ -2075,6 +2311,12 @@ struct ixgbe_hw_stats {
u64 fdirfstat_fremove;
u64 fdirmatch;
u64 fdirmiss;
+ u64 fccrc;
+ u64 fcoerpdc;
+ u64 fcoeprc;
+ u64 fcoeptc;
+ u64 fcoedwrc;
+ u64 fcoedwtc;
};
/* forward declaration */
@@ -2101,6 +2343,8 @@ struct ixgbe_mac_operations {
enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
u32 (*get_supported_physical_layer)(struct ixgbe_hw *);
s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
+ s32 (*get_san_mac_addr)(struct ixgbe_hw *, u8 *);
+ s32 (*get_device_caps)(struct ixgbe_hw *, u16 *);
s32 (*stop_adapter)(struct ixgbe_hw *);
s32 (*get_bus_info)(struct ixgbe_hw *);
void (*set_lan_id)(struct ixgbe_hw *);
@@ -2129,8 +2373,7 @@ struct ixgbe_mac_operations {
s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32);
s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32);
s32 (*init_rx_addrs)(struct ixgbe_hw *);
- s32 (*update_uc_addr_list)(struct ixgbe_hw *, u8 *, u32,
- ixgbe_mc_addr_itr);
+ s32 (*update_uc_addr_list)(struct ixgbe_hw *, struct list_head *);
s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32,
ixgbe_mc_addr_itr);
s32 (*enable_mc)(struct ixgbe_hw *);
@@ -2140,12 +2383,13 @@ struct ixgbe_mac_operations {
s32 (*init_uta_tables)(struct ixgbe_hw *);
/* Flow Control */
- s32 (*setup_fc)(struct ixgbe_hw *, s32);
+ s32 (*fc_enable)(struct ixgbe_hw *, s32);
};
struct ixgbe_phy_operations {
s32 (*identify)(struct ixgbe_hw *);
s32 (*identify_sfp)(struct ixgbe_hw *);
+ s32 (*init)(struct ixgbe_hw *);
s32 (*reset)(struct ixgbe_hw *);
s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *);
s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16);
@@ -2173,6 +2417,7 @@ struct ixgbe_mac_info {
enum ixgbe_mac_type type;
u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
u8 perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
+ u8 san_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
s32 mc_filter_type;
u32 mcft_size;
u32 vft_size;
@@ -2185,14 +2430,16 @@ struct ixgbe_mac_info {
bool orig_link_settings_stored;
bool autoneg;
bool autoneg_succeeded;
+ bool autotry_restart;
};
struct ixgbe_phy_info {
struct ixgbe_phy_operations ops;
+ struct mdio_if_info mdio;
enum ixgbe_phy_type type;
- u32 addr;
u32 id;
enum ixgbe_sfp_type sfp_type;
+ bool sfp_setup_needed;
u32 revision;
enum ixgbe_media_type media_type;
bool reset_disable;
@@ -2249,6 +2496,8 @@ struct ixgbe_info {
#define IXGBE_ERR_SFP_NOT_SUPPORTED -19
#define IXGBE_ERR_SFP_NOT_PRESENT -20
#define IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT -21
+#define IXGBE_ERR_FDIR_REINIT_FAILED -23
+#define IXGBE_ERR_EEPROM_VERSION -24
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
#endif /* _IXGBE_TYPE_H_ */
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
index d3bf2f017cc..2a0174b62e9 100644
--- a/drivers/net/ixp2000/ixpdev.c
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -270,6 +270,18 @@ static int ixpdev_close(struct net_device *dev)
return 0;
}
+static const struct net_device_ops ixpdev_netdev_ops = {
+ .ndo_open = ixpdev_open,
+ .ndo_stop = ixpdev_close,
+ .ndo_start_xmit = ixpdev_xmit,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ixpdev_poll_controller,
+#endif
+};
+
struct net_device *ixpdev_alloc(int channel, int sizeof_priv)
{
struct net_device *dev;
@@ -279,12 +291,7 @@ struct net_device *ixpdev_alloc(int channel, int sizeof_priv)
if (dev == NULL)
return NULL;
- dev->hard_start_xmit = ixpdev_xmit;
- dev->open = ixpdev_open;
- dev->stop = ixpdev_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ixpdev_poll_controller;
-#endif
+ dev->netdev_ops = &ixpdev_netdev_ops;
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index 14248cfc3df..d12106b47bf 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -96,6 +96,18 @@ static int jazzsonic_close(struct net_device* dev)
return err;
}
+static const struct net_device_ops sonic_netdev_ops = {
+ .ndo_open = jazzsonic_open,
+ .ndo_stop = jazzsonic_close,
+ .ndo_start_xmit = sonic_send_packet,
+ .ndo_get_stats = sonic_get_stats,
+ .ndo_set_multicast_list = sonic_multicast_list,
+ .ndo_tx_timeout = sonic_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int __init sonic_probe1(struct net_device *dev)
{
static unsigned version_printed;
@@ -179,12 +191,7 @@ static int __init sonic_probe1(struct net_device *dev)
lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
* SONIC_BUS_SCALE(lp->dma_bitmode));
- dev->open = jazzsonic_open;
- dev->stop = jazzsonic_close;
- dev->hard_start_xmit = sonic_send_packet;
- dev->get_stats = sonic_get_stats;
- dev->set_multicast_list = &sonic_multicast_list;
- dev->tx_timeout = sonic_tx_timeout;
+ dev->netdev_ops = &sonic_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
/*
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index 621a7c0c46b..1e3c63d67b9 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -1939,7 +1939,6 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev)
TXCS_SELECT_QUEUE0 |
TXCS_QUEUE0S |
TXCS_ENABLE);
- netdev->trans_start = jiffies;
tx_dbg(jme, "xmit: %d+%d@%lu\n", idx,
skb_shinfo(skb)->nr_frags + 2,
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index 38d6649a29c..b4cf602c32b 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -133,6 +133,7 @@ struct korina_private {
int dma_halt_cnt;
int dma_run_cnt;
struct napi_struct napi;
+ struct timer_list media_check_timer;
struct mii_if_info mii_if;
struct net_device *dev;
int phy_addr;
@@ -664,6 +665,15 @@ static void korina_check_media(struct net_device *dev, unsigned int init_media)
&lp->eth_regs->ethmac2);
}
+static void korina_poll_media(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *) data;
+ struct korina_private *lp = netdev_priv(dev);
+
+ korina_check_media(dev, 0);
+ mod_timer(&lp->media_check_timer, jiffies + HZ);
+}
+
static void korina_set_carrier(struct mii_if_info *mii)
{
if (mii->force_media) {
@@ -1034,6 +1044,7 @@ static int korina_open(struct net_device *dev)
dev->name, lp->und_irq);
goto err_free_ovr_irq;
}
+ mod_timer(&lp->media_check_timer, jiffies + 1);
out:
return ret;
@@ -1053,6 +1064,8 @@ static int korina_close(struct net_device *dev)
struct korina_private *lp = netdev_priv(dev);
u32 tmp;
+ del_timer(&lp->media_check_timer);
+
/* Disable interrupts */
disable_irq(lp->rx_irq);
disable_irq(lp->tx_irq);
@@ -1081,6 +1094,21 @@ static int korina_close(struct net_device *dev)
return 0;
}
+static const struct net_device_ops korina_netdev_ops = {
+ .ndo_open = korina_open,
+ .ndo_stop = korina_close,
+ .ndo_start_xmit = korina_send_packet,
+ .ndo_set_multicast_list = korina_multicast_list,
+ .ndo_tx_timeout = korina_tx_timeout,
+ .ndo_do_ioctl = korina_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = korina_poll_controller,
+#endif
+};
+
static int korina_probe(struct platform_device *pdev)
{
struct korina_device *bif = platform_get_drvdata(pdev);
@@ -1149,17 +1177,9 @@ static int korina_probe(struct platform_device *pdev)
dev->irq = lp->rx_irq;
lp->dev = dev;
- dev->open = korina_open;
- dev->stop = korina_close;
- dev->hard_start_xmit = korina_send_packet;
- dev->set_multicast_list = &korina_multicast_list;
+ dev->netdev_ops = &korina_netdev_ops;
dev->ethtool_ops = &netdev_ethtool_ops;
- dev->tx_timeout = korina_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
- dev->do_ioctl = &korina_ioctl;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = korina_poll_controller;
-#endif
netif_napi_add(dev, &lp->napi, korina_poll, 64);
lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05);
@@ -1176,6 +1196,7 @@ static int korina_probe(struct platform_device *pdev)
": cannot register net device %d\n", rc);
goto probe_err_register;
}
+ setup_timer(&lp->media_check_timer, korina_poll_media, (unsigned long) dev);
out:
return rc;
diff --git a/drivers/net/ks8842.c b/drivers/net/ks8842.c
new file mode 100644
index 00000000000..39b0aea2aab
--- /dev/null
+++ b/drivers/net/ks8842.c
@@ -0,0 +1,732 @@
+/*
+ * ks8842_main.c timberdale KS8842 ethernet driver
+ * Copyright (c) 2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * The Micrel KS8842 behind the timberdale FPGA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+
+#define DRV_NAME "ks8842"
+
+/* Timberdale specific Registers */
+#define REG_TIMB_RST 0x1c
+
+/* KS8842 registers */
+
+#define REG_SELECT_BANK 0x0e
+
+/* bank 0 registers */
+#define REG_QRFCR 0x04
+
+/* bank 2 registers */
+#define REG_MARL 0x00
+#define REG_MARM 0x02
+#define REG_MARH 0x04
+
+/* bank 3 registers */
+#define REG_GRR 0x06
+
+/* bank 16 registers */
+#define REG_TXCR 0x00
+#define REG_TXSR 0x02
+#define REG_RXCR 0x04
+#define REG_TXMIR 0x08
+#define REG_RXMIR 0x0A
+
+/* bank 17 registers */
+#define REG_TXQCR 0x00
+#define REG_RXQCR 0x02
+#define REG_TXFDPR 0x04
+#define REG_RXFDPR 0x06
+#define REG_QMU_DATA_LO 0x08
+#define REG_QMU_DATA_HI 0x0A
+
+/* bank 18 registers */
+#define REG_IER 0x00
+#define IRQ_LINK_CHANGE 0x8000
+#define IRQ_TX 0x4000
+#define IRQ_RX 0x2000
+#define IRQ_RX_OVERRUN 0x0800
+#define IRQ_TX_STOPPED 0x0200
+#define IRQ_RX_STOPPED 0x0100
+#define IRQ_RX_ERROR 0x0080
+#define ENABLED_IRQS (IRQ_LINK_CHANGE | IRQ_TX | IRQ_RX | IRQ_RX_STOPPED | \
+ IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR)
+#define REG_ISR 0x02
+#define REG_RXSR 0x04
+#define RXSR_VALID 0x8000
+#define RXSR_BROADCAST 0x80
+#define RXSR_MULTICAST 0x40
+#define RXSR_UNICAST 0x20
+#define RXSR_FRAMETYPE 0x08
+#define RXSR_TOO_LONG 0x04
+#define RXSR_RUNT 0x02
+#define RXSR_CRC_ERROR 0x01
+#define RXSR_ERROR (RXSR_TOO_LONG | RXSR_RUNT | RXSR_CRC_ERROR)
+
+/* bank 32 registers */
+#define REG_SW_ID_AND_ENABLE 0x00
+#define REG_SGCR1 0x02
+#define REG_SGCR2 0x04
+#define REG_SGCR3 0x06
+
+/* bank 39 registers */
+#define REG_MACAR1 0x00
+#define REG_MACAR2 0x02
+#define REG_MACAR3 0x04
+
+/* bank 45 registers */
+#define REG_P1MBCR 0x00
+#define REG_P1MBSR 0x02
+
+/* bank 46 registers */
+#define REG_P2MBCR 0x00
+#define REG_P2MBSR 0x02
+
+/* bank 48 registers */
+#define REG_P1CR2 0x02
+
+/* bank 49 registers */
+#define REG_P1CR4 0x02
+#define REG_P1SR 0x04
+
+struct ks8842_adapter {
+ void __iomem *hw_addr;
+ int irq;
+ struct tasklet_struct tasklet;
+ spinlock_t lock; /* spinlock to be interrupt safe */
+ struct platform_device *pdev;
+};
+
+static inline void ks8842_select_bank(struct ks8842_adapter *adapter, u16 bank)
+{
+ iowrite16(bank, adapter->hw_addr + REG_SELECT_BANK);
+}
+
+static inline void ks8842_write8(struct ks8842_adapter *adapter, u16 bank,
+ u8 value, int offset)
+{
+ ks8842_select_bank(adapter, bank);
+ iowrite8(value, adapter->hw_addr + offset);
+}
+
+static inline void ks8842_write16(struct ks8842_adapter *adapter, u16 bank,
+ u16 value, int offset)
+{
+ ks8842_select_bank(adapter, bank);
+ iowrite16(value, adapter->hw_addr + offset);
+}
+
+static inline void ks8842_enable_bits(struct ks8842_adapter *adapter, u16 bank,
+ u16 bits, int offset)
+{
+ u16 reg;
+ ks8842_select_bank(adapter, bank);
+ reg = ioread16(adapter->hw_addr + offset);
+ reg |= bits;
+ iowrite16(reg, adapter->hw_addr + offset);
+}
+
+static inline void ks8842_clear_bits(struct ks8842_adapter *adapter, u16 bank,
+ u16 bits, int offset)
+{
+ u16 reg;
+ ks8842_select_bank(adapter, bank);
+ reg = ioread16(adapter->hw_addr + offset);
+ reg &= ~bits;
+ iowrite16(reg, adapter->hw_addr + offset);
+}
+
+static inline void ks8842_write32(struct ks8842_adapter *adapter, u16 bank,
+ u32 value, int offset)
+{
+ ks8842_select_bank(adapter, bank);
+ iowrite32(value, adapter->hw_addr + offset);
+}
+
+static inline u8 ks8842_read8(struct ks8842_adapter *adapter, u16 bank,
+ int offset)
+{
+ ks8842_select_bank(adapter, bank);
+ return ioread8(adapter->hw_addr + offset);
+}
+
+static inline u16 ks8842_read16(struct ks8842_adapter *adapter, u16 bank,
+ int offset)
+{
+ ks8842_select_bank(adapter, bank);
+ return ioread16(adapter->hw_addr + offset);
+}
+
+static inline u32 ks8842_read32(struct ks8842_adapter *adapter, u16 bank,
+ int offset)
+{
+ ks8842_select_bank(adapter, bank);
+ return ioread32(adapter->hw_addr + offset);
+}
+
+static void ks8842_reset(struct ks8842_adapter *adapter)
+{
+ /* The KS8842 goes haywire when doing softare reset
+ * a work around in the timberdale IP is implemented to
+ * do a hardware reset instead
+ ks8842_write16(adapter, 3, 1, REG_GRR);
+ msleep(10);
+ iowrite16(0, adapter->hw_addr + REG_GRR);
+ */
+ iowrite16(32, adapter->hw_addr + REG_SELECT_BANK);
+ iowrite32(0x1, adapter->hw_addr + REG_TIMB_RST);
+ msleep(20);
+}
+
+static void ks8842_update_link_status(struct net_device *netdev,
+ struct ks8842_adapter *adapter)
+{
+ /* check the status of the link */
+ if (ks8842_read16(adapter, 45, REG_P1MBSR) & 0x4) {
+ netif_carrier_on(netdev);
+ netif_wake_queue(netdev);
+ } else {
+ netif_stop_queue(netdev);
+ netif_carrier_off(netdev);
+ }
+}
+
+static void ks8842_enable_tx(struct ks8842_adapter *adapter)
+{
+ ks8842_enable_bits(adapter, 16, 0x01, REG_TXCR);
+}
+
+static void ks8842_disable_tx(struct ks8842_adapter *adapter)
+{
+ ks8842_clear_bits(adapter, 16, 0x01, REG_TXCR);
+}
+
+static void ks8842_enable_rx(struct ks8842_adapter *adapter)
+{
+ ks8842_enable_bits(adapter, 16, 0x01, REG_RXCR);
+}
+
+static void ks8842_disable_rx(struct ks8842_adapter *adapter)
+{
+ ks8842_clear_bits(adapter, 16, 0x01, REG_RXCR);
+}
+
+static void ks8842_reset_hw(struct ks8842_adapter *adapter)
+{
+ /* reset the HW */
+ ks8842_reset(adapter);
+
+ /* Enable QMU Transmit flow control / transmit padding / Transmit CRC */
+ ks8842_write16(adapter, 16, 0x000E, REG_TXCR);
+
+ /* enable the receiver, uni + multi + broadcast + flow ctrl
+ + crc strip */
+ ks8842_write16(adapter, 16, 0x8 | 0x20 | 0x40 | 0x80 | 0x400,
+ REG_RXCR);
+
+ /* TX frame pointer autoincrement */
+ ks8842_write16(adapter, 17, 0x4000, REG_TXFDPR);
+
+ /* RX frame pointer autoincrement */
+ ks8842_write16(adapter, 17, 0x4000, REG_RXFDPR);
+
+ /* RX 2 kb high watermark */
+ ks8842_write16(adapter, 0, 0x1000, REG_QRFCR);
+
+ /* aggresive back off in half duplex */
+ ks8842_enable_bits(adapter, 32, 1 << 8, REG_SGCR1);
+
+ /* enable no excessive collison drop */
+ ks8842_enable_bits(adapter, 32, 1 << 3, REG_SGCR2);
+
+ /* Enable port 1 force flow control / back pressure / transmit / recv */
+ ks8842_write16(adapter, 48, 0x1E07, REG_P1CR2);
+
+ /* restart port auto-negotiation */
+ ks8842_enable_bits(adapter, 49, 1 << 13, REG_P1CR4);
+ /* only advertise 10Mbps */
+ ks8842_clear_bits(adapter, 49, 3 << 2, REG_P1CR4);
+
+ /* Enable the transmitter */
+ ks8842_enable_tx(adapter);
+
+ /* Enable the receiver */
+ ks8842_enable_rx(adapter);
+
+ /* clear all interrupts */
+ ks8842_write16(adapter, 18, 0xffff, REG_ISR);
+
+ /* enable interrupts */
+ ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
+
+ /* enable the switch */
+ ks8842_write16(adapter, 32, 0x1, REG_SW_ID_AND_ENABLE);
+}
+
+static void ks8842_read_mac_addr(struct ks8842_adapter *adapter, u8 *dest)
+{
+ int i;
+ u16 mac;
+
+ for (i = 0; i < ETH_ALEN; i++)
+ dest[ETH_ALEN - i - 1] = ks8842_read8(adapter, 2, REG_MARL + i);
+
+ /* make sure the switch port uses the same MAC as the QMU */
+ mac = ks8842_read16(adapter, 2, REG_MARL);
+ ks8842_write16(adapter, 39, mac, REG_MACAR1);
+ mac = ks8842_read16(adapter, 2, REG_MARM);
+ ks8842_write16(adapter, 39, mac, REG_MACAR2);
+ mac = ks8842_read16(adapter, 2, REG_MARH);
+ ks8842_write16(adapter, 39, mac, REG_MACAR3);
+}
+
+static inline u16 ks8842_tx_fifo_space(struct ks8842_adapter *adapter)
+{
+ return ks8842_read16(adapter, 16, REG_TXMIR) & 0x1fff;
+}
+
+static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct ks8842_adapter *adapter = netdev_priv(netdev);
+ int len = skb->len;
+ u32 *ptr = (u32 *)skb->data;
+ u32 ctrl;
+
+ dev_dbg(&adapter->pdev->dev,
+ "%s: len %u head %p data %p tail %p end %p\n",
+ __func__, skb->len, skb->head, skb->data,
+ skb_tail_pointer(skb), skb_end_pointer(skb));
+
+ /* check FIFO buffer space, we need space for CRC and command bits */
+ if (ks8842_tx_fifo_space(adapter) < len + 8)
+ return NETDEV_TX_BUSY;
+
+ /* the control word, enable IRQ, port 1 and the length */
+ ctrl = 0x8000 | 0x100 | (len << 16);
+ ks8842_write32(adapter, 17, ctrl, REG_QMU_DATA_LO);
+
+ netdev->stats.tx_bytes += len;
+
+ /* copy buffer */
+ while (len > 0) {
+ iowrite32(*ptr, adapter->hw_addr + REG_QMU_DATA_LO);
+ len -= sizeof(u32);
+ ptr++;
+ }
+
+ /* enqueue packet */
+ ks8842_write16(adapter, 17, 1, REG_TXQCR);
+
+ dev_kfree_skb(skb);
+
+ return NETDEV_TX_OK;
+}
+
+static void ks8842_rx_frame(struct net_device *netdev,
+ struct ks8842_adapter *adapter)
+{
+ u32 status = ks8842_read32(adapter, 17, REG_QMU_DATA_LO);
+ int len = (status >> 16) & 0x7ff;
+
+ status &= 0xffff;
+
+ dev_dbg(&adapter->pdev->dev, "%s - rx_data: status: %x\n",
+ __func__, status);
+
+ /* check the status */
+ if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) {
+ struct sk_buff *skb = netdev_alloc_skb(netdev, len + 2);
+
+ dev_dbg(&adapter->pdev->dev, "%s, got package, len: %d\n",
+ __func__, len);
+ if (skb) {
+ u32 *data;
+
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += len;
+ if (status & RXSR_MULTICAST)
+ netdev->stats.multicast++;
+
+ /* Align socket buffer in 4-byte boundary for
+ better performance. */
+ skb_reserve(skb, 2);
+ data = (u32 *)skb_put(skb, len);
+
+ ks8842_select_bank(adapter, 17);
+ while (len > 0) {
+ *data++ = ioread32(adapter->hw_addr +
+ REG_QMU_DATA_LO);
+ len -= sizeof(u32);
+ }
+
+ skb->protocol = eth_type_trans(skb, netdev);
+ netif_rx(skb);
+ } else
+ netdev->stats.rx_dropped++;
+ } else {
+ dev_dbg(&adapter->pdev->dev, "RX error, status: %x\n", status);
+ netdev->stats.rx_errors++;
+ if (status & RXSR_TOO_LONG)
+ netdev->stats.rx_length_errors++;
+ if (status & RXSR_CRC_ERROR)
+ netdev->stats.rx_crc_errors++;
+ if (status & RXSR_RUNT)
+ netdev->stats.rx_frame_errors++;
+ }
+
+ /* set high watermark to 3K */
+ ks8842_clear_bits(adapter, 0, 1 << 12, REG_QRFCR);
+
+ /* release the frame */
+ ks8842_write16(adapter, 17, 0x01, REG_RXQCR);
+
+ /* set high watermark to 2K */
+ ks8842_enable_bits(adapter, 0, 1 << 12, REG_QRFCR);
+}
+
+void ks8842_handle_rx(struct net_device *netdev, struct ks8842_adapter *adapter)
+{
+ u16 rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff;
+ dev_dbg(&adapter->pdev->dev, "%s Entry - rx_data: %d\n",
+ __func__, rx_data);
+ while (rx_data) {
+ ks8842_rx_frame(netdev, adapter);
+ rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff;
+ }
+}
+
+void ks8842_handle_tx(struct net_device *netdev, struct ks8842_adapter *adapter)
+{
+ u16 sr = ks8842_read16(adapter, 16, REG_TXSR);
+ dev_dbg(&adapter->pdev->dev, "%s - entry, sr: %x\n", __func__, sr);
+ netdev->stats.tx_packets++;
+ if (netif_queue_stopped(netdev))
+ netif_wake_queue(netdev);
+}
+
+void ks8842_handle_rx_overrun(struct net_device *netdev,
+ struct ks8842_adapter *adapter)
+{
+ dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__);
+ netdev->stats.rx_errors++;
+ netdev->stats.rx_fifo_errors++;
+}
+
+void ks8842_tasklet(unsigned long arg)
+{
+ struct net_device *netdev = (struct net_device *)arg;
+ struct ks8842_adapter *adapter = netdev_priv(netdev);
+ u16 isr;
+ unsigned long flags;
+ u16 entry_bank;
+
+ /* read current bank to be able to set it back */
+ spin_lock_irqsave(&adapter->lock, flags);
+ entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK);
+ spin_unlock_irqrestore(&adapter->lock, flags);
+
+ isr = ks8842_read16(adapter, 18, REG_ISR);
+ dev_dbg(&adapter->pdev->dev, "%s - ISR: 0x%x\n", __func__, isr);
+
+ /* Ack */
+ ks8842_write16(adapter, 18, isr, REG_ISR);
+
+ if (!netif_running(netdev))
+ return;
+
+ if (isr & IRQ_LINK_CHANGE)
+ ks8842_update_link_status(netdev, adapter);
+
+ if (isr & (IRQ_RX | IRQ_RX_ERROR))
+ ks8842_handle_rx(netdev, adapter);
+
+ if (isr & IRQ_TX)
+ ks8842_handle_tx(netdev, adapter);
+
+ if (isr & IRQ_RX_OVERRUN)
+ ks8842_handle_rx_overrun(netdev, adapter);
+
+ if (isr & IRQ_TX_STOPPED) {
+ ks8842_disable_tx(adapter);
+ ks8842_enable_tx(adapter);
+ }
+
+ if (isr & IRQ_RX_STOPPED) {
+ ks8842_disable_rx(adapter);
+ ks8842_enable_rx(adapter);
+ }
+
+ /* re-enable interrupts, put back the bank selection register */
+ spin_lock_irqsave(&adapter->lock, flags);
+ ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
+ iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK);
+ spin_unlock_irqrestore(&adapter->lock, flags);
+}
+
+static irqreturn_t ks8842_irq(int irq, void *devid)
+{
+ struct ks8842_adapter *adapter = devid;
+ u16 isr;
+ u16 entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK);
+ irqreturn_t ret = IRQ_NONE;
+
+ isr = ks8842_read16(adapter, 18, REG_ISR);
+ dev_dbg(&adapter->pdev->dev, "%s - ISR: 0x%x\n", __func__, isr);
+
+ if (isr) {
+ /* disable IRQ */
+ ks8842_write16(adapter, 18, 0x00, REG_IER);
+
+ /* schedule tasklet */
+ tasklet_schedule(&adapter->tasklet);
+
+ ret = IRQ_HANDLED;
+ }
+
+ iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK);
+
+ return ret;
+}
+
+
+/* Netdevice operations */
+
+static int ks8842_open(struct net_device *netdev)
+{
+ struct ks8842_adapter *adapter = netdev_priv(netdev);
+ int err;
+
+ dev_dbg(&adapter->pdev->dev, "%s - entry\n", __func__);
+
+ /* reset the HW */
+ ks8842_reset_hw(adapter);
+
+ ks8842_update_link_status(netdev, adapter);
+
+ err = request_irq(adapter->irq, ks8842_irq, IRQF_SHARED, DRV_NAME,
+ adapter);
+ if (err) {
+ printk(KERN_ERR "Failed to request IRQ: %d: %d\n",
+ adapter->irq, err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int ks8842_close(struct net_device *netdev)
+{
+ struct ks8842_adapter *adapter = netdev_priv(netdev);
+
+ dev_dbg(&adapter->pdev->dev, "%s - entry\n", __func__);
+
+ /* free the irq */
+ free_irq(adapter->irq, adapter);
+
+ /* disable the switch */
+ ks8842_write16(adapter, 32, 0x0, REG_SW_ID_AND_ENABLE);
+
+ return 0;
+}
+
+static int ks8842_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+ int ret;
+ struct ks8842_adapter *adapter = netdev_priv(netdev);
+
+ dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__);
+
+ ret = ks8842_tx_frame(skb, netdev);
+
+ if (ks8842_tx_fifo_space(adapter) < netdev->mtu + 8)
+ netif_stop_queue(netdev);
+
+ return ret;
+}
+
+static int ks8842_set_mac(struct net_device *netdev, void *p)
+{
+ struct ks8842_adapter *adapter = netdev_priv(netdev);
+ unsigned long flags;
+ struct sockaddr *addr = p;
+ char *mac = (u8 *)addr->sa_data;
+ int i;
+
+ dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__);
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(netdev->dev_addr, mac, netdev->addr_len);
+
+ spin_lock_irqsave(&adapter->lock, flags);
+ for (i = 0; i < ETH_ALEN; i++) {
+ ks8842_write8(adapter, 2, mac[ETH_ALEN - i - 1], REG_MARL + i);
+ ks8842_write8(adapter, 39, mac[ETH_ALEN - i - 1],
+ REG_MACAR1 + i);
+ }
+ spin_unlock_irqrestore(&adapter->lock, flags);
+ return 0;
+}
+
+static void ks8842_tx_timeout(struct net_device *netdev)
+{
+ struct ks8842_adapter *adapter = netdev_priv(netdev);
+ unsigned long flags;
+
+ dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__);
+
+ spin_lock_irqsave(&adapter->lock, flags);
+ /* disable interrupts */
+ ks8842_write16(adapter, 18, 0, REG_IER);
+ ks8842_write16(adapter, 18, 0xFFFF, REG_ISR);
+ spin_unlock_irqrestore(&adapter->lock, flags);
+
+ ks8842_reset_hw(adapter);
+
+ ks8842_update_link_status(netdev, adapter);
+}
+
+static const struct net_device_ops ks8842_netdev_ops = {
+ .ndo_open = ks8842_open,
+ .ndo_stop = ks8842_close,
+ .ndo_start_xmit = ks8842_xmit_frame,
+ .ndo_set_mac_address = ks8842_set_mac,
+ .ndo_tx_timeout = ks8842_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr
+};
+
+static struct ethtool_ops ks8842_ethtool_ops = {
+ .get_link = ethtool_op_get_link,
+};
+
+static int __devinit ks8842_probe(struct platform_device *pdev)
+{
+ int err = -ENOMEM;
+ struct resource *iomem;
+ struct net_device *netdev;
+ struct ks8842_adapter *adapter;
+ u16 id;
+
+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!request_mem_region(iomem->start, resource_size(iomem), DRV_NAME))
+ goto err_mem_region;
+
+ netdev = alloc_etherdev(sizeof(struct ks8842_adapter));
+ if (!netdev)
+ goto err_alloc_etherdev;
+
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+
+ adapter = netdev_priv(netdev);
+ adapter->hw_addr = ioremap(iomem->start, resource_size(iomem));
+ if (!adapter->hw_addr)
+ goto err_ioremap;
+
+ adapter->irq = platform_get_irq(pdev, 0);
+ if (adapter->irq < 0) {
+ err = adapter->irq;
+ goto err_get_irq;
+ }
+
+ adapter->pdev = pdev;
+
+ tasklet_init(&adapter->tasklet, ks8842_tasklet, (unsigned long)netdev);
+ spin_lock_init(&adapter->lock);
+
+ netdev->netdev_ops = &ks8842_netdev_ops;
+ netdev->ethtool_ops = &ks8842_ethtool_ops;
+
+ ks8842_read_mac_addr(adapter, netdev->dev_addr);
+
+ id = ks8842_read16(adapter, 32, REG_SW_ID_AND_ENABLE);
+
+ strcpy(netdev->name, "eth%d");
+ err = register_netdev(netdev);
+ if (err)
+ goto err_register;
+
+ platform_set_drvdata(pdev, netdev);
+
+ printk(KERN_INFO DRV_NAME
+ " Found chip, family: 0x%x, id: 0x%x, rev: 0x%x\n",
+ (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7);
+
+ return 0;
+
+err_register:
+err_get_irq:
+ iounmap(adapter->hw_addr);
+err_ioremap:
+ free_netdev(netdev);
+err_alloc_etherdev:
+ release_mem_region(iomem->start, resource_size(iomem));
+err_mem_region:
+ return err;
+}
+
+static int __devexit ks8842_remove(struct platform_device *pdev)
+{
+ struct net_device *netdev = platform_get_drvdata(pdev);
+ struct ks8842_adapter *adapter = netdev_priv(netdev);
+ struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ unregister_netdev(netdev);
+ tasklet_kill(&adapter->tasklet);
+ iounmap(adapter->hw_addr);
+ free_netdev(netdev);
+ release_mem_region(iomem->start, resource_size(iomem));
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+
+static struct platform_driver ks8842_platform_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = ks8842_probe,
+ .remove = ks8842_remove,
+};
+
+static int __init ks8842_init(void)
+{
+ return platform_driver_register(&ks8842_platform_driver);
+}
+
+static void __exit ks8842_exit(void)
+{
+ platform_driver_unregister(&ks8842_platform_driver);
+}
+
+module_init(ks8842_init);
+module_exit(ks8842_exit);
+
+MODULE_DESCRIPTION("Timberdale KS8842 ethernet driver");
+MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:ks8842");
+
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
index efbae4b8398..a0c578585a5 100644
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -161,12 +161,12 @@ lan_init_chip(struct parisc_device *dev)
if (!dev->irq) {
printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n",
- __FILE__, dev->hpa.start);
+ __FILE__, (unsigned long)dev->hpa.start);
return -ENODEV;
}
- printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa.start,
- dev->irq);
+ printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n",
+ (unsigned long)dev->hpa.start, dev->irq);
netdevice = alloc_etherdev(sizeof(struct i596_private));
if (!netdevice)
diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c
index 7415f517491..070fa450087 100644
--- a/drivers/net/lib82596.c
+++ b/drivers/net/lib82596.c
@@ -1036,6 +1036,19 @@ static void print_eth(unsigned char *add, char *str)
printk(KERN_DEBUG "i596 0x%p, %pM --> %pM %02X%02X, %s\n",
add, add + 6, add, add[12], add[13], str);
}
+static const struct net_device_ops i596_netdev_ops = {
+ .ndo_open = i596_open,
+ .ndo_stop = i596_close,
+ .ndo_start_xmit = i596_start_xmit,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_tx_timeout = i596_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = i596_poll_controller,
+#endif
+};
static int __devinit i82596_probe(struct net_device *dev)
{
@@ -1062,16 +1075,8 @@ static int __devinit i82596_probe(struct net_device *dev)
return -ENOMEM;
}
- /* The 82596-specific entries in the device structure. */
- dev->open = i596_open;
- dev->stop = i596_close;
- dev->hard_start_xmit = i596_start_xmit;
- dev->set_multicast_list = set_multicast_list;
- dev->tx_timeout = i596_tx_timeout;
+ dev->netdev_ops = &i596_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = i596_poll_controller;
-#endif
memset(dma, 0, sizeof(struct i596_dma));
lp->dma = dma;
diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c
index 789b6cb744b..f28c2334300 100644
--- a/drivers/net/lib8390.c
+++ b/drivers/net/lib8390.c
@@ -370,7 +370,7 @@ static int __ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock(&ei_local->page_lock);
enable_irq_lockdep_irqrestore(dev->irq, &flags);
dev->stats.tx_errors++;
- return 1;
+ return NETDEV_TX_BUSY;
}
/*
diff --git a/drivers/net/ll_temac.h b/drivers/net/ll_temac.h
new file mode 100644
index 00000000000..1af66a1e691
--- /dev/null
+++ b/drivers/net/ll_temac.h
@@ -0,0 +1,374 @@
+
+#ifndef XILINX_LL_TEMAC_H
+#define XILINX_LL_TEMAC_H
+
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/spinlock.h>
+#include <asm/dcr.h>
+#include <asm/dcr-regs.h>
+
+/* packet size info */
+#define XTE_HDR_SIZE 14 /* size of Ethernet header */
+#define XTE_TRL_SIZE 4 /* size of Ethernet trailer (FCS) */
+#define XTE_JUMBO_MTU 9000
+#define XTE_MAX_JUMBO_FRAME_SIZE (XTE_JUMBO_MTU + XTE_HDR_SIZE + XTE_TRL_SIZE)
+
+/* Configuration options */
+
+/* Accept all incoming packets.
+ * This option defaults to disabled (cleared) */
+#define XTE_OPTION_PROMISC (1 << 0)
+/* Jumbo frame support for Tx & Rx.
+ * This option defaults to disabled (cleared) */
+#define XTE_OPTION_JUMBO (1 << 1)
+/* VLAN Rx & Tx frame support.
+ * This option defaults to disabled (cleared) */
+#define XTE_OPTION_VLAN (1 << 2)
+/* Enable recognition of flow control frames on Rx
+ * This option defaults to enabled (set) */
+#define XTE_OPTION_FLOW_CONTROL (1 << 4)
+/* Strip FCS and PAD from incoming frames.
+ * Note: PAD from VLAN frames is not stripped.
+ * This option defaults to disabled (set) */
+#define XTE_OPTION_FCS_STRIP (1 << 5)
+/* Generate FCS field and add PAD automatically for outgoing frames.
+ * This option defaults to enabled (set) */
+#define XTE_OPTION_FCS_INSERT (1 << 6)
+/* Enable Length/Type error checking for incoming frames. When this option is
+set, the MAC will filter frames that have a mismatched type/length field
+and if XTE_OPTION_REPORT_RXERR is set, the user is notified when these
+types of frames are encountered. When this option is cleared, the MAC will
+allow these types of frames to be received.
+This option defaults to enabled (set) */
+#define XTE_OPTION_LENTYPE_ERR (1 << 7)
+/* Enable the transmitter.
+ * This option defaults to enabled (set) */
+#define XTE_OPTION_TXEN (1 << 11)
+/* Enable the receiver
+* This option defaults to enabled (set) */
+#define XTE_OPTION_RXEN (1 << 12)
+
+/* Default options set when device is initialized or reset */
+#define XTE_OPTION_DEFAULTS \
+ (XTE_OPTION_TXEN | \
+ XTE_OPTION_FLOW_CONTROL | \
+ XTE_OPTION_RXEN)
+
+/* XPS_LL_TEMAC SDMA registers definition */
+
+#define TX_NXTDESC_PTR 0x00 /* r */
+#define TX_CURBUF_ADDR 0x01 /* r */
+#define TX_CURBUF_LENGTH 0x02 /* r */
+#define TX_CURDESC_PTR 0x03 /* rw */
+#define TX_TAILDESC_PTR 0x04 /* rw */
+#define TX_CHNL_CTRL 0x05 /* rw */
+/*
+ 0:7 24:31 IRQTimeout
+ 8:15 16:23 IRQCount
+ 16:20 11:15 Reserved
+ 21 10 0
+ 22 9 UseIntOnEnd
+ 23 8 LdIRQCnt
+ 24 7 IRQEn
+ 25:28 3:6 Reserved
+ 29 2 IrqErrEn
+ 30 1 IrqDlyEn
+ 31 0 IrqCoalEn
+*/
+#define CHNL_CTRL_IRQ_IOE (1 << 9)
+#define CHNL_CTRL_IRQ_EN (1 << 7)
+#define CHNL_CTRL_IRQ_ERR_EN (1 << 2)
+#define CHNL_CTRL_IRQ_DLY_EN (1 << 1)
+#define CHNL_CTRL_IRQ_COAL_EN (1 << 0)
+#define TX_IRQ_REG 0x06 /* rw */
+/*
+ 0:7 24:31 DltTmrValue
+ 8:15 16:23 ClscCntrValue
+ 16:17 14:15 Reserved
+ 18:21 10:13 ClscCnt
+ 22:23 8:9 DlyCnt
+ 24:28 3::7 Reserved
+ 29 2 ErrIrq
+ 30 1 DlyIrq
+ 31 0 CoalIrq
+ */
+#define TX_CHNL_STS 0x07 /* r */
+/*
+ 0:9 22:31 Reserved
+ 10 21 TailPErr
+ 11 20 CmpErr
+ 12 19 AddrErr
+ 13 18 NxtPErr
+ 14 17 CurPErr
+ 15 16 BsyWr
+ 16:23 8:15 Reserved
+ 24 7 Error
+ 25 6 IOE
+ 26 5 SOE
+ 27 4 Cmplt
+ 28 3 SOP
+ 29 2 EOP
+ 30 1 EngBusy
+ 31 0 Reserved
+*/
+
+#define RX_NXTDESC_PTR 0x08 /* r */
+#define RX_CURBUF_ADDR 0x09 /* r */
+#define RX_CURBUF_LENGTH 0x0a /* r */
+#define RX_CURDESC_PTR 0x0b /* rw */
+#define RX_TAILDESC_PTR 0x0c /* rw */
+#define RX_CHNL_CTRL 0x0d /* rw */
+/*
+ 0:7 24:31 IRQTimeout
+ 8:15 16:23 IRQCount
+ 16:20 11:15 Reserved
+ 21 10 0
+ 22 9 UseIntOnEnd
+ 23 8 LdIRQCnt
+ 24 7 IRQEn
+ 25:28 3:6 Reserved
+ 29 2 IrqErrEn
+ 30 1 IrqDlyEn
+ 31 0 IrqCoalEn
+ */
+#define RX_IRQ_REG 0x0e /* rw */
+#define IRQ_COAL (1 << 0)
+#define IRQ_DLY (1 << 1)
+#define IRQ_ERR (1 << 2)
+#define IRQ_DMAERR (1 << 7) /* this is not documented ??? */
+/*
+ 0:7 24:31 DltTmrValue
+ 8:15 16:23 ClscCntrValue
+ 16:17 14:15 Reserved
+ 18:21 10:13 ClscCnt
+ 22:23 8:9 DlyCnt
+ 24:28 3::7 Reserved
+*/
+#define RX_CHNL_STS 0x0f /* r */
+#define CHNL_STS_ENGBUSY (1 << 1)
+#define CHNL_STS_EOP (1 << 2)
+#define CHNL_STS_SOP (1 << 3)
+#define CHNL_STS_CMPLT (1 << 4)
+#define CHNL_STS_SOE (1 << 5)
+#define CHNL_STS_IOE (1 << 6)
+#define CHNL_STS_ERR (1 << 7)
+
+#define CHNL_STS_BSYWR (1 << 16)
+#define CHNL_STS_CURPERR (1 << 17)
+#define CHNL_STS_NXTPERR (1 << 18)
+#define CHNL_STS_ADDRERR (1 << 19)
+#define CHNL_STS_CMPERR (1 << 20)
+#define CHNL_STS_TAILERR (1 << 21)
+/*
+ 0:9 22:31 Reserved
+ 10 21 TailPErr
+ 11 20 CmpErr
+ 12 19 AddrErr
+ 13 18 NxtPErr
+ 14 17 CurPErr
+ 15 16 BsyWr
+ 16:23 8:15 Reserved
+ 24 7 Error
+ 25 6 IOE
+ 26 5 SOE
+ 27 4 Cmplt
+ 28 3 SOP
+ 29 2 EOP
+ 30 1 EngBusy
+ 31 0 Reserved
+*/
+
+#define DMA_CONTROL_REG 0x10 /* rw */
+#define DMA_CONTROL_RST (1 << 0)
+#define DMA_TAIL_ENABLE (1 << 2)
+
+/* XPS_LL_TEMAC direct registers definition */
+
+#define XTE_RAF0_OFFSET 0x00
+#define RAF0_RST (1 << 0)
+#define RAF0_MCSTREJ (1 << 1)
+#define RAF0_BCSTREJ (1 << 2)
+#define XTE_TPF0_OFFSET 0x04
+#define XTE_IFGP0_OFFSET 0x08
+#define XTE_ISR0_OFFSET 0x0c
+#define ISR0_HARDACSCMPLT (1 << 0)
+#define ISR0_AUTONEG (1 << 1)
+#define ISR0_RXCMPLT (1 << 2)
+#define ISR0_RXREJ (1 << 3)
+#define ISR0_RXFIFOOVR (1 << 4)
+#define ISR0_TXCMPLT (1 << 5)
+#define ISR0_RXDCMLCK (1 << 6)
+
+#define XTE_IPR0_OFFSET 0x10
+#define XTE_IER0_OFFSET 0x14
+
+#define XTE_MSW0_OFFSET 0x20
+#define XTE_LSW0_OFFSET 0x24
+#define XTE_CTL0_OFFSET 0x28
+#define XTE_RDY0_OFFSET 0x2c
+
+#define XTE_RSE_MIIM_RR_MASK 0x0002
+#define XTE_RSE_MIIM_WR_MASK 0x0004
+#define XTE_RSE_CFG_RR_MASK 0x0020
+#define XTE_RSE_CFG_WR_MASK 0x0040
+#define XTE_RDY0_HARD_ACS_RDY_MASK (0x10000)
+
+/* XPS_LL_TEMAC indirect registers offset definition */
+
+#define XTE_RXC0_OFFSET 0x00000200 /* Rx configuration word 0 */
+#define XTE_RXC1_OFFSET 0x00000240 /* Rx configuration word 1 */
+#define XTE_RXC1_RXRST_MASK (1 << 31) /* Receiver reset */
+#define XTE_RXC1_RXJMBO_MASK (1 << 30) /* Jumbo frame enable */
+#define XTE_RXC1_RXFCS_MASK (1 << 29) /* FCS not stripped */
+#define XTE_RXC1_RXEN_MASK (1 << 28) /* Receiver enable */
+#define XTE_RXC1_RXVLAN_MASK (1 << 27) /* VLAN enable */
+#define XTE_RXC1_RXHD_MASK (1 << 26) /* Half duplex */
+#define XTE_RXC1_RXLT_MASK (1 << 25) /* Length/type check disable */
+
+#define XTE_TXC_OFFSET 0x00000280 /* Tx configuration */
+#define XTE_TXC_TXRST_MASK (1 << 31) /* Transmitter reset */
+#define XTE_TXC_TXJMBO_MASK (1 << 30) /* Jumbo frame enable */
+#define XTE_TXC_TXFCS_MASK (1 << 29) /* Generate FCS */
+#define XTE_TXC_TXEN_MASK (1 << 28) /* Transmitter enable */
+#define XTE_TXC_TXVLAN_MASK (1 << 27) /* VLAN enable */
+#define XTE_TXC_TXHD_MASK (1 << 26) /* Half duplex */
+
+#define XTE_FCC_OFFSET 0x000002C0 /* Flow control config */
+#define XTE_FCC_RXFLO_MASK (1 << 29) /* Rx flow control enable */
+#define XTE_FCC_TXFLO_MASK (1 << 30) /* Tx flow control enable */
+
+#define XTE_EMCFG_OFFSET 0x00000300 /* EMAC configuration */
+#define XTE_EMCFG_LINKSPD_MASK 0xC0000000 /* Link speed */
+#define XTE_EMCFG_HOSTEN_MASK (1 << 26) /* Host interface enable */
+#define XTE_EMCFG_LINKSPD_10 0x00000000 /* 10 Mbit LINKSPD_MASK */
+#define XTE_EMCFG_LINKSPD_100 (1 << 30) /* 100 Mbit LINKSPD_MASK */
+#define XTE_EMCFG_LINKSPD_1000 (1 << 31) /* 1000 Mbit LINKSPD_MASK */
+
+#define XTE_GMIC_OFFSET 0x00000320 /* RGMII/SGMII config */
+#define XTE_MC_OFFSET 0x00000340 /* MDIO configuration */
+#define XTE_UAW0_OFFSET 0x00000380 /* Unicast address word 0 */
+#define XTE_UAW1_OFFSET 0x00000384 /* Unicast address word 1 */
+
+#define XTE_MAW0_OFFSET 0x00000388 /* Multicast addr word 0 */
+#define XTE_MAW1_OFFSET 0x0000038C /* Multicast addr word 1 */
+#define XTE_AFM_OFFSET 0x00000390 /* Promiscuous mode */
+#define XTE_AFM_EPPRM_MASK (1 << 31) /* Promiscuous mode enable */
+
+/* Interrupt Request status */
+#define XTE_TIS_OFFSET 0x000003A0
+#define TIS_FRIS (1 << 0)
+#define TIS_MRIS (1 << 1)
+#define TIS_MWIS (1 << 2)
+#define TIS_ARIS (1 << 3)
+#define TIS_AWIS (1 << 4)
+#define TIS_CRIS (1 << 5)
+#define TIS_CWIS (1 << 6)
+
+#define XTE_TIE_OFFSET 0x000003A4 /* Interrupt enable */
+
+/** MII Mamagement Control register (MGTCR) */
+#define XTE_MGTDR_OFFSET 0x000003B0 /* MII data */
+#define XTE_MIIMAI_OFFSET 0x000003B4 /* MII control */
+
+#define CNTLREG_WRITE_ENABLE_MASK 0x8000
+#define CNTLREG_EMAC1SEL_MASK 0x0400
+#define CNTLREG_ADDRESSCODE_MASK 0x03ff
+
+/* CDMAC descriptor status bit definitions */
+
+#define STS_CTRL_APP0_ERR (1 << 31)
+#define STS_CTRL_APP0_IRQONEND (1 << 30)
+/* undoccumented */
+#define STS_CTRL_APP0_STOPONEND (1 << 29)
+#define STS_CTRL_APP0_CMPLT (1 << 28)
+#define STS_CTRL_APP0_SOP (1 << 27)
+#define STS_CTRL_APP0_EOP (1 << 26)
+#define STS_CTRL_APP0_ENGBUSY (1 << 25)
+/* undocumented */
+#define STS_CTRL_APP0_ENGRST (1 << 24)
+
+#define TX_CONTROL_CALC_CSUM_MASK 1
+
+#define XTE_ALIGN 32
+#define BUFFER_ALIGN(adr) ((XTE_ALIGN - ((u32) adr)) % XTE_ALIGN)
+
+#define MULTICAST_CAM_TABLE_NUM 4
+
+/* TX/RX CURDESC_PTR points to first descriptor */
+/* TX/RX TAILDESC_PTR points to last descriptor in linked list */
+
+/**
+ * struct cdmac_bd - LocalLink buffer descriptor format
+ *
+ * app0 bits:
+ * 0 Error
+ * 1 IrqOnEnd generate an interrupt at completion of DMA op
+ * 2 reserved
+ * 3 completed Current descriptor completed
+ * 4 SOP TX - marks first desc/ RX marks first desct
+ * 5 EOP TX marks last desc/RX marks last desc
+ * 6 EngBusy DMA is processing
+ * 7 reserved
+ * 8:31 application specific
+ */
+struct cdmac_bd {
+ u32 next; /* Physical address of next buffer descriptor */
+ u32 phys;
+ u32 len;
+ u32 app0;
+ u32 app1; /* TX start << 16 | insert */
+ u32 app2; /* TX csum */
+ u32 app3;
+ u32 app4; /* skb for TX length for RX */
+};
+
+struct temac_local {
+ struct net_device *ndev;
+ struct device *dev;
+
+ /* Connection to PHY device */
+ struct phy_device *phy_dev; /* Pointer to PHY device */
+ struct device_node *phy_node;
+
+ /* MDIO bus data */
+ struct mii_bus *mii_bus; /* MII bus reference */
+ int mdio_irqs[PHY_MAX_ADDR]; /* IRQs table for MDIO bus */
+
+ /* IO registers and IRQs */
+ void __iomem *regs;
+ dcr_host_t sdma_dcrs;
+ int tx_irq;
+ int rx_irq;
+ int emac_num;
+
+ struct sk_buff **rx_skb;
+ spinlock_t rx_lock;
+ struct mutex indirect_mutex;
+ u32 options; /* Current options word */
+ int last_link;
+
+ /* Buffer descriptors */
+ struct cdmac_bd *tx_bd_v;
+ dma_addr_t tx_bd_p;
+ struct cdmac_bd *rx_bd_v;
+ dma_addr_t rx_bd_p;
+ int tx_bd_ci;
+ int tx_bd_next;
+ int tx_bd_tail;
+ int rx_bd_ci;
+};
+
+/* xilinx_temac.c */
+u32 temac_ior(struct temac_local *lp, int offset);
+void temac_iow(struct temac_local *lp, int offset, u32 value);
+int temac_indirect_busywait(struct temac_local *lp);
+u32 temac_indirect_in32(struct temac_local *lp, int reg);
+void temac_indirect_out32(struct temac_local *lp, int reg, u32 value);
+
+
+/* xilinx_temac_mdio.c */
+int temac_mdio_setup(struct temac_local *lp, struct device_node *np);
+void temac_mdio_teardown(struct temac_local *lp);
+
+#endif /* XILINX_LL_TEMAC_H */
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
new file mode 100644
index 00000000000..96e7248876c
--- /dev/null
+++ b/drivers/net/ll_temac_main.c
@@ -0,0 +1,969 @@
+/*
+ * Driver for Xilinx TEMAC Ethernet device
+ *
+ * Copyright (c) 2008 Nissin Systems Co., Ltd., Yoshio Kashiwagi
+ * Copyright (c) 2005-2008 DLA Systems, David H. Lynch Jr. <dhlii@dlasys.net>
+ * Copyright (c) 2008-2009 Secret Lab Technologies Ltd.
+ *
+ * This is a driver for the Xilinx ll_temac ipcore which is often used
+ * in the Virtex and Spartan series of chips.
+ *
+ * Notes:
+ * - The ll_temac hardware uses indirect access for many of the TEMAC
+ * registers, include the MDIO bus. However, indirect access to MDIO
+ * registers take considerably more clock cycles than to TEMAC registers.
+ * MDIO accesses are long, so threads doing them should probably sleep
+ * rather than busywait. However, since only one indirect access can be
+ * in progress at any given time, that means that *all* indirect accesses
+ * could end up sleeping (to wait for an MDIO access to complete).
+ * Fortunately none of the indirect accesses are on the 'hot' path for tx
+ * or rx, so this should be okay.
+ *
+ * TODO:
+ * - Fix driver to work on more than just Virtex5. Right now the driver
+ * assumes that the locallink DMA registers are accessed via DCR
+ * instructions.
+ * - Factor out locallink DMA code into separate driver
+ * - Fix multicast assignment.
+ * - Fix support for hardware checksumming.
+ * - Testing. Lots and lots of testing.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_mdio.h>
+#include <linux/of_platform.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/tcp.h> /* needed for sizeof(tcphdr) */
+#include <linux/udp.h> /* needed for sizeof(udphdr) */
+#include <linux/phy.h>
+#include <linux/in.h>
+#include <linux/io.h>
+#include <linux/ip.h>
+
+#include "ll_temac.h"
+
+#define TX_BD_NUM 64
+#define RX_BD_NUM 128
+
+/* ---------------------------------------------------------------------
+ * Low level register access functions
+ */
+
+u32 temac_ior(struct temac_local *lp, int offset)
+{
+ return in_be32((u32 *)(lp->regs + offset));
+}
+
+void temac_iow(struct temac_local *lp, int offset, u32 value)
+{
+ out_be32((u32 *) (lp->regs + offset), value);
+}
+
+int temac_indirect_busywait(struct temac_local *lp)
+{
+ long end = jiffies + 2;
+
+ while (!(temac_ior(lp, XTE_RDY0_OFFSET) & XTE_RDY0_HARD_ACS_RDY_MASK)) {
+ if (end - jiffies <= 0) {
+ WARN_ON(1);
+ return -ETIMEDOUT;
+ }
+ msleep(1);
+ }
+ return 0;
+}
+
+/**
+ * temac_indirect_in32
+ *
+ * lp->indirect_mutex must be held when calling this function
+ */
+u32 temac_indirect_in32(struct temac_local *lp, int reg)
+{
+ u32 val;
+
+ if (temac_indirect_busywait(lp))
+ return -ETIMEDOUT;
+ temac_iow(lp, XTE_CTL0_OFFSET, reg);
+ if (temac_indirect_busywait(lp))
+ return -ETIMEDOUT;
+ val = temac_ior(lp, XTE_LSW0_OFFSET);
+
+ return val;
+}
+
+/**
+ * temac_indirect_out32
+ *
+ * lp->indirect_mutex must be held when calling this function
+ */
+void temac_indirect_out32(struct temac_local *lp, int reg, u32 value)
+{
+ if (temac_indirect_busywait(lp))
+ return;
+ temac_iow(lp, XTE_LSW0_OFFSET, value);
+ temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg);
+}
+
+static u32 temac_dma_in32(struct temac_local *lp, int reg)
+{
+ return dcr_read(lp->sdma_dcrs, reg);
+}
+
+static void temac_dma_out32(struct temac_local *lp, int reg, u32 value)
+{
+ dcr_write(lp->sdma_dcrs, reg, value);
+}
+
+/**
+ * temac_dma_bd_init - Setup buffer descriptor rings
+ */
+static int temac_dma_bd_init(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ struct sk_buff *skb;
+ int i;
+
+ lp->rx_skb = kzalloc(sizeof(struct sk_buff)*RX_BD_NUM, GFP_KERNEL);
+ /* allocate the tx and rx ring buffer descriptors. */
+ /* returns a virtual addres and a physical address. */
+ lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent,
+ sizeof(*lp->tx_bd_v) * TX_BD_NUM,
+ &lp->tx_bd_p, GFP_KERNEL);
+ lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent,
+ sizeof(*lp->rx_bd_v) * RX_BD_NUM,
+ &lp->rx_bd_p, GFP_KERNEL);
+
+ memset(lp->tx_bd_v, 0, sizeof(*lp->tx_bd_v) * TX_BD_NUM);
+ for (i = 0; i < TX_BD_NUM; i++) {
+ lp->tx_bd_v[i].next = lp->tx_bd_p +
+ sizeof(*lp->tx_bd_v) * ((i + 1) % TX_BD_NUM);
+ }
+
+ memset(lp->rx_bd_v, 0, sizeof(*lp->rx_bd_v) * RX_BD_NUM);
+ for (i = 0; i < RX_BD_NUM; i++) {
+ lp->rx_bd_v[i].next = lp->rx_bd_p +
+ sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM);
+
+ skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE
+ + XTE_ALIGN, GFP_ATOMIC);
+ if (skb == 0) {
+ dev_err(&ndev->dev, "alloc_skb error %d\n", i);
+ return -1;
+ }
+ lp->rx_skb[i] = skb;
+ skb_reserve(skb, BUFFER_ALIGN(skb->data));
+ /* returns physical address of skb->data */
+ lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent,
+ skb->data,
+ XTE_MAX_JUMBO_FRAME_SIZE,
+ DMA_FROM_DEVICE);
+ lp->rx_bd_v[i].len = XTE_MAX_JUMBO_FRAME_SIZE;
+ lp->rx_bd_v[i].app0 = STS_CTRL_APP0_IRQONEND;
+ }
+
+ temac_dma_out32(lp, TX_CHNL_CTRL, 0x10220400 |
+ CHNL_CTRL_IRQ_EN |
+ CHNL_CTRL_IRQ_DLY_EN |
+ CHNL_CTRL_IRQ_COAL_EN);
+ /* 0x10220483 */
+ /* 0x00100483 */
+ temac_dma_out32(lp, RX_CHNL_CTRL, 0xff010000 |
+ CHNL_CTRL_IRQ_EN |
+ CHNL_CTRL_IRQ_DLY_EN |
+ CHNL_CTRL_IRQ_COAL_EN |
+ CHNL_CTRL_IRQ_IOE);
+ /* 0xff010283 */
+
+ temac_dma_out32(lp, RX_CURDESC_PTR, lp->rx_bd_p);
+ temac_dma_out32(lp, RX_TAILDESC_PTR,
+ lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1)));
+ temac_dma_out32(lp, TX_CURDESC_PTR, lp->tx_bd_p);
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------
+ * net_device_ops
+ */
+
+static int temac_set_mac_address(struct net_device *ndev, void *address)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+
+ if (address)
+ memcpy(ndev->dev_addr, address, ETH_ALEN);
+
+ if (!is_valid_ether_addr(ndev->dev_addr))
+ random_ether_addr(ndev->dev_addr);
+
+ /* set up unicast MAC address filter set its mac address */
+ mutex_lock(&lp->indirect_mutex);
+ temac_indirect_out32(lp, XTE_UAW0_OFFSET,
+ (ndev->dev_addr[0]) |
+ (ndev->dev_addr[1] << 8) |
+ (ndev->dev_addr[2] << 16) |
+ (ndev->dev_addr[3] << 24));
+ /* There are reserved bits in EUAW1
+ * so don't affect them Set MAC bits [47:32] in EUAW1 */
+ temac_indirect_out32(lp, XTE_UAW1_OFFSET,
+ (ndev->dev_addr[4] & 0x000000ff) |
+ (ndev->dev_addr[5] << 8));
+ mutex_unlock(&lp->indirect_mutex);
+
+ return 0;
+}
+
+static void temac_set_multicast_list(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ u32 multi_addr_msw, multi_addr_lsw, val;
+ int i;
+
+ mutex_lock(&lp->indirect_mutex);
+ if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)
+ || ndev->mc_count > MULTICAST_CAM_TABLE_NUM) {
+ /*
+ * We must make the kernel realise we had to move
+ * into promisc mode or we start all out war on
+ * the cable. If it was a promisc request the
+ * flag is already set. If not we assert it.
+ */
+ ndev->flags |= IFF_PROMISC;
+ temac_indirect_out32(lp, XTE_AFM_OFFSET, XTE_AFM_EPPRM_MASK);
+ dev_info(&ndev->dev, "Promiscuous mode enabled.\n");
+ } else if (ndev->mc_count) {
+ struct dev_mc_list *mclist = ndev->mc_list;
+ for (i = 0; mclist && i < ndev->mc_count; i++) {
+
+ if (i >= MULTICAST_CAM_TABLE_NUM)
+ break;
+ multi_addr_msw = ((mclist->dmi_addr[3] << 24) |
+ (mclist->dmi_addr[2] << 16) |
+ (mclist->dmi_addr[1] << 8) |
+ (mclist->dmi_addr[0]));
+ temac_indirect_out32(lp, XTE_MAW0_OFFSET,
+ multi_addr_msw);
+ multi_addr_lsw = ((mclist->dmi_addr[5] << 8) |
+ (mclist->dmi_addr[4]) | (i << 16));
+ temac_indirect_out32(lp, XTE_MAW1_OFFSET,
+ multi_addr_lsw);
+ mclist = mclist->next;
+ }
+ } else {
+ val = temac_indirect_in32(lp, XTE_AFM_OFFSET);
+ temac_indirect_out32(lp, XTE_AFM_OFFSET,
+ val & ~XTE_AFM_EPPRM_MASK);
+ temac_indirect_out32(lp, XTE_MAW0_OFFSET, 0);
+ temac_indirect_out32(lp, XTE_MAW1_OFFSET, 0);
+ dev_info(&ndev->dev, "Promiscuous mode disabled.\n");
+ }
+ mutex_unlock(&lp->indirect_mutex);
+}
+
+struct temac_option {
+ int flg;
+ u32 opt;
+ u32 reg;
+ u32 m_or;
+ u32 m_and;
+} temac_options[] = {
+ /* Turn on jumbo packet support for both Rx and Tx */
+ {
+ .opt = XTE_OPTION_JUMBO,
+ .reg = XTE_TXC_OFFSET,
+ .m_or = XTE_TXC_TXJMBO_MASK,
+ },
+ {
+ .opt = XTE_OPTION_JUMBO,
+ .reg = XTE_RXC1_OFFSET,
+ .m_or =XTE_RXC1_RXJMBO_MASK,
+ },
+ /* Turn on VLAN packet support for both Rx and Tx */
+ {
+ .opt = XTE_OPTION_VLAN,
+ .reg = XTE_TXC_OFFSET,
+ .m_or =XTE_TXC_TXVLAN_MASK,
+ },
+ {
+ .opt = XTE_OPTION_VLAN,
+ .reg = XTE_RXC1_OFFSET,
+ .m_or =XTE_RXC1_RXVLAN_MASK,
+ },
+ /* Turn on FCS stripping on receive packets */
+ {
+ .opt = XTE_OPTION_FCS_STRIP,
+ .reg = XTE_RXC1_OFFSET,
+ .m_or =XTE_RXC1_RXFCS_MASK,
+ },
+ /* Turn on FCS insertion on transmit packets */
+ {
+ .opt = XTE_OPTION_FCS_INSERT,
+ .reg = XTE_TXC_OFFSET,
+ .m_or =XTE_TXC_TXFCS_MASK,
+ },
+ /* Turn on length/type field checking on receive packets */
+ {
+ .opt = XTE_OPTION_LENTYPE_ERR,
+ .reg = XTE_RXC1_OFFSET,
+ .m_or =XTE_RXC1_RXLT_MASK,
+ },
+ /* Turn on flow control */
+ {
+ .opt = XTE_OPTION_FLOW_CONTROL,
+ .reg = XTE_FCC_OFFSET,
+ .m_or =XTE_FCC_RXFLO_MASK,
+ },
+ /* Turn on flow control */
+ {
+ .opt = XTE_OPTION_FLOW_CONTROL,
+ .reg = XTE_FCC_OFFSET,
+ .m_or =XTE_FCC_TXFLO_MASK,
+ },
+ /* Turn on promiscuous frame filtering (all frames are received ) */
+ {
+ .opt = XTE_OPTION_PROMISC,
+ .reg = XTE_AFM_OFFSET,
+ .m_or =XTE_AFM_EPPRM_MASK,
+ },
+ /* Enable transmitter if not already enabled */
+ {
+ .opt = XTE_OPTION_TXEN,
+ .reg = XTE_TXC_OFFSET,
+ .m_or =XTE_TXC_TXEN_MASK,
+ },
+ /* Enable receiver? */
+ {
+ .opt = XTE_OPTION_RXEN,
+ .reg = XTE_RXC1_OFFSET,
+ .m_or =XTE_RXC1_RXEN_MASK,
+ },
+ {}
+};
+
+/**
+ * temac_setoptions
+ */
+static u32 temac_setoptions(struct net_device *ndev, u32 options)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ struct temac_option *tp = &temac_options[0];
+ int reg;
+
+ mutex_lock(&lp->indirect_mutex);
+ while (tp->opt) {
+ reg = temac_indirect_in32(lp, tp->reg) & ~tp->m_or;
+ if (options & tp->opt)
+ reg |= tp->m_or;
+ temac_indirect_out32(lp, tp->reg, reg);
+ tp++;
+ }
+ lp->options |= options;
+ mutex_unlock(&lp->indirect_mutex);
+
+ return (0);
+}
+
+/* Initilize temac */
+static void temac_device_reset(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ u32 timeout;
+ u32 val;
+
+ /* Perform a software reset */
+
+ /* 0x300 host enable bit ? */
+ /* reset PHY through control register ?:1 */
+
+ dev_dbg(&ndev->dev, "%s()\n", __func__);
+
+ mutex_lock(&lp->indirect_mutex);
+ /* Reset the receiver and wait for it to finish reset */
+ temac_indirect_out32(lp, XTE_RXC1_OFFSET, XTE_RXC1_RXRST_MASK);
+ timeout = 1000;
+ while (temac_indirect_in32(lp, XTE_RXC1_OFFSET) & XTE_RXC1_RXRST_MASK) {
+ udelay(1);
+ if (--timeout == 0) {
+ dev_err(&ndev->dev,
+ "temac_device_reset RX reset timeout!!\n");
+ break;
+ }
+ }
+
+ /* Reset the transmitter and wait for it to finish reset */
+ temac_indirect_out32(lp, XTE_TXC_OFFSET, XTE_TXC_TXRST_MASK);
+ timeout = 1000;
+ while (temac_indirect_in32(lp, XTE_TXC_OFFSET) & XTE_TXC_TXRST_MASK) {
+ udelay(1);
+ if (--timeout == 0) {
+ dev_err(&ndev->dev,
+ "temac_device_reset TX reset timeout!!\n");
+ break;
+ }
+ }
+
+ /* Disable the receiver */
+ val = temac_indirect_in32(lp, XTE_RXC1_OFFSET);
+ temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK);
+
+ /* Reset Local Link (DMA) */
+ temac_dma_out32(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
+ timeout = 1000;
+ while (temac_dma_in32(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) {
+ udelay(1);
+ if (--timeout == 0) {
+ dev_err(&ndev->dev,
+ "temac_device_reset DMA reset timeout!!\n");
+ break;
+ }
+ }
+ temac_dma_out32(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE);
+
+ temac_dma_bd_init(ndev);
+
+ temac_indirect_out32(lp, XTE_RXC0_OFFSET, 0);
+ temac_indirect_out32(lp, XTE_RXC1_OFFSET, 0);
+ temac_indirect_out32(lp, XTE_TXC_OFFSET, 0);
+ temac_indirect_out32(lp, XTE_FCC_OFFSET, XTE_FCC_RXFLO_MASK);
+
+ mutex_unlock(&lp->indirect_mutex);
+
+ /* Sync default options with HW
+ * but leave receiver and transmitter disabled. */
+ temac_setoptions(ndev,
+ lp->options & ~(XTE_OPTION_TXEN | XTE_OPTION_RXEN));
+
+ temac_set_mac_address(ndev, NULL);
+
+ /* Set address filter table */
+ temac_set_multicast_list(ndev);
+ if (temac_setoptions(ndev, lp->options))
+ dev_err(&ndev->dev, "Error setting TEMAC options\n");
+
+ /* Init Driver variable */
+ ndev->trans_start = 0;
+}
+
+void temac_adjust_link(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ struct phy_device *phy = lp->phy_dev;
+ u32 mii_speed;
+ int link_state;
+
+ /* hash together the state values to decide if something has changed */
+ link_state = phy->speed | (phy->duplex << 1) | phy->link;
+
+ mutex_lock(&lp->indirect_mutex);
+ if (lp->last_link != link_state) {
+ mii_speed = temac_indirect_in32(lp, XTE_EMCFG_OFFSET);
+ mii_speed &= ~XTE_EMCFG_LINKSPD_MASK;
+
+ switch (phy->speed) {
+ case SPEED_1000: mii_speed |= XTE_EMCFG_LINKSPD_1000; break;
+ case SPEED_100: mii_speed |= XTE_EMCFG_LINKSPD_100; break;
+ case SPEED_10: mii_speed |= XTE_EMCFG_LINKSPD_10; break;
+ }
+
+ /* Write new speed setting out to TEMAC */
+ temac_indirect_out32(lp, XTE_EMCFG_OFFSET, mii_speed);
+ lp->last_link = link_state;
+ phy_print_status(phy);
+ }
+ mutex_unlock(&lp->indirect_mutex);
+}
+
+static void temac_start_xmit_done(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ struct cdmac_bd *cur_p;
+ unsigned int stat = 0;
+
+ cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
+ stat = cur_p->app0;
+
+ while (stat & STS_CTRL_APP0_CMPLT) {
+ dma_unmap_single(ndev->dev.parent, cur_p->phys, cur_p->len,
+ DMA_TO_DEVICE);
+ if (cur_p->app4)
+ dev_kfree_skb_irq((struct sk_buff *)cur_p->app4);
+ cur_p->app0 = 0;
+
+ ndev->stats.tx_packets++;
+ ndev->stats.tx_bytes += cur_p->len;
+
+ lp->tx_bd_ci++;
+ if (lp->tx_bd_ci >= TX_BD_NUM)
+ lp->tx_bd_ci = 0;
+
+ cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
+ stat = cur_p->app0;
+ }
+
+ netif_wake_queue(ndev);
+}
+
+static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ struct cdmac_bd *cur_p;
+ dma_addr_t start_p, tail_p;
+ int ii;
+ unsigned long num_frag;
+ skb_frag_t *frag;
+
+ num_frag = skb_shinfo(skb)->nr_frags;
+ frag = &skb_shinfo(skb)->frags[0];
+ start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
+ cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
+
+ if (cur_p->app0 & STS_CTRL_APP0_CMPLT) {
+ if (!netif_queue_stopped(ndev)) {
+ netif_stop_queue(ndev);
+ return NETDEV_TX_BUSY;
+ }
+ return NETDEV_TX_BUSY;
+ }
+
+ cur_p->app0 = 0;
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ const struct iphdr *ip = ip_hdr(skb);
+ int length = 0, start = 0, insert = 0;
+
+ switch (ip->protocol) {
+ case IPPROTO_TCP:
+ start = sizeof(struct iphdr) + ETH_HLEN;
+ insert = sizeof(struct iphdr) + ETH_HLEN + 16;
+ length = ip->tot_len - sizeof(struct iphdr);
+ break;
+ case IPPROTO_UDP:
+ start = sizeof(struct iphdr) + ETH_HLEN;
+ insert = sizeof(struct iphdr) + ETH_HLEN + 6;
+ length = ip->tot_len - sizeof(struct iphdr);
+ break;
+ default:
+ break;
+ }
+ cur_p->app1 = ((start << 16) | insert);
+ cur_p->app2 = csum_tcpudp_magic(ip->saddr, ip->daddr,
+ length, ip->protocol, 0);
+ skb->data[insert] = 0;
+ skb->data[insert + 1] = 0;
+ }
+ cur_p->app0 |= STS_CTRL_APP0_SOP;
+ cur_p->len = skb_headlen(skb);
+ cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len,
+ DMA_TO_DEVICE);
+ cur_p->app4 = (unsigned long)skb;
+
+ for (ii = 0; ii < num_frag; ii++) {
+ lp->tx_bd_tail++;
+ if (lp->tx_bd_tail >= TX_BD_NUM)
+ lp->tx_bd_tail = 0;
+
+ cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
+ cur_p->phys = dma_map_single(ndev->dev.parent,
+ (void *)page_address(frag->page) +
+ frag->page_offset,
+ frag->size, DMA_TO_DEVICE);
+ cur_p->len = frag->size;
+ cur_p->app0 = 0;
+ frag++;
+ }
+ cur_p->app0 |= STS_CTRL_APP0_EOP;
+
+ tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
+ lp->tx_bd_tail++;
+ if (lp->tx_bd_tail >= TX_BD_NUM)
+ lp->tx_bd_tail = 0;
+
+ /* Kick off the transfer */
+ temac_dma_out32(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */
+
+ return 0;
+}
+
+
+static void ll_temac_recv(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ struct sk_buff *skb, *new_skb;
+ unsigned int bdstat;
+ struct cdmac_bd *cur_p;
+ dma_addr_t tail_p;
+ int length;
+ unsigned long skb_vaddr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lp->rx_lock, flags);
+
+ tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci;
+ cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+
+ bdstat = cur_p->app0;
+ while ((bdstat & STS_CTRL_APP0_CMPLT)) {
+
+ skb = lp->rx_skb[lp->rx_bd_ci];
+ length = cur_p->app4;
+
+ skb_vaddr = virt_to_bus(skb->data);
+ dma_unmap_single(ndev->dev.parent, skb_vaddr, length,
+ DMA_FROM_DEVICE);
+
+ skb_put(skb, length);
+ skb->dev = ndev;
+ skb->protocol = eth_type_trans(skb, ndev);
+ skb->ip_summed = CHECKSUM_NONE;
+
+ netif_rx(skb);
+
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += length;
+
+ new_skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE + XTE_ALIGN,
+ GFP_ATOMIC);
+ if (new_skb == 0) {
+ dev_err(&ndev->dev, "no memory for new sk_buff\n");
+ spin_unlock_irqrestore(&lp->rx_lock, flags);
+ return;
+ }
+
+ skb_reserve(new_skb, BUFFER_ALIGN(new_skb->data));
+
+ cur_p->app0 = STS_CTRL_APP0_IRQONEND;
+ cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data,
+ XTE_MAX_JUMBO_FRAME_SIZE,
+ DMA_FROM_DEVICE);
+ cur_p->len = XTE_MAX_JUMBO_FRAME_SIZE;
+ lp->rx_skb[lp->rx_bd_ci] = new_skb;
+
+ lp->rx_bd_ci++;
+ if (lp->rx_bd_ci >= RX_BD_NUM)
+ lp->rx_bd_ci = 0;
+
+ cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+ bdstat = cur_p->app0;
+ }
+ temac_dma_out32(lp, RX_TAILDESC_PTR, tail_p);
+
+ spin_unlock_irqrestore(&lp->rx_lock, flags);
+}
+
+static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev)
+{
+ struct net_device *ndev = _ndev;
+ struct temac_local *lp = netdev_priv(ndev);
+ unsigned int status;
+
+ status = temac_dma_in32(lp, TX_IRQ_REG);
+ temac_dma_out32(lp, TX_IRQ_REG, status);
+
+ if (status & (IRQ_COAL | IRQ_DLY))
+ temac_start_xmit_done(lp->ndev);
+ if (status & 0x080)
+ dev_err(&ndev->dev, "DMA error 0x%x\n", status);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t ll_temac_rx_irq(int irq, void *_ndev)
+{
+ struct net_device *ndev = _ndev;
+ struct temac_local *lp = netdev_priv(ndev);
+ unsigned int status;
+
+ /* Read and clear the status registers */
+ status = temac_dma_in32(lp, RX_IRQ_REG);
+ temac_dma_out32(lp, RX_IRQ_REG, status);
+
+ if (status & (IRQ_COAL | IRQ_DLY))
+ ll_temac_recv(lp->ndev);
+
+ return IRQ_HANDLED;
+}
+
+static int temac_open(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ int rc;
+
+ dev_dbg(&ndev->dev, "temac_open()\n");
+
+ if (lp->phy_node) {
+ lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node,
+ temac_adjust_link, 0, 0);
+ if (!lp->phy_dev) {
+ dev_err(lp->dev, "of_phy_connect() failed\n");
+ return -ENODEV;
+ }
+
+ phy_start(lp->phy_dev);
+ }
+
+ rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev);
+ if (rc)
+ goto err_tx_irq;
+ rc = request_irq(lp->rx_irq, ll_temac_rx_irq, 0, ndev->name, ndev);
+ if (rc)
+ goto err_rx_irq;
+
+ temac_device_reset(ndev);
+ return 0;
+
+ err_rx_irq:
+ free_irq(lp->tx_irq, ndev);
+ err_tx_irq:
+ if (lp->phy_dev)
+ phy_disconnect(lp->phy_dev);
+ lp->phy_dev = NULL;
+ dev_err(lp->dev, "request_irq() failed\n");
+ return rc;
+}
+
+static int temac_stop(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+
+ dev_dbg(&ndev->dev, "temac_close()\n");
+
+ free_irq(lp->tx_irq, ndev);
+ free_irq(lp->rx_irq, ndev);
+
+ if (lp->phy_dev)
+ phy_disconnect(lp->phy_dev);
+ lp->phy_dev = NULL;
+
+ return 0;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void
+temac_poll_controller(struct net_device *ndev)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+
+ disable_irq(lp->tx_irq);
+ disable_irq(lp->rx_irq);
+
+ ll_temac_rx_irq(lp->tx_irq, lp);
+ ll_temac_tx_irq(lp->rx_irq, lp);
+
+ enable_irq(lp->tx_irq);
+ enable_irq(lp->rx_irq);
+}
+#endif
+
+static const struct net_device_ops temac_netdev_ops = {
+ .ndo_open = temac_open,
+ .ndo_stop = temac_stop,
+ .ndo_start_xmit = temac_start_xmit,
+ .ndo_set_mac_address = temac_set_mac_address,
+ //.ndo_set_multicast_list = temac_set_multicast_list,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = temac_poll_controller,
+#endif
+};
+
+/* ---------------------------------------------------------------------
+ * SYSFS device attributes
+ */
+static ssize_t temac_show_llink_regs(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct temac_local *lp = netdev_priv(ndev);
+ int i, len = 0;
+
+ for (i = 0; i < 0x11; i++)
+ len += sprintf(buf + len, "%.8x%s", temac_dma_in32(lp, i),
+ (i % 8) == 7 ? "\n" : " ");
+ len += sprintf(buf + len, "\n");
+
+ return len;
+}
+
+static DEVICE_ATTR(llink_regs, 0440, temac_show_llink_regs, NULL);
+
+static struct attribute *temac_device_attrs[] = {
+ &dev_attr_llink_regs.attr,
+ NULL,
+};
+
+static const struct attribute_group temac_attr_group = {
+ .attrs = temac_device_attrs,
+};
+
+static int __init
+temac_of_probe(struct of_device *op, const struct of_device_id *match)
+{
+ struct device_node *np;
+ struct temac_local *lp;
+ struct net_device *ndev;
+ const void *addr;
+ int size, rc = 0;
+ unsigned int dcrs;
+
+ /* Init network device structure */
+ ndev = alloc_etherdev(sizeof(*lp));
+ if (!ndev) {
+ dev_err(&op->dev, "could not allocate device.\n");
+ return -ENOMEM;
+ }
+ ether_setup(ndev);
+ dev_set_drvdata(&op->dev, ndev);
+ SET_NETDEV_DEV(ndev, &op->dev);
+ ndev->flags &= ~IFF_MULTICAST; /* clear multicast */
+ ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST;
+ ndev->netdev_ops = &temac_netdev_ops;
+#if 0
+ ndev->features |= NETIF_F_IP_CSUM; /* Can checksum TCP/UDP over IPv4. */
+ ndev->features |= NETIF_F_HW_CSUM; /* Can checksum all the packets. */
+ ndev->features |= NETIF_F_IPV6_CSUM; /* Can checksum IPV6 TCP/UDP */
+ ndev->features |= NETIF_F_HIGHDMA; /* Can DMA to high memory. */
+ ndev->features |= NETIF_F_HW_VLAN_TX; /* Transmit VLAN hw accel */
+ ndev->features |= NETIF_F_HW_VLAN_RX; /* Receive VLAN hw acceleration */
+ ndev->features |= NETIF_F_HW_VLAN_FILTER; /* Receive VLAN filtering */
+ ndev->features |= NETIF_F_VLAN_CHALLENGED; /* cannot handle VLAN pkts */
+ ndev->features |= NETIF_F_GSO; /* Enable software GSO. */
+ ndev->features |= NETIF_F_MULTI_QUEUE; /* Has multiple TX/RX queues */
+ ndev->features |= NETIF_F_LRO; /* large receive offload */
+#endif
+
+ /* setup temac private info structure */
+ lp = netdev_priv(ndev);
+ lp->ndev = ndev;
+ lp->dev = &op->dev;
+ lp->options = XTE_OPTION_DEFAULTS;
+ spin_lock_init(&lp->rx_lock);
+ mutex_init(&lp->indirect_mutex);
+
+ /* map device registers */
+ lp->regs = of_iomap(op->node, 0);
+ if (!lp->regs) {
+ dev_err(&op->dev, "could not map temac regs.\n");
+ goto nodev;
+ }
+
+ /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */
+ np = of_parse_phandle(op->node, "llink-connected", 0);
+ if (!np) {
+ dev_err(&op->dev, "could not find DMA node\n");
+ goto nodev;
+ }
+
+ dcrs = dcr_resource_start(np, 0);
+ if (dcrs == 0) {
+ dev_err(&op->dev, "could not get DMA register address\n");
+ goto nodev;;
+ }
+ lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0));
+ dev_dbg(&op->dev, "DCR base: %x\n", dcrs);
+
+ lp->rx_irq = irq_of_parse_and_map(np, 0);
+ lp->tx_irq = irq_of_parse_and_map(np, 1);
+ if (!lp->rx_irq || !lp->tx_irq) {
+ dev_err(&op->dev, "could not determine irqs\n");
+ rc = -ENOMEM;
+ goto nodev;
+ }
+
+ of_node_put(np); /* Finished with the DMA node; drop the reference */
+
+ /* Retrieve the MAC address */
+ addr = of_get_property(op->node, "local-mac-address", &size);
+ if ((!addr) || (size != 6)) {
+ dev_err(&op->dev, "could not find MAC address\n");
+ rc = -ENODEV;
+ goto nodev;
+ }
+ temac_set_mac_address(ndev, (void *)addr);
+
+ rc = temac_mdio_setup(lp, op->node);
+ if (rc)
+ dev_warn(&op->dev, "error registering MDIO bus\n");
+
+ lp->phy_node = of_parse_phandle(op->node, "phy-handle", 0);
+ if (lp->phy_node)
+ dev_dbg(lp->dev, "using PHY node %s (%p)\n", np->full_name, np);
+
+ /* Add the device attributes */
+ rc = sysfs_create_group(&lp->dev->kobj, &temac_attr_group);
+ if (rc) {
+ dev_err(lp->dev, "Error creating sysfs files\n");
+ goto nodev;
+ }
+
+ rc = register_netdev(lp->ndev);
+ if (rc) {
+ dev_err(lp->dev, "register_netdev() error (%i)\n", rc);
+ goto err_register_ndev;
+ }
+
+ return 0;
+
+ err_register_ndev:
+ sysfs_remove_group(&lp->dev->kobj, &temac_attr_group);
+ nodev:
+ free_netdev(ndev);
+ ndev = NULL;
+ return rc;
+}
+
+static int __devexit temac_of_remove(struct of_device *op)
+{
+ struct net_device *ndev = dev_get_drvdata(&op->dev);
+ struct temac_local *lp = netdev_priv(ndev);
+
+ temac_mdio_teardown(lp);
+ unregister_netdev(ndev);
+ sysfs_remove_group(&lp->dev->kobj, &temac_attr_group);
+ if (lp->phy_node)
+ of_node_put(lp->phy_node);
+ lp->phy_node = NULL;
+ dev_set_drvdata(&op->dev, NULL);
+ free_netdev(ndev);
+ return 0;
+}
+
+static struct of_device_id temac_of_match[] __devinitdata = {
+ { .compatible = "xlnx,xps-ll-temac-1.01.b", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, temac_of_match);
+
+static struct of_platform_driver temac_of_driver = {
+ .match_table = temac_of_match,
+ .probe = temac_of_probe,
+ .remove = __devexit_p(temac_of_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "xilinx_temac",
+ },
+};
+
+static int __init temac_init(void)
+{
+ return of_register_platform_driver(&temac_of_driver);
+}
+module_init(temac_init);
+
+static void __exit temac_exit(void)
+{
+ of_unregister_platform_driver(&temac_of_driver);
+}
+module_exit(temac_exit);
+
+MODULE_DESCRIPTION("Xilinx LL_TEMAC Ethernet driver");
+MODULE_AUTHOR("Yoshio Kashiwagi");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ll_temac_mdio.c b/drivers/net/ll_temac_mdio.c
new file mode 100644
index 00000000000..da0e462308d
--- /dev/null
+++ b/drivers/net/ll_temac_mdio.c
@@ -0,0 +1,120 @@
+/*
+ * MDIO bus driver for the Xilinx TEMAC device
+ *
+ * Copyright (c) 2009 Secret Lab Technologies, Ltd.
+ */
+
+#include <linux/io.h>
+#include <linux/netdevice.h>
+#include <linux/mutex.h>
+#include <linux/phy.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_mdio.h>
+
+#include "ll_temac.h"
+
+/* ---------------------------------------------------------------------
+ * MDIO Bus functions
+ */
+static int temac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+{
+ struct temac_local *lp = bus->priv;
+ u32 rc;
+
+ /* Write the PHY address to the MIIM Access Initiator register.
+ * When the transfer completes, the PHY register value will appear
+ * in the LSW0 register */
+ mutex_lock(&lp->indirect_mutex);
+ temac_iow(lp, XTE_LSW0_OFFSET, (phy_id << 5) | reg);
+ rc = temac_indirect_in32(lp, XTE_MIIMAI_OFFSET);
+ mutex_unlock(&lp->indirect_mutex);
+
+ dev_dbg(lp->dev, "temac_mdio_read(phy_id=%i, reg=%x) == %x\n",
+ phy_id, reg, rc);
+
+ return rc;
+}
+
+static int temac_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
+{
+ struct temac_local *lp = bus->priv;
+
+ dev_dbg(lp->dev, "temac_mdio_write(phy_id=%i, reg=%x, val=%x)\n",
+ phy_id, reg, val);
+
+ /* First write the desired value into the write data register
+ * and then write the address into the access initiator register
+ */
+ mutex_lock(&lp->indirect_mutex);
+ temac_indirect_out32(lp, XTE_MGTDR_OFFSET, val);
+ temac_indirect_out32(lp, XTE_MIIMAI_OFFSET, (phy_id << 5) | reg);
+ mutex_unlock(&lp->indirect_mutex);
+
+ return 0;
+}
+
+int temac_mdio_setup(struct temac_local *lp, struct device_node *np)
+{
+ struct mii_bus *bus;
+ const u32 *bus_hz;
+ int clk_div;
+ int rc, size;
+ struct resource res;
+
+ /* Calculate a reasonable divisor for the clock rate */
+ clk_div = 0x3f; /* worst-case default setting */
+ bus_hz = of_get_property(np, "clock-frequency", &size);
+ if (bus_hz && size >= sizeof(*bus_hz)) {
+ clk_div = (*bus_hz) / (2500 * 1000 * 2) - 1;
+ if (clk_div < 1)
+ clk_div = 1;
+ if (clk_div > 0x3f)
+ clk_div = 0x3f;
+ }
+
+ /* Enable the MDIO bus by asserting the enable bit and writing
+ * in the clock config */
+ mutex_lock(&lp->indirect_mutex);
+ temac_indirect_out32(lp, XTE_MC_OFFSET, 1 << 6 | clk_div);
+ mutex_unlock(&lp->indirect_mutex);
+
+ bus = mdiobus_alloc();
+ if (!bus)
+ return -ENOMEM;
+
+ of_address_to_resource(np, 0, &res);
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx",
+ (unsigned long long)res.start);
+ bus->priv = lp;
+ bus->name = "Xilinx TEMAC MDIO";
+ bus->read = temac_mdio_read;
+ bus->write = temac_mdio_write;
+ bus->parent = lp->dev;
+ bus->irq = lp->mdio_irqs; /* preallocated IRQ table */
+
+ lp->mii_bus = bus;
+
+ rc = of_mdiobus_register(bus, np);
+ if (rc)
+ goto err_register;
+
+ mutex_lock(&lp->indirect_mutex);
+ dev_dbg(lp->dev, "MDIO bus registered; MC:%x\n",
+ temac_indirect_in32(lp, XTE_MC_OFFSET));
+ mutex_unlock(&lp->indirect_mutex);
+ return 0;
+
+ err_register:
+ mdiobus_free(bus);
+ return rc;
+}
+
+void temac_mdio_teardown(struct temac_local *lp)
+{
+ mdiobus_unregister(lp->mii_bus);
+ kfree(lp->mii_bus->irq);
+ mdiobus_free(lp->mii_bus);
+ lp->mii_bus = NULL;
+}
+
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index b7d438a367f..da472c68748 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -62,6 +62,7 @@
struct pcpu_lstats {
unsigned long packets;
unsigned long bytes;
+ unsigned long drops;
};
/*
@@ -71,18 +72,22 @@ struct pcpu_lstats {
static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct pcpu_lstats *pcpu_lstats, *lb_stats;
+ int len;
skb_orphan(skb);
- skb->protocol = eth_type_trans(skb,dev);
+ skb->protocol = eth_type_trans(skb, dev);
/* it's OK to use per_cpu_ptr() because BHs are off */
pcpu_lstats = dev->ml_priv;
lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id());
- lb_stats->bytes += skb->len;
- lb_stats->packets++;
- netif_rx(skb);
+ len = skb->len;
+ if (likely(netif_rx(skb) == NET_RX_SUCCESS)) {
+ lb_stats->bytes += len;
+ lb_stats->packets++;
+ } else
+ lb_stats->drops++;
return 0;
}
@@ -93,6 +98,7 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev)
struct net_device_stats *stats = &dev->stats;
unsigned long bytes = 0;
unsigned long packets = 0;
+ unsigned long drops = 0;
int i;
pcpu_lstats = dev->ml_priv;
@@ -102,11 +108,14 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev)
lb_stats = per_cpu_ptr(pcpu_lstats, i);
bytes += lb_stats->bytes;
packets += lb_stats->packets;
+ drops += lb_stats->drops;
}
stats->rx_packets = packets;
stats->tx_packets = packets;
- stats->rx_bytes = bytes;
- stats->tx_bytes = bytes;
+ stats->rx_dropped = drops;
+ stats->rx_errors = drops;
+ stats->rx_bytes = bytes;
+ stats->tx_bytes = bytes;
return stats;
}
@@ -161,6 +170,7 @@ static void loopback_setup(struct net_device *dev)
dev->tx_queue_len = 0;
dev->type = ARPHRD_LOOPBACK; /* 0x0001*/
dev->flags = IFF_LOOPBACK;
+ dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
| NETIF_F_TSO
| NETIF_F_NO_CSUM
diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c
index 22e74a0e036..f8fa0c3f0f6 100644
--- a/drivers/net/mac8390.c
+++ b/drivers/net/mac8390.c
@@ -620,19 +620,12 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd
/* Good, done, now spit out some messages */
printk(KERN_INFO "%s: %s in slot %X (type %s)\n",
- dev->name, ndev->board->name, ndev->board->slot, cardname[type]);
- printk(KERN_INFO "MAC ");
- {
- int i;
- for (i = 0; i < 6; i++) {
- printk("%2.2x", dev->dev_addr[i]);
- if (i < 5)
- printk(":");
- }
- }
- printk(" IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n",
- dev->irq, (int)((dev->mem_end - dev->mem_start)/0x1000) * 4,
- dev->mem_start, access_bitmode?32:16);
+ dev->name, ndev->board->name, ndev->board->slot, cardname[type]);
+ printk(KERN_INFO
+ "MAC %pM IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n",
+ dev->dev_addr, dev->irq,
+ (unsigned int)(dev->mem_end - dev->mem_start) >> 10,
+ dev->mem_start, access_bitmode ? 32 : 16);
return 0;
}
diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c
index 384e072de2e..dab45339d3a 100644
--- a/drivers/net/mac89x0.c
+++ b/drivers/net/mac89x0.c
@@ -73,8 +73,6 @@ static char *version =
or override something. */
#include <linux/module.h>
-#define PRINTK(x) printk x
-
/*
Sources:
@@ -402,7 +400,7 @@ net_send_packet(struct sk_buff *skb, struct net_device *dev)
/* Gasp! It hasn't. But that shouldn't happen since
we're waiting for TxOk, so return 1 and requeue this packet. */
local_irq_restore(flags);
- return 1;
+ return NETDEV_TX_BUSY;
}
/* Write the contents of the packet */
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index e82aee41d77..5b5c25368d1 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -599,6 +599,21 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling receive - used by netconsole and other diagnostic tools
+ * to allow network i/o with interrupts disabled.
+ */
+static void macb_poll_controller(struct net_device *dev)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ macb_interrupt(dev->irq, dev);
+ local_irq_restore(flags);
+}
+#endif
+
static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct macb *bp = netdev_priv(dev);
@@ -630,7 +645,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
"BUG! Tx Ring full when queue awake!\n");
dev_dbg(&bp->pdev->dev, "tx_head = %u, tx_tail = %u\n",
bp->tx_head, bp->tx_tail);
- return 1;
+ return NETDEV_TX_BUSY;
}
entry = bp->tx_head;
@@ -1094,6 +1109,9 @@ static const struct net_device_ops macb_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = eth_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = macb_poll_controller,
+#endif
};
static int __init macb_probe(struct platform_device *pdev)
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index feebbd92aff..1427755c224 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -94,6 +94,16 @@ static void __mace_set_address(struct net_device *dev, void *addr);
*/
static unsigned char *dummy_buf;
+static const struct net_device_ops mace_netdev_ops = {
+ .ndo_open = mace_open,
+ .ndo_stop = mace_close,
+ .ndo_start_xmit = mace_xmit_start,
+ .ndo_set_multicast_list = mace_set_multicast,
+ .ndo_set_mac_address = mace_set_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_id *match)
{
struct device_node *mace = macio_get_of_node(mdev);
@@ -207,11 +217,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
}
}
- dev->open = mace_open;
- dev->stop = mace_close;
- dev->hard_start_xmit = mace_xmit_start;
- dev->set_multicast_list = mace_set_multicast;
- dev->set_mac_address = mace_set_address;
+ dev->netdev_ops = &mace_netdev_ops;
/*
* Most of what is below could be moved to mace_open()
@@ -541,7 +547,7 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
mp->tx_fullup = 1;
spin_unlock_irqrestore(&mp->lock, flags);
- return 1; /* can't take it at the moment */
+ return NETDEV_TX_BUSY; /* can't take it at the moment */
}
spin_unlock_irqrestore(&mp->lock, flags);
diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c
index 274e99bb63a..44f3c2896f2 100644
--- a/drivers/net/macmace.c
+++ b/drivers/net/macmace.c
@@ -180,6 +180,17 @@ static void mace_dma_off(struct net_device *dev)
psc_write_word(PSC_ENETWR_CMD + PSC_SET1, 0x1100);
}
+static const struct net_device_ops mace_netdev_ops = {
+ .ndo_open = mace_open,
+ .ndo_stop = mace_close,
+ .ndo_start_xmit = mace_xmit_start,
+ .ndo_tx_timeout = mace_tx_timeout,
+ .ndo_set_multicast_list = mace_set_multicast,
+ .ndo_set_mac_address = mace_set_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*
* Not really much of a probe. The hardware table tells us if this
* model of Macintrash has a MACE (AV macintoshes)
@@ -240,13 +251,8 @@ static int __devinit mace_probe(struct platform_device *pdev)
return -ENODEV;
}
- dev->open = mace_open;
- dev->stop = mace_close;
- dev->hard_start_xmit = mace_xmit_start;
- dev->tx_timeout = mace_tx_timeout;
+ dev->netdev_ops = &mace_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
- dev->set_multicast_list = mace_set_multicast;
- dev->set_mac_address = mace_set_address;
printk(KERN_INFO "%s: 68K MACE, hardware address %pM\n",
dev->name, dev->dev_addr);
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 214a8cf2b70..99eed9f37c8 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -232,7 +232,7 @@ static int macvlan_open(struct net_device *dev)
if (macvlan_addr_busy(vlan->port, dev->dev_addr))
goto out;
- err = dev_unicast_add(lowerdev, dev->dev_addr, ETH_ALEN);
+ err = dev_unicast_add(lowerdev, dev->dev_addr);
if (err < 0)
goto out;
if (dev->flags & IFF_ALLMULTI) {
@@ -244,7 +244,7 @@ static int macvlan_open(struct net_device *dev)
return 0;
del_unicast:
- dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+ dev_unicast_delete(lowerdev, dev->dev_addr);
out:
return err;
}
@@ -258,7 +258,7 @@ static int macvlan_stop(struct net_device *dev)
if (dev->flags & IFF_ALLMULTI)
dev_set_allmulti(lowerdev, -1);
- dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+ dev_unicast_delete(lowerdev, dev->dev_addr);
macvlan_hash_del(vlan);
return 0;
@@ -282,10 +282,11 @@ static int macvlan_set_mac_address(struct net_device *dev, void *p)
if (macvlan_addr_busy(vlan->port, addr->sa_data))
return -EBUSY;
- if ((err = dev_unicast_add(lowerdev, addr->sa_data, ETH_ALEN)))
+ err = dev_unicast_add(lowerdev, addr->sa_data);
+ if (err)
return err;
- dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+ dev_unicast_delete(lowerdev, dev->dev_addr);
macvlan_hash_change_addr(vlan, addr->sa_data);
}
@@ -358,6 +359,7 @@ static int macvlan_init(struct net_device *dev)
(lowerdev->state & MACVLAN_STATE_MASK);
dev->features = lowerdev->features & MACVLAN_FEATURES;
dev->iflink = lowerdev->ifindex;
+ dev->hard_header_len = lowerdev->hard_header_len;
macvlan_set_lockdep_class(dev);
@@ -374,36 +376,20 @@ static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev)
{
const struct macvlan_dev *vlan = netdev_priv(dev);
- struct net_device *lowerdev = vlan->lowerdev;
-
- if (lowerdev->ethtool_ops == NULL ||
- lowerdev->ethtool_ops->get_rx_csum == NULL)
- return 0;
- return lowerdev->ethtool_ops->get_rx_csum(lowerdev);
+ return dev_ethtool_get_rx_csum(vlan->lowerdev);
}
static int macvlan_ethtool_get_settings(struct net_device *dev,
struct ethtool_cmd *cmd)
{
const struct macvlan_dev *vlan = netdev_priv(dev);
- struct net_device *lowerdev = vlan->lowerdev;
-
- if (!lowerdev->ethtool_ops ||
- !lowerdev->ethtool_ops->get_settings)
- return -EOPNOTSUPP;
-
- return lowerdev->ethtool_ops->get_settings(lowerdev, cmd);
+ return dev_ethtool_get_settings(vlan->lowerdev, cmd);
}
static u32 macvlan_ethtool_get_flags(struct net_device *dev)
{
const struct macvlan_dev *vlan = netdev_priv(dev);
- struct net_device *lowerdev = vlan->lowerdev;
-
- if (!lowerdev->ethtool_ops ||
- !lowerdev->ethtool_ops->get_flags)
- return 0;
- return lowerdev->ethtool_ops->get_flags(lowerdev);
+ return dev_ethtool_get_flags(vlan->lowerdev);
}
static const struct ethtool_ops macvlan_ethtool_ops = {
@@ -430,6 +416,7 @@ static void macvlan_setup(struct net_device *dev)
{
ether_setup(dev);
+ dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
dev->netdev_ops = &macvlan_netdev_ops;
dev->destructor = free_netdev;
dev->header_ops = &macvlan_hard_header_ops,
diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c
new file mode 100644
index 00000000000..dc45e9856c3
--- /dev/null
+++ b/drivers/net/mdio.c
@@ -0,0 +1,431 @@
+/*
+ * mdio.c: Generic support for MDIO-compatible transceivers
+ * Copyright 2006-2009 Solarflare Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include <linux/kernel.h>
+#include <linux/capability.h>
+#include <linux/errno.h>
+#include <linux/ethtool.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+
+/**
+ * mdio45_probe - probe for an MDIO (clause 45) device
+ * @mdio: MDIO interface
+ * @prtad: Expected PHY address
+ *
+ * This sets @prtad and @mmds in the MDIO interface if successful.
+ * Returns 0 on success, negative on error.
+ */
+int mdio45_probe(struct mdio_if_info *mdio, int prtad)
+{
+ int mmd, stat2, devs1, devs2;
+
+ /* Assume PHY must have at least one of PMA/PMD, WIS, PCS, PHY
+ * XS or DTE XS; give up if none is present. */
+ for (mmd = 1; mmd <= 5; mmd++) {
+ /* Is this MMD present? */
+ stat2 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_STAT2);
+ if (stat2 < 0 ||
+ (stat2 & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL)
+ continue;
+
+ /* It should tell us about all the other MMDs */
+ devs1 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_DEVS1);
+ devs2 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_DEVS2);
+ if (devs1 < 0 || devs2 < 0)
+ continue;
+
+ mdio->prtad = prtad;
+ mdio->mmds = devs1 | (devs2 << 16);
+ return 0;
+ }
+
+ return -ENODEV;
+}
+EXPORT_SYMBOL(mdio45_probe);
+
+/**
+ * mdio_set_flag - set or clear flag in an MDIO register
+ * @mdio: MDIO interface
+ * @prtad: PHY address
+ * @devad: MMD address
+ * @addr: Register address
+ * @mask: Mask for flag (single bit set)
+ * @sense: New value of flag
+ *
+ * This debounces changes: it does not write the register if the flag
+ * already has the proper value. Returns 0 on success, negative on error.
+ */
+int mdio_set_flag(const struct mdio_if_info *mdio,
+ int prtad, int devad, u16 addr, int mask,
+ bool sense)
+{
+ int old_val = mdio->mdio_read(mdio->dev, prtad, devad, addr);
+ int new_val;
+
+ if (old_val < 0)
+ return old_val;
+ if (sense)
+ new_val = old_val | mask;
+ else
+ new_val = old_val & ~mask;
+ if (old_val == new_val)
+ return 0;
+ return mdio->mdio_write(mdio->dev, prtad, devad, addr, new_val);
+}
+EXPORT_SYMBOL(mdio_set_flag);
+
+/**
+ * mdio_link_ok - is link status up/OK
+ * @mdio: MDIO interface
+ * @mmd_mask: Mask for MMDs to check
+ *
+ * Returns 1 if the PHY reports link status up/OK, 0 otherwise.
+ * @mmd_mask is normally @mdio->mmds, but if loopback is enabled
+ * the MMDs being bypassed should be excluded from the mask.
+ */
+int mdio45_links_ok(const struct mdio_if_info *mdio, u32 mmd_mask)
+{
+ int devad, reg;
+
+ if (!mmd_mask) {
+ /* Use absence of XGMII faults in lieu of link state */
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad,
+ MDIO_MMD_PHYXS, MDIO_STAT2);
+ return reg >= 0 && !(reg & MDIO_STAT2_RXFAULT);
+ }
+
+ for (devad = 0; mmd_mask; devad++) {
+ if (mmd_mask & (1 << devad)) {
+ mmd_mask &= ~(1 << devad);
+
+ /* Read twice because link state is latched and a
+ * read moves the current state into the register */
+ mdio->mdio_read(mdio->dev, mdio->prtad,
+ devad, MDIO_STAT1);
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad,
+ devad, MDIO_STAT1);
+ if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS))
+ return false;
+ }
+ }
+
+ return true;
+}
+EXPORT_SYMBOL(mdio45_links_ok);
+
+/**
+ * mdio45_nway_restart - restart auto-negotiation for this interface
+ * @mdio: MDIO interface
+ *
+ * Returns 0 on success, negative on error.
+ */
+int mdio45_nway_restart(const struct mdio_if_info *mdio)
+{
+ if (!(mdio->mmds & MDIO_DEVS_AN))
+ return -EOPNOTSUPP;
+
+ mdio_set_flag(mdio, mdio->prtad, MDIO_MMD_AN, MDIO_CTRL1,
+ MDIO_AN_CTRL1_RESTART, true);
+ return 0;
+}
+EXPORT_SYMBOL(mdio45_nway_restart);
+
+static u32 mdio45_get_an(const struct mdio_if_info *mdio, u16 addr)
+{
+ u32 result = 0;
+ int reg;
+
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN, addr);
+ if (reg & ADVERTISE_10HALF)
+ result |= ADVERTISED_10baseT_Half;
+ if (reg & ADVERTISE_10FULL)
+ result |= ADVERTISED_10baseT_Full;
+ if (reg & ADVERTISE_100HALF)
+ result |= ADVERTISED_100baseT_Half;
+ if (reg & ADVERTISE_100FULL)
+ result |= ADVERTISED_100baseT_Full;
+ return result;
+}
+
+/**
+ * mdio45_ethtool_gset_npage - get settings for ETHTOOL_GSET
+ * @mdio: MDIO interface
+ * @ecmd: Ethtool request structure
+ * @npage_adv: Modes currently advertised on next pages
+ * @npage_lpa: Modes advertised by link partner on next pages
+ *
+ * Since the CSRs for auto-negotiation using next pages are not fully
+ * standardised, this function does not attempt to decode them. The
+ * caller must pass them in.
+ */
+void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
+ struct ethtool_cmd *ecmd,
+ u32 npage_adv, u32 npage_lpa)
+{
+ int reg;
+
+ ecmd->transceiver = XCVR_INTERNAL;
+ ecmd->phy_address = mdio->prtad;
+ ecmd->mdio_support =
+ mdio->mode_support & (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22);
+
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+ MDIO_CTRL2);
+ switch (reg & MDIO_PMA_CTRL2_TYPE) {
+ case MDIO_PMA_CTRL2_10GBT:
+ case MDIO_PMA_CTRL2_1000BT:
+ case MDIO_PMA_CTRL2_100BTX:
+ case MDIO_PMA_CTRL2_10BT:
+ ecmd->port = PORT_TP;
+ ecmd->supported = SUPPORTED_TP;
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+ MDIO_SPEED);
+ if (reg & MDIO_SPEED_10G)
+ ecmd->supported |= SUPPORTED_10000baseT_Full;
+ if (reg & MDIO_PMA_SPEED_1000)
+ ecmd->supported |= (SUPPORTED_1000baseT_Full |
+ SUPPORTED_1000baseT_Half);
+ if (reg & MDIO_PMA_SPEED_100)
+ ecmd->supported |= (SUPPORTED_100baseT_Full |
+ SUPPORTED_100baseT_Half);
+ if (reg & MDIO_PMA_SPEED_10)
+ ecmd->supported |= (SUPPORTED_10baseT_Full |
+ SUPPORTED_10baseT_Half);
+ ecmd->advertising = ADVERTISED_TP;
+ break;
+
+ case MDIO_PMA_CTRL2_10GBCX4:
+ ecmd->port = PORT_OTHER;
+ ecmd->supported = 0;
+ ecmd->advertising = 0;
+ break;
+
+ case MDIO_PMA_CTRL2_10GBKX4:
+ case MDIO_PMA_CTRL2_10GBKR:
+ case MDIO_PMA_CTRL2_1000BKX:
+ ecmd->port = PORT_OTHER;
+ ecmd->supported = SUPPORTED_Backplane;
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+ MDIO_PMA_EXTABLE);
+ if (reg & MDIO_PMA_EXTABLE_10GBKX4)
+ ecmd->supported |= SUPPORTED_10000baseKX4_Full;
+ if (reg & MDIO_PMA_EXTABLE_10GBKR)
+ ecmd->supported |= SUPPORTED_10000baseKR_Full;
+ if (reg & MDIO_PMA_EXTABLE_1000BKX)
+ ecmd->supported |= SUPPORTED_1000baseKX_Full;
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+ MDIO_PMA_10GBR_FECABLE);
+ if (reg & MDIO_PMA_10GBR_FECABLE_ABLE)
+ ecmd->supported |= SUPPORTED_10000baseR_FEC;
+ ecmd->advertising = ADVERTISED_Backplane;
+ break;
+
+ /* All the other defined modes are flavours of optical */
+ default:
+ ecmd->port = PORT_FIBRE;
+ ecmd->supported = SUPPORTED_FIBRE;
+ ecmd->advertising = ADVERTISED_FIBRE;
+ break;
+ }
+
+ if (mdio->mmds & MDIO_DEVS_AN) {
+ ecmd->supported |= SUPPORTED_Autoneg;
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN,
+ MDIO_CTRL1);
+ if (reg & MDIO_AN_CTRL1_ENABLE) {
+ ecmd->autoneg = AUTONEG_ENABLE;
+ ecmd->advertising |=
+ ADVERTISED_Autoneg |
+ mdio45_get_an(mdio, MDIO_AN_ADVERTISE) |
+ npage_adv;
+ } else {
+ ecmd->autoneg = AUTONEG_DISABLE;
+ }
+ } else {
+ ecmd->autoneg = AUTONEG_DISABLE;
+ }
+
+ if (ecmd->autoneg) {
+ u32 modes = 0;
+ int an_stat = mdio->mdio_read(mdio->dev, mdio->prtad,
+ MDIO_MMD_AN, MDIO_STAT1);
+
+ /* If AN is complete and successful, report best common
+ * mode, otherwise report best advertised mode. */
+ if (an_stat & MDIO_AN_STAT1_COMPLETE) {
+ ecmd->lp_advertising =
+ mdio45_get_an(mdio, MDIO_AN_LPA) | npage_lpa;
+ if (an_stat & MDIO_AN_STAT1_LPABLE)
+ ecmd->lp_advertising |= ADVERTISED_Autoneg;
+ modes = ecmd->advertising & ecmd->lp_advertising;
+ }
+ if ((modes & ~ADVERTISED_Autoneg) == 0)
+ modes = ecmd->advertising;
+
+ if (modes & (ADVERTISED_10000baseT_Full |
+ ADVERTISED_10000baseKX4_Full |
+ ADVERTISED_10000baseKR_Full)) {
+ ecmd->speed = SPEED_10000;
+ ecmd->duplex = DUPLEX_FULL;
+ } else if (modes & (ADVERTISED_1000baseT_Full |
+ ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseKX_Full)) {
+ ecmd->speed = SPEED_1000;
+ ecmd->duplex = !(modes & ADVERTISED_1000baseT_Half);
+ } else if (modes & (ADVERTISED_100baseT_Full |
+ ADVERTISED_100baseT_Half)) {
+ ecmd->speed = SPEED_100;
+ ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
+ } else {
+ ecmd->speed = SPEED_10;
+ ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
+ }
+ } else {
+ /* Report forced settings */
+ reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+ MDIO_CTRL1);
+ ecmd->speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1) *
+ ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10));
+ ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX ||
+ ecmd->speed == SPEED_10000);
+ }
+
+ /* 10GBASE-T MDI/MDI-X */
+ if (ecmd->port == PORT_TP && ecmd->speed == SPEED_10000) {
+ switch (mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+ MDIO_PMA_10GBT_SWAPPOL)) {
+ case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX:
+ ecmd->eth_tp_mdix = ETH_TP_MDI;
+ break;
+ case 0:
+ ecmd->eth_tp_mdix = ETH_TP_MDI_X;
+ break;
+ default:
+ /* It's complicated... */
+ ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
+ break;
+ }
+ }
+}
+EXPORT_SYMBOL(mdio45_ethtool_gset_npage);
+
+/**
+ * mdio45_ethtool_spauseparam_an - set auto-negotiated pause parameters
+ * @mdio: MDIO interface
+ * @ecmd: Ethtool request structure
+ *
+ * This function assumes that the PHY has an auto-negotiation MMD. It
+ * will enable and disable advertising of flow control as appropriate.
+ */
+void mdio45_ethtool_spauseparam_an(const struct mdio_if_info *mdio,
+ const struct ethtool_pauseparam *ecmd)
+{
+ int adv, old_adv;
+
+ WARN_ON(!(mdio->mmds & MDIO_DEVS_AN));
+
+ old_adv = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN,
+ MDIO_AN_ADVERTISE);
+ adv = old_adv & ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
+ if (ecmd->autoneg)
+ adv |= mii_advertise_flowctrl(
+ (ecmd->rx_pause ? FLOW_CTRL_RX : 0) |
+ (ecmd->tx_pause ? FLOW_CTRL_TX : 0));
+ if (adv != old_adv) {
+ mdio->mdio_write(mdio->dev, mdio->prtad, MDIO_MMD_AN,
+ MDIO_AN_ADVERTISE, adv);
+ mdio45_nway_restart(mdio);
+ }
+}
+EXPORT_SYMBOL(mdio45_ethtool_spauseparam_an);
+
+/**
+ * mdio_mii_ioctl - MII ioctl interface for MDIO (clause 22 or 45) PHYs
+ * @mdio: MDIO interface
+ * @mii_data: MII ioctl data structure
+ * @cmd: MII ioctl command
+ *
+ * Returns 0 on success, negative on error.
+ */
+int mdio_mii_ioctl(const struct mdio_if_info *mdio,
+ struct mii_ioctl_data *mii_data, int cmd)
+{
+ int prtad, devad;
+ u16 addr = mii_data->reg_num;
+
+ /* Validate/convert cmd to one of SIOC{G,S}MIIREG */
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ if (mdio->prtad == MDIO_PRTAD_NONE)
+ return -EOPNOTSUPP;
+ mii_data->phy_id = mdio->prtad;
+ cmd = SIOCGMIIREG;
+ break;
+ case SIOCGMIIREG:
+ break;
+ case SIOCSMIIREG:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ /* Validate/convert phy_id */
+ if ((mdio->mode_support & MDIO_SUPPORTS_C45) &&
+ mdio_phy_id_is_c45(mii_data->phy_id)) {
+ prtad = mdio_phy_id_prtad(mii_data->phy_id);
+ devad = mdio_phy_id_devad(mii_data->phy_id);
+ } else if ((mdio->mode_support & MDIO_SUPPORTS_C22) &&
+ mii_data->phy_id < 0x20) {
+ prtad = mii_data->phy_id;
+ devad = MDIO_DEVAD_NONE;
+ addr &= 0x1f;
+ } else if ((mdio->mode_support & MDIO_EMULATE_C22) &&
+ mdio->prtad != MDIO_PRTAD_NONE &&
+ mii_data->phy_id == mdio->prtad) {
+ /* Remap commonly-used MII registers. */
+ prtad = mdio->prtad;
+ switch (addr) {
+ case MII_BMCR:
+ case MII_BMSR:
+ case MII_PHYSID1:
+ case MII_PHYSID2:
+ devad = __ffs(mdio->mmds);
+ break;
+ case MII_ADVERTISE:
+ case MII_LPA:
+ if (!(mdio->mmds & MDIO_DEVS_AN))
+ return -EINVAL;
+ devad = MDIO_MMD_AN;
+ if (addr == MII_ADVERTISE)
+ addr = MDIO_AN_ADVERTISE;
+ else
+ addr = MDIO_AN_LPA;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else {
+ return -EINVAL;
+ }
+
+ if (cmd == SIOCGMIIREG) {
+ int rc = mdio->mdio_read(mdio->dev, prtad, devad, addr);
+ if (rc < 0)
+ return rc;
+ mii_data->val_out = rc;
+ return 0;
+ } else {
+ return mdio->mdio_write(mdio->dev, prtad, devad, addr,
+ mii_data->val_in);
+ }
+}
+EXPORT_SYMBOL(mdio_mii_ioctl);
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index dbd3436912b..5d04d94f2a2 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -770,9 +770,17 @@ static int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
}
}
-/*
- * Return statistics to the caller
- */
+static const struct net_device_ops meth_netdev_ops = {
+ .ndo_open = meth_open,
+ .ndo_stop = meth_release,
+ .ndo_start_xmit = meth_tx,
+ .ndo_do_ioctl = meth_ioctl,
+ .ndo_tx_timeout = meth_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
/*
* The init function.
*/
@@ -786,16 +794,10 @@ static int __init meth_probe(struct platform_device *pdev)
if (!dev)
return -ENOMEM;
- dev->open = meth_open;
- dev->stop = meth_release;
- dev->hard_start_xmit = meth_tx;
- dev->do_ioctl = meth_ioctl;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = meth_tx_timeout;
- dev->watchdog_timeo = timeout;
-#endif
- dev->irq = MACE_ETHERNET_IRQ;
- dev->base_addr = (unsigned long)&mace->eth;
+ dev->netdev_ops = &meth_netdev_ops;
+ dev->watchdog_timeo = timeout;
+ dev->irq = MACE_ETHERNET_IRQ;
+ dev->base_addr = (unsigned long)&mace->eth;
memcpy(dev->dev_addr, o2meth_eaddr, 6);
priv = netdev_priv(dev);
diff --git a/drivers/net/mii.c b/drivers/net/mii.c
index 92056051f26..d81a5d22a3a 100644
--- a/drivers/net/mii.c
+++ b/drivers/net/mii.c
@@ -31,7 +31,27 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/ethtool.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
+
+static u32 mii_get_an(struct mii_if_info *mii, u16 addr)
+{
+ u32 result = 0;
+ int advert;
+
+ advert = mii->mdio_read(mii->dev, mii->phy_id, addr);
+ if (advert & LPA_LPACK)
+ result |= ADVERTISED_Autoneg;
+ if (advert & ADVERTISE_10HALF)
+ result |= ADVERTISED_10baseT_Half;
+ if (advert & ADVERTISE_10FULL)
+ result |= ADVERTISED_10baseT_Full;
+ if (advert & ADVERTISE_100HALF)
+ result |= ADVERTISED_100baseT_Half;
+ if (advert & ADVERTISE_100FULL)
+ result |= ADVERTISED_100baseT_Full;
+
+ return result;
+}
/**
* mii_ethtool_gset - get settings that are specified in @ecmd
@@ -43,8 +63,8 @@
int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
{
struct net_device *dev = mii->dev;
- u32 advert, bmcr, lpa, nego;
- u32 advert2 = 0, bmcr2 = 0, lpa2 = 0;
+ u16 bmcr, bmsr, ctrl1000 = 0, stat1000 = 0;
+ u32 nego;
ecmd->supported =
(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
@@ -62,50 +82,51 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
/* this isn't fully supported at higher layers */
ecmd->phy_address = mii->phy_id;
+ ecmd->mdio_support = MDIO_SUPPORTS_C22;
ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
- advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
- if (mii->supports_gmii)
- advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
-
- if (advert & ADVERTISE_10HALF)
- ecmd->advertising |= ADVERTISED_10baseT_Half;
- if (advert & ADVERTISE_10FULL)
- ecmd->advertising |= ADVERTISED_10baseT_Full;
- if (advert & ADVERTISE_100HALF)
- ecmd->advertising |= ADVERTISED_100baseT_Half;
- if (advert & ADVERTISE_100FULL)
- ecmd->advertising |= ADVERTISED_100baseT_Full;
- if (advert2 & ADVERTISE_1000HALF)
- ecmd->advertising |= ADVERTISED_1000baseT_Half;
- if (advert2 & ADVERTISE_1000FULL)
- ecmd->advertising |= ADVERTISED_1000baseT_Full;
bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
- lpa = mii->mdio_read(dev, mii->phy_id, MII_LPA);
+ bmsr = mii->mdio_read(dev, mii->phy_id, MII_BMSR);
if (mii->supports_gmii) {
- bmcr2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
- lpa2 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000);
+ ctrl1000 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
+ stat1000 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000);
}
if (bmcr & BMCR_ANENABLE) {
ecmd->advertising |= ADVERTISED_Autoneg;
ecmd->autoneg = AUTONEG_ENABLE;
- nego = mii_nway_result(advert & lpa);
- if ((bmcr2 & (ADVERTISE_1000HALF | ADVERTISE_1000FULL)) &
- (lpa2 >> 2))
+ ecmd->advertising |= mii_get_an(mii, MII_ADVERTISE);
+ if (ctrl1000 & ADVERTISE_1000HALF)
+ ecmd->advertising |= ADVERTISED_1000baseT_Half;
+ if (ctrl1000 & ADVERTISE_1000FULL)
+ ecmd->advertising |= ADVERTISED_1000baseT_Full;
+
+ if (bmsr & BMSR_ANEGCOMPLETE) {
+ ecmd->lp_advertising = mii_get_an(mii, MII_LPA);
+ if (stat1000 & LPA_1000HALF)
+ ecmd->lp_advertising |=
+ ADVERTISED_1000baseT_Half;
+ if (stat1000 & LPA_1000FULL)
+ ecmd->lp_advertising |=
+ ADVERTISED_1000baseT_Full;
+ } else {
+ ecmd->lp_advertising = 0;
+ }
+
+ nego = ecmd->advertising & ecmd->lp_advertising;
+
+ if (nego & (ADVERTISED_1000baseT_Full |
+ ADVERTISED_1000baseT_Half)) {
ecmd->speed = SPEED_1000;
- else if (nego == LPA_100FULL || nego == LPA_100HALF)
+ ecmd->duplex = !!(nego & ADVERTISED_1000baseT_Full);
+ } else if (nego & (ADVERTISED_100baseT_Full |
+ ADVERTISED_100baseT_Half)) {
ecmd->speed = SPEED_100;
- else
- ecmd->speed = SPEED_10;
- if ((lpa2 & LPA_1000FULL) || nego == LPA_100FULL ||
- nego == LPA_10FULL) {
- ecmd->duplex = DUPLEX_FULL;
- mii->full_duplex = 1;
+ ecmd->duplex = !!(nego & ADVERTISED_100baseT_Full);
} else {
- ecmd->duplex = DUPLEX_HALF;
- mii->full_duplex = 0;
+ ecmd->speed = SPEED_10;
+ ecmd->duplex = !!(nego & ADVERTISED_10baseT_Full);
}
} else {
ecmd->autoneg = AUTONEG_DISABLE;
@@ -116,6 +137,8 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
}
+ mii->full_duplex = ecmd->duplex;
+
/* ignore maxtxpkt, maxrxpkt for now */
return 0;
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index 664835b822f..b3b9a147d09 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -237,6 +237,16 @@ static void mipsnet_set_mclist(struct net_device *dev)
{
}
+static const struct net_device_ops mipsnet_netdev_ops = {
+ .ndo_open = mipsnet_open,
+ .ndo_stop = mipsnet_close,
+ .ndo_start_xmit = mipsnet_xmit,
+ .ndo_set_multicast_list = mipsnet_set_mclist,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int __init mipsnet_probe(struct platform_device *dev)
{
struct net_device *netdev;
@@ -250,10 +260,7 @@ static int __init mipsnet_probe(struct platform_device *dev)
platform_set_drvdata(dev, netdev);
- netdev->open = mipsnet_open;
- netdev->stop = mipsnet_close;
- netdev->hard_start_xmit = mipsnet_xmit;
- netdev->set_multicast_list = mipsnet_set_mclist;
+ netdev->netdev_ops = &mipsnet_netdev_ops;
/*
* TODO: probe for these or load them from PARAM
diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile
index 21040a0d81f..1fd068e1d93 100644
--- a/drivers/net/mlx4/Makefile
+++ b/drivers/net/mlx4/Makefile
@@ -5,5 +5,5 @@ mlx4_core-y := alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \
obj-$(CONFIG_MLX4_EN) += mlx4_en.o
-mlx4_en-y := en_main.o en_tx.o en_rx.o en_params.o en_port.o en_cq.o \
+mlx4_en-y := en_main.o en_tx.o en_rx.o en_ethtool.o en_port.o en_cq.o \
en_resources.o en_netdev.o
diff --git a/drivers/net/mlx4/en_cq.c b/drivers/net/mlx4/en_cq.c
index a276125b709..21786ad4455 100644
--- a/drivers/net/mlx4/en_cq.c
+++ b/drivers/net/mlx4/en_cq.c
@@ -89,6 +89,9 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
*cq->mcq.arm_db = 0;
memset(cq->buf, 0, cq->buf_size);
+ if (!cq->is_tx)
+ cq->size = priv->rx_ring[cq->ring].actual_size;
+
err = mlx4_cq_alloc(mdev->dev, cq->size, &cq->wqres.mtt, &mdev->priv_uar,
cq->wqres.db.dma, &cq->mcq, cq->vector, cq->is_tx);
if (err)
diff --git a/drivers/net/mlx4/en_params.c b/drivers/net/mlx4/en_ethtool.c
index c1bd040b9e0..091f99052c9 100644
--- a/drivers/net/mlx4/en_params.c
+++ b/drivers/net/mlx4/en_ethtool.c
@@ -38,64 +38,6 @@
#include "mlx4_en.h"
#include "en_port.h"
-#define MLX4_EN_PARM_INT(X, def_val, desc) \
- static unsigned int X = def_val;\
- module_param(X , uint, 0444); \
- MODULE_PARM_DESC(X, desc);
-
-
-/*
- * Device scope module parameters
- */
-
-
-/* Use a XOR rathern than Toeplitz hash function for RSS */
-MLX4_EN_PARM_INT(rss_xor, 0, "Use XOR hash function for RSS");
-
-/* RSS hash type mask - default to <saddr, daddr, sport, dport> */
-MLX4_EN_PARM_INT(rss_mask, 0xf, "RSS hash type bitmask");
-
-/* Number of LRO sessions per Rx ring (rounded up to a power of two) */
-MLX4_EN_PARM_INT(num_lro, MLX4_EN_MAX_LRO_DESCRIPTORS,
- "Number of LRO sessions per ring or disabled (0)");
-
-/* Priority pausing */
-MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]."
- " Per priority bit mask");
-MLX4_EN_PARM_INT(pfcrx, 0, "Priority based Flow Control policy on RX[7:0]."
- " Per priority bit mask");
-
-int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
-{
- struct mlx4_en_profile *params = &mdev->profile;
- int i;
-
- params->rss_xor = (rss_xor != 0);
- params->rss_mask = rss_mask & 0x1f;
- params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS);
- for (i = 1; i <= MLX4_MAX_PORTS; i++) {
- params->prof[i].rx_pause = 1;
- params->prof[i].rx_ppp = pfcrx;
- params->prof[i].tx_pause = 1;
- params->prof[i].tx_ppp = pfctx;
- params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE;
- params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
- }
- if (pfcrx || pfctx) {
- params->prof[1].tx_ring_num = MLX4_EN_TX_RING_NUM;
- params->prof[2].tx_ring_num = MLX4_EN_TX_RING_NUM;
- } else {
- params->prof[1].tx_ring_num = 1;
- params->prof[2].tx_ring_num = 1;
- }
-
- return 0;
-}
-
-
-/*
- * Ethtool support
- */
static void mlx4_en_update_lro_stats(struct mlx4_en_priv *priv)
{
@@ -326,8 +268,7 @@ static int mlx4_en_set_coalesce(struct net_device *dev,
priv->rx_frames = (coal->rx_max_coalesced_frames ==
MLX4_EN_AUTO_CONF) ?
- MLX4_EN_RX_COAL_TARGET /
- priv->dev->mtu + 1 :
+ MLX4_EN_RX_COAL_TARGET :
coal->rx_max_coalesced_frames;
priv->rx_usecs = (coal->rx_coalesce_usecs ==
MLX4_EN_AUTO_CONF) ?
@@ -371,7 +312,7 @@ static int mlx4_en_set_pauseparam(struct net_device *dev,
priv->prof->rx_pause,
priv->prof->rx_ppp);
if (err)
- mlx4_err(mdev, "Failed setting pause params to\n");
+ en_err(priv, "Failed setting pause params\n");
return err;
}
@@ -421,13 +362,13 @@ static int mlx4_en_set_ringparam(struct net_device *dev,
err = mlx4_en_alloc_resources(priv);
if (err) {
- mlx4_err(mdev, "Failed reallocating port resources\n");
+ en_err(priv, "Failed reallocating port resources\n");
goto out;
}
if (port_up) {
err = mlx4_en_start_port(dev);
if (err)
- mlx4_err(mdev, "Failed starting port\n");
+ en_err(priv, "Failed starting port\n");
}
out:
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c
index 510633fd57f..9ed4a158f89 100644
--- a/drivers/net/mlx4/en_main.c
+++ b/drivers/net/mlx4/en_main.c
@@ -51,6 +51,55 @@ static const char mlx4_en_version[] =
DRV_NAME ": Mellanox ConnectX HCA Ethernet driver v"
DRV_VERSION " (" DRV_RELDATE ")\n";
+#define MLX4_EN_PARM_INT(X, def_val, desc) \
+ static unsigned int X = def_val;\
+ module_param(X , uint, 0444); \
+ MODULE_PARM_DESC(X, desc);
+
+
+/*
+ * Device scope module parameters
+ */
+
+
+/* Use a XOR rathern than Toeplitz hash function for RSS */
+MLX4_EN_PARM_INT(rss_xor, 0, "Use XOR hash function for RSS");
+
+/* RSS hash type mask - default to <saddr, daddr, sport, dport> */
+MLX4_EN_PARM_INT(rss_mask, 0xf, "RSS hash type bitmask");
+
+/* Number of LRO sessions per Rx ring (rounded up to a power of two) */
+MLX4_EN_PARM_INT(num_lro, MLX4_EN_MAX_LRO_DESCRIPTORS,
+ "Number of LRO sessions per ring or disabled (0)");
+
+/* Priority pausing */
+MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]."
+ " Per priority bit mask");
+MLX4_EN_PARM_INT(pfcrx, 0, "Priority based Flow Control policy on RX[7:0]."
+ " Per priority bit mask");
+
+static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
+{
+ struct mlx4_en_profile *params = &mdev->profile;
+ int i;
+
+ params->rss_xor = (rss_xor != 0);
+ params->rss_mask = rss_mask & 0x1f;
+ params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS);
+ for (i = 1; i <= MLX4_MAX_PORTS; i++) {
+ params->prof[i].rx_pause = 1;
+ params->prof[i].rx_ppp = pfcrx;
+ params->prof[i].tx_pause = 1;
+ params->prof[i].tx_ppp = pfctx;
+ params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE;
+ params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
+ params->prof[i].tx_ring_num = MLX4_EN_NUM_TX_RINGS +
+ (!!pfcrx) * MLX4_EN_NUM_PPP_RINGS;
+ }
+
+ return 0;
+}
+
static void mlx4_en_event(struct mlx4_dev *dev, void *endev_ptr,
enum mlx4_dev_event event, int port)
{
@@ -194,28 +243,11 @@ static void *mlx4_en_add(struct mlx4_dev *dev)
/* Create a netdev for each port */
mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) {
mlx4_info(mdev, "Activating port:%d\n", i);
- if (mlx4_en_init_netdev(mdev, i, &mdev->profile.prof[i])) {
+ if (mlx4_en_init_netdev(mdev, i, &mdev->profile.prof[i]))
mdev->pndev[i] = NULL;
- goto err_free_netdev;
- }
}
return mdev;
-
-err_free_netdev:
- mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) {
- if (mdev->pndev[i])
- mlx4_en_destroy_netdev(mdev->pndev[i]);
- }
-
- mutex_lock(&mdev->state_lock);
- mdev->device_up = false;
- mutex_unlock(&mdev->state_lock);
- flush_workqueue(mdev->workqueue);
-
- /* Stop event queue before we drop down to release shared SW state */
- destroy_workqueue(mdev->workqueue);
-
err_mr:
mlx4_mr_free(dev, &mdev->mr);
err_uar:
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index e8eeef0c9c9..e02bafdd368 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -51,14 +51,14 @@ static void mlx4_en_vlan_rx_register(struct net_device *dev, struct vlan_group *
struct mlx4_en_dev *mdev = priv->mdev;
int err;
- mlx4_dbg(HW, priv, "Registering VLAN group:%p\n", grp);
+ en_dbg(HW, priv, "Registering VLAN group:%p\n", grp);
priv->vlgrp = grp;
mutex_lock(&mdev->state_lock);
if (mdev->device_up && priv->port_up) {
err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, grp);
if (err)
- mlx4_err(mdev, "Failed configuring VLAN filter\n");
+ en_err(priv, "Failed configuring VLAN filter\n");
}
mutex_unlock(&mdev->state_lock);
}
@@ -72,15 +72,15 @@ static void mlx4_en_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
if (!priv->vlgrp)
return;
- mlx4_dbg(HW, priv, "adding VLAN:%d (vlgrp entry:%p)\n",
- vid, vlan_group_get_device(priv->vlgrp, vid));
+ en_dbg(HW, priv, "adding VLAN:%d (vlgrp entry:%p)\n",
+ vid, vlan_group_get_device(priv->vlgrp, vid));
/* Add VID to port VLAN filter */
mutex_lock(&mdev->state_lock);
if (mdev->device_up && priv->port_up) {
err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
if (err)
- mlx4_err(mdev, "Failed configuring VLAN filter\n");
+ en_err(priv, "Failed configuring VLAN filter\n");
}
mutex_unlock(&mdev->state_lock);
}
@@ -94,9 +94,8 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
if (!priv->vlgrp)
return;
- mlx4_dbg(HW, priv, "Killing VID:%d (vlgrp:%p vlgrp "
- "entry:%p)\n", vid, priv->vlgrp,
- vlan_group_get_device(priv->vlgrp, vid));
+ en_dbg(HW, priv, "Killing VID:%d (vlgrp:%p vlgrp entry:%p)\n",
+ vid, priv->vlgrp, vlan_group_get_device(priv->vlgrp, vid));
vlan_group_set_device(priv->vlgrp, vid, NULL);
/* Remove VID from port VLAN filter */
@@ -104,7 +103,7 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
if (mdev->device_up && priv->port_up) {
err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
if (err)
- mlx4_err(mdev, "Failed configuring VLAN filter\n");
+ en_err(priv, "Failed configuring VLAN filter\n");
}
mutex_unlock(&mdev->state_lock);
}
@@ -150,9 +149,10 @@ static void mlx4_en_do_set_mac(struct work_struct *work)
err = mlx4_register_mac(mdev->dev, priv->port,
priv->mac, &priv->mac_index);
if (err)
- mlx4_err(mdev, "Failed changing HW MAC address\n");
+ en_err(priv, "Failed changing HW MAC address\n");
} else
- mlx4_dbg(HW, priv, "Port is down, exiting...\n");
+ en_dbg(HW, priv, "Port is down while "
+ "registering mac, exiting...\n");
mutex_unlock(&mdev->state_lock);
}
@@ -174,7 +174,6 @@ static void mlx4_en_clear_list(struct net_device *dev)
static void mlx4_en_cache_mclist(struct net_device *dev)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
- struct mlx4_en_dev *mdev = priv->mdev;
struct dev_mc_list *mclist;
struct dev_mc_list *tmp;
struct dev_mc_list *plist = NULL;
@@ -182,7 +181,7 @@ static void mlx4_en_cache_mclist(struct net_device *dev)
for (mclist = dev->mc_list; mclist; mclist = mclist->next) {
tmp = kmalloc(sizeof(struct dev_mc_list), GFP_ATOMIC);
if (!tmp) {
- mlx4_err(mdev, "failed to allocate multicast list\n");
+ en_err(priv, "failed to allocate multicast list\n");
mlx4_en_clear_list(dev);
return;
}
@@ -219,13 +218,13 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
mutex_lock(&mdev->state_lock);
if (!mdev->device_up) {
- mlx4_dbg(HW, priv, "Card is not up, ignoring "
- "multicast change.\n");
+ en_dbg(HW, priv, "Card is not up, "
+ "ignoring multicast change.\n");
goto out;
}
if (!priv->port_up) {
- mlx4_dbg(HW, priv, "Port is down, ignoring "
- "multicast change.\n");
+ en_dbg(HW, priv, "Port is down, "
+ "ignoring multicast change.\n");
goto out;
}
@@ -236,29 +235,27 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
if (dev->flags & IFF_PROMISC) {
if (!(priv->flags & MLX4_EN_FLAG_PROMISC)) {
if (netif_msg_rx_status(priv))
- mlx4_warn(mdev, "Port:%d entering promiscuous mode\n",
- priv->port);
+ en_warn(priv, "Entering promiscuous mode\n");
priv->flags |= MLX4_EN_FLAG_PROMISC;
/* Enable promiscouos mode */
err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port,
priv->base_qpn, 1);
if (err)
- mlx4_err(mdev, "Failed enabling "
- "promiscous mode\n");
+ en_err(priv, "Failed enabling "
+ "promiscous mode\n");
/* Disable port multicast filter (unconditionally) */
err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
0, MLX4_MCAST_DISABLE);
if (err)
- mlx4_err(mdev, "Failed disabling "
- "multicast filter\n");
+ en_err(priv, "Failed disabling "
+ "multicast filter\n");
/* Disable port VLAN filter */
err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, NULL);
if (err)
- mlx4_err(mdev, "Failed disabling "
- "VLAN filter\n");
+ en_err(priv, "Failed disabling VLAN filter\n");
}
goto out;
}
@@ -269,20 +266,19 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
if (priv->flags & MLX4_EN_FLAG_PROMISC) {
if (netif_msg_rx_status(priv))
- mlx4_warn(mdev, "Port:%d leaving promiscuous mode\n",
- priv->port);
+ en_warn(priv, "Leaving promiscuous mode\n");
priv->flags &= ~MLX4_EN_FLAG_PROMISC;
/* Disable promiscouos mode */
err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port,
priv->base_qpn, 0);
if (err)
- mlx4_err(mdev, "Failed disabling promiscous mode\n");
+ en_err(priv, "Failed disabling promiscous mode\n");
/* Enable port VLAN filter */
err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
if (err)
- mlx4_err(mdev, "Failed enabling VLAN filter\n");
+ en_err(priv, "Failed enabling VLAN filter\n");
}
/* Enable/disable the multicast filter according to IFF_ALLMULTI */
@@ -290,12 +286,12 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
0, MLX4_MCAST_DISABLE);
if (err)
- mlx4_err(mdev, "Failed disabling multicast filter\n");
+ en_err(priv, "Failed disabling multicast filter\n");
} else {
err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
0, MLX4_MCAST_DISABLE);
if (err)
- mlx4_err(mdev, "Failed disabling multicast filter\n");
+ en_err(priv, "Failed disabling multicast filter\n");
/* Flush mcast filter and init it with broadcast address */
mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, ETH_BCAST,
@@ -314,7 +310,7 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
0, MLX4_MCAST_ENABLE);
if (err)
- mlx4_err(mdev, "Failed enabling multicast filter\n");
+ en_err(priv, "Failed enabling multicast filter\n");
mlx4_en_clear_list(dev);
}
@@ -346,10 +342,10 @@ static void mlx4_en_tx_timeout(struct net_device *dev)
struct mlx4_en_dev *mdev = priv->mdev;
if (netif_msg_timer(priv))
- mlx4_warn(mdev, "Tx timeout called on port:%d\n", priv->port);
+ en_warn(priv, "Tx timeout called on port:%d\n", priv->port);
priv->port_stats.tx_timeout++;
- mlx4_dbg(DRV, priv, "Scheduling watchdog\n");
+ en_dbg(DRV, priv, "Scheduling watchdog\n");
queue_work(mdev->workqueue, &priv->watchdog_task);
}
@@ -376,10 +372,10 @@ static void mlx4_en_set_default_moderation(struct mlx4_en_priv *priv)
* satisfy our coelsing target.
* - moder_time is set to a fixed value.
*/
- priv->rx_frames = MLX4_EN_RX_COAL_TARGET / priv->dev->mtu + 1;
+ priv->rx_frames = MLX4_EN_RX_COAL_TARGET;
priv->rx_usecs = MLX4_EN_RX_COAL_TIME;
- mlx4_dbg(INTR, priv, "Default coalesing params for mtu:%d - "
- "rx_frames:%d rx_usecs:%d\n",
+ en_dbg(INTR, priv, "Default coalesing params for mtu:%d - "
+ "rx_frames:%d rx_usecs:%d\n",
priv->dev->mtu, priv->rx_frames, priv->rx_usecs);
/* Setup cq moderation params */
@@ -412,7 +408,6 @@ static void mlx4_en_set_default_moderation(struct mlx4_en_priv *priv)
static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
{
unsigned long period = (unsigned long) (jiffies - priv->last_moder_jiffies);
- struct mlx4_en_dev *mdev = priv->mdev;
struct mlx4_en_cq *cq;
unsigned long packets;
unsigned long rate;
@@ -472,11 +467,11 @@ static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
moder_time = priv->rx_usecs;
}
- mlx4_dbg(INTR, priv, "tx rate:%lu rx_rate:%lu\n",
- tx_pkt_diff * HZ / period, rx_pkt_diff * HZ / period);
+ en_dbg(INTR, priv, "tx rate:%lu rx_rate:%lu\n",
+ tx_pkt_diff * HZ / period, rx_pkt_diff * HZ / period);
- mlx4_dbg(INTR, priv, "Rx moder_time changed from:%d to %d period:%lu "
- "[jiff] packets:%lu avg_pkt_size:%lu rate:%lu [p/s])\n",
+ en_dbg(INTR, priv, "Rx moder_time changed from:%d to %d period:%lu "
+ "[jiff] packets:%lu avg_pkt_size:%lu rate:%lu [p/s])\n",
priv->last_moder_time, moder_time, period, packets,
avg_pkt_size, rate);
@@ -487,8 +482,7 @@ static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
cq->moder_time = moder_time;
err = mlx4_en_set_cq_moder(priv, cq);
if (err) {
- mlx4_err(mdev, "Failed modifying moderation for cq:%d "
- "on port:%d\n", i, priv->port);
+ en_err(priv, "Failed modifying moderation for cq:%d\n", i);
break;
}
}
@@ -511,8 +505,7 @@ static void mlx4_en_do_get_stats(struct work_struct *work)
err = mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 0);
if (err)
- mlx4_dbg(HW, priv, "Could not update stats for "
- "port:%d\n", priv->port);
+ en_dbg(HW, priv, "Could not update stats \n");
mutex_lock(&mdev->state_lock);
if (mdev->device_up) {
@@ -536,12 +529,10 @@ static void mlx4_en_linkstate(struct work_struct *work)
* report to system log */
if (priv->last_link_state != linkstate) {
if (linkstate == MLX4_DEV_EVENT_PORT_DOWN) {
- if (netif_msg_link(priv))
- mlx4_info(mdev, "Port %d - link down\n", priv->port);
+ en_dbg(LINK, priv, "Link Down\n");
netif_carrier_off(priv->dev);
} else {
- if (netif_msg_link(priv))
- mlx4_info(mdev, "Port %d - link up\n", priv->port);
+ en_dbg(LINK, priv, "Link Up\n");
netif_carrier_on(priv->dev);
}
}
@@ -556,58 +547,53 @@ int mlx4_en_start_port(struct net_device *dev)
struct mlx4_en_dev *mdev = priv->mdev;
struct mlx4_en_cq *cq;
struct mlx4_en_tx_ring *tx_ring;
- struct mlx4_en_rx_ring *rx_ring;
int rx_index = 0;
int tx_index = 0;
- u16 stride;
int err = 0;
int i;
int j;
if (priv->port_up) {
- mlx4_dbg(DRV, priv, "start port called while port already up\n");
+ en_dbg(DRV, priv, "start port called while port already up\n");
return 0;
}
/* Calculate Rx buf size */
dev->mtu = min(dev->mtu, priv->max_mtu);
mlx4_en_calc_rx_buf(dev);
- mlx4_dbg(DRV, priv, "Rx buf size:%d\n", priv->rx_skb_size);
- stride = roundup_pow_of_two(sizeof(struct mlx4_en_rx_desc) +
- DS_SIZE * priv->num_frags);
+ en_dbg(DRV, priv, "Rx buf size:%d\n", priv->rx_skb_size);
+
/* Configure rx cq's and rings */
+ err = mlx4_en_activate_rx_rings(priv);
+ if (err) {
+ en_err(priv, "Failed to activate RX rings\n");
+ return err;
+ }
for (i = 0; i < priv->rx_ring_num; i++) {
cq = &priv->rx_cq[i];
- rx_ring = &priv->rx_ring[i];
err = mlx4_en_activate_cq(priv, cq);
if (err) {
- mlx4_err(mdev, "Failed activating Rx CQ\n");
+ en_err(priv, "Failed activating Rx CQ\n");
goto cq_err;
}
for (j = 0; j < cq->size; j++)
cq->buf[j].owner_sr_opcode = MLX4_CQE_OWNER_MASK;
err = mlx4_en_set_cq_moder(priv, cq);
if (err) {
- mlx4_err(mdev, "Failed setting cq moderation parameters");
+ en_err(priv, "Failed setting cq moderation parameters");
mlx4_en_deactivate_cq(priv, cq);
goto cq_err;
}
mlx4_en_arm_cq(priv, cq);
-
+ priv->rx_ring[i].cqn = cq->mcq.cqn;
++rx_index;
}
- err = mlx4_en_activate_rx_rings(priv);
- if (err) {
- mlx4_err(mdev, "Failed to activate RX rings\n");
- goto cq_err;
- }
-
err = mlx4_en_config_rss_steer(priv);
if (err) {
- mlx4_err(mdev, "Failed configuring rss steering\n");
- goto rx_err;
+ en_err(priv, "Failed configuring rss steering\n");
+ goto cq_err;
}
/* Configure tx cq's and rings */
@@ -616,16 +602,16 @@ int mlx4_en_start_port(struct net_device *dev)
cq = &priv->tx_cq[i];
err = mlx4_en_activate_cq(priv, cq);
if (err) {
- mlx4_err(mdev, "Failed allocating Tx CQ\n");
+ en_err(priv, "Failed allocating Tx CQ\n");
goto tx_err;
}
err = mlx4_en_set_cq_moder(priv, cq);
if (err) {
- mlx4_err(mdev, "Failed setting cq moderation parameters");
+ en_err(priv, "Failed setting cq moderation parameters");
mlx4_en_deactivate_cq(priv, cq);
goto tx_err;
}
- mlx4_dbg(DRV, priv, "Resetting index of collapsed CQ:%d to -1\n", i);
+ en_dbg(DRV, priv, "Resetting index of collapsed CQ:%d to -1\n", i);
cq->buf->wqe_index = cpu_to_be16(0xffff);
/* Configure ring */
@@ -633,7 +619,7 @@ int mlx4_en_start_port(struct net_device *dev)
err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn,
priv->rx_ring[0].srq.srqn);
if (err) {
- mlx4_err(mdev, "Failed allocating Tx ring\n");
+ en_err(priv, "Failed allocating Tx ring\n");
mlx4_en_deactivate_cq(priv, cq);
goto tx_err;
}
@@ -651,30 +637,30 @@ int mlx4_en_start_port(struct net_device *dev)
priv->prof->rx_pause,
priv->prof->rx_ppp);
if (err) {
- mlx4_err(mdev, "Failed setting port general configurations"
- " for port %d, with error %d\n", priv->port, err);
+ en_err(priv, "Failed setting port general configurations "
+ "for port %d, with error %d\n", priv->port, err);
goto tx_err;
}
/* Set default qp number */
err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, priv->base_qpn, 0);
if (err) {
- mlx4_err(mdev, "Failed setting default qp numbers\n");
+ en_err(priv, "Failed setting default qp numbers\n");
goto tx_err;
}
/* Set port mac number */
- mlx4_dbg(DRV, priv, "Setting mac for port %d\n", priv->port);
+ en_dbg(DRV, priv, "Setting mac for port %d\n", priv->port);
err = mlx4_register_mac(mdev->dev, priv->port,
priv->mac, &priv->mac_index);
if (err) {
- mlx4_err(mdev, "Failed setting port mac\n");
+ en_err(priv, "Failed setting port mac\n");
goto tx_err;
}
/* Init port */
- mlx4_dbg(HW, priv, "Initializing port\n");
+ en_dbg(HW, priv, "Initializing port\n");
err = mlx4_INIT_PORT(mdev->dev, priv->port);
if (err) {
- mlx4_err(mdev, "Failed Initializing port\n");
+ en_err(priv, "Failed Initializing port\n");
goto mac_err;
}
@@ -694,12 +680,11 @@ tx_err:
}
mlx4_en_release_rss_steer(priv);
-rx_err:
- for (i = 0; i < priv->rx_ring_num; i++)
- mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
cq_err:
while (rx_index--)
mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]);
+ for (i = 0; i < priv->rx_ring_num; i++)
+ mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
return err; /* need to close devices */
}
@@ -712,8 +697,7 @@ void mlx4_en_stop_port(struct net_device *dev)
int i;
if (!priv->port_up) {
- mlx4_dbg(DRV, priv, "stop port (%d) called while port already down\n",
- priv->port);
+ en_dbg(DRV, priv, "stop port called while port already down\n");
return;
}
netif_stop_queue(dev);
@@ -758,13 +742,13 @@ static void mlx4_en_restart(struct work_struct *work)
struct mlx4_en_dev *mdev = priv->mdev;
struct net_device *dev = priv->dev;
- mlx4_dbg(DRV, priv, "Watchdog task called for port %d\n", priv->port);
+ en_dbg(DRV, priv, "Watchdog task called for port %d\n", priv->port);
mutex_lock(&mdev->state_lock);
if (priv->port_up) {
mlx4_en_stop_port(dev);
if (mlx4_en_start_port(dev))
- mlx4_err(mdev, "Failed restarting port %d\n", priv->port);
+ en_err(priv, "Failed restarting port %d\n", priv->port);
}
mutex_unlock(&mdev->state_lock);
}
@@ -780,14 +764,14 @@ static int mlx4_en_open(struct net_device *dev)
mutex_lock(&mdev->state_lock);
if (!mdev->device_up) {
- mlx4_err(mdev, "Cannot open - device down/disabled\n");
+ en_err(priv, "Cannot open - device down/disabled\n");
err = -EBUSY;
goto out;
}
/* Reset HW statistics and performance counters */
if (mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 1))
- mlx4_dbg(HW, priv, "Failed dumping statistics\n");
+ en_dbg(HW, priv, "Failed dumping statistics\n");
memset(&priv->stats, 0, sizeof(priv->stats));
memset(&priv->pstats, 0, sizeof(priv->pstats));
@@ -804,7 +788,7 @@ static int mlx4_en_open(struct net_device *dev)
mlx4_en_set_default_moderation(priv);
err = mlx4_en_start_port(dev);
if (err)
- mlx4_err(mdev, "Failed starting port:%d\n", priv->port);
+ en_err(priv, "Failed starting port:%d\n", priv->port);
out:
mutex_unlock(&mdev->state_lock);
@@ -817,8 +801,7 @@ static int mlx4_en_close(struct net_device *dev)
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = priv->mdev;
- if (netif_msg_ifdown(priv))
- mlx4_info(mdev, "Close called for port:%d\n", priv->port);
+ en_dbg(IFDOWN, priv, "Close port called\n");
mutex_lock(&mdev->state_lock);
@@ -850,7 +833,6 @@ void mlx4_en_free_resources(struct mlx4_en_priv *priv)
int mlx4_en_alloc_resources(struct mlx4_en_priv *priv)
{
- struct mlx4_en_dev *mdev = priv->mdev;
struct mlx4_en_port_profile *prof = priv->prof;
int i;
@@ -879,7 +861,7 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv)
return 0;
err:
- mlx4_err(mdev, "Failed to allocate NIC resources\n");
+ en_err(priv, "Failed to allocate NIC resources\n");
return -ENOMEM;
}
@@ -889,7 +871,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = priv->mdev;
- mlx4_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
+ en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
/* Unregister device - this will close the port if it was up */
if (priv->registered)
@@ -918,11 +900,11 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
struct mlx4_en_dev *mdev = priv->mdev;
int err = 0;
- mlx4_dbg(DRV, priv, "Change MTU called - current:%d new:%d\n",
+ en_dbg(DRV, priv, "Change MTU called - current:%d new:%d\n",
dev->mtu, new_mtu);
if ((new_mtu < MLX4_EN_MIN_MTU) || (new_mtu > priv->max_mtu)) {
- mlx4_err(mdev, "Bad MTU size:%d.\n", new_mtu);
+ en_err(priv, "Bad MTU size:%d.\n", new_mtu);
return -EPERM;
}
dev->mtu = new_mtu;
@@ -932,13 +914,13 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
if (!mdev->device_up) {
/* NIC is probably restarting - let watchdog task reset
* the port */
- mlx4_dbg(DRV, priv, "Change MTU called with card down!?\n");
+ en_dbg(DRV, priv, "Change MTU called with card down!?\n");
} else {
mlx4_en_stop_port(dev);
mlx4_en_set_default_moderation(priv);
err = mlx4_en_start_port(dev);
if (err) {
- mlx4_err(mdev, "Failed restarting port:%d\n",
+ en_err(priv, "Failed restarting port:%d\n",
priv->port);
queue_work(mdev->workqueue, &priv->watchdog_task);
}
@@ -952,6 +934,7 @@ static const struct net_device_ops mlx4_netdev_ops = {
.ndo_open = mlx4_en_open,
.ndo_stop = mlx4_en_close,
.ndo_start_xmit = mlx4_en_xmit,
+ .ndo_select_queue = mlx4_en_select_queue,
.ndo_get_stats = mlx4_en_get_stats,
.ndo_set_multicast_list = mlx4_en_set_multicast,
.ndo_set_mac_address = mlx4_en_set_mac,
@@ -974,7 +957,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
int i;
int err;
- dev = alloc_etherdev(sizeof(struct mlx4_en_priv));
+ dev = alloc_etherdev_mq(sizeof(struct mlx4_en_priv), prof->tx_ring_num);
if (dev == NULL) {
mlx4_err(mdev, "Net device allocation failed\n");
return -ENOMEM;
@@ -1012,7 +995,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
priv->max_mtu = mdev->dev->caps.eth_mtu_cap[priv->port];
priv->mac = mdev->dev->caps.def_mac[priv->port];
if (ILLEGAL_MAC(priv->mac)) {
- mlx4_err(mdev, "Port: %d, invalid mac burned: 0x%llx, quiting\n",
+ en_err(priv, "Port: %d, invalid mac burned: 0x%llx, quiting\n",
priv->port, priv->mac);
err = -EINVAL;
goto out;
@@ -1031,19 +1014,17 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
err = mlx4_alloc_hwq_res(mdev->dev, &priv->res,
MLX4_EN_PAGE_SIZE, MLX4_EN_PAGE_SIZE);
if (err) {
- mlx4_err(mdev, "Failed to allocate page for rx qps\n");
+ en_err(priv, "Failed to allocate page for rx qps\n");
goto out;
}
priv->allocated = 1;
- /* Populate Tx priority mappings */
- mlx4_en_set_prio_map(priv, priv->tx_prio_map, prof->tx_ring_num);
-
/*
* Initialize netdev entry points
*/
dev->netdev_ops = &mlx4_netdev_ops;
dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT;
+ dev->real_num_tx_queues = MLX4_EN_NUM_TX_RINGS;
SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops);
@@ -1057,7 +1038,9 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
* Set driver features
*/
dev->features |= NETIF_F_SG;
+ dev->vlan_features |= NETIF_F_SG;
dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
dev->features |= NETIF_F_HIGHDMA;
dev->features |= NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
@@ -1067,6 +1050,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
if (mdev->LSO_support) {
dev->features |= NETIF_F_TSO;
dev->features |= NETIF_F_TSO6;
+ dev->vlan_features |= NETIF_F_TSO;
+ dev->vlan_features |= NETIF_F_TSO6;
}
mdev->pndev[port] = dev;
@@ -1074,9 +1059,13 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
netif_carrier_off(dev);
err = register_netdev(dev);
if (err) {
- mlx4_err(mdev, "Netdev registration failed\n");
+ en_err(priv, "Netdev registration failed for port %d\n", port);
goto out;
}
+
+ en_warn(priv, "Using %d TX rings\n", prof->tx_ring_num);
+ en_warn(priv, "Using %d RX rings\n", prof->rx_ring_num);
+
priv->registered = 1;
queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
return 0;
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index 9ee873e872b..5a14899c1e2 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -114,8 +114,8 @@ static int mlx4_en_init_allocator(struct mlx4_en_priv *priv,
goto out;
page_alloc->offset = priv->frag_info[i].frag_align;
- mlx4_dbg(DRV, priv, "Initialized allocator:%d with page:%p\n",
- i, page_alloc->page);
+ en_dbg(DRV, priv, "Initialized allocator:%d with page:%p\n",
+ i, page_alloc->page);
}
return 0;
@@ -136,8 +136,8 @@ static void mlx4_en_destroy_allocator(struct mlx4_en_priv *priv,
for (i = 0; i < priv->num_frags; i++) {
page_alloc = &ring->page_alloc[i];
- mlx4_dbg(DRV, priv, "Freeing allocator:%d count:%d\n",
- i, page_count(page_alloc->page));
+ en_dbg(DRV, priv, "Freeing allocator:%d count:%d\n",
+ i, page_count(page_alloc->page));
put_page(page_alloc->page);
page_alloc->page = NULL;
@@ -202,12 +202,34 @@ static inline void mlx4_en_update_rx_prod_db(struct mlx4_en_rx_ring *ring)
*ring->wqres.db.db = cpu_to_be32(ring->prod & 0xffff);
}
-static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv)
+static void mlx4_en_free_rx_desc(struct mlx4_en_priv *priv,
+ struct mlx4_en_rx_ring *ring,
+ int index)
{
struct mlx4_en_dev *mdev = priv->mdev;
+ struct skb_frag_struct *skb_frags;
+ struct mlx4_en_rx_desc *rx_desc = ring->buf + (index << ring->log_stride);
+ dma_addr_t dma;
+ int nr;
+
+ skb_frags = ring->rx_info + (index << priv->log_rx_info);
+ for (nr = 0; nr < priv->num_frags; nr++) {
+ en_dbg(DRV, priv, "Freeing fragment:%d\n", nr);
+ dma = be64_to_cpu(rx_desc->data[nr].addr);
+
+ en_dbg(DRV, priv, "Unmaping buffer at dma:0x%llx\n", (u64) dma);
+ pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size,
+ PCI_DMA_FROMDEVICE);
+ put_page(skb_frags[nr].page);
+ }
+}
+
+static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv)
+{
struct mlx4_en_rx_ring *ring;
int ring_ind;
int buf_ind;
+ int new_size;
for (buf_ind = 0; buf_ind < priv->prof->rx_ring_size; buf_ind++) {
for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) {
@@ -216,22 +238,34 @@ static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv)
if (mlx4_en_prepare_rx_desc(priv, ring,
ring->actual_size)) {
if (ring->actual_size < MLX4_EN_MIN_RX_SIZE) {
- mlx4_err(mdev, "Failed to allocate "
- "enough rx buffers\n");
+ en_err(priv, "Failed to allocate "
+ "enough rx buffers\n");
return -ENOMEM;
} else {
- if (netif_msg_rx_err(priv))
- mlx4_warn(mdev,
- "Only %d buffers allocated\n",
- ring->actual_size);
- goto out;
+ new_size = rounddown_pow_of_two(ring->actual_size);
+ en_warn(priv, "Only %d buffers allocated "
+ "reducing ring size to %d",
+ ring->actual_size, new_size);
+ goto reduce_rings;
}
}
ring->actual_size++;
ring->prod++;
}
}
-out:
+ return 0;
+
+reduce_rings:
+ for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) {
+ ring = &priv->rx_ring[ring_ind];
+ while (ring->actual_size > new_size) {
+ ring->actual_size--;
+ ring->prod--;
+ mlx4_en_free_rx_desc(priv, ring, ring->actual_size);
+ }
+ ring->size_mask = ring->actual_size - 1;
+ }
+
return 0;
}
@@ -247,15 +281,14 @@ static int mlx4_en_fill_rx_buf(struct net_device *dev,
ring->size_mask);
if (err) {
if (netif_msg_rx_err(priv))
- mlx4_warn(priv->mdev,
- "Failed preparing rx descriptor\n");
+ en_warn(priv, "Failed preparing rx descriptor\n");
priv->port_stats.rx_alloc_failed++;
break;
}
++num;
++ring->prod;
}
- if ((u32) (ring->prod - ring->cons) == ring->size)
+ if ((u32) (ring->prod - ring->cons) == ring->actual_size)
ring->full = 1;
return num;
@@ -264,33 +297,17 @@ static int mlx4_en_fill_rx_buf(struct net_device *dev,
static void mlx4_en_free_rx_buf(struct mlx4_en_priv *priv,
struct mlx4_en_rx_ring *ring)
{
- struct mlx4_en_dev *mdev = priv->mdev;
- struct skb_frag_struct *skb_frags;
- struct mlx4_en_rx_desc *rx_desc;
- dma_addr_t dma;
int index;
- int nr;
- mlx4_dbg(DRV, priv, "Freeing Rx buf - cons:%d prod:%d\n",
- ring->cons, ring->prod);
+ en_dbg(DRV, priv, "Freeing Rx buf - cons:%d prod:%d\n",
+ ring->cons, ring->prod);
/* Unmap and free Rx buffers */
- BUG_ON((u32) (ring->prod - ring->cons) > ring->size);
+ BUG_ON((u32) (ring->prod - ring->cons) > ring->actual_size);
while (ring->cons != ring->prod) {
index = ring->cons & ring->size_mask;
- rx_desc = ring->buf + (index << ring->log_stride);
- skb_frags = ring->rx_info + (index << priv->log_rx_info);
- mlx4_dbg(DRV, priv, "Processing descriptor:%d\n", index);
-
- for (nr = 0; nr < priv->num_frags; nr++) {
- mlx4_dbg(DRV, priv, "Freeing fragment:%d\n", nr);
- dma = be64_to_cpu(rx_desc->data[nr].addr);
-
- mlx4_dbg(DRV, priv, "Unmaping buffer at dma:0x%llx\n", (u64) dma);
- pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size,
- PCI_DMA_FROMDEVICE);
- put_page(skb_frags[nr].page);
- }
+ en_dbg(DRV, priv, "Processing descriptor:%d\n", index);
+ mlx4_en_free_rx_desc(priv, ring, index);
++ring->cons;
}
}
@@ -354,10 +371,10 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
sizeof(struct skb_frag_struct));
ring->rx_info = vmalloc(tmp);
if (!ring->rx_info) {
- mlx4_err(mdev, "Failed allocating rx_info ring\n");
+ en_err(priv, "Failed allocating rx_info ring\n");
return -ENOMEM;
}
- mlx4_dbg(DRV, priv, "Allocated rx_info ring at addr:%p size:%d\n",
+ en_dbg(DRV, priv, "Allocated rx_info ring at addr:%p size:%d\n",
ring->rx_info, tmp);
err = mlx4_alloc_hwq_res(mdev->dev, &ring->wqres,
@@ -367,7 +384,7 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
err = mlx4_en_map_buffer(&ring->wqres.buf);
if (err) {
- mlx4_err(mdev, "Failed to map RX buffer\n");
+ en_err(priv, "Failed to map RX buffer\n");
goto err_hwq;
}
ring->buf = ring->wqres.buf.direct.buf;
@@ -385,7 +402,7 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
sizeof(struct net_lro_desc),
GFP_KERNEL);
if (!ring->lro.lro_arr) {
- mlx4_err(mdev, "Failed to allocate lro array\n");
+ en_err(priv, "Failed to allocate lro array\n");
goto err_map;
}
ring->lro.get_frag_header = mlx4_en_get_frag_header;
@@ -436,7 +453,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
/* Initialize page allocators */
err = mlx4_en_init_allocator(priv, ring);
if (err) {
- mlx4_err(mdev, "Failed initializing ring allocator\n");
+ en_err(priv, "Failed initializing ring allocator\n");
ring_ind--;
goto err_allocator;
}
@@ -454,7 +471,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
mlx4_en_update_rx_prod_db(ring);
/* Configure SRQ representing the ring */
- ring->srq.max = ring->size;
+ ring->srq.max = ring->actual_size;
ring->srq.max_gs = max_gs;
ring->srq.wqe_shift = ilog2(ring->stride);
@@ -467,7 +484,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
err = mlx4_srq_alloc(mdev->dev, mdev->priv_pdn, &ring->wqres.mtt,
ring->wqres.db.dma, &ring->srq);
if (err){
- mlx4_err(mdev, "Failed to allocate srq\n");
+ en_err(priv, "Failed to allocate srq\n");
ring_ind--;
goto err_srq;
}
@@ -582,7 +599,7 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
skb = dev_alloc_skb(SMALL_PACKET_SIZE + NET_IP_ALIGN);
if (!skb) {
- mlx4_dbg(RX_ERR, priv, "Failed allocating skb\n");
+ en_dbg(RX_ERR, priv, "Failed allocating skb\n");
return NULL;
}
skb->dev = priv->dev;
@@ -661,7 +678,6 @@ static void mlx4_en_copy_desc(struct mlx4_en_priv *priv,
int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
- struct mlx4_en_dev *mdev = priv->mdev;
struct mlx4_cqe *cqe;
struct mlx4_en_rx_ring *ring = &priv->rx_ring[cq->ring];
struct skb_frag_struct *skb_frags;
@@ -698,14 +714,14 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
/* Drop packet on bad receive or bad checksum */
if (unlikely((cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) ==
MLX4_CQE_OPCODE_ERROR)) {
- mlx4_err(mdev, "CQE completed in error - vendor "
+ en_err(priv, "CQE completed in error - vendor "
"syndrom:%d syndrom:%d\n",
((struct mlx4_err_cqe *) cqe)->vendor_err_syndrome,
((struct mlx4_err_cqe *) cqe)->syndrome);
goto next;
}
if (unlikely(cqe->badfcs_enc & MLX4_CQE_BAD_FCS)) {
- mlx4_dbg(RX_ERR, priv, "Accepted frame with bad FCS\n");
+ en_dbg(RX_ERR, priv, "Accepted frame with bad FCS\n");
goto next;
}
@@ -855,7 +871,7 @@ static int mlx4_en_last_alloc_offset(struct mlx4_en_priv *priv, u16 stride, u16
u16 res = MLX4_EN_ALLOC_SIZE % stride;
u16 offset = MLX4_EN_ALLOC_SIZE - stride - res + align;
- mlx4_dbg(DRV, priv, "Calculated last offset for stride:%d align:%d "
+ en_dbg(DRV, priv, "Calculated last offset for stride:%d align:%d "
"res:%d offset:%d\n", stride, align, res, offset);
return offset;
}
@@ -900,10 +916,10 @@ void mlx4_en_calc_rx_buf(struct net_device *dev)
priv->rx_skb_size = eff_mtu;
priv->log_rx_info = ROUNDUP_LOG2(i * sizeof(struct skb_frag_struct));
- mlx4_dbg(DRV, priv, "Rx buffer scatter-list (effective-mtu:%d "
+ en_dbg(DRV, priv, "Rx buffer scatter-list (effective-mtu:%d "
"num_frags:%d):\n", eff_mtu, priv->num_frags);
for (i = 0; i < priv->num_frags; i++) {
- mlx4_dbg(DRV, priv, " frag:%d - size:%d prefix:%d align:%d "
+ en_dbg(DRV, priv, " frag:%d - size:%d prefix:%d align:%d "
"stride:%d last_offset:%d\n", i,
priv->frag_info[i].frag_size,
priv->frag_info[i].frag_prefix_size,
@@ -923,12 +939,12 @@ void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv,
int i;
rss_map->size = roundup_pow_of_two(num_entries);
- mlx4_dbg(DRV, priv, "Setting default RSS map of %d entires\n",
- rss_map->size);
+ en_dbg(DRV, priv, "Setting default RSS map of %d entires\n",
+ rss_map->size);
for (i = 0; i < rss_map->size; i++) {
rss_map->map[i] = i % num_rings;
- mlx4_dbg(DRV, priv, "Entry %d ---> ring %d\n", i, rss_map->map[i]);
+ en_dbg(DRV, priv, "Entry %d ---> ring %d\n", i, rss_map->map[i]);
}
}
@@ -943,13 +959,13 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv,
context = kmalloc(sizeof *context , GFP_KERNEL);
if (!context) {
- mlx4_err(mdev, "Failed to allocate qp context\n");
+ en_err(priv, "Failed to allocate qp context\n");
return -ENOMEM;
}
err = mlx4_qp_alloc(mdev->dev, qpn, qp);
if (err) {
- mlx4_err(mdev, "Failed to allocate qp #%d\n", qpn);
+ en_err(priv, "Failed to allocate qp #%x\n", qpn);
goto out;
}
qp->event = mlx4_en_sqp_event;
@@ -981,12 +997,11 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
int err = 0;
int good_qps = 0;
- mlx4_dbg(DRV, priv, "Configuring rss steering for port %u\n", priv->port);
+ en_dbg(DRV, priv, "Configuring rss steering\n");
err = mlx4_qp_reserve_range(mdev->dev, rss_map->size,
rss_map->size, &rss_map->base_qpn);
if (err) {
- mlx4_err(mdev, "Failed reserving %d qps for port %u\n",
- rss_map->size, priv->port);
+ en_err(priv, "Failed reserving %d qps\n", rss_map->size);
return err;
}
@@ -1006,13 +1021,13 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
/* Configure RSS indirection qp */
err = mlx4_qp_reserve_range(mdev->dev, 1, 1, &priv->base_qpn);
if (err) {
- mlx4_err(mdev, "Failed to reserve range for RSS "
- "indirection qp\n");
+ en_err(priv, "Failed to reserve range for RSS "
+ "indirection qp\n");
goto rss_err;
}
err = mlx4_qp_alloc(mdev->dev, priv->base_qpn, &rss_map->indir_qp);
if (err) {
- mlx4_err(mdev, "Failed to allocate RSS indirection QP\n");
+ en_err(priv, "Failed to allocate RSS indirection QP\n");
goto reserve_err;
}
rss_map->indir_qp.event = mlx4_en_sqp_event;
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
index e5c98a98ad3..5dc7466ad03 100644
--- a/drivers/net/mlx4/en_tx.c
+++ b/drivers/net/mlx4/en_tx.c
@@ -68,15 +68,15 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
tmp = size * sizeof(struct mlx4_en_tx_info);
ring->tx_info = vmalloc(tmp);
if (!ring->tx_info) {
- mlx4_err(mdev, "Failed allocating tx_info ring\n");
+ en_err(priv, "Failed allocating tx_info ring\n");
return -ENOMEM;
}
- mlx4_dbg(DRV, priv, "Allocated tx_info ring at addr:%p size:%d\n",
+ en_dbg(DRV, priv, "Allocated tx_info ring at addr:%p size:%d\n",
ring->tx_info, tmp);
ring->bounce_buf = kmalloc(MAX_DESC_SIZE, GFP_KERNEL);
if (!ring->bounce_buf) {
- mlx4_err(mdev, "Failed allocating bounce buffer\n");
+ en_err(priv, "Failed allocating bounce buffer\n");
err = -ENOMEM;
goto err_tx;
}
@@ -85,31 +85,31 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
err = mlx4_alloc_hwq_res(mdev->dev, &ring->wqres, ring->buf_size,
2 * PAGE_SIZE);
if (err) {
- mlx4_err(mdev, "Failed allocating hwq resources\n");
+ en_err(priv, "Failed allocating hwq resources\n");
goto err_bounce;
}
err = mlx4_en_map_buffer(&ring->wqres.buf);
if (err) {
- mlx4_err(mdev, "Failed to map TX buffer\n");
+ en_err(priv, "Failed to map TX buffer\n");
goto err_hwq_res;
}
ring->buf = ring->wqres.buf.direct.buf;
- mlx4_dbg(DRV, priv, "Allocated TX ring (addr:%p) - buf:%p size:%d "
- "buf_size:%d dma:%llx\n", ring, ring->buf, ring->size,
- ring->buf_size, (unsigned long long) ring->wqres.buf.direct.map);
+ en_dbg(DRV, priv, "Allocated TX ring (addr:%p) - buf:%p size:%d "
+ "buf_size:%d dma:%llx\n", ring, ring->buf, ring->size,
+ ring->buf_size, (unsigned long long) ring->wqres.buf.direct.map);
err = mlx4_qp_reserve_range(mdev->dev, 1, 1, &ring->qpn);
if (err) {
- mlx4_err(mdev, "Failed reserving qp for tx ring.\n");
+ en_err(priv, "Failed reserving qp for tx ring.\n");
goto err_map;
}
err = mlx4_qp_alloc(mdev->dev, ring->qpn, &ring->qp);
if (err) {
- mlx4_err(mdev, "Failed allocating qp %d\n", ring->qpn);
+ en_err(priv, "Failed allocating qp %d\n", ring->qpn);
goto err_reserve;
}
ring->qp.event = mlx4_en_sqp_event;
@@ -135,7 +135,7 @@ void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv,
struct mlx4_en_tx_ring *ring)
{
struct mlx4_en_dev *mdev = priv->mdev;
- mlx4_dbg(DRV, priv, "Destroying tx ring, qpn: %d\n", ring->qpn);
+ en_dbg(DRV, priv, "Destroying tx ring, qpn: %d\n", ring->qpn);
mlx4_qp_remove(mdev->dev, &ring->qp);
mlx4_qp_free(mdev->dev, &ring->qp);
@@ -274,12 +274,12 @@ int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring)
/* Skip last polled descriptor */
ring->cons += ring->last_nr_txbb;
- mlx4_dbg(DRV, priv, "Freeing Tx buf - cons:0x%x prod:0x%x\n",
+ en_dbg(DRV, priv, "Freeing Tx buf - cons:0x%x prod:0x%x\n",
ring->cons, ring->prod);
if ((u32) (ring->prod - ring->cons) > ring->size) {
if (netif_msg_tx_err(priv))
- mlx4_warn(priv->mdev, "Tx consumer passed producer!\n");
+ en_warn(priv, "Tx consumer passed producer!\n");
return 0;
}
@@ -292,39 +292,11 @@ int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring)
}
if (cnt)
- mlx4_dbg(DRV, priv, "Freed %d uncompleted tx descriptors\n", cnt);
+ en_dbg(DRV, priv, "Freed %d uncompleted tx descriptors\n", cnt);
return cnt;
}
-void mlx4_en_set_prio_map(struct mlx4_en_priv *priv, u16 *prio_map, u32 ring_num)
-{
- int block = 8 / ring_num;
- int extra = 8 - (block * ring_num);
- int num = 0;
- u16 ring = 1;
- int prio;
-
- if (ring_num == 1) {
- for (prio = 0; prio < 8; prio++)
- prio_map[prio] = 0;
- return;
- }
-
- for (prio = 0; prio < 8; prio++) {
- if (extra && (num == block + 1)) {
- ring++;
- num = 0;
- extra--;
- } else if (!extra && (num == block)) {
- ring++;
- num = 0;
- }
- prio_map[prio] = ring;
- mlx4_dbg(DRV, priv, " prio:%d --> ring:%d\n", prio, ring);
- num++;
- }
-}
static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
{
@@ -386,18 +358,8 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
if (unlikely(ring->blocked)) {
if ((u32) (ring->prod - ring->cons) <=
ring->size - HEADROOM - MAX_DESC_TXBBS) {
-
- /* TODO: support multiqueue netdevs. Currently, we block
- * when *any* ring is full. Note that:
- * - 2 Tx rings can unblock at the same time and call
- * netif_wake_queue(), which is OK since this
- * operation is idempotent.
- * - We might wake the queue just after another ring
- * stopped it. This is no big deal because the next
- * transmission on that ring would stop the queue.
- */
ring->blocked = 0;
- netif_wake_queue(dev);
+ netif_tx_wake_queue(netdev_get_tx_queue(dev, cq->ring));
priv->port_stats.wake_queue++;
}
}
@@ -539,7 +501,6 @@ static int get_real_size(struct sk_buff *skb, struct net_device *dev,
int *lso_header_size)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
- struct mlx4_en_dev *mdev = priv->mdev;
int real_size;
if (skb_is_gso(skb)) {
@@ -553,14 +514,14 @@ static int get_real_size(struct sk_buff *skb, struct net_device *dev,
real_size += DS_SIZE;
else {
if (netif_msg_tx_err(priv))
- mlx4_warn(mdev, "Non-linear headers\n");
+ en_warn(priv, "Non-linear headers\n");
dev_kfree_skb_any(skb);
return 0;
}
}
if (unlikely(*lso_header_size > MAX_LSO_HDR_SIZE)) {
if (netif_msg_tx_err(priv))
- mlx4_warn(mdev, "LSO header size too big\n");
+ en_warn(priv, "LSO header size too big\n");
dev_kfree_skb_any(skb);
return 0;
}
@@ -617,21 +578,20 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk
tx_desc->ctrl.fence_size = (real_size / 16) & 0x3f;
}
-static int get_vlan_info(struct mlx4_en_priv *priv, struct sk_buff *skb,
- u16 *vlan_tag)
+u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb)
{
- int tx_ind;
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ u16 vlan_tag = 0;
- /* Obtain VLAN information if present */
- if (priv->vlgrp && vlan_tx_tag_present(skb)) {
- *vlan_tag = vlan_tx_tag_get(skb);
- /* Set the Tx ring to use according to vlan priority */
- tx_ind = priv->tx_prio_map[*vlan_tag >> 13];
- } else {
- *vlan_tag = 0;
- tx_ind = 0;
+ /* If we support per priority flow control and the packet contains
+ * a vlan tag, send the packet to the TX ring assigned to that priority
+ */
+ if (priv->prof->rx_ppp && priv->vlgrp && vlan_tx_tag_present(skb)) {
+ vlan_tag = vlan_tx_tag_get(skb);
+ return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13);
}
- return tx_ind;
+
+ return skb_tx_hash(dev, skb);
}
int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -651,7 +611,7 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
dma_addr_t dma;
u32 index;
__be32 op_own;
- u16 vlan_tag;
+ u16 vlan_tag = 0;
int i;
int lso_header_size;
void *fragptr;
@@ -669,20 +629,21 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
nr_txbb = desc_size / TXBB_SIZE;
if (unlikely(nr_txbb > MAX_DESC_TXBBS)) {
if (netif_msg_tx_err(priv))
- mlx4_warn(mdev, "Oversized header or SG list\n");
+ en_warn(priv, "Oversized header or SG list\n");
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
- tx_ind = get_vlan_info(priv, skb, &vlan_tag);
+ tx_ind = skb->queue_mapping;
ring = &priv->tx_ring[tx_ind];
+ if (priv->vlgrp && vlan_tx_tag_present(skb))
+ vlan_tag = vlan_tx_tag_get(skb);
/* Check available TXBBs And 2K spare for prefetch */
if (unlikely(((int)(ring->prod - ring->cons)) >
ring->size - HEADROOM - MAX_DESC_TXBBS)) {
- /* every full Tx ring stops queue.
- * TODO: implement multi-queue support (per-queue stop) */
- netif_stop_queue(dev);
+ /* every full Tx ring stops queue */
+ netif_tx_stop_queue(netdev_get_tx_queue(dev, tx_ind));
ring->blocked = 1;
priv->port_stats.queue_stopped++;
@@ -695,7 +656,7 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
/* Now that we know what Tx ring to use */
if (unlikely(!priv->port_up)) {
if (netif_msg_tx_err(priv))
- mlx4_warn(mdev, "xmit: port down!\n");
+ en_warn(priv, "xmit: port down!\n");
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
@@ -819,7 +780,6 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
/* Ring doorbell! */
wmb();
writel(ring->doorbell_qpn, mdev->uar_map + MLX4_SEND_DOORBELL);
- dev->trans_start = jiffies;
/* Poll CQ here */
mlx4_en_xmit_poll(priv, tx_ind);
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index ce064e32420..b9ceddde46c 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -625,8 +625,10 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
err = mlx4_create_eq(dev, dev->caps.num_cqs + MLX4_NUM_SPARE_EQE,
(dev->flags & MLX4_FLAG_MSI_X) ? i : 0,
&priv->eq_table.eq[i]);
- if (err)
+ if (err) {
+ --i;
goto err_out_unmap;
+ }
}
err = mlx4_create_eq(dev, MLX4_NUM_ASYNC_EQE + MLX4_NUM_SPARE_EQE,
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
index ef840abbcd3..d43a9e4c2ae 100644
--- a/drivers/net/mlx4/mlx4_en.h
+++ b/drivers/net/mlx4/mlx4_en.h
@@ -49,26 +49,42 @@
#include "en_port.h"
#define DRV_NAME "mlx4_en"
-#define DRV_VERSION "1.4.0"
-#define DRV_RELDATE "Sep 2008"
+#define DRV_VERSION "1.4.1.1"
+#define DRV_RELDATE "June 2009"
#define MLX4_EN_MSG_LEVEL (NETIF_MSG_LINK | NETIF_MSG_IFDOWN)
-#define mlx4_dbg(mlevel, priv, format, arg...) \
- if (NETIF_MSG_##mlevel & priv->msg_enable) \
- printk(KERN_DEBUG "%s %s: " format , DRV_NAME ,\
- (dev_name(&priv->mdev->pdev->dev)) , ## arg)
+#define en_print(level, priv, format, arg...) \
+ { \
+ if ((priv)->registered) \
+ printk(level "%s: %s: " format, DRV_NAME, \
+ (priv->dev)->name, ## arg); \
+ else \
+ printk(level "%s: %s: Port %d: " format, \
+ DRV_NAME, dev_name(&priv->mdev->pdev->dev), \
+ (priv)->port, ## arg); \
+ }
+
+#define en_dbg(mlevel, priv, format, arg...) \
+ { \
+ if (NETIF_MSG_##mlevel & priv->msg_enable) \
+ en_print(KERN_DEBUG, priv, format, ## arg) \
+ }
+#define en_warn(priv, format, arg...) \
+ en_print(KERN_WARNING, priv, format, ## arg)
+#define en_err(priv, format, arg...) \
+ en_print(KERN_ERR, priv, format, ## arg)
#define mlx4_err(mdev, format, arg...) \
printk(KERN_ERR "%s %s: " format , DRV_NAME ,\
- (dev_name(&mdev->pdev->dev)) , ## arg)
+ dev_name(&mdev->pdev->dev) , ## arg)
#define mlx4_info(mdev, format, arg...) \
printk(KERN_INFO "%s %s: " format , DRV_NAME ,\
- (dev_name(&mdev->pdev->dev)) , ## arg)
+ dev_name(&mdev->pdev->dev) , ## arg)
#define mlx4_warn(mdev, format, arg...) \
printk(KERN_WARNING "%s %s: " format , DRV_NAME ,\
- (dev_name(&mdev->pdev->dev)) , ## arg)
+ dev_name(&mdev->pdev->dev) , ## arg)
/*
* Device constants
@@ -123,12 +139,14 @@ enum {
#define MLX4_EN_MIN_RX_SIZE (MLX4_EN_ALLOC_SIZE / SMP_CACHE_BYTES)
#define MLX4_EN_MIN_TX_SIZE (4096 / TXBB_SIZE)
-#define MLX4_EN_TX_RING_NUM 9
-#define MLX4_EN_DEF_TX_RING_SIZE 1024
+#define MLX4_EN_SMALL_PKT_SIZE 64
+#define MLX4_EN_NUM_TX_RINGS 8
+#define MLX4_EN_NUM_PPP_RINGS 8
+#define MLX4_EN_DEF_TX_RING_SIZE 512
#define MLX4_EN_DEF_RX_RING_SIZE 1024
-/* Target number of bytes to coalesce with interrupt moderation */
-#define MLX4_EN_RX_COAL_TARGET 0x20000
+/* Target number of packets to coalesce with interrupt moderation */
+#define MLX4_EN_RX_COAL_TARGET 44
#define MLX4_EN_RX_COAL_TIME 0x10
#define MLX4_EN_TX_COAL_PKTS 5
@@ -462,7 +480,6 @@ struct mlx4_en_priv {
int base_qpn;
struct mlx4_en_rss_map rss_map;
- u16 tx_prio_map[8];
u32 flags;
#define MLX4_EN_FLAG_PROMISC 0x1
u32 tx_ring_num;
@@ -500,8 +517,6 @@ void mlx4_en_stop_port(struct net_device *dev);
void mlx4_en_free_resources(struct mlx4_en_priv *priv);
int mlx4_en_alloc_resources(struct mlx4_en_priv *priv);
-int mlx4_en_get_profile(struct mlx4_en_dev *mdev);
-
int mlx4_en_create_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
int entries, int ring, enum cq_type mode);
void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
@@ -512,6 +527,7 @@ int mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
void mlx4_en_poll_tx_cq(unsigned long data);
void mlx4_en_tx_irq(struct mlx4_cq *mcq);
+u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb);
int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev);
int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring,
@@ -546,7 +562,6 @@ void mlx4_en_calc_rx_buf(struct net_device *dev);
void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv,
struct mlx4_en_rss_map *rss_map,
int num_entries, int num_rings);
-void mlx4_en_set_prio_map(struct mlx4_en_priv *priv, u16 *prio_map, u32 ring_num);
int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv);
void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv);
int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring);
diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c
index 3b8973d1993..5887e4764d2 100644
--- a/drivers/net/mlx4/mr.c
+++ b/drivers/net/mlx4/mr.c
@@ -402,7 +402,8 @@ static int mlx4_write_mtt_chunk(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
for (i = 0; i < npages; ++i)
mtts[i] = cpu_to_be64(page_list[i] | MLX4_MTT_FLAG_PRESENT);
- dma_sync_single(&dev->pdev->dev, dma_handle, npages * sizeof (u64), DMA_TO_DEVICE);
+ dma_sync_single_for_cpu(&dev->pdev->dev, dma_handle,
+ npages * sizeof (u64), DMA_TO_DEVICE);
return 0;
}
@@ -549,8 +550,8 @@ int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list
for (i = 0; i < npages; ++i)
fmr->mtts[i] = cpu_to_be64(page_list[i] | MLX4_MTT_FLAG_PRESENT);
- dma_sync_single(&dev->pdev->dev, fmr->dma_handle,
- npages * sizeof(u64), DMA_TO_DEVICE);
+ dma_sync_single_for_cpu(&dev->pdev->dev, fmr->dma_handle,
+ npages * sizeof(u64), DMA_TO_DEVICE);
fmr->mpt->key = cpu_to_be32(key);
fmr->mpt->lkey = cpu_to_be32(key);
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 6bb5af35eda..b4e18a58cb1 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -55,6 +55,7 @@
#include <linux/types.h>
#include <linux/inet_lro.h>
#include <asm/system.h>
+#include <linux/list.h>
static char mv643xx_eth_driver_name[] = "mv643xx_eth";
static char mv643xx_eth_driver_version[] = "1.4";
@@ -88,7 +89,24 @@ static char mv643xx_eth_driver_version[] = "1.4";
#define MAC_ADDR_LOW 0x0014
#define MAC_ADDR_HIGH 0x0018
#define SDMA_CONFIG 0x001c
+#define TX_BURST_SIZE_16_64BIT 0x01000000
+#define TX_BURST_SIZE_4_64BIT 0x00800000
+#define BLM_TX_NO_SWAP 0x00000020
+#define BLM_RX_NO_SWAP 0x00000010
+#define RX_BURST_SIZE_16_64BIT 0x00000008
+#define RX_BURST_SIZE_4_64BIT 0x00000004
#define PORT_SERIAL_CONTROL 0x003c
+#define SET_MII_SPEED_TO_100 0x01000000
+#define SET_GMII_SPEED_TO_1000 0x00800000
+#define SET_FULL_DUPLEX_MODE 0x00200000
+#define MAX_RX_PACKET_9700BYTE 0x000a0000
+#define DISABLE_AUTO_NEG_SPEED_GMII 0x00002000
+#define DO_NOT_FORCE_LINK_FAIL 0x00000400
+#define SERIAL_PORT_CONTROL_RESERVED 0x00000200
+#define DISABLE_AUTO_NEG_FOR_FLOW_CTRL 0x00000008
+#define DISABLE_AUTO_NEG_FOR_DUPLEX 0x00000004
+#define FORCE_LINK_PASS 0x00000002
+#define SERIAL_PORT_ENABLE 0x00000001
#define PORT_STATUS 0x0044
#define TX_FIFO_EMPTY 0x00000400
#define TX_IN_PROGRESS 0x00000080
@@ -106,7 +124,9 @@ static char mv643xx_eth_driver_version[] = "1.4";
#define TX_BW_BURST 0x005c
#define INT_CAUSE 0x0060
#define INT_TX_END 0x07f80000
+#define INT_TX_END_0 0x00080000
#define INT_RX 0x000003fc
+#define INT_RX_0 0x00000004
#define INT_EXT 0x00000002
#define INT_CAUSE_EXT 0x0064
#define INT_EXT_LINK_PHY 0x00110000
@@ -135,15 +155,8 @@ static char mv643xx_eth_driver_version[] = "1.4";
/*
- * SDMA configuration register.
+ * SDMA configuration register default value.
*/
-#define RX_BURST_SIZE_4_64BIT (2 << 1)
-#define RX_BURST_SIZE_16_64BIT (4 << 1)
-#define BLM_RX_NO_SWAP (1 << 4)
-#define BLM_TX_NO_SWAP (1 << 5)
-#define TX_BURST_SIZE_4_64BIT (2 << 22)
-#define TX_BURST_SIZE_16_64BIT (4 << 22)
-
#if defined(__BIG_ENDIAN)
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
(RX_BURST_SIZE_4_64BIT | \
@@ -160,22 +173,11 @@ static char mv643xx_eth_driver_version[] = "1.4";
/*
- * Port serial control register.
+ * Misc definitions.
*/
-#define SET_MII_SPEED_TO_100 (1 << 24)
-#define SET_GMII_SPEED_TO_1000 (1 << 23)
-#define SET_FULL_DUPLEX_MODE (1 << 21)
-#define MAX_RX_PACKET_9700BYTE (5 << 17)
-#define DISABLE_AUTO_NEG_SPEED_GMII (1 << 13)
-#define DO_NOT_FORCE_LINK_FAIL (1 << 10)
-#define SERIAL_PORT_CONTROL_RESERVED (1 << 9)
-#define DISABLE_AUTO_NEG_FOR_FLOW_CTRL (1 << 3)
-#define DISABLE_AUTO_NEG_FOR_DUPLEX (1 << 2)
-#define FORCE_LINK_PASS (1 << 1)
-#define SERIAL_PORT_ENABLE (1 << 0)
-
-#define DEFAULT_RX_QUEUE_SIZE 128
-#define DEFAULT_TX_QUEUE_SIZE 256
+#define DEFAULT_RX_QUEUE_SIZE 128
+#define DEFAULT_TX_QUEUE_SIZE 256
+#define SKB_DMA_REALIGN ((PAGE_SIZE - NET_SKB_PAD) % SMP_CACHE_BYTES)
/*
@@ -393,6 +395,7 @@ struct mv643xx_eth_private {
struct work_struct tx_timeout_task;
struct napi_struct napi;
+ u32 int_mask;
u8 oom;
u8 work_link;
u8 work_tx;
@@ -651,23 +654,20 @@ static int rxq_refill(struct rx_queue *rxq, int budget)
refilled = 0;
while (refilled < budget && rxq->rx_desc_count < rxq->rx_ring_size) {
struct sk_buff *skb;
- int unaligned;
int rx;
struct rx_desc *rx_desc;
skb = __skb_dequeue(&mp->rx_recycle);
if (skb == NULL)
- skb = dev_alloc_skb(mp->skb_size +
- dma_get_cache_alignment() - 1);
+ skb = dev_alloc_skb(mp->skb_size);
if (skb == NULL) {
mp->oom = 1;
goto oom;
}
- unaligned = (u32)skb->data & (dma_get_cache_alignment() - 1);
- if (unaligned)
- skb_reserve(skb, dma_get_cache_alignment() - unaligned);
+ if (SKB_DMA_REALIGN)
+ skb_reserve(skb, SKB_DMA_REALIGN);
refilled++;
rxq->rx_desc_count++;
@@ -969,8 +969,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force)
if (skb != NULL) {
if (skb_queue_len(&mp->rx_recycle) <
mp->rx_ring_size &&
- skb_recycle_check(skb, mp->skb_size +
- dma_get_cache_alignment() - 1))
+ skb_recycle_check(skb, mp->skb_size))
__skb_queue_head(&mp->rx_recycle, skb);
else
dev_kfree_skb(skb);
@@ -1723,20 +1722,20 @@ static void uc_addr_set(struct mv643xx_eth_private *mp, unsigned char *addr)
static u32 uc_addr_filter_mask(struct net_device *dev)
{
- struct dev_addr_list *uc_ptr;
+ struct netdev_hw_addr *ha;
u32 nibbles;
if (dev->flags & IFF_PROMISC)
return 0;
nibbles = 1 << (dev->dev_addr[5] & 0x0f);
- for (uc_ptr = dev->uc_list; uc_ptr != NULL; uc_ptr = uc_ptr->next) {
- if (memcmp(dev->dev_addr, uc_ptr->da_addr, 5))
+ list_for_each_entry(ha, &dev->uc_list, list) {
+ if (memcmp(dev->dev_addr, ha->addr, 5))
return 0;
- if ((dev->dev_addr[5] ^ uc_ptr->da_addr[5]) & 0xf0)
+ if ((dev->dev_addr[5] ^ ha->addr[5]) & 0xf0)
return 0;
- nibbles |= 1 << (uc_ptr->da_addr[5] & 0x0f);
+ nibbles |= 1 << (ha->addr[5] & 0x0f);
}
return nibbles;
@@ -1810,7 +1809,6 @@ static void mv643xx_eth_program_multicast_filter(struct net_device *dev)
if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
int port_num;
u32 accept;
- int i;
oom:
port_num = mp->port_num;
@@ -2067,15 +2065,16 @@ static int mv643xx_eth_collect_events(struct mv643xx_eth_private *mp)
u32 int_cause;
u32 int_cause_ext;
- int_cause = rdlp(mp, INT_CAUSE) & (INT_TX_END | INT_RX | INT_EXT);
+ int_cause = rdlp(mp, INT_CAUSE) & mp->int_mask;
if (int_cause == 0)
return 0;
int_cause_ext = 0;
- if (int_cause & INT_EXT)
+ if (int_cause & INT_EXT) {
+ int_cause &= ~INT_EXT;
int_cause_ext = rdlp(mp, INT_CAUSE_EXT);
+ }
- int_cause &= INT_TX_END | INT_RX;
if (int_cause) {
wrlp(mp, INT_CAUSE, ~int_cause);
mp->work_tx_end |= ((int_cause & INT_TX_END) >> 19) &
@@ -2182,6 +2181,7 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
if (mp->work_link) {
mp->work_link = 0;
handle_link_event(mp);
+ work_done++;
continue;
}
@@ -2220,7 +2220,7 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
if (mp->oom)
mod_timer(&mp->rx_oom, jiffies + (HZ / 10));
napi_complete(napi);
- wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
+ wrlp(mp, INT_MASK, mp->int_mask);
}
return work_done;
@@ -2341,6 +2341,14 @@ static void mv643xx_eth_recalc_skb_size(struct mv643xx_eth_private *mp)
* size field are ignored by the hardware.
*/
mp->skb_size = (skb_size + 7) & ~7;
+
+ /*
+ * If NET_SKB_PAD is smaller than a cache line,
+ * netdev_alloc_skb() will cause skb->data to be misaligned
+ * to a cache line boundary. If this is the case, include
+ * some extra space to allow re-aligning the data area.
+ */
+ mp->skb_size += SKB_DMA_REALIGN;
}
static int mv643xx_eth_open(struct net_device *dev)
@@ -2366,6 +2374,8 @@ static int mv643xx_eth_open(struct net_device *dev)
skb_queue_head_init(&mp->rx_recycle);
+ mp->int_mask = INT_EXT;
+
for (i = 0; i < mp->rxq_count; i++) {
err = rxq_init(mp, i);
if (err) {
@@ -2375,6 +2385,7 @@ static int mv643xx_eth_open(struct net_device *dev)
}
rxq_refill(mp->rxq + i, INT_MAX);
+ mp->int_mask |= INT_RX_0 << i;
}
if (mp->oom) {
@@ -2389,12 +2400,13 @@ static int mv643xx_eth_open(struct net_device *dev)
txq_deinit(mp->txq + i);
goto out_free;
}
+ mp->int_mask |= INT_TX_END_0 << i;
}
port_start(mp);
wrlp(mp, INT_MASK_EXT, INT_EXT_LINK_PHY | INT_EXT_TX);
- wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
+ wrlp(mp, INT_MASK, mp->int_mask);
return 0;
@@ -2538,7 +2550,7 @@ static void mv643xx_eth_netpoll(struct net_device *dev)
mv643xx_eth_irq(dev->irq, dev);
- wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
+ wrlp(mp, INT_MASK, mp->int_mask);
}
#endif
diff --git a/drivers/net/mvme147.c b/drivers/net/mvme147.c
index 435e5a847c4..93c709d63e2 100644
--- a/drivers/net/mvme147.c
+++ b/drivers/net/mvme147.c
@@ -57,6 +57,17 @@ typedef void (*writerap_t)(void *, unsigned short);
typedef void (*writerdp_t)(void *, unsigned short);
typedef unsigned short (*readrdp_t)(void *);
+static const struct net_device_ops lance_netdev_ops = {
+ .ndo_open = m147lance_open,
+ .ndo_stop = m147lance_close,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_set_multicast_list = lance_set_multicast,
+ .ndo_tx_timeout = lance_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
/* Initialise the one and only on-board 7990 */
struct net_device * __init mvme147lance_probe(int unit)
{
@@ -81,11 +92,7 @@ struct net_device * __init mvme147lance_probe(int unit)
/* Fill the dev fields */
dev->base_addr = (unsigned long)MVME147_LANCE_BASE;
- dev->open = &m147lance_open;
- dev->stop = &m147lance_close;
- dev->hard_start_xmit = &lance_start_xmit;
- dev->set_multicast_list = &lance_set_multicast;
- dev->tx_timeout = &lance_tx_timeout;
+ dev->netdev_ops = &lance_netdev_ops;
dev->dma = 0;
addr=(u_long *)ETHERNET_ADDRESS;
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index f2c4a665e93..1f6e36ea669 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -75,7 +75,7 @@
#include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h"
-#define MYRI10GE_VERSION_STR "1.4.4-1.401"
+#define MYRI10GE_VERSION_STR "1.5.0-1.418"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -255,6 +255,7 @@ struct myri10ge_priv {
u32 read_write_dma;
u32 link_changes;
u32 msg_enable;
+ unsigned int board_number;
};
static char *myri10ge_fw_unaligned = "myri10ge_ethp_z8e.dat";
@@ -266,6 +267,13 @@ static char *myri10ge_fw_name = NULL;
module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name");
+#define MYRI10GE_MAX_BOARDS 8
+static char *myri10ge_fw_names[MYRI10GE_MAX_BOARDS] =
+ {[0 ... (MYRI10GE_MAX_BOARDS - 1)] = NULL };
+module_param_array_named(myri10ge_fw_names, myri10ge_fw_names, charp, NULL,
+ 0444);
+MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image names per board");
+
static int myri10ge_ecrc_enable = 1;
module_param(myri10ge_ecrc_enable, int, S_IRUGO);
MODULE_PARM_DESC(myri10ge_ecrc_enable, "Enable Extended CRC on PCI-E");
@@ -319,10 +327,6 @@ static int myri10ge_debug = -1; /* defaults above */
module_param(myri10ge_debug, int, 0);
MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)");
-static int myri10ge_lro = 1;
-module_param(myri10ge_lro, int, S_IRUGO);
-MODULE_PARM_DESC(myri10ge_lro, "Enable large receive offload");
-
static int myri10ge_lro_max_pkts = MYRI10GE_LRO_MAX_PKTS;
module_param(myri10ge_lro_max_pkts, int, S_IRUGO);
MODULE_PARM_DESC(myri10ge_lro_max_pkts,
@@ -361,6 +365,8 @@ static inline void put_be32(__be32 val, __be32 __iomem * p)
__raw_writel((__force __u32) val, (__force void __iomem *)p);
}
+static struct net_device_stats *myri10ge_get_stats(struct net_device *dev);
+
static int
myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
struct myri10ge_cmd *data, int atomic)
@@ -1290,7 +1296,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
remainder -= MYRI10GE_ALLOC_SIZE;
}
- if (mgp->csum_flag && myri10ge_lro) {
+ if (dev->features & NETIF_F_LRO) {
rx_frags[0].page_offset += MXGEFW_PAD;
rx_frags[0].size -= MXGEFW_PAD;
len -= MXGEFW_PAD;
@@ -1412,6 +1418,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
{
struct myri10ge_rx_done *rx_done = &ss->rx_done;
struct myri10ge_priv *mgp = ss->mgp;
+ struct net_device *netdev = mgp->dev;
unsigned long rx_bytes = 0;
unsigned long rx_packets = 0;
unsigned long rx_ok;
@@ -1445,7 +1452,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
ss->stats.rx_packets += rx_packets;
ss->stats.rx_bytes += rx_bytes;
- if (myri10ge_lro)
+ if (netdev->features & NETIF_F_LRO)
lro_flush_all(&rx_done->lro_mgr);
/* restock receive rings if needed */
@@ -1686,7 +1693,7 @@ myri10ge_get_ringparam(struct net_device *netdev,
ring->rx_mini_max_pending = mgp->ss[0].rx_small.mask + 1;
ring->rx_max_pending = mgp->ss[0].rx_big.mask + 1;
ring->rx_jumbo_max_pending = 0;
- ring->tx_max_pending = mgp->ss[0].rx_small.mask + 1;
+ ring->tx_max_pending = mgp->ss[0].tx.mask + 1;
ring->rx_mini_pending = ring->rx_mini_max_pending;
ring->rx_pending = ring->rx_max_pending;
ring->rx_jumbo_pending = ring->rx_jumbo_max_pending;
@@ -1706,12 +1713,17 @@ static u32 myri10ge_get_rx_csum(struct net_device *netdev)
static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled)
{
struct myri10ge_priv *mgp = netdev_priv(netdev);
+ int err = 0;
if (csum_enabled)
mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
- else
+ else {
+ u32 flags = ethtool_op_get_flags(netdev);
+ err = ethtool_op_set_flags(netdev, (flags & ~ETH_FLAG_LRO));
mgp->csum_flag = 0;
- return 0;
+
+ }
+ return err;
}
static int myri10ge_set_tso(struct net_device *netdev, u32 tso_enabled)
@@ -1803,6 +1815,8 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
int slice;
int i;
+ /* force stats update */
+ (void)myri10ge_get_stats(netdev);
for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++)
data[i] = ((unsigned long *)&mgp->stats)[i];
@@ -1892,7 +1906,9 @@ static const struct ethtool_ops myri10ge_ethtool_ops = {
.get_sset_count = myri10ge_get_sset_count,
.get_ethtool_stats = myri10ge_get_ethtool_stats,
.set_msglevel = myri10ge_set_msglevel,
- .get_msglevel = myri10ge_get_msglevel
+ .get_msglevel = myri10ge_get_msglevel,
+ .get_flags = ethtool_op_get_flags,
+ .set_flags = ethtool_op_set_flags
};
static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss)
@@ -2671,7 +2687,7 @@ again:
/* we are out of transmit resources */
tx->stop_queue++;
netif_tx_stop_queue(netdev_queue);
- return 1;
+ return NETDEV_TX_BUSY;
}
/* Setup checksum offloading, if needed */
@@ -2876,7 +2892,6 @@ again:
tx->stop_queue++;
netif_tx_stop_queue(netdev_queue);
}
- dev->trans_start = jiffies;
return 0;
abort_linearize:
@@ -2969,6 +2984,7 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
struct net_device_stats *stats = &mgp->stats;
int i;
+ spin_lock(&mgp->stats_lock);
memset(stats, 0, sizeof(*stats));
for (i = 0; i < mgp->num_slices; i++) {
slice_stats = &mgp->ss[i].stats;
@@ -2979,6 +2995,7 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
stats->rx_dropped += slice_stats->rx_dropped;
stats->tx_dropped += slice_stats->tx_dropped;
}
+ spin_unlock(&mgp->stats_lock);
return stats;
}
@@ -3253,6 +3270,8 @@ abort:
static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
{
+ int overridden = 0;
+
if (myri10ge_force_firmware == 0) {
int link_width, exp_cap;
u16 lnk;
@@ -3286,10 +3305,18 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
}
}
if (myri10ge_fw_name != NULL) {
- dev_info(&mgp->pdev->dev, "overriding firmware to %s\n",
- myri10ge_fw_name);
+ overridden = 1;
mgp->fw_name = myri10ge_fw_name;
}
+ if (mgp->board_number < MYRI10GE_MAX_BOARDS &&
+ myri10ge_fw_names[mgp->board_number] != NULL &&
+ strlen(myri10ge_fw_names[mgp->board_number])) {
+ mgp->fw_name = myri10ge_fw_names[mgp->board_number];
+ overridden = 1;
+ }
+ if (overridden)
+ dev_info(&mgp->pdev->dev, "overriding firmware to %s\n",
+ mgp->fw_name);
}
#ifdef CONFIG_PM
@@ -3754,6 +3781,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int status = -ENXIO;
int dac_enabled;
unsigned hdr_offset, ss_offset;
+ static int board_number;
netdev = alloc_etherdev_mq(sizeof(*mgp), MYRI10GE_MAX_SLICES);
if (netdev == NULL) {
@@ -3770,6 +3798,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
mgp->pause = myri10ge_flow_control;
mgp->intr_coal_delay = myri10ge_intr_coal_delay;
mgp->msg_enable = netif_msg_init(myri10ge_debug, MYRI10GE_MSG_DEFAULT);
+ mgp->board_number = board_number;
init_waitqueue_head(&mgp->down_wq);
if (pci_enable_device(pdev)) {
@@ -3884,6 +3913,13 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (dac_enabled)
netdev->features |= NETIF_F_HIGHDMA;
+ netdev->features |= NETIF_F_LRO;
+
+ netdev->vlan_features |= mgp->features;
+ if (mgp->fw_ver_tiny < 37)
+ netdev->vlan_features &= ~NETIF_F_TSO6;
+ if (mgp->fw_ver_tiny < 32)
+ netdev->vlan_features &= ~NETIF_F_TSO;
/* make sure we can get an irq, and that MSI can be
* setup (if available). Also ensure netdev->irq
@@ -3902,6 +3938,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer,
(unsigned long)mgp);
+ spin_lock_init(&mgp->stats_lock);
SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops);
INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog);
status = register_netdev(netdev);
@@ -3919,6 +3956,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->irq, mgp->tx_boundary, mgp->fw_name,
(mgp->wc_enabled ? "Enabled" : "Disabled"));
+ board_number++;
return 0;
abort_with_state:
@@ -4008,6 +4046,8 @@ static struct pci_device_id myri10ge_pci_tbl[] = {
{0},
};
+MODULE_DEVICE_TABLE(pci, myri10ge_pci_tbl);
+
static struct pci_driver myri10ge_driver = {
.name = "myri10ge",
.probe = myri10ge_probe,
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index 9a802adba9a..5f0758bda6b 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -640,7 +640,7 @@ static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (!TX_BUFFS_AVAIL(head, tail)) {
DTX(("no buffs available, returning 1\n"));
- return 1;
+ return NETDEV_TX_BUSY;
}
spin_lock_irqsave(&mp->irq_lock, flags);
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index 7d83896b8c2..3fcebb70151 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -374,7 +374,7 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
dev->ethtool_ops = &ne2k_pci_ethtool_ops;
NS8390_init(dev, 0);
- memcpy(dev->dev_addr, SA_prom, 6);
+ memcpy(dev->dev_addr, SA_prom, dev->addr_len);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
i = register_netdev(dev);
diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c
index 6a843f7350a..a00bbfb9aed 100644
--- a/drivers/net/ne3210.c
+++ b/drivers/net/ne3210.c
@@ -104,7 +104,7 @@ static int __init ne3210_eisa_probe (struct device *device)
}
SET_NETDEV_DEV(dev, device);
- device->driver_data = dev;
+ dev_set_drvdata(device, dev);
ioaddr = edev->base_addr;
if (!request_region(ioaddr, NE3210_IO_EXTENT, DRV_NAME)) {
@@ -225,7 +225,7 @@ static int __init ne3210_eisa_probe (struct device *device)
static int __devexit ne3210_eisa_remove (struct device *device)
{
- struct net_device *dev = device->driver_data;
+ struct net_device *dev = dev_get_drvdata(device);
unsigned long ioaddr = to_eisa_device (device)->base_addr;
unregister_netdev (dev);
diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c
index 1861d5bbd96..946366dcc99 100644
--- a/drivers/net/netx-eth.c
+++ b/drivers/net/netx-eth.c
@@ -301,6 +301,17 @@ netx_eth_phy_write(struct net_device *ndev, int phy_id, int reg, int value)
while (readl(NETX_MIIMU) & MIIMU_SNRDY);
}
+static const struct net_device_ops netx_eth_netdev_ops = {
+ .ndo_open = netx_eth_open,
+ .ndo_stop = netx_eth_close,
+ .ndo_start_xmit = netx_eth_hard_start_xmit,
+ .ndo_tx_timeout = netx_eth_timeout,
+ .ndo_set_multicast_list = netx_eth_set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int netx_eth_enable(struct net_device *ndev)
{
struct netx_eth_priv *priv = netdev_priv(ndev);
@@ -309,12 +320,8 @@ static int netx_eth_enable(struct net_device *ndev)
ether_setup(ndev);
- ndev->open = netx_eth_open;
- ndev->stop = netx_eth_close;
- ndev->hard_start_xmit = netx_eth_hard_start_xmit;
- ndev->tx_timeout = netx_eth_timeout;
+ ndev->netdev_ops = &netx_eth_netdev_ops;
ndev->watchdog_timeo = msecs_to_jiffies(5000);
- ndev->set_multicast_list = netx_eth_set_multicast_list;
priv->msg_enable = NETIF_MSG_LINK;
priv->mii.phy_id_mask = 0x1f;
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index c40815169f3..ab11c2b3f0f 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -34,10 +34,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
@@ -46,21 +42,16 @@
#include <linux/in.h>
#include <linux/tcp.h>
#include <linux/skbuff.h>
+#include <linux/firmware.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
-#include <linux/interrupt.h>
#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
#include <linux/vmalloc.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <asm/byteorder.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
#include "netxen_nic_hw.h"
@@ -84,10 +75,10 @@
(sizeof(struct netxen_rx_buffer) * rds_ring->num_desc)
#define STATUS_DESC_RINGSIZE(sds_ring) \
(sizeof(struct status_desc) * (sds_ring)->num_desc)
-#define TX_BUFF_RINGSIZE(adapter) \
- (sizeof(struct netxen_cmd_buffer) * adapter->num_txd)
-#define TX_DESC_RINGSIZE(adapter) \
- (sizeof(struct cmd_desc_type0) * adapter->num_txd)
+#define TX_BUFF_RINGSIZE(tx_ring) \
+ (sizeof(struct netxen_cmd_buffer) * tx_ring->num_desc)
+#define TX_DESC_RINGSIZE(tx_ring) \
+ (sizeof(struct cmd_desc_type0) * tx_ring->num_desc)
#define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
@@ -118,6 +109,7 @@
#define NX_P3_A2 0x30
#define NX_P3_B0 0x40
#define NX_P3_B1 0x41
+#define NX_P3_B2 0x42
#define NX_IS_REVISION_P2(REVISION) (REVISION <= NX_P2_C1)
#define NX_IS_REVISION_P3(REVISION) (REVISION >= NX_P3_A0)
@@ -203,18 +195,10 @@
#define MAX_RCV_DESCRIPTORS_10G 4096
#define MAX_JUMBO_RCV_DESCRIPTORS 1024
#define MAX_LRO_RCV_DESCRIPTORS 8
-#define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS
-#define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS
-#define MAX_RCV_DESC MAX_RCV_DESCRIPTORS
-#define MAX_RCVSTATUS_DESC MAX_RCV_DESCRIPTORS
-#define MAX_EPG_DESCRIPTORS (MAX_CMD_DESCRIPTORS * 8)
-#define NUM_RCV_DESC (MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS + \
- MAX_LRO_RCV_DESCRIPTORS)
-#define MIN_TX_COUNT 4096
-#define MIN_RX_COUNT 4096
#define NETXEN_CTX_SIGNATURE 0xdee0
+#define NETXEN_CTX_SIGNATURE_V2 0x0002dee0
+#define NETXEN_CTX_RESET 0xbad0
#define NETXEN_RCV_PRODUCER(ringid) (ringid)
-#define MAX_FRAME_SIZE 0x10000 /* 64K MAX size for LSO */
#define PHAN_PEG_RCV_INITIALIZED 0xff01
#define PHAN_PEG_RCV_START_INITIALIZE 0xff00
@@ -253,12 +237,19 @@ typedef u32 netxen_ctx_msg;
#define netxen_set_msg_opcode(config_word, val) \
((config_word) &= ~(0xf<<28), (config_word) |= (val & 0xf) << 28)
-struct netxen_rcv_context {
- __le64 rcv_ring_addr;
- __le32 rcv_ring_size;
+struct netxen_rcv_ring {
+ __le64 addr;
+ __le32 size;
__le32 rsrvd;
};
+struct netxen_sts_ring {
+ __le64 addr;
+ __le32 size;
+ __le16 msi_index;
+ __le16 rsvd;
+} ;
+
struct netxen_ring_ctx {
/* one command ring */
@@ -268,13 +259,18 @@ struct netxen_ring_ctx {
__le32 rsrvd;
/* three receive rings */
- struct netxen_rcv_context rcv_ctx[3];
+ struct netxen_rcv_ring rcv_rings[NUM_RCV_DESC_RINGS];
- /* one status ring */
__le64 sts_ring_addr;
__le32 sts_ring_size;
__le32 ctx_id;
+
+ __le64 rsrvd_2[3];
+ __le32 sts_ring_count;
+ __le32 rsrvd_3;
+ struct netxen_sts_ring sts_rings[NUM_STS_DESC_RINGS];
+
} __attribute__ ((aligned(64)));
/*
@@ -373,6 +369,7 @@ struct rcv_desc {
/* opcode field in status_desc */
#define NETXEN_NIC_RXPKT_DESC 0x04
#define NETXEN_OLD_RXPKT_DESC 0x3f
+#define NETXEN_NIC_RESPONSE_DESC 0x05
/* for status field in status_desc */
#define STATUS_NEED_CKSUM (1)
@@ -382,13 +379,11 @@ struct rcv_desc {
#define STATUS_OWNER_HOST (0x1ULL << 56)
#define STATUS_OWNER_PHANTOM (0x2ULL << 56)
-/* Note: sizeof(status_desc) should always be a mutliple of 2 */
-
-#define netxen_get_sts_desc_lro_cnt(status_desc) \
- ((status_desc)->lro & 0x7F)
-#define netxen_get_sts_desc_lro_last_frag(status_desc) \
- (((status_desc)->lro & 0x80) >> 7)
-
+/* Status descriptor:
+ 0-3 port, 4-7 status, 8-11 type, 12-27 total_length
+ 28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset
+ 53-55 desc_cnt, 56-57 owner, 58-63 opcode
+ */
#define netxen_get_sts_port(sts_data) \
((sts_data) & 0x0F)
#define netxen_get_sts_status(sts_data) \
@@ -403,41 +398,15 @@ struct rcv_desc {
(((sts_data) >> 44) & 0x0F)
#define netxen_get_sts_pkt_offset(sts_data) \
(((sts_data) >> 48) & 0x1F)
+#define netxen_get_sts_desc_cnt(sts_data) \
+ (((sts_data) >> 53) & 0x7)
#define netxen_get_sts_opcode(sts_data) \
(((sts_data) >> 58) & 0x03F)
struct status_desc {
- /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length
- 28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset
- 53-55 desc_cnt, 56-57 owner, 58-63 opcode
- */
- __le64 status_desc_data;
- union {
- struct {
- __le32 hash_value;
- u8 hash_type;
- u8 msg_type;
- u8 unused;
- union {
- /* Bit pattern: 0-6 lro_count indicates frag
- * sequence, 7 last_frag indicates last frag
- */
- u8 lro;
-
- /* chained buffers */
- u8 nr_frags;
- };
- };
- struct {
- __le16 frag_handles[4];
- };
- };
+ __le64 status_desc_data[2];
} __attribute__ ((aligned(16)));
-enum {
- NETXEN_RCV_PEG_0 = 0,
- NETXEN_RCV_PEG_1
-};
/* The version of the main data structure */
#define NETXEN_BDINFO_VERSION 1
@@ -447,85 +416,35 @@ enum {
/* Max number of Gig ports on a Phantom board */
#define NETXEN_MAX_PORTS 4
-typedef enum {
- NETXEN_BRDTYPE_P1_BD = 0x0000,
- NETXEN_BRDTYPE_P1_SB = 0x0001,
- NETXEN_BRDTYPE_P1_SMAX = 0x0002,
- NETXEN_BRDTYPE_P1_SOCK = 0x0003,
-
- NETXEN_BRDTYPE_P2_SOCK_31 = 0x0008,
- NETXEN_BRDTYPE_P2_SOCK_35 = 0x0009,
- NETXEN_BRDTYPE_P2_SB35_4G = 0x000a,
- NETXEN_BRDTYPE_P2_SB31_10G = 0x000b,
- NETXEN_BRDTYPE_P2_SB31_2G = 0x000c,
-
- NETXEN_BRDTYPE_P2_SB31_10G_IMEZ = 0x000d,
- NETXEN_BRDTYPE_P2_SB31_10G_HMEZ = 0x000e,
- NETXEN_BRDTYPE_P2_SB31_10G_CX4 = 0x000f,
-
- NETXEN_BRDTYPE_P3_REF_QG = 0x0021,
- NETXEN_BRDTYPE_P3_HMEZ = 0x0022,
- NETXEN_BRDTYPE_P3_10G_CX4_LP = 0x0023,
- NETXEN_BRDTYPE_P3_4_GB = 0x0024,
- NETXEN_BRDTYPE_P3_IMEZ = 0x0025,
- NETXEN_BRDTYPE_P3_10G_SFP_PLUS = 0x0026,
- NETXEN_BRDTYPE_P3_10000_BASE_T = 0x0027,
- NETXEN_BRDTYPE_P3_XG_LOM = 0x0028,
- NETXEN_BRDTYPE_P3_4_GB_MM = 0x0029,
- NETXEN_BRDTYPE_P3_10G_SFP_CT = 0x002a,
- NETXEN_BRDTYPE_P3_10G_SFP_QT = 0x002b,
- NETXEN_BRDTYPE_P3_10G_CX4 = 0x0031,
- NETXEN_BRDTYPE_P3_10G_XFP = 0x0032,
- NETXEN_BRDTYPE_P3_10G_TP = 0x0080
-
-} netxen_brdtype_t;
-
-typedef enum {
- NETXEN_BRDMFG_INVENTEC = 1
-} netxen_brdmfg;
-
-typedef enum {
- MEM_ORG_128Mbx4 = 0x0, /* DDR1 only */
- MEM_ORG_128Mbx8 = 0x1, /* DDR1 only */
- MEM_ORG_128Mbx16 = 0x2, /* DDR1 only */
- MEM_ORG_256Mbx4 = 0x3,
- MEM_ORG_256Mbx8 = 0x4,
- MEM_ORG_256Mbx16 = 0x5,
- MEM_ORG_512Mbx4 = 0x6,
- MEM_ORG_512Mbx8 = 0x7,
- MEM_ORG_512Mbx16 = 0x8,
- MEM_ORG_1Gbx4 = 0x9,
- MEM_ORG_1Gbx8 = 0xa,
- MEM_ORG_1Gbx16 = 0xb,
- MEM_ORG_2Gbx4 = 0xc,
- MEM_ORG_2Gbx8 = 0xd,
- MEM_ORG_2Gbx16 = 0xe,
- MEM_ORG_128Mbx32 = 0x10002, /* GDDR only */
- MEM_ORG_256Mbx32 = 0x10005 /* GDDR only */
-} netxen_mn_mem_org_t;
-
-typedef enum {
- MEM_ORG_512Kx36 = 0x0,
- MEM_ORG_1Mx36 = 0x1,
- MEM_ORG_2Mx36 = 0x2
-} netxen_sn_mem_org_t;
-
-typedef enum {
- MEM_DEPTH_4MB = 0x1,
- MEM_DEPTH_8MB = 0x2,
- MEM_DEPTH_16MB = 0x3,
- MEM_DEPTH_32MB = 0x4,
- MEM_DEPTH_64MB = 0x5,
- MEM_DEPTH_128MB = 0x6,
- MEM_DEPTH_256MB = 0x7,
- MEM_DEPTH_512MB = 0x8,
- MEM_DEPTH_1GB = 0x9,
- MEM_DEPTH_2GB = 0xa,
- MEM_DEPTH_4GB = 0xb,
- MEM_DEPTH_8GB = 0xc,
- MEM_DEPTH_16GB = 0xd,
- MEM_DEPTH_32GB = 0xe
-} netxen_mem_depth_t;
+#define NETXEN_BRDTYPE_P1_BD 0x0000
+#define NETXEN_BRDTYPE_P1_SB 0x0001
+#define NETXEN_BRDTYPE_P1_SMAX 0x0002
+#define NETXEN_BRDTYPE_P1_SOCK 0x0003
+
+#define NETXEN_BRDTYPE_P2_SOCK_31 0x0008
+#define NETXEN_BRDTYPE_P2_SOCK_35 0x0009
+#define NETXEN_BRDTYPE_P2_SB35_4G 0x000a
+#define NETXEN_BRDTYPE_P2_SB31_10G 0x000b
+#define NETXEN_BRDTYPE_P2_SB31_2G 0x000c
+
+#define NETXEN_BRDTYPE_P2_SB31_10G_IMEZ 0x000d
+#define NETXEN_BRDTYPE_P2_SB31_10G_HMEZ 0x000e
+#define NETXEN_BRDTYPE_P2_SB31_10G_CX4 0x000f
+
+#define NETXEN_BRDTYPE_P3_REF_QG 0x0021
+#define NETXEN_BRDTYPE_P3_HMEZ 0x0022
+#define NETXEN_BRDTYPE_P3_10G_CX4_LP 0x0023
+#define NETXEN_BRDTYPE_P3_4_GB 0x0024
+#define NETXEN_BRDTYPE_P3_IMEZ 0x0025
+#define NETXEN_BRDTYPE_P3_10G_SFP_PLUS 0x0026
+#define NETXEN_BRDTYPE_P3_10000_BASE_T 0x0027
+#define NETXEN_BRDTYPE_P3_XG_LOM 0x0028
+#define NETXEN_BRDTYPE_P3_4_GB_MM 0x0029
+#define NETXEN_BRDTYPE_P3_10G_SFP_CT 0x002a
+#define NETXEN_BRDTYPE_P3_10G_SFP_QT 0x002b
+#define NETXEN_BRDTYPE_P3_10G_CX4 0x0031
+#define NETXEN_BRDTYPE_P3_10G_XFP 0x0032
+#define NETXEN_BRDTYPE_P3_10G_TP 0x0080
struct netxen_board_info {
u32 header_version;
@@ -676,17 +595,15 @@ struct netxen_new_user_info {
#define PRIMARY_IMAGE_BAD 0xffffffff
/* Flash memory map */
-typedef enum {
- NETXEN_CRBINIT_START = 0, /* Crbinit section */
- NETXEN_BRDCFG_START = 0x4000, /* board config */
- NETXEN_INITCODE_START = 0x6000, /* pegtune code */
- NETXEN_BOOTLD_START = 0x10000, /* bootld */
- NETXEN_IMAGE_START = 0x43000, /* compressed image */
- NETXEN_SECONDARY_START = 0x200000, /* backup images */
- NETXEN_PXE_START = 0x3E0000, /* user defined region */
- NETXEN_USER_START = 0x3E8000, /* User defined region for new boards */
- NETXEN_FIXED_START = 0x3F0000 /* backup of crbinit */
-} netxen_flash_map_t;
+#define NETXEN_CRBINIT_START 0 /* crbinit section */
+#define NETXEN_BRDCFG_START 0x4000 /* board config */
+#define NETXEN_INITCODE_START 0x6000 /* pegtune code */
+#define NETXEN_BOOTLD_START 0x10000 /* bootld */
+#define NETXEN_IMAGE_START 0x43000 /* compressed image */
+#define NETXEN_SECONDARY_START 0x200000 /* backup images */
+#define NETXEN_PXE_START 0x3E0000 /* PXE boot rom */
+#define NETXEN_USER_START 0x3E8000 /* Firmare info */
+#define NETXEN_FIXED_START 0x3F0000 /* backup of crbinit */
#define NX_FW_VERSION_OFFSET (NETXEN_USER_START+0x408)
#define NX_FW_SIZE_OFFSET (NETXEN_USER_START+0x40c)
@@ -708,21 +625,8 @@ typedef enum {
#define NETXEN_FLASH_SECONDARY_SIZE (NETXEN_USER_START-NETXEN_SECONDARY_START)
#define NETXEN_NUM_PRIMARY_SECTORS (0x20)
#define NETXEN_NUM_CONFIG_SECTORS (1)
-#define PFX "NetXen: "
extern char netxen_nic_driver_name[];
-/* Note: Make sure to not call this before adapter->port is valid */
-#if !defined(NETXEN_DEBUG)
-#define DPRINTK(klevel, fmt, args...) do { \
- } while (0)
-#else
-#define DPRINTK(klevel, fmt, args...) do { \
- printk(KERN_##klevel PFX "%s: %s: " fmt, __func__,\
- (adapter != NULL && adapter->netdev != NULL) ? \
- adapter->netdev->name : NULL, \
- ## args); } while(0)
-#endif
-
/* Number of status descriptors to handle per interrupt */
#define MAX_STATUS_HANDLE (64)
@@ -732,7 +636,7 @@ extern char netxen_nic_driver_name[];
*/
struct netxen_skb_frag {
u64 dma;
- ulong length;
+ u64 length;
};
#define _netxen_set_bits(config_word, start, bits, val) {\
@@ -793,34 +697,24 @@ struct netxen_hardware_context {
u8 cut_through;
u8 revision_id;
+ u8 pci_func;
+ u8 linkup;
u16 port_type;
- int board_type;
- u32 linkup;
- /* Address of cmd ring in Phantom */
- struct cmd_desc_type0 *cmd_desc_head;
- dma_addr_t cmd_desc_phys_addr;
- struct netxen_adapter *adapter;
- int pci_func;
+ u16 board_type;
};
#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */
#define ETHERNET_FCS_SIZE 4
struct netxen_adapter_stats {
- u64 rcvdbadskb;
u64 xmitcalled;
- u64 xmitedframes;
u64 xmitfinished;
- u64 badskblen;
- u64 nocmddescriptor;
- u64 polled;
u64 rxdropped;
u64 txdropped;
u64 csummed;
u64 no_rcv;
u64 rxbytes;
u64 txbytes;
- u64 ints;
};
/*
@@ -852,14 +746,25 @@ struct nx_host_sds_ring {
struct napi_struct napi;
struct list_head free_list[NUM_RCV_DESC_RINGS];
- u16 clean_tx;
- u16 post_rxd;
int irq;
dma_addr_t phys_addr;
char name[IFNAMSIZ+4];
};
+struct nx_host_tx_ring {
+ u32 producer;
+ __le32 *hw_consumer;
+ u32 sw_consumer;
+ u32 crb_cmd_producer;
+ u32 crb_cmd_consumer;
+ u32 num_desc;
+
+ struct netxen_cmd_buffer *cmd_buf_arr;
+ struct cmd_desc_type0 *desc_head;
+ dma_addr_t phys_addr;
+};
+
/*
* Receive context. There is one such structure per instance of the
* receive processing. Any state information that is relevant to
@@ -871,8 +776,11 @@ struct netxen_recv_context {
u16 context_id;
u16 virt_port;
- struct nx_host_rds_ring rds_rings[NUM_RCV_DESC_RINGS];
- struct nx_host_sds_ring sds_rings[NUM_STS_DESC_RINGS];
+ struct nx_host_rds_ring *rds_rings;
+ struct nx_host_sds_ring *sds_rings;
+
+ struct netxen_ring_ctx *hwctx;
+ dma_addr_t phys_addr;
};
/* New HW context creation */
@@ -1111,8 +1019,8 @@ typedef struct {
#define NETXEN_MAC_DEL 2
typedef struct nx_mac_list_s {
- struct nx_mac_list_s *next;
- uint8_t mac_addr[MAX_ADDR_LEN];
+ struct list_head list;
+ uint8_t mac_addr[ETH_ALEN+2];
} nx_mac_list_t;
/*
@@ -1154,31 +1062,118 @@ typedef struct {
#define NX_MAC_EVENT 0x1
-enum {
- NX_NIC_H2C_OPCODE_START = 0,
- NX_NIC_H2C_OPCODE_CONFIG_RSS,
- NX_NIC_H2C_OPCODE_CONFIG_RSS_TBL,
- NX_NIC_H2C_OPCODE_CONFIG_INTR_COALESCE,
- NX_NIC_H2C_OPCODE_CONFIG_LED,
- NX_NIC_H2C_OPCODE_CONFIG_PROMISCUOUS,
- NX_NIC_H2C_OPCODE_CONFIG_L2_MAC,
- NX_NIC_H2C_OPCODE_LRO_REQUEST,
- NX_NIC_H2C_OPCODE_GET_SNMP_STATS,
- NX_NIC_H2C_OPCODE_PROXY_START_REQUEST,
- NX_NIC_H2C_OPCODE_PROXY_STOP_REQUEST,
- NX_NIC_H2C_OPCODE_PROXY_SET_MTU,
- NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE,
- NX_H2P_OPCODE_GET_FINGER_PRINT_REQUEST,
- NX_H2P_OPCODE_INSTALL_LICENSE_REQUEST,
- NX_H2P_OPCODE_GET_LICENSE_CAPABILITY_REQUEST,
- NX_NIC_H2C_OPCODE_GET_NET_STATS,
- NX_NIC_H2C_OPCODE_LAST
-};
+/*
+ * Driver --> Firmware
+ */
+#define NX_NIC_H2C_OPCODE_START 0
+#define NX_NIC_H2C_OPCODE_CONFIG_RSS 1
+#define NX_NIC_H2C_OPCODE_CONFIG_RSS_TBL 2
+#define NX_NIC_H2C_OPCODE_CONFIG_INTR_COALESCE 3
+#define NX_NIC_H2C_OPCODE_CONFIG_LED 4
+#define NX_NIC_H2C_OPCODE_CONFIG_PROMISCUOUS 5
+#define NX_NIC_H2C_OPCODE_CONFIG_L2_MAC 6
+#define NX_NIC_H2C_OPCODE_LRO_REQUEST 7
+#define NX_NIC_H2C_OPCODE_GET_SNMP_STATS 8
+#define NX_NIC_H2C_OPCODE_PROXY_START_REQUEST 9
+#define NX_NIC_H2C_OPCODE_PROXY_STOP_REQUEST 10
+#define NX_NIC_H2C_OPCODE_PROXY_SET_MTU 11
+#define NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE 12
+#define NX_NIC_H2C_OPCODE_GET_FINGER_PRINT_REQUEST 13
+#define NX_NIC_H2C_OPCODE_INSTALL_LICENSE_REQUEST 14
+#define NX_NIC_H2C_OPCODE_GET_LICENSE_CAPABILITY_REQUEST 15
+#define NX_NIC_H2C_OPCODE_GET_NET_STATS 16
+#define NX_NIC_H2C_OPCODE_PROXY_UPDATE_P2V 17
+#define NX_NIC_H2C_OPCODE_CONFIG_IPADDR 18
+#define NX_NIC_H2C_OPCODE_CONFIG_LOOPBACK 19
+#define NX_NIC_H2C_OPCODE_PROXY_STOP_DONE 20
+#define NX_NIC_H2C_OPCODE_GET_LINKEVENT 21
+#define NX_NIC_C2C_OPCODE 22
+#define NX_NIC_H2C_OPCODE_LAST 23
+
+/*
+ * Firmware --> Driver
+ */
+
+#define NX_NIC_C2H_OPCODE_START 128
+#define NX_NIC_C2H_OPCODE_CONFIG_RSS_RESPONSE 129
+#define NX_NIC_C2H_OPCODE_CONFIG_RSS_TBL_RESPONSE 130
+#define NX_NIC_C2H_OPCODE_CONFIG_MAC_RESPONSE 131
+#define NX_NIC_C2H_OPCODE_CONFIG_PROMISCUOUS_RESPONSE 132
+#define NX_NIC_C2H_OPCODE_CONFIG_L2_MAC_RESPONSE 133
+#define NX_NIC_C2H_OPCODE_LRO_DELETE_RESPONSE 134
+#define NX_NIC_C2H_OPCODE_LRO_ADD_FAILURE_RESPONSE 135
+#define NX_NIC_C2H_OPCODE_GET_SNMP_STATS 136
+#define NX_NIC_C2H_OPCODE_GET_FINGER_PRINT_REPLY 137
+#define NX_NIC_C2H_OPCODE_INSTALL_LICENSE_REPLY 138
+#define NX_NIC_C2H_OPCODE_GET_LICENSE_CAPABILITIES_REPLY 139
+#define NX_NIC_C2H_OPCODE_GET_NET_STATS_RESPONSE 140
+#define NX_NIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE 141
+#define NX_NIC_C2H_OPCODE_LAST 142
#define VPORT_MISS_MODE_DROP 0 /* drop all unmatched */
#define VPORT_MISS_MODE_ACCEPT_ALL 1 /* accept all packets */
#define VPORT_MISS_MODE_ACCEPT_MULTI 2 /* accept unmatched multicast */
+#define NX_FW_CAPABILITY_LINK_NOTIFICATION (1 << 5)
+#define NX_FW_CAPABILITY_SWITCHING (1 << 6)
+
+/* module types */
+#define LINKEVENT_MODULE_NOT_PRESENT 1
+#define LINKEVENT_MODULE_OPTICAL_UNKNOWN 2
+#define LINKEVENT_MODULE_OPTICAL_SRLR 3
+#define LINKEVENT_MODULE_OPTICAL_LRM 4
+#define LINKEVENT_MODULE_OPTICAL_SFP_1G 5
+#define LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE 6
+#define LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN 7
+#define LINKEVENT_MODULE_TWINAX 8
+
+#define LINKSPEED_10GBPS 10000
+#define LINKSPEED_1GBPS 1000
+#define LINKSPEED_100MBPS 100
+#define LINKSPEED_10MBPS 10
+
+#define LINKSPEED_ENCODED_10MBPS 0
+#define LINKSPEED_ENCODED_100MBPS 1
+#define LINKSPEED_ENCODED_1GBPS 2
+
+#define LINKEVENT_AUTONEG_DISABLED 0
+#define LINKEVENT_AUTONEG_ENABLED 1
+
+#define LINKEVENT_HALF_DUPLEX 0
+#define LINKEVENT_FULL_DUPLEX 1
+
+#define LINKEVENT_LINKSPEED_MBPS 0
+#define LINKEVENT_LINKSPEED_ENCODED 1
+
+/* firmware response header:
+ * 63:58 - message type
+ * 57:56 - owner
+ * 55:53 - desc count
+ * 52:48 - reserved
+ * 47:40 - completion id
+ * 39:32 - opcode
+ * 31:16 - error code
+ * 15:00 - reserved
+ */
+#define netxen_get_nic_msgtype(msg_hdr) \
+ ((msg_hdr >> 58) & 0x3F)
+#define netxen_get_nic_msg_compid(msg_hdr) \
+ ((msg_hdr >> 40) & 0xFF)
+#define netxen_get_nic_msg_opcode(msg_hdr) \
+ ((msg_hdr >> 32) & 0xFF)
+#define netxen_get_nic_msg_errcode(msg_hdr) \
+ ((msg_hdr >> 16) & 0xFFFF)
+
+typedef struct {
+ union {
+ struct {
+ u64 hdr;
+ u64 body[7];
+ };
+ u64 words[8];
+ };
+} nx_fw_msg_t;
+
typedef struct {
__le64 qhdr;
__le64 req_hdr;
@@ -1218,99 +1213,96 @@ struct netxen_adapter {
struct net_device *netdev;
struct pci_dev *pdev;
- int pci_using_dac;
- struct net_device_stats net_stats;
- int mtu;
- int portnum;
- u8 physical_port;
- u16 tx_context_id;
-
- uint8_t mc_enabled;
- uint8_t max_mc_count;
- nx_mac_list_t *mac_list;
-
- struct netxen_legacy_intr_set legacy_intr;
-
- struct work_struct watchdog_task;
- struct timer_list watchdog_timer;
- struct work_struct tx_timeout_task;
+ struct list_head mac_list;
u32 curr_window;
u32 crb_win;
rwlock_t adapter_lock;
- u32 cmd_producer;
- __le32 *cmd_consumer;
- u32 last_cmd_consumer;
- u32 crb_addr_cmd_producer;
- u32 crb_addr_cmd_consumer;
spinlock_t tx_clean_lock;
- u32 num_txd;
- u32 num_rxd;
- u32 num_jumbo_rxd;
- u32 num_lro_rxd;
+ u16 num_txd;
+ u16 num_rxd;
+ u16 num_jumbo_rxd;
+ u16 num_lro_rxd;
+
+ u8 max_rds_rings;
+ u8 max_sds_rings;
+ u8 driver_mismatch;
+ u8 msix_supported;
+ u8 rx_csum;
+ u8 pci_using_dac;
+ u8 portnum;
+ u8 physical_port;
+
+ u8 mc_enabled;
+ u8 max_mc_count;
+ u8 rss_supported;
+ u8 resv2;
+ u32 resv3;
+
+ u8 has_link_events;
+ u8 resv1;
+ u16 tx_context_id;
+ u16 mtu;
+ u16 is_up;
- int max_rds_rings;
- int max_sds_rings;
+ u16 link_speed;
+ u16 link_duplex;
+ u16 link_autoneg;
+ u16 module_type;
+ u32 capabilities;
u32 flags;
u32 irq;
- int driver_mismatch;
u32 temp;
- u32 fw_major;
- u32 fw_version;
-
- int msix_supported;
- struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
+ u32 msi_tgt_status;
+ u32 resv4;
struct netxen_adapter_stats stats;
- u16 link_speed;
- u16 link_duplex;
- u16 state;
- u16 link_autoneg;
- int rx_csum;
-
- struct netxen_cmd_buffer *cmd_buf_arr; /* Command buffers for xmit */
-
- /*
- * Receive instances. These can be either one per port,
- * or one per peg, etc.
- */
struct netxen_recv_context recv_ctx;
+ struct nx_host_tx_ring *tx_ring;
- int is_up;
- struct netxen_dummy_dma dummy_dma;
- nx_nic_intr_coalesce_t coal;
-
- /* Context interface shared between card and host */
- struct netxen_ring_ctx *ctx_desc;
- dma_addr_t ctx_desc_phys_addr;
- int intr_scheme;
- int msi_mode;
int (*enable_phy_interrupts) (struct netxen_adapter *);
int (*disable_phy_interrupts) (struct netxen_adapter *);
- int (*macaddr_set) (struct netxen_adapter *, netxen_ethernet_macaddr_t);
+ int (*macaddr_set) (struct netxen_adapter *, u8 *);
int (*set_mtu) (struct netxen_adapter *, int);
int (*set_promisc) (struct netxen_adapter *, u32);
+ void (*set_multi) (struct net_device *);
int (*phy_read) (struct netxen_adapter *, long reg, u32 *);
int (*phy_write) (struct netxen_adapter *, long reg, u32 val);
int (*init_port) (struct netxen_adapter *, int);
int (*stop_port) (struct netxen_adapter *);
- int (*hw_read_wx)(struct netxen_adapter *, ulong, void *, int);
- int (*hw_write_wx)(struct netxen_adapter *, ulong, void *, int);
+ u32 (*hw_read_wx)(struct netxen_adapter *, ulong);
+ int (*hw_write_wx)(struct netxen_adapter *, ulong, u32);
int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int);
int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int);
int (*pci_write_immediate)(struct netxen_adapter *, u64, u32);
u32 (*pci_read_immediate)(struct netxen_adapter *, u64);
- void (*pci_write_normalize)(struct netxen_adapter *, u64, u32);
- u32 (*pci_read_normalize)(struct netxen_adapter *, u64);
unsigned long (*pci_set_window)(struct netxen_adapter *,
unsigned long long);
-}; /* netxen_adapter structure */
+
+ struct netxen_legacy_intr_set legacy_intr;
+
+ struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
+
+ struct netxen_dummy_dma dummy_dma;
+
+ struct work_struct watchdog_task;
+ struct timer_list watchdog_timer;
+ struct work_struct tx_timeout_task;
+
+ struct net_device_stats net_stats;
+
+ nx_nic_intr_coalesce_t coal;
+
+ u32 fw_major;
+ u32 fw_version;
+ const struct firmware *fw;
+};
/*
* NetXen dma watchdog control structure
@@ -1330,46 +1322,6 @@ struct netxen_adapter {
#define netxen_get_dma_watchdog_disabled(config_word) \
(((config_word) >> 1) & 0x1)
-/* Max number of xmit producer threads that can run simultaneously */
-#define MAX_XMIT_PRODUCERS 16
-
-#define PCI_OFFSET_FIRST_RANGE(adapter, off) \
- ((adapter)->ahw.pci_base0 + (off))
-#define PCI_OFFSET_SECOND_RANGE(adapter, off) \
- ((adapter)->ahw.pci_base1 + (off) - SECOND_PAGE_GROUP_START)
-#define PCI_OFFSET_THIRD_RANGE(adapter, off) \
- ((adapter)->ahw.pci_base2 + (off) - THIRD_PAGE_GROUP_START)
-
-static inline void __iomem *pci_base_offset(struct netxen_adapter *adapter,
- unsigned long off)
-{
- if ((off < FIRST_PAGE_GROUP_END) && (off >= FIRST_PAGE_GROUP_START)) {
- return (adapter->ahw.pci_base0 + off);
- } else if ((off < SECOND_PAGE_GROUP_END) &&
- (off >= SECOND_PAGE_GROUP_START)) {
- return (adapter->ahw.pci_base1 + off - SECOND_PAGE_GROUP_START);
- } else if ((off < THIRD_PAGE_GROUP_END) &&
- (off >= THIRD_PAGE_GROUP_START)) {
- return (adapter->ahw.pci_base2 + off - THIRD_PAGE_GROUP_START);
- }
- return NULL;
-}
-
-static inline void __iomem *pci_base(struct netxen_adapter *adapter,
- unsigned long off)
-{
- if ((off < FIRST_PAGE_GROUP_END) && (off >= FIRST_PAGE_GROUP_START)) {
- return adapter->ahw.pci_base0;
- } else if ((off < SECOND_PAGE_GROUP_END) &&
- (off >= SECOND_PAGE_GROUP_START)) {
- return adapter->ahw.pci_base1;
- } else if ((off < THIRD_PAGE_GROUP_END) &&
- (off >= THIRD_PAGE_GROUP_START)) {
- return adapter->ahw.pci_base2;
- }
- return NULL;
-}
-
int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter);
int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter);
int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter);
@@ -1382,21 +1334,22 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter,
/* Functions available from netxen_nic_hw.c */
int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu);
int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu);
-void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val);
-int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off);
-void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value);
-void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value);
-void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value);
-void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value);
+
+int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
+int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
+
+#define NXRD32(adapter, off) \
+ (adapter->hw_read_wx(adapter, off))
+#define NXWR32(adapter, off, val) \
+ (adapter->hw_write_wx(adapter, off, val))
int netxen_nic_get_board_info(struct netxen_adapter *adapter);
void netxen_nic_get_firmware_info(struct netxen_adapter *adapter);
int netxen_nic_wol_supported(struct netxen_adapter *adapter);
-int netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
- ulong off, void *data, int len);
+u32 netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off);
int netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
- ulong off, void *data, int len);
+ ulong off, u32 data);
int netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
u64 off, void *data, int size);
int netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
@@ -1412,16 +1365,13 @@ unsigned long netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
void netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter,
u32 wndw);
-int netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
- ulong off, void *data, int len);
+u32 netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off);
int netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
- ulong off, void *data, int len);
+ ulong off, u32 data);
int netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
u64 off, void *data, int size);
int netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
u64 off, void *data, int size);
-void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
- unsigned long off, int data);
int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
u64 off, u32 data);
u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off);
@@ -1435,8 +1385,9 @@ unsigned long netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
void netxen_free_adapter_offload(struct netxen_adapter *adapter);
int netxen_initialize_adapter_offload(struct netxen_adapter *adapter);
int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
-int netxen_receive_peg_ready(struct netxen_adapter *adapter);
int netxen_load_firmware(struct netxen_adapter *adapter);
+void netxen_request_firmware(struct netxen_adapter *adapter);
+void netxen_release_firmware(struct netxen_adapter *adapter);
int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose);
int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp);
@@ -1475,6 +1426,8 @@ void netxen_p3_free_mac_list(struct netxen_adapter *adapter);
int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32);
int netxen_config_intr_coalesce(struct netxen_adapter *adapter);
int netxen_config_rss(struct netxen_adapter *adapter, int enable);
+int netxen_linkevent_request(struct netxen_adapter *adapter, int enable);
+void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup);
int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
@@ -1483,7 +1436,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p);
struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
- uint32_t crb_producer);
+ struct nx_host_tx_ring *tx_ring, uint32_t crb_producer);
/*
* NetXen Board information
@@ -1491,7 +1444,7 @@ void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
#define NETXEN_MAX_SHORT_NAME 32
struct netxen_brdinfo {
- netxen_brdtype_t brdtype; /* type of board */
+ int brdtype; /* type of board */
long ports; /* max no of physical ports */
char short_name[NETXEN_MAX_SHORT_NAME];
};
@@ -1541,17 +1494,15 @@ dma_watchdog_shutdown_request(struct netxen_adapter *adapter)
u32 ctrl;
/* check if already inactive */
- if (adapter->hw_read_wx(adapter,
- NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
- printk(KERN_ERR "failed to read dma watchdog status\n");
+ ctrl = adapter->hw_read_wx(adapter,
+ NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
if (netxen_get_dma_watchdog_enabled(ctrl) == 0)
return 1;
/* Send the disable request */
netxen_set_dma_watchdog_disable_req(ctrl);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
+ NXWR32(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
return 0;
}
@@ -1561,9 +1512,8 @@ dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter)
{
u32 ctrl;
- if (adapter->hw_read_wx(adapter,
- NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
- printk(KERN_ERR "failed to read dma watchdog status\n");
+ ctrl = adapter->hw_read_wx(adapter,
+ NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
return (netxen_get_dma_watchdog_enabled(ctrl) == 0);
}
@@ -1573,9 +1523,8 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
{
u32 ctrl;
- if (adapter->hw_read_wx(adapter,
- NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
- printk(KERN_ERR "failed to read dma watchdog status\n");
+ ctrl = adapter->hw_read_wx(adapter,
+ NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
if (netxen_get_dma_watchdog_enabled(ctrl))
return 1;
@@ -1583,8 +1532,7 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
/* send the wakeup request */
netxen_set_dma_watchdog_enable_req(ctrl);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
+ NXWR32(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
return 0;
}
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 9234473bc08..4754f5cffad 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -41,8 +41,7 @@ netxen_api_lock(struct netxen_adapter *adapter)
for (;;) {
/* Acquire PCIE HW semaphore5 */
- netxen_nic_read_w0(adapter,
- NETXEN_PCIE_REG(PCIE_SEM5_LOCK), &done);
+ done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_LOCK));
if (done == 1)
break;
@@ -56,7 +55,7 @@ netxen_api_lock(struct netxen_adapter *adapter)
}
#if 0
- netxen_nic_write_w1(adapter,
+ NXWR32(adapter,
NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER);
#endif
return 0;
@@ -65,11 +64,8 @@ netxen_api_lock(struct netxen_adapter *adapter)
static int
netxen_api_unlock(struct netxen_adapter *adapter)
{
- u32 val;
-
/* Release PCIE HW semaphore5 */
- netxen_nic_read_w0(adapter,
- NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK), &val);
+ NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK));
return 0;
}
@@ -86,7 +82,7 @@ netxen_poll_rsp(struct netxen_adapter *adapter)
if (++timeout > NX_OS_CRB_RETRY_COUNT)
return NX_CDRP_RSP_TIMEOUT;
- netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET, &rsp);
+ rsp = NXRD32(adapter, NX_CDRP_CRB_OFFSET);
} while (!NX_CDRP_IS_RSP(rsp));
return rsp;
@@ -106,16 +102,15 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
if (netxen_api_lock(adapter))
return NX_RCODE_TIMEOUT;
- netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET, signature);
+ NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature);
- netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET, arg1);
+ NXWR32(adapter, NX_ARG1_CRB_OFFSET, arg1);
- netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET, arg2);
+ NXWR32(adapter, NX_ARG2_CRB_OFFSET, arg2);
- netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET, arg3);
+ NXWR32(adapter, NX_ARG3_CRB_OFFSET, arg3);
- netxen_nic_write_w1(adapter, NX_CDRP_CRB_OFFSET,
- NX_CDRP_FORM_CMD(cmd));
+ NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd));
rsp = netxen_poll_rsp(adapter);
@@ -125,7 +120,7 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
rcode = NX_RCODE_TIMEOUT;
} else if (rsp == NX_CDRP_RSP_FAIL) {
- netxen_nic_read_w1(adapter, NX_ARG1_CRB_OFFSET, &rcode);
+ rcode = NXRD32(adapter, NX_ARG1_CRB_OFFSET);
printk(KERN_ERR "%s: failed card response code:0x%x\n",
netxen_nic_driver_name, rcode);
@@ -328,6 +323,8 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
int err = 0;
u64 offset, phys_addr;
dma_addr_t rq_phys_addr, rsp_phys_addr;
+ struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
rq_addr = pci_alloc_consistent(adapter->pdev,
@@ -362,15 +359,13 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
prq->dummy_dma_addr = cpu_to_le64(adapter->dummy_dma.phys_addr);
- offset = adapter->ctx_desc_phys_addr+sizeof(struct netxen_ring_ctx);
+ offset = recv_ctx->phys_addr + sizeof(struct netxen_ring_ctx);
prq->cmd_cons_dma_addr = cpu_to_le64(offset);
prq_cds = &prq->cds_ring;
- prq_cds->host_phys_addr =
- cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
-
- prq_cds->ring_size = cpu_to_le32(adapter->num_txd);
+ prq_cds->host_phys_addr = cpu_to_le64(tx_ring->phys_addr);
+ prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc);
phys_addr = rq_phys_addr;
err = netxen_issue_cmd(adapter,
@@ -383,8 +378,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
if (err == NX_RCODE_SUCCESS) {
temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
- adapter->crb_addr_cmd_producer =
- NETXEN_NIC_REG(temp - 0x200);
+ tx_ring->crb_cmd_producer = NETXEN_NIC_REG(temp - 0x200);
#if 0
adapter->tx_state =
le32_to_cpu(prsp->host_ctx_state);
@@ -448,7 +442,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
NETXEN_NIC_REG(0x120)
},
/* crb_sts_consumer: */
- NETXEN_NIC_REG(0x138),
+ {
+ NETXEN_NIC_REG(0x138),
+ NETXEN_NIC_REG_2(0x000),
+ NETXEN_NIC_REG_2(0x004),
+ NETXEN_NIC_REG_2(0x008),
+ },
+ /* sw_int_mask */
+ {
+ CRB_SW_INT_MASK_0,
+ NETXEN_NIC_REG_2(0x044),
+ NETXEN_NIC_REG_2(0x048),
+ NETXEN_NIC_REG_2(0x04c),
+ },
},
/* Instance 1 */
{
@@ -461,7 +467,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
NETXEN_NIC_REG(0x164)
},
/* crb_sts_consumer: */
- NETXEN_NIC_REG(0x17c),
+ {
+ NETXEN_NIC_REG(0x17c),
+ NETXEN_NIC_REG_2(0x020),
+ NETXEN_NIC_REG_2(0x024),
+ NETXEN_NIC_REG_2(0x028),
+ },
+ /* sw_int_mask */
+ {
+ CRB_SW_INT_MASK_1,
+ NETXEN_NIC_REG_2(0x064),
+ NETXEN_NIC_REG_2(0x068),
+ NETXEN_NIC_REG_2(0x06c),
+ },
},
/* Instance 2 */
{
@@ -474,7 +492,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
NETXEN_NIC_REG(0x208)
},
/* crb_sts_consumer: */
- NETXEN_NIC_REG(0x220),
+ {
+ NETXEN_NIC_REG(0x220),
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ },
+ /* sw_int_mask */
+ {
+ CRB_SW_INT_MASK_2,
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ },
},
/* Instance 3 */
{
@@ -487,7 +517,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
NETXEN_NIC_REG(0x24c)
},
/* crb_sts_consumer: */
- NETXEN_NIC_REG(0x264),
+ {
+ NETXEN_NIC_REG(0x264),
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ },
+ /* sw_int_mask */
+ {
+ CRB_SW_INT_MASK_3,
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ NETXEN_NIC_REG_2(0x03c),
+ },
},
};
@@ -497,84 +539,91 @@ netxen_init_old_ctx(struct netxen_adapter *adapter)
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
struct nx_host_sds_ring *sds_ring;
+ struct nx_host_tx_ring *tx_ring;
int ring;
- int func_id = adapter->portnum;
-
- adapter->ctx_desc->cmd_ring_addr =
- cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
- adapter->ctx_desc->cmd_ring_size =
- cpu_to_le32(adapter->num_txd);
+ int port = adapter->portnum;
+ struct netxen_ring_ctx *hwctx;
+ u32 signature;
+ tx_ring = adapter->tx_ring;
recv_ctx = &adapter->recv_ctx;
+ hwctx = recv_ctx->hwctx;
+
+ hwctx->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr);
+ hwctx->cmd_ring_size = cpu_to_le32(tx_ring->num_desc);
+
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
- adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr =
+ hwctx->rcv_rings[ring].addr =
cpu_to_le64(rds_ring->phys_addr);
- adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
+ hwctx->rcv_rings[ring].size =
cpu_to_le32(rds_ring->num_desc);
}
- sds_ring = &recv_ctx->sds_rings[0];
- adapter->ctx_desc->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr);
- adapter->ctx_desc->sts_ring_size = cpu_to_le32(sds_ring->num_desc);
-
- adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id),
- lower32(adapter->ctx_desc_phys_addr));
- adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_HI(func_id),
- upper32(adapter->ctx_desc_phys_addr));
- adapter->pci_write_normalize(adapter, CRB_CTX_SIGNATURE_REG(func_id),
- NETXEN_CTX_SIGNATURE | func_id);
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+
+ if (ring == 0) {
+ hwctx->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr);
+ hwctx->sts_ring_size = cpu_to_le32(sds_ring->num_desc);
+ }
+ hwctx->sts_rings[ring].addr = cpu_to_le64(sds_ring->phys_addr);
+ hwctx->sts_rings[ring].size = cpu_to_le32(sds_ring->num_desc);
+ hwctx->sts_rings[ring].msi_index = cpu_to_le16(ring);
+ }
+ hwctx->sts_ring_count = cpu_to_le32(adapter->max_sds_rings);
+
+ signature = (adapter->max_sds_rings > 1) ?
+ NETXEN_CTX_SIGNATURE_V2 : NETXEN_CTX_SIGNATURE;
+
+ NXWR32(adapter, CRB_CTX_ADDR_REG_LO(port),
+ lower32(recv_ctx->phys_addr));
+ NXWR32(adapter, CRB_CTX_ADDR_REG_HI(port),
+ upper32(recv_ctx->phys_addr));
+ NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port),
+ signature | port);
return 0;
}
-static uint32_t sw_int_mask[4] = {
- CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1,
- CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3
-};
-
int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
{
- struct netxen_hardware_context *hw = &adapter->ahw;
- u32 state = 0;
void *addr;
int err = 0;
int ring;
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
struct nx_host_sds_ring *sds_ring;
+ struct nx_host_tx_ring *tx_ring;
struct pci_dev *pdev = adapter->pdev;
struct net_device *netdev = adapter->netdev;
+ int port = adapter->portnum;
- err = netxen_receive_peg_ready(adapter);
- if (err) {
- printk(KERN_ERR "Rcv Peg initialization not complete:%x.\n",
- state);
- return err;
- }
+ recv_ctx = &adapter->recv_ctx;
+ tx_ring = adapter->tx_ring;
addr = pci_alloc_consistent(pdev,
sizeof(struct netxen_ring_ctx) + sizeof(uint32_t),
- &adapter->ctx_desc_phys_addr);
-
+ &recv_ctx->phys_addr);
if (addr == NULL) {
dev_err(&pdev->dev, "failed to allocate hw context\n");
return -ENOMEM;
}
+
memset(addr, 0, sizeof(struct netxen_ring_ctx));
- adapter->ctx_desc = (struct netxen_ring_ctx *)addr;
- adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum);
- adapter->ctx_desc->cmd_consumer_offset =
- cpu_to_le64(adapter->ctx_desc_phys_addr +
+ recv_ctx->hwctx = (struct netxen_ring_ctx *)addr;
+ recv_ctx->hwctx->ctx_id = cpu_to_le32(port);
+ recv_ctx->hwctx->cmd_consumer_offset =
+ cpu_to_le64(recv_ctx->phys_addr +
sizeof(struct netxen_ring_ctx));
- adapter->cmd_consumer =
+ tx_ring->hw_consumer =
(__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx));
/* cmd desc ring */
- addr = pci_alloc_consistent(pdev,
- TX_DESC_RINGSIZE(adapter),
- &hw->cmd_desc_phys_addr);
+ addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring),
+ &tx_ring->phys_addr);
if (addr == NULL) {
dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n",
@@ -582,9 +631,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
return -ENOMEM;
}
- hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
-
- recv_ctx = &adapter->recv_ctx;
+ tx_ring->desc_head = (struct cmd_desc_type0 *)addr;
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
@@ -602,8 +649,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
if (adapter->fw_major < 4)
rds_ring->crb_rcv_producer =
- recv_crb_registers[adapter->portnum].
- crb_rcv_producer[ring];
+ recv_crb_registers[port].crb_rcv_producer[ring];
}
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
@@ -620,13 +666,16 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
goto err_out_free;
}
sds_ring->desc_head = (struct status_desc *)addr;
+
+ sds_ring->crb_sts_consumer =
+ recv_crb_registers[port].crb_sts_consumer[ring];
+
+ sds_ring->crb_intr_mask =
+ recv_crb_registers[port].sw_int_mask[ring];
}
if (adapter->fw_major >= 4) {
- adapter->intr_scheme = INTR_SCHEME_PERPORT;
- adapter->msi_mode = MSI_MODE_MULTIFUNC;
-
err = nx_fw_cmd_create_rx_ctx(adapter);
if (err)
goto err_out_free;
@@ -634,23 +683,11 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
if (err)
goto err_out_free;
} else {
- sds_ring = &recv_ctx->sds_rings[0];
- sds_ring->crb_sts_consumer =
- recv_crb_registers[adapter->portnum].crb_sts_consumer;
-
- adapter->intr_scheme = adapter->pci_read_normalize(adapter,
- CRB_NIC_CAPABILITIES_FW);
- adapter->msi_mode = adapter->pci_read_normalize(adapter,
- CRB_NIC_MSI_MODE_FW);
- recv_ctx->sds_rings[0].crb_intr_mask =
- sw_int_mask[adapter->portnum];
-
err = netxen_init_old_ctx(adapter);
if (err) {
netxen_free_hw_resources(adapter);
return err;
}
-
}
return 0;
@@ -665,32 +702,40 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
struct nx_host_sds_ring *sds_ring;
+ struct nx_host_tx_ring *tx_ring;
int ring;
+ int port = adapter->portnum;
+
if (adapter->fw_major >= 4) {
nx_fw_cmd_destroy_tx_ctx(adapter);
nx_fw_cmd_destroy_rx_ctx(adapter);
+ } else {
+ netxen_api_lock(adapter);
+ NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port),
+ NETXEN_CTX_RESET | port);
+ netxen_api_unlock(adapter);
}
- if (adapter->ctx_desc != NULL) {
+ recv_ctx = &adapter->recv_ctx;
+
+ if (recv_ctx->hwctx != NULL) {
pci_free_consistent(adapter->pdev,
sizeof(struct netxen_ring_ctx) +
sizeof(uint32_t),
- adapter->ctx_desc,
- adapter->ctx_desc_phys_addr);
- adapter->ctx_desc = NULL;
+ recv_ctx->hwctx,
+ recv_ctx->phys_addr);
+ recv_ctx->hwctx = NULL;
}
- if (adapter->ahw.cmd_desc_head != NULL) {
+ tx_ring = adapter->tx_ring;
+ if (tx_ring->desc_head != NULL) {
pci_free_consistent(adapter->pdev,
- sizeof(struct cmd_desc_type0) *
- adapter->num_txd,
- adapter->ahw.cmd_desc_head,
- adapter->ahw.cmd_desc_phys_addr);
- adapter->ahw.cmd_desc_head = NULL;
+ TX_DESC_RINGSIZE(tx_ring),
+ tx_ring->desc_head, tx_ring->phys_addr);
+ tx_ring->desc_head = NULL;
}
- recv_ctx = &adapter->recv_ctx;
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index a677ff89518..e16ea46c24b 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -30,7 +30,6 @@
#include <linux/types.h>
#include <linux/delay.h>
-#include <asm/uaccess.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <linux/netdevice.h>
@@ -53,13 +52,9 @@ struct netxen_nic_stats {
#define NETXEN_NIC_INVALID_DATA 0xDEADBEEF
static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = {
- {"rcvd_bad_skb", NETXEN_NIC_STAT(stats.rcvdbadskb)},
{"xmit_called", NETXEN_NIC_STAT(stats.xmitcalled)},
- {"xmited_frames", NETXEN_NIC_STAT(stats.xmitedframes)},
{"xmit_finished", NETXEN_NIC_STAT(stats.xmitfinished)},
- {"bad_skb_len", NETXEN_NIC_STAT(stats.badskblen)},
- {"no_cmd_desc", NETXEN_NIC_STAT(stats.nocmddescriptor)},
- {"polled", NETXEN_NIC_STAT(stats.polled)},
+ {"rx_dropped", NETXEN_NIC_STAT(stats.rxdropped)},
{"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)},
{"csummed", NETXEN_NIC_STAT(stats.csummed)},
{"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)},
@@ -97,12 +92,9 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
strncpy(drvinfo->driver, netxen_nic_driver_name, 32);
strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32);
write_lock_irqsave(&adapter->adapter_lock, flags);
- fw_major = adapter->pci_read_normalize(adapter,
- NETXEN_FW_VERSION_MAJOR);
- fw_minor = adapter->pci_read_normalize(adapter,
- NETXEN_FW_VERSION_MINOR);
- fw_build = adapter->pci_read_normalize(adapter,
- NETXEN_FW_VERSION_SUB);
+ fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
+ fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
+ fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
write_unlock_irqrestore(&adapter->adapter_lock, flags);
sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
@@ -115,6 +107,7 @@ static int
netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
struct netxen_adapter *adapter = netdev_priv(dev);
+ int check_sfp_module = 0;
/* read which mode */
if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
@@ -139,7 +132,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
u32 val;
- adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR, &val, 4);
+ val = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
if (val == NETXEN_PORT_MODE_802_3_AP) {
ecmd->supported = SUPPORTED_1000baseT_Full;
ecmd->advertising = ADVERTISED_1000baseT_Full;
@@ -148,13 +141,19 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->advertising = ADVERTISED_10000baseT_Full;
}
+ if (netif_running(dev) && adapter->has_link_events) {
+ ecmd->speed = adapter->link_speed;
+ ecmd->autoneg = adapter->link_autoneg;
+ ecmd->duplex = adapter->link_duplex;
+ goto skip;
+ }
+
ecmd->port = PORT_TP;
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
u16 pcifn = adapter->ahw.pci_func;
- adapter->hw_read_wx(adapter,
- P3_LINK_SPEED_REG(pcifn), &val, 4);
+ val = NXRD32(adapter, P3_LINK_SPEED_REG(pcifn));
ecmd->speed = P3_LINK_SPEED_MHZ *
P3_LINK_SPEED_VAL(pcifn, val);
} else
@@ -165,10 +164,11 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
} else
return -EIO;
+skip:
ecmd->phy_address = adapter->physical_port;
ecmd->transceiver = XCVR_EXTERNAL;
- switch ((netxen_brdtype_t)adapter->ahw.board_type) {
+ switch (adapter->ahw.board_type) {
case NETXEN_BRDTYPE_P2_SB35_4G:
case NETXEN_BRDTYPE_P2_SB31_2G:
case NETXEN_BRDTYPE_P3_REF_QG:
@@ -195,7 +195,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
case NETXEN_BRDTYPE_P3_HMEZ:
ecmd->supported |= SUPPORTED_MII;
ecmd->advertising |= ADVERTISED_MII;
- ecmd->port = PORT_FIBRE;
+ ecmd->port = PORT_MII;
ecmd->autoneg = AUTONEG_DISABLE;
break;
case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
@@ -203,6 +203,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
case NETXEN_BRDTYPE_P3_10G_SFP_QT:
ecmd->advertising |= ADVERTISED_TP;
ecmd->supported |= SUPPORTED_TP;
+ check_sfp_module = netif_running(dev) &&
+ adapter->has_link_events;
case NETXEN_BRDTYPE_P2_SB31_10G:
case NETXEN_BRDTYPE_P3_10G_XFP:
ecmd->supported |= SUPPORTED_FIBRE;
@@ -217,6 +219,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->advertising |=
(ADVERTISED_FIBRE | ADVERTISED_TP);
ecmd->port = PORT_FIBRE;
+ check_sfp_module = netif_running(dev) &&
+ adapter->has_link_events;
} else {
ecmd->autoneg = AUTONEG_ENABLE;
ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg);
@@ -227,10 +231,28 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
break;
default:
printk(KERN_ERR "netxen-nic: Unsupported board model %d\n",
- (netxen_brdtype_t)adapter->ahw.board_type);
+ adapter->ahw.board_type);
return -EIO;
}
+ if (check_sfp_module) {
+ switch (adapter->module_type) {
+ case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
+ case LINKEVENT_MODULE_OPTICAL_SRLR:
+ case LINKEVENT_MODULE_OPTICAL_LRM:
+ case LINKEVENT_MODULE_OPTICAL_SFP_1G:
+ ecmd->port = PORT_FIBRE;
+ break;
+ case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
+ case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
+ case LINKEVENT_MODULE_TWINAX:
+ ecmd->port = PORT_TP;
+ break;
+ default:
+ ecmd->port = -1;
+ }
+ }
+
return 0;
}
@@ -398,12 +420,11 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
(adapter->pdev)->device;
/* which mode */
- adapter->hw_read_wx(adapter, NETXEN_NIU_MODE, &regs_buff[0], 4);
+ regs_buff[0] = NXRD32(adapter, NETXEN_NIU_MODE);
mode = regs_buff[0];
/* Common registers to all the modes */
- adapter->hw_read_wx(adapter,
- NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER, &regs_buff[2], 4);
+ regs_buff[2] = NXRD32(adapter, NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER);
/* GB/XGB Mode */
mode = (mode / 2) - 1;
window = 0;
@@ -414,9 +435,8 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
window = adapter->physical_port *
NETXEN_NIC_PORT_WINDOW;
- adapter->hw_read_wx(adapter,
- niu_registers[mode].reg[i - 3] + window,
- &regs_buff[i], 4);
+ regs_buff[i] = NXRD32(adapter,
+ niu_registers[mode].reg[i - 3] + window);
}
}
@@ -440,7 +460,7 @@ static u32 netxen_nic_test_link(struct net_device *dev)
return !val;
}
} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
- val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
+ val = NXRD32(adapter, CRB_XG_STATE);
return (val == XG_LINK_UP) ? 0 : 1;
}
return -EIO;
@@ -504,10 +524,9 @@ netxen_nic_get_pauseparam(struct net_device *dev,
if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
return;
/* get flow control settings */
- netxen_nic_read_w0(adapter,NETXEN_NIU_GB_MAC_CONFIG_0(port),
- &val);
+ val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
pause->rx_pause = netxen_gb_get_rx_flowctl(val);
- netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val);
+ val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
switch (port) {
case 0:
pause->tx_pause = !(netxen_gb_get_gb0_mask(val));
@@ -527,7 +546,7 @@ netxen_nic_get_pauseparam(struct net_device *dev,
if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
return;
pause->rx_pause = 1;
- netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);
+ val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
if (port == 0)
pause->tx_pause = !(netxen_xg_get_xg0_mask(val));
else
@@ -550,18 +569,17 @@ netxen_nic_set_pauseparam(struct net_device *dev,
if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
return -EIO;
/* set flow control */
- netxen_nic_read_w0(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0(port), &val);
+ val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
if (pause->rx_pause)
netxen_gb_rx_flowctl(val);
else
netxen_gb_unset_rx_flowctl(val);
- netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
val);
/* set autoneg */
- netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val);
+ val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
switch (port) {
case 0:
if (pause->tx_pause)
@@ -589,11 +607,11 @@ netxen_nic_set_pauseparam(struct net_device *dev,
netxen_gb_set_gb3_mask(val);
break;
}
- netxen_nic_write_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
+ NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
return -EIO;
- netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);
+ val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
if (port == 0) {
if (pause->tx_pause)
netxen_xg_unset_xg0_mask(val);
@@ -605,7 +623,7 @@ netxen_nic_set_pauseparam(struct net_device *dev,
else
netxen_xg_set_xg1_mask(val);
}
- netxen_nic_write_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
+ NXWR32(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
} else {
printk(KERN_ERR "%s: Unknown board type: %x\n",
netxen_nic_driver_name,
@@ -619,14 +637,14 @@ static int netxen_nic_reg_test(struct net_device *dev)
struct netxen_adapter *adapter = netdev_priv(dev);
u32 data_read, data_written;
- netxen_nic_read_w0(adapter, NETXEN_PCIX_PH_REG(0), &data_read);
+ data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0));
if ((data_read & 0xffff) != PHAN_VENDOR_ID)
return 1;
data_written = (u32)0xa5a5a5a5;
- netxen_nic_reg_write(adapter, CRB_SCRATCHPAD_TEST, data_written);
- data_read = adapter->pci_read_normalize(adapter, CRB_SCRATCHPAD_TEST);
+ NXWR32(adapter, CRB_SCRATCHPAD_TEST, data_written);
+ data_read = NXRD32(adapter, CRB_SCRATCHPAD_TEST);
if (data_written != data_read)
return 1;
@@ -743,11 +761,11 @@ netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
return;
- wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+ wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
if (wol_cfg & (1UL << adapter->portnum))
wol->supported |= WAKE_MAGIC;
- wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+ wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
if (wol_cfg & (1UL << adapter->portnum))
wol->wolopts |= WAKE_MAGIC;
}
@@ -764,16 +782,16 @@ netxen_nic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
if (wol->wolopts & ~WAKE_MAGIC)
return -EOPNOTSUPP;
- wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+ wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
if (!(wol_cfg & (1 << adapter->portnum)))
return -EOPNOTSUPP;
- wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+ wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
if (wol->wolopts & WAKE_MAGIC)
wol_cfg |= 1UL << adapter->portnum;
else
wol_cfg &= ~(1UL << adapter->portnum);
- netxen_nic_reg_write(adapter, NETXEN_WOL_CONFIG, wol_cfg);
+ NXWR32(adapter, NETXEN_WOL_CONFIG, wol_cfg);
return 0;
}
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index 016c62129c7..7f0ddbfa7b2 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -31,16 +31,8 @@
#ifndef __NETXEN_NIC_HDR_H_
#define __NETXEN_NIC_HDR_H_
-#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <asm/irq.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
#include <linux/types.h>
-#include <asm/uaccess.h>
-#include <asm/string.h> /* for memset */
/*
* The basic unit of access when reading/writing control registers.
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 5026811c04c..42ffb825ebf 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -32,7 +32,6 @@
#include "netxen_nic_hw.h"
#include "netxen_nic_phan_reg.h"
-#include <linux/firmware.h>
#include <net/ip.h>
#define MASK(n) ((1ULL<<(n))-1)
@@ -48,8 +47,49 @@
#define CRB_HI(off) ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
#define CRB_INDIRECT_2M (0x1e0000UL)
+#ifndef readq
+static inline u64 readq(void __iomem *addr)
+{
+ return readl(addr) | (((u64) readl(addr + 4)) << 32LL);
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(u64 val, void __iomem *addr)
+{
+ writel(((u32) (val)), (addr));
+ writel(((u32) (val >> 32)), (addr + 4));
+}
+#endif
+
+#define ADDR_IN_RANGE(addr, low, high) \
+ (((addr) < (high)) && ((addr) >= (low)))
+
+#define PCI_OFFSET_FIRST_RANGE(adapter, off) \
+ ((adapter)->ahw.pci_base0 + (off))
+#define PCI_OFFSET_SECOND_RANGE(adapter, off) \
+ ((adapter)->ahw.pci_base1 + (off) - SECOND_PAGE_GROUP_START)
+#define PCI_OFFSET_THIRD_RANGE(adapter, off) \
+ ((adapter)->ahw.pci_base2 + (off) - THIRD_PAGE_GROUP_START)
+
+static void __iomem *pci_base_offset(struct netxen_adapter *adapter,
+ unsigned long off)
+{
+ if (ADDR_IN_RANGE(off, FIRST_PAGE_GROUP_START, FIRST_PAGE_GROUP_END))
+ return PCI_OFFSET_FIRST_RANGE(adapter, off);
+
+ if (ADDR_IN_RANGE(off, SECOND_PAGE_GROUP_START, SECOND_PAGE_GROUP_END))
+ return PCI_OFFSET_SECOND_RANGE(adapter, off);
+
+ if (ADDR_IN_RANGE(off, THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_END))
+ return PCI_OFFSET_THIRD_RANGE(adapter, off);
+
+ return NULL;
+}
+
#define CRB_WIN_LOCK_TIMEOUT 100000000
-static crb_128M_2M_block_map_t crb_128M_2M_map[64] = {
+static crb_128M_2M_block_map_t
+crb_128M_2M_map[64] __cacheline_aligned_in_smp = {
{{{0, 0, 0, 0} } }, /* 0: PCI */
{{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */
{1, 0x0110000, 0x0120000, 0x130000},
@@ -279,39 +319,8 @@ static unsigned crb_hub_agt[64] =
/* PCI Windowing for DDR regions. */
-#define ADDR_IN_RANGE(addr, low, high) \
- (((addr) <= (high)) && ((addr) >= (low)))
-
#define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */
-#define NETXEN_NIC_ZERO_PAUSE_ADDR 0ULL
-#define NETXEN_NIC_UNIT_PAUSE_ADDR 0x200ULL
-#define NETXEN_NIC_EPG_PAUSE_ADDR1 0x2200010000c28001ULL
-#define NETXEN_NIC_EPG_PAUSE_ADDR2 0x0100088866554433ULL
-
-#define NETXEN_NIC_WINDOW_MARGIN 0x100000
-
-int netxen_nic_set_mac(struct net_device *netdev, void *p)
-{
- struct netxen_adapter *adapter = netdev_priv(netdev);
- struct sockaddr *addr = p;
-
- if (netif_running(netdev))
- return -EBUSY;
-
- if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
-
- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-
- /* For P3, MAC addr is not set in NIU */
- if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
- if (adapter->macaddr_set)
- adapter->macaddr_set(adapter, addr->sa_data);
-
- return 0;
-}
-
#define NETXEN_UNICAST_ADDR(port, index) \
(NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8))
#define NETXEN_MCAST_ADDR(port, index) \
@@ -331,22 +340,20 @@ netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter)
if (adapter->mc_enabled)
return 0;
- adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+ val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG);
val |= (1UL << (28+port));
- adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+ NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
/* add broadcast addr to filter */
val = 0xffffff;
- netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_UNICAST_ADDR(port, 0)+4, val);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val);
/* add station addr to filter */
val = MAC_HI(addr);
- netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1), val);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), val);
val = MAC_LO(addr);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_UNICAST_ADDR(port, 1)+4, val);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, val);
adapter->mc_enabled = 1;
return 0;
@@ -362,18 +369,17 @@ netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter)
if (!adapter->mc_enabled)
return 0;
- adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+ val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG);
val &= ~(1UL << (28+port));
- adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+ NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
val = MAC_HI(addr);
- netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
val = MAC_LO(addr);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_UNICAST_ADDR(port, 0)+4, val);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val);
- netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1), 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), 0);
+ NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0);
adapter->mc_enabled = 0;
return 0;
@@ -389,10 +395,8 @@ netxen_nic_set_mcast_addr(struct netxen_adapter *adapter,
lo = MAC_LO(addr);
hi = MAC_HI(addr);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_MCAST_ADDR(port, index), hi);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_MCAST_ADDR(port, index)+4, lo);
+ NXWR32(adapter, NETXEN_MCAST_ADDR(port, index), hi);
+ NXWR32(adapter, NETXEN_MCAST_ADDR(port, index)+4, lo);
return 0;
}
@@ -445,100 +449,58 @@ void netxen_p2_nic_set_multi(struct net_device *netdev)
netxen_nic_set_mcast_addr(adapter, index, null_addr);
}
-static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
- u8 *addr, nx_mac_list_t **add_list, nx_mac_list_t **del_list)
-{
- nx_mac_list_t *cur, *prev;
-
- /* if in del_list, move it to adapter->mac_list */
- for (cur = *del_list, prev = NULL; cur;) {
- if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
- if (prev == NULL)
- *del_list = cur->next;
- else
- prev->next = cur->next;
- cur->next = adapter->mac_list;
- adapter->mac_list = cur;
- return 0;
- }
- prev = cur;
- cur = cur->next;
- }
-
- /* make sure to add each mac address only once */
- for (cur = adapter->mac_list; cur; cur = cur->next) {
- if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
- return 0;
- }
- /* not in del_list, create new entry and add to add_list */
- cur = kmalloc(sizeof(*cur), in_atomic()? GFP_ATOMIC : GFP_KERNEL);
- if (cur == NULL) {
- printk(KERN_ERR "%s: cannot allocate memory. MAC filtering may"
- "not work properly from now.\n", __func__);
- return -1;
- }
-
- memcpy(cur->mac_addr, addr, ETH_ALEN);
- cur->next = *add_list;
- *add_list = cur;
- return 0;
-}
-
static int
netxen_send_cmd_descs(struct netxen_adapter *adapter,
- struct cmd_desc_type0 *cmd_desc_arr, int nr_elements)
+ struct cmd_desc_type0 *cmd_desc_arr, int nr_desc)
{
- uint32_t i, producer;
+ u32 i, producer, consumer;
struct netxen_cmd_buffer *pbuf;
struct cmd_desc_type0 *cmd_desc;
-
- if (nr_elements > MAX_PENDING_DESC_BLOCK_SIZE || nr_elements == 0) {
- printk(KERN_WARNING "%s: Too many command descriptors in a "
- "request\n", __func__);
- return -EINVAL;
- }
+ struct nx_host_tx_ring *tx_ring;
i = 0;
+ tx_ring = adapter->tx_ring;
netif_tx_lock_bh(adapter->netdev);
- producer = adapter->cmd_producer;
+ producer = tx_ring->producer;
+ consumer = tx_ring->sw_consumer;
+
+ if (nr_desc >= find_diff_among(producer, consumer, tx_ring->num_desc)) {
+ netif_tx_unlock_bh(adapter->netdev);
+ return -EBUSY;
+ }
+
do {
cmd_desc = &cmd_desc_arr[i];
- pbuf = &adapter->cmd_buf_arr[producer];
+ pbuf = &tx_ring->cmd_buf_arr[producer];
pbuf->skb = NULL;
pbuf->frag_count = 0;
- /* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */
- memcpy(&adapter->ahw.cmd_desc_head[producer],
+ memcpy(&tx_ring->desc_head[producer],
&cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
- producer = get_next_index(producer,
- adapter->num_txd);
+ producer = get_next_index(producer, tx_ring->num_desc);
i++;
- } while (i != nr_elements);
-
- adapter->cmd_producer = producer;
+ } while (i != nr_desc);
- /* write producer index to start the xmit */
+ tx_ring->producer = producer;
- netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer);
+ netxen_nic_update_cmd_producer(adapter, tx_ring, producer);
netif_tx_unlock_bh(adapter->netdev);
return 0;
}
-static int nx_p3_sre_macaddr_change(struct net_device *dev,
- u8 *addr, unsigned op)
+static int
+nx_p3_sre_macaddr_change(struct netxen_adapter *adapter, u8 *addr, unsigned op)
{
- struct netxen_adapter *adapter = netdev_priv(dev);
nx_nic_req_t req;
nx_mac_req_t *mac_req;
u64 word;
- int rv;
memset(&req, 0, sizeof(nx_nic_req_t));
req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23);
@@ -550,28 +512,51 @@ static int nx_p3_sre_macaddr_change(struct net_device *dev,
mac_req->op = op;
memcpy(mac_req->mac_addr, addr, 6);
- rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
- if (rv != 0) {
- printk(KERN_ERR "ERROR. Could not send mac update\n");
- return rv;
+ return netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+}
+
+static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
+ u8 *addr, struct list_head *del_list)
+{
+ struct list_head *head;
+ nx_mac_list_t *cur;
+
+ /* look up if already exists */
+ list_for_each(head, del_list) {
+ cur = list_entry(head, nx_mac_list_t, list);
+
+ if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
+ list_move_tail(head, &adapter->mac_list);
+ return 0;
+ }
}
- return 0;
+ cur = kzalloc(sizeof(nx_mac_list_t), GFP_ATOMIC);
+ if (cur == NULL) {
+ printk(KERN_ERR "%s: failed to add mac address filter\n",
+ adapter->netdev->name);
+ return -ENOMEM;
+ }
+ memcpy(cur->mac_addr, addr, ETH_ALEN);
+ list_add_tail(&cur->list, &adapter->mac_list);
+ return nx_p3_sre_macaddr_change(adapter,
+ cur->mac_addr, NETXEN_MAC_ADD);
}
void netxen_p3_nic_set_multi(struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
- nx_mac_list_t *cur, *next, *del_list, *add_list = NULL;
struct dev_mc_list *mc_ptr;
u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
u32 mode = VPORT_MISS_MODE_DROP;
+ LIST_HEAD(del_list);
+ struct list_head *head;
+ nx_mac_list_t *cur;
- del_list = adapter->mac_list;
- adapter->mac_list = NULL;
+ list_splice_tail_init(&adapter->mac_list, &del_list);
- nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list);
- nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list);
+ nx_p3_nic_add_mac(adapter, netdev->dev_addr, &del_list);
+ nx_p3_nic_add_mac(adapter, bcast_addr, &del_list);
if (netdev->flags & IFF_PROMISC) {
mode = VPORT_MISS_MODE_ACCEPT_ALL;
@@ -587,25 +572,20 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
if (netdev->mc_count > 0) {
for (mc_ptr = netdev->mc_list; mc_ptr;
mc_ptr = mc_ptr->next) {
- nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr,
- &add_list, &del_list);
+ nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, &del_list);
}
}
send_fw_cmd:
adapter->set_promisc(adapter, mode);
- for (cur = del_list; cur;) {
- nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL);
- next = cur->next;
+ head = &del_list;
+ while (!list_empty(head)) {
+ cur = list_entry(head->next, nx_mac_list_t, list);
+
+ nx_p3_sre_macaddr_change(adapter,
+ cur->mac_addr, NETXEN_MAC_DEL);
+ list_del(&cur->list);
kfree(cur);
- cur = next;
- }
- for (cur = add_list; cur;) {
- nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_ADD);
- next = cur->next;
- cur->next = adapter->mac_list;
- adapter->mac_list = cur;
- cur = next;
}
}
@@ -630,17 +610,25 @@ int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
void netxen_p3_free_mac_list(struct netxen_adapter *adapter)
{
- nx_mac_list_t *cur, *next;
-
- cur = adapter->mac_list;
-
- while (cur) {
- next = cur->next;
+ nx_mac_list_t *cur;
+ struct list_head *head = &adapter->mac_list;
+
+ while (!list_empty(head)) {
+ cur = list_entry(head->next, nx_mac_list_t, list);
+ nx_p3_sre_macaddr_change(adapter,
+ cur->mac_addr, NETXEN_MAC_DEL);
+ list_del(&cur->list);
kfree(cur);
- cur = next;
}
}
+int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
+{
+ /* assuming caller has already copied new addr to netdev */
+ netxen_p3_nic_set_multi(adapter->netdev);
+ return 0;
+}
+
#define NETXEN_CONFIG_INTR_COALESCE 3
/*
@@ -717,6 +705,28 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable)
return rv;
}
+int netxen_linkevent_request(struct netxen_adapter *adapter, int enable)
+{
+ nx_nic_req_t req;
+ u64 word;
+ int rv;
+
+ memset(&req, 0, sizeof(nx_nic_req_t));
+ req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+ word = NX_NIC_H2C_OPCODE_GET_LINKEVENT | ((u64)adapter->portnum << 16);
+ req.req_hdr = cpu_to_le64(word);
+ req.words[0] = cpu_to_le64(enable | (enable << 8));
+
+ rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+ if (rv != 0) {
+ printk(KERN_ERR "%s: could not configure link notification\n",
+ adapter->netdev->name);
+ }
+
+ return rv;
+}
+
/*
* netxen_nic_change_mtu - Change the Maximum Transfer Unit
* @returns 0 on success, negative on failure
@@ -812,8 +822,8 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
crbaddr = CRB_MAC_BLOCK_START +
(4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
- adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4);
- adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4);
+ mac_lo = NXRD32(adapter, crbaddr);
+ mac_hi = NXRD32(adapter, crbaddr+4);
if (pci_func & 1)
*mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16));
@@ -831,8 +841,7 @@ static int crb_win_lock(struct netxen_adapter *adapter)
while (!done) {
/* acquire semaphore3 from PCI HW block */
- adapter->hw_read_wx(adapter,
- NETXEN_PCIE_REG(PCIE_SEM7_LOCK), &done, 4);
+ done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_LOCK));
if (done == 1)
break;
if (timeout >= CRB_WIN_LOCK_TIMEOUT)
@@ -840,8 +849,7 @@ static int crb_win_lock(struct netxen_adapter *adapter)
timeout++;
udelay(1);
}
- netxen_crb_writelit_adapter(adapter,
- NETXEN_CRB_WIN_LOCK_ID, adapter->portnum);
+ NXWR32(adapter, NETXEN_CRB_WIN_LOCK_ID, adapter->portnum);
return 0;
}
@@ -849,8 +857,7 @@ static void crb_win_unlock(struct netxen_adapter *adapter)
{
int val;
- adapter->hw_read_wx(adapter,
- NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK), &val, 4);
+ val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK));
}
/*
@@ -907,17 +914,15 @@ netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw)
* In: 'off' is offset from base in 128M pci map
*/
static int
-netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter,
- ulong *off, int len)
+netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, ulong *off)
{
- unsigned long end = *off + len;
crb_128M_2M_sub_block_map_t *m;
if (*off >= NETXEN_CRB_MAX)
return -1;
- if (*off >= NETXEN_PCI_CAMQM && (end <= NETXEN_PCI_CAMQM_2M_END)) {
+ if (*off >= NETXEN_PCI_CAMQM && (*off < NETXEN_PCI_CAMQM_2M_END)) {
*off = (*off - NETXEN_PCI_CAMQM) + NETXEN_PCI_CAMQM_2M_BASE +
(ulong)adapter->ahw.pci_base0;
return 0;
@@ -927,14 +932,13 @@ netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter,
return -1;
*off -= NETXEN_PCI_CRBSPACE;
- end = *off + len;
/*
* Try direct map
*/
m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
- if (m->valid && (m->start_128M <= *off) && (m->end_128M >= end)) {
+ if (m->valid && (m->start_128M <= *off) && (m->end_128M > *off)) {
*off = *off + m->start_2M - m->start_128M +
(ulong)adapter->ahw.pci_base0;
return 0;
@@ -972,214 +976,11 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
(ulong)adapter->ahw.pci_base0;
}
-static int
-netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname,
- const struct firmware *fw)
-{
- u64 *ptr64;
- u32 i, flashaddr, size;
- struct pci_dev *pdev = adapter->pdev;
-
- if (fw)
- dev_info(&pdev->dev, "loading firmware from file %s\n", fwname);
- else
- dev_info(&pdev->dev, "loading firmware from flash\n");
-
- if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
- adapter->pci_write_normalize(adapter,
- NETXEN_ROMUSB_GLB_CAS_RST, 1);
-
- if (fw) {
- __le64 data;
-
- size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8;
-
- ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START];
- flashaddr = NETXEN_BOOTLD_START;
-
- for (i = 0; i < size; i++) {
- data = cpu_to_le64(ptr64[i]);
- adapter->pci_mem_write(adapter, flashaddr, &data, 8);
- flashaddr += 8;
- }
-
- size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET];
- size = (__force u32)cpu_to_le32(size) / 8;
-
- ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START];
- flashaddr = NETXEN_IMAGE_START;
-
- for (i = 0; i < size; i++) {
- data = cpu_to_le64(ptr64[i]);
-
- if (adapter->pci_mem_write(adapter,
- flashaddr, &data, 8))
- return -EIO;
-
- flashaddr += 8;
- }
- } else {
- u32 data;
-
- size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4;
- flashaddr = NETXEN_BOOTLD_START;
-
- for (i = 0; i < size; i++) {
- if (netxen_rom_fast_read(adapter,
- flashaddr, (int *)&data) != 0)
- return -EIO;
-
- if (adapter->pci_mem_write(adapter,
- flashaddr, &data, 4))
- return -EIO;
-
- flashaddr += 4;
- }
- }
- msleep(1);
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- adapter->pci_write_normalize(adapter,
- NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d);
- else {
- adapter->pci_write_normalize(adapter,
- NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff);
- adapter->pci_write_normalize(adapter,
- NETXEN_ROMUSB_GLB_CAS_RST, 0);
- }
-
- return 0;
-}
-
-static int
-netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname,
- const struct firmware *fw)
-{
- __le32 val;
- u32 major, minor, build, ver, min_ver, bios;
- struct pci_dev *pdev = adapter->pdev;
-
- if (fw->size < NX_FW_MIN_SIZE)
- return -EINVAL;
-
- val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
- if ((__force u32)val != NETXEN_BDINFO_MAGIC)
- return -EINVAL;
-
- val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
- major = (__force u32)val & 0xff;
- minor = ((__force u32)val >> 8) & 0xff;
- build = (__force u32)val >> 16;
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- min_ver = NETXEN_VERSION_CODE(4, 0, 216);
- else
- min_ver = NETXEN_VERSION_CODE(3, 4, 216);
-
- ver = NETXEN_VERSION_CODE(major, minor, build);
-
- if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
- dev_err(&pdev->dev,
- "%s: firmware version %d.%d.%d unsupported\n",
- fwname, major, minor, build);
- return -EINVAL;
- }
-
- val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
- netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios);
- if ((__force u32)val != bios) {
- dev_err(&pdev->dev, "%s: firmware bios is incompatible\n",
- fwname);
- return -EINVAL;
- }
-
- /* check if flashed firmware is newer */
- if (netxen_rom_fast_read(adapter,
- NX_FW_VERSION_OFFSET, (int *)&val))
- return -EIO;
- major = (__force u32)val & 0xff;
- minor = ((__force u32)val >> 8) & 0xff;
- build = (__force u32)val >> 16;
- if (NETXEN_VERSION_CODE(major, minor, build) > ver)
- return -EINVAL;
-
- netxen_nic_reg_write(adapter, NETXEN_CAM_RAM(0x1fc),
- NETXEN_BDINFO_MAGIC);
- return 0;
-}
-
-static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" };
-
-int netxen_load_firmware(struct netxen_adapter *adapter)
-{
- u32 capability, flashed_ver;
- const struct firmware *fw;
- int fw_type;
- struct pci_dev *pdev = adapter->pdev;
- int rc = 0;
-
- if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
- fw_type = NX_P2_MN_ROMIMAGE;
- goto request_fw;
- } else {
- fw_type = NX_P3_CT_ROMIMAGE;
- goto request_fw;
- }
-
-request_mn:
- capability = 0;
-
- netxen_rom_fast_read(adapter,
- NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
- if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) {
- adapter->hw_read_wx(adapter,
- NX_PEG_TUNE_CAPABILITY, &capability, 4);
- if (capability & NX_PEG_TUNE_MN_PRESENT) {
- fw_type = NX_P3_MN_ROMIMAGE;
- goto request_fw;
- }
- }
-
-request_fw:
- rc = request_firmware(&fw, fw_name[fw_type], &pdev->dev);
- if (rc != 0) {
- if (fw_type == NX_P3_CT_ROMIMAGE) {
- msleep(1);
- goto request_mn;
- }
-
- fw = NULL;
- goto load_fw;
- }
-
- rc = netxen_validate_firmware(adapter, fw_name[fw_type], fw);
- if (rc != 0) {
- release_firmware(fw);
-
- if (fw_type == NX_P3_CT_ROMIMAGE) {
- msleep(1);
- goto request_mn;
- }
-
- fw = NULL;
- }
-
-load_fw:
- rc = netxen_do_load_firmware(adapter, fw_name[fw_type], fw);
-
- if (fw)
- release_firmware(fw);
- return rc;
-}
-
int
-netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
- ulong off, void *data, int len)
+netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data)
{
void __iomem *addr;
- BUG_ON(len != 4);
-
if (ADDR_IN_WINDOW1(off)) {
addr = NETXEN_CRB_NORMALIZE(adapter, off);
} else { /* Window 0 */
@@ -1192,7 +993,7 @@ netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
return 1;
}
- writel(*(u32 *) data, addr);
+ writel(data, addr);
if (!ADDR_IN_WINDOW1(off))
netxen_nic_pci_change_crbwindow_128M(adapter, 1);
@@ -1200,13 +1001,11 @@ netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
return 0;
}
-int
-netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
- ulong off, void *data, int len)
+u32
+netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off)
{
void __iomem *addr;
-
- BUG_ON(len != 4);
+ u32 data;
if (ADDR_IN_WINDOW1(off)) { /* Window 1 */
addr = NETXEN_CRB_NORMALIZE(adapter, off);
@@ -1220,24 +1019,21 @@ netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
return 1;
}
- *(u32 *)data = readl(addr);
+ data = readl(addr);
if (!ADDR_IN_WINDOW1(off))
netxen_nic_pci_change_crbwindow_128M(adapter, 1);
- return 0;
+ return data;
}
int
-netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
- ulong off, void *data, int len)
+netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
{
unsigned long flags = 0;
int rv;
- BUG_ON(len != 4);
-
- rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
+ rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);
if (rv == -1) {
printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
@@ -1250,26 +1046,24 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
write_lock_irqsave(&adapter->adapter_lock, flags);
crb_win_lock(adapter);
netxen_nic_pci_set_crbwindow_2M(adapter, &off);
- writel(*(uint32_t *)data, (void __iomem *)off);
+ writel(data, (void __iomem *)off);
crb_win_unlock(adapter);
write_unlock_irqrestore(&adapter->adapter_lock, flags);
} else
- writel(*(uint32_t *)data, (void __iomem *)off);
+ writel(data, (void __iomem *)off);
return 0;
}
-int
-netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
- ulong off, void *data, int len)
+u32
+netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
{
unsigned long flags = 0;
int rv;
+ u32 data;
- BUG_ON(len != 4);
-
- rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
+ rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);
if (rv == -1) {
printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
@@ -1282,47 +1076,13 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
write_lock_irqsave(&adapter->adapter_lock, flags);
crb_win_lock(adapter);
netxen_nic_pci_set_crbwindow_2M(adapter, &off);
- *(uint32_t *)data = readl((void __iomem *)off);
+ data = readl((void __iomem *)off);
crb_win_unlock(adapter);
write_unlock_irqrestore(&adapter->adapter_lock, flags);
} else
- *(uint32_t *)data = readl((void __iomem *)off);
-
- return 0;
-}
+ data = readl((void __iomem *)off);
-void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val)
-{
- adapter->hw_write_wx(adapter, off, &val, 4);
-}
-
-int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off)
-{
- int val;
- adapter->hw_read_wx(adapter, off, &val, 4);
- return val;
-}
-
-/* Change the window to 0, write and change back to window 1. */
-void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value)
-{
- adapter->hw_write_wx(adapter, index, &value, 4);
-}
-
-/* Change the window to 0, read and change back to window 1. */
-void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value)
-{
- adapter->hw_read_wx(adapter, index, value, 4);
-}
-
-void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value)
-{
- adapter->hw_write_wx(adapter, index, &value, 4);
-}
-
-void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value)
-{
- adapter->hw_read_wx(adapter, index, value, 4);
+ return data;
}
/*
@@ -1425,17 +1185,6 @@ u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off)
return readl((void __iomem *)(pci_base_offset(adapter, off)));
}
-void netxen_nic_pci_write_normalize_128M(struct netxen_adapter *adapter,
- u64 off, u32 data)
-{
- writel(data, NETXEN_CRB_NORMALIZE(adapter, off));
-}
-
-u32 netxen_nic_pci_read_normalize_128M(struct netxen_adapter *adapter, u64 off)
-{
- return readl(NETXEN_CRB_NORMALIZE(adapter, off));
-}
-
unsigned long
netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
unsigned long long addr)
@@ -1447,12 +1196,10 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
/* DDR network side */
window = MN_WIN(addr);
adapter->ahw.ddr_mn_window = window;
- adapter->hw_write_wx(adapter,
- adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
- &window, 4);
- adapter->hw_read_wx(adapter,
- adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
- &win_read, 4);
+ NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
+ window);
+ win_read = NXRD32(adapter,
+ adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
if ((win_read << 17) != window) {
printk(KERN_INFO "Written MNwin (0x%x) != "
"Read MNwin (0x%x)\n", window, win_read);
@@ -1467,12 +1214,10 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
window = OCM_WIN(addr);
adapter->ahw.ddr_mn_window = window;
- adapter->hw_write_wx(adapter,
- adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
- &window, 4);
- adapter->hw_read_wx(adapter,
- adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
- &win_read, 4);
+ NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
+ window);
+ win_read = NXRD32(adapter,
+ adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
if ((win_read >> 7) != window) {
printk(KERN_INFO "%s: Written OCMwin (0x%x) != "
"Read OCMwin (0x%x)\n",
@@ -1485,12 +1230,10 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
/* QDR network side */
window = MS_WIN(addr);
adapter->ahw.qdr_sn_window = window;
- adapter->hw_write_wx(adapter,
- adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
- &window, 4);
- adapter->hw_read_wx(adapter,
- adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
- &win_read, 4);
+ NXWR32(adapter, adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
+ window);
+ win_read = NXRD32(adapter,
+ adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE);
if (win_read != window) {
printk(KERN_INFO "%s: Written MSwin (0x%x) != "
"Read MSwin (0x%x)\n",
@@ -1936,27 +1679,20 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
for (i = 0; i < loop; i++) {
temp = off8 + (i << 3);
- adapter->hw_write_wx(adapter,
- mem_crb+MIU_TEST_AGT_ADDR_LO, &temp, 4);
+ NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
temp = 0;
- adapter->hw_write_wx(adapter,
- mem_crb+MIU_TEST_AGT_ADDR_HI, &temp, 4);
+ NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);
temp = word[i] & 0xffffffff;
- adapter->hw_write_wx(adapter,
- mem_crb+MIU_TEST_AGT_WRDATA_LO, &temp, 4);
+ NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);
temp = (word[i] >> 32) & 0xffffffff;
- adapter->hw_write_wx(adapter,
- mem_crb+MIU_TEST_AGT_WRDATA_HI, &temp, 4);
+ NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);
temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
- adapter->hw_write_wx(adapter,
- mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
+ NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
- adapter->hw_write_wx(adapter,
- mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
+ NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
for (j = 0; j < MAX_CTL_CHECK; j++) {
- adapter->hw_read_wx(adapter,
- mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+ temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
if ((temp & MIU_TA_CTL_BUSY) == 0)
break;
}
@@ -2013,21 +1749,16 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
for (i = 0; i < loop; i++) {
temp = off8 + (i << 3);
- adapter->hw_write_wx(adapter,
- mem_crb + MIU_TEST_AGT_ADDR_LO, &temp, 4);
+ NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
temp = 0;
- adapter->hw_write_wx(adapter,
- mem_crb + MIU_TEST_AGT_ADDR_HI, &temp, 4);
+ NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
temp = MIU_TA_CTL_ENABLE;
- adapter->hw_write_wx(adapter,
- mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+ NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
- adapter->hw_write_wx(adapter,
- mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+ NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
for (j = 0; j < MAX_CTL_CHECK; j++) {
- adapter->hw_read_wx(adapter,
- mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+ temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
if ((temp & MIU_TA_CTL_BUSY) == 0)
break;
}
@@ -2042,8 +1773,8 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
start = off0[i] >> 2;
end = (off0[i] + sz[i] - 1) >> 2;
for (k = start; k <= end; k++) {
- adapter->hw_read_wx(adapter,
- mem_crb + MIU_TEST_AGT_RDDATA(k), &temp, 4);
+ temp = NXRD32(adapter,
+ mem_crb + MIU_TEST_AGT_RDDATA(k));
word[i] |= ((uint64_t)temp << (32 * k));
}
}
@@ -2086,29 +1817,14 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
u64 off, u32 data)
{
- adapter->hw_write_wx(adapter, off, &data, 4);
+ NXWR32(adapter, off, data);
return 0;
}
u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off)
{
- u32 temp;
- adapter->hw_read_wx(adapter, off, &temp, 4);
- return temp;
-}
-
-void netxen_nic_pci_write_normalize_2M(struct netxen_adapter *adapter,
- u64 off, u32 data)
-{
- adapter->hw_write_wx(adapter, off, &data, 4);
-}
-
-u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off)
-{
- u32 temp;
- adapter->hw_read_wx(adapter, off, &temp, 4);
- return temp;
+ return NXRD32(adapter, off);
}
int netxen_nic_get_board_info(struct netxen_adapter *adapter)
@@ -2142,13 +1858,12 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
adapter->ahw.board_type = board_type;
if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
- u32 gpio = netxen_nic_reg_read(adapter,
- NETXEN_ROMUSB_GLB_PAD_GPIO_I);
+ u32 gpio = NXRD32(adapter, NETXEN_ROMUSB_GLB_PAD_GPIO_I);
if ((gpio & 0x8000) == 0)
board_type = NETXEN_BRDTYPE_P3_10G_TP;
}
- switch ((netxen_brdtype_t)board_type) {
+ switch (board_type) {
case NETXEN_BRDTYPE_P2_SB35_4G:
adapter->ahw.port_type = NETXEN_NIC_GBE;
break;
@@ -2195,8 +1910,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
{
new_mtu += MTU_FUDGE_FACTOR;
- netxen_nic_write_w0(adapter,
- NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
+ NXWR32(adapter, NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
new_mtu);
return 0;
}
@@ -2205,21 +1919,12 @@ int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
{
new_mtu += MTU_FUDGE_FACTOR;
if (adapter->physical_port == 0)
- netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE,
- new_mtu);
+ NXWR32(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
else
- netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE,
- new_mtu);
+ NXWR32(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu);
return 0;
}
-void
-netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
- unsigned long off, int data)
-{
- adapter->hw_write_wx(adapter, off, &data, 4);
-}
-
void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
{
__u32 status;
@@ -2234,8 +1939,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
}
if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
- adapter->hw_read_wx(adapter,
- NETXEN_PORT_MODE_ADDR, &port_mode, 4);
+ port_mode = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
adapter->link_speed = SPEED_1000;
adapter->link_duplex = DUPLEX_FULL;
@@ -2312,9 +2016,9 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
addr += sizeof(u32);
}
- adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MAJOR, &fw_major, 4);
- adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MINOR, &fw_minor, 4);
- adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB, &fw_build, 4);
+ fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
+ fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
+ fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
adapter->fw_major = fw_major;
adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
@@ -2337,8 +2041,7 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
fw_major, fw_minor, fw_build);
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
- adapter->hw_read_wx(adapter,
- NETXEN_MIU_MN_CONTROL, &i, 4);
+ i = NXRD32(adapter, NETXEN_MIU_MN_CONTROL);
adapter->ahw.cut_through = (i & 0x4) ? 1 : 0;
dev_info(&pdev->dev, "firmware running in %s mode\n",
adapter->ahw.cut_through ? "cut-through" : "legacy");
@@ -2353,9 +2056,9 @@ netxen_nic_wol_supported(struct netxen_adapter *adapter)
if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
return 0;
- wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+ wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
if (wol_cfg & (1UL << adapter->portnum)) {
- wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+ wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
if (wol_cfg & (1 << adapter->portnum))
return 1;
}
diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h
index 04b47a7993c..d4e83333978 100644
--- a/drivers/net/netxen/netxen_nic_hw.h
+++ b/drivers/net/netxen/netxen_nic_hw.h
@@ -36,35 +36,13 @@
/* Hardware memory size of 128 meg */
#define NETXEN_MEMADDR_MAX (128 * 1024 * 1024)
-#ifndef readq
-static inline u64 readq(void __iomem * addr)
-{
- return readl(addr) | (((u64) readl(addr + 4)) << 32LL);
-}
-#endif
-
-#ifndef writeq
-static inline void writeq(u64 val, void __iomem * addr)
-{
- writel(((u32) (val)), (addr));
- writel(((u32) (val >> 32)), (addr + 4));
-}
-#endif
-
struct netxen_adapter;
#define NETXEN_PCI_MAPSIZE_BYTES (NETXEN_PCI_MAPSIZE << 20)
-struct netxen_port;
void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
-typedef u8 netxen_ethernet_macaddr_t[6];
-
/* Nibble or Byte mode for phy interface (GbE mode only) */
-typedef enum {
- NETXEN_NIU_10_100_MB = 0,
- NETXEN_NIU_1000_MB
-} netxen_niu_gbe_ifmode_t;
#define _netxen_crb_get_bit(var, bit) ((var >> bit) & 0x1)
@@ -222,30 +200,28 @@ typedef enum {
/*
* PHY-Specific MII control/status registers.
*/
-typedef enum {
- NETXEN_NIU_GB_MII_MGMT_ADDR_CONTROL = 0,
- NETXEN_NIU_GB_MII_MGMT_ADDR_STATUS = 1,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_0 = 2,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_1 = 3,
- NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG = 4,
- NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART = 5,
- NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG_MORE = 6,
- NETXEN_NIU_GB_MII_MGMT_ADDR_NEXTPAGE_XMIT = 7,
- NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART_NEXTPAGE = 8,
- NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_CONTROL = 9,
- NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_STATUS = 10,
- NETXEN_NIU_GB_MII_MGMT_ADDR_EXTENDED_STATUS = 15,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL = 16,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS = 17,
- NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE = 18,
- NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS = 19,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE = 20,
- NETXEN_NIU_GB_MII_MGMT_ADDR_RECV_ERROR_COUNT = 21,
- NETXEN_NIU_GB_MII_MGMT_ADDR_LED_CONTROL = 24,
- NETXEN_NIU_GB_MII_MGMT_ADDR_LED_OVERRIDE = 25,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE_YET = 26,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS_MORE = 27
-} netxen_niu_phy_register_t;
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_CONTROL 0
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_STATUS 1
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_0 2
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_1 3
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG 4
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART 5
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG_MORE 6
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_NEXTPAGE_XMIT 7
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART_NEXTPAGE 8
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_CONTROL 9
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_STATUS 10
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_EXTENDED_STATUS 15
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL 16
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS 17
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE 18
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS 19
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE 20
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_RECV_ERROR_COUNT 21
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LED_CONTROL 24
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LED_OVERRIDE 25
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE_YET 26
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS_MORE 27
/*
* PHY-Specific Status Register (reg 17).
@@ -417,14 +393,6 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
u32 mode);
-/* set the MAC address for a given MAC */
-int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
- netxen_ethernet_macaddr_t addr);
-
-/* XG version */
-int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
- netxen_ethernet_macaddr_t addr);
-
/* Generic enable for GbE ports. Will detect the speed of the link. */
int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port);
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 0759c35f16a..6f77ad58e3b 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -108,42 +108,6 @@ static void crb_addr_transform_setup(void)
crb_addr_transform(I2C0);
}
-int netxen_init_firmware(struct netxen_adapter *adapter)
-{
- u32 state = 0, loops = 0, err = 0;
-
- /* Window 1 call */
- state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
-
- if (state == PHAN_INITIALIZE_ACK)
- return 0;
-
- while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) {
- msleep(1);
- /* Window 1 call */
- state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
-
- loops++;
- }
- if (loops >= 2000) {
- printk(KERN_ERR "Cmd Peg initialization not complete:%x.\n",
- state);
- err = -EIO;
- return err;
- }
- /* Window 1 call */
- adapter->pci_write_normalize(adapter,
- CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
- adapter->pci_write_normalize(adapter,
- CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
- adapter->pci_write_normalize(adapter,
- CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
- adapter->pci_write_normalize(adapter,
- CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
-
- return err;
-}
-
void netxen_release_rx_buffers(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx;
@@ -173,9 +137,10 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
struct netxen_cmd_buffer *cmd_buf;
struct netxen_skb_frag *buffrag;
int i, j;
+ struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
- cmd_buf = adapter->cmd_buf_arr;
- for (i = 0; i < adapter->num_txd; i++) {
+ cmd_buf = tx_ring->cmd_buf_arr;
+ for (i = 0; i < tx_ring->num_desc; i++) {
buffrag = cmd_buf->frag_array;
if (buffrag->dma) {
pci_unmap_single(adapter->pdev, buffrag->dma,
@@ -203,20 +168,27 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
+ struct nx_host_tx_ring *tx_ring;
int ring;
recv_ctx = &adapter->recv_ctx;
+
+ if (recv_ctx->rds_rings == NULL)
+ goto skip_rds;
+
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
- if (rds_ring->rx_buf_arr) {
- vfree(rds_ring->rx_buf_arr);
- rds_ring->rx_buf_arr = NULL;
- }
+ vfree(rds_ring->rx_buf_arr);
+ rds_ring->rx_buf_arr = NULL;
}
+ kfree(recv_ctx->rds_rings);
- if (adapter->cmd_buf_arr)
- vfree(adapter->cmd_buf_arr);
- return;
+skip_rds:
+ if (adapter->tx_ring == NULL)
+ return;
+
+ tx_ring = adapter->tx_ring;
+ vfree(tx_ring->cmd_buf_arr);
}
int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
@@ -224,23 +196,45 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
struct nx_host_sds_ring *sds_ring;
+ struct nx_host_tx_ring *tx_ring;
struct netxen_rx_buffer *rx_buf;
- int ring, i, num_rx_bufs;
+ int ring, i, size;
struct netxen_cmd_buffer *cmd_buf_arr;
struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
- cmd_buf_arr =
- (struct netxen_cmd_buffer *)vmalloc(TX_BUFF_RINGSIZE(adapter));
+ size = sizeof(struct nx_host_tx_ring);
+ tx_ring = kzalloc(size, GFP_KERNEL);
+ if (tx_ring == NULL) {
+ dev_err(&pdev->dev, "%s: failed to allocate tx ring struct\n",
+ netdev->name);
+ return -ENOMEM;
+ }
+ adapter->tx_ring = tx_ring;
+
+ tx_ring->num_desc = adapter->num_txd;
+
+ cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring));
if (cmd_buf_arr == NULL) {
- printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n",
+ dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n",
netdev->name);
return -ENOMEM;
}
- memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(adapter));
- adapter->cmd_buf_arr = cmd_buf_arr;
+ memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring));
+ tx_ring->cmd_buf_arr = cmd_buf_arr;
recv_ctx = &adapter->recv_ctx;
+
+ size = adapter->max_rds_rings * sizeof (struct nx_host_rds_ring);
+ rds_ring = kzalloc(size, GFP_KERNEL);
+ if (rds_ring == NULL) {
+ dev_err(&pdev->dev, "%s: failed to allocate rds ring struct\n",
+ netdev->name);
+ return -ENOMEM;
+ }
+ recv_ctx->rds_rings = rds_ring;
+
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
switch (ring) {
@@ -292,9 +286,8 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
* Now go through all of them, set reference handles
* and put them in the queues.
*/
- num_rx_bufs = rds_ring->num_desc;
rx_buf = rds_ring->rx_buf_arr;
- for (i = 0; i < num_rx_bufs; i++) {
+ for (i = 0; i < rds_ring->num_desc; i++) {
list_add_tail(&rx_buf->list,
&rds_ring->free_list);
rx_buf->ref_handle = i;
@@ -307,8 +300,6 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &recv_ctx->sds_rings[ring];
sds_ring->irq = adapter->msix_entries[ring].vector;
- sds_ring->clean_tx = (ring == 0);
- sds_ring->post_rxd = (ring == 0);
sds_ring->adapter = adapter;
sds_ring->num_desc = adapter->num_rxd;
@@ -325,13 +316,15 @@ err_out:
void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
{
+ adapter->macaddr_set = netxen_p2_nic_set_mac_addr;
+ adapter->set_multi = netxen_p2_nic_set_multi;
+
switch (adapter->ahw.port_type) {
case NETXEN_NIC_GBE:
adapter->enable_phy_interrupts =
netxen_niu_gbe_enable_phy_interrupts;
adapter->disable_phy_interrupts =
netxen_niu_gbe_disable_phy_interrupts;
- adapter->macaddr_set = netxen_niu_macaddr_set;
adapter->set_mtu = netxen_nic_set_mtu_gb;
adapter->set_promisc = netxen_niu_set_promiscuous_mode;
adapter->phy_read = netxen_niu_gbe_phy_read;
@@ -345,7 +338,6 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
netxen_niu_xgbe_enable_phy_interrupts;
adapter->disable_phy_interrupts =
netxen_niu_xgbe_disable_phy_interrupts;
- adapter->macaddr_set = netxen_niu_xg_macaddr_set;
adapter->set_mtu = netxen_nic_set_mtu_xgb;
adapter->init_port = netxen_niu_xg_init_port;
adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode;
@@ -359,6 +351,8 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
adapter->set_mtu = nx_fw_cmd_set_mtu;
adapter->set_promisc = netxen_p3_nic_set_promisc;
+ adapter->macaddr_set = netxen_p3_nic_set_mac_addr;
+ adapter->set_multi = netxen_p3_nic_set_multi;
}
}
@@ -400,8 +394,7 @@ static int rom_lock(struct netxen_adapter *adapter)
while (!done) {
/* acquire semaphore2 from PCI HW block */
- netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK),
- &done);
+ done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK));
if (done == 1)
break;
if (timeout >= rom_lock_timeout)
@@ -418,7 +411,7 @@ static int rom_lock(struct netxen_adapter *adapter)
cpu_relax(); /*This a nop instr on i386 */
}
}
- netxen_nic_reg_write(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER);
+ NXWR32(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER);
return 0;
}
@@ -430,7 +423,7 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
cond_resched();
while (done == 0) {
- done = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_GLB_STATUS);
+ done = NXRD32(adapter, NETXEN_ROMUSB_GLB_STATUS);
done &= 2;
timeout++;
if (timeout >= rom_max_timeout) {
@@ -443,30 +436,28 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
static void netxen_rom_unlock(struct netxen_adapter *adapter)
{
- u32 val;
-
/* release semaphore2 */
- netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK), &val);
+ NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK));
}
static int do_rom_fast_read(struct netxen_adapter *adapter,
int addr, int *valp)
{
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
+ NXWR32(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
+ NXWR32(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+ NXWR32(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
+ NXWR32(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
if (netxen_wait_rom_done(adapter)) {
printk("Error waiting for rom done\n");
return -EIO;
}
/* reset abyte_cnt and dummy_byte_cnt */
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
+ NXWR32(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
udelay(10);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+ NXWR32(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
- *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA);
+ *valp = NXRD32(adapter, NETXEN_ROMUSB_ROM_RDATA);
return 0;
}
@@ -530,8 +521,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
/* resetall */
rom_lock(adapter);
- netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
- 0xffffffff);
+ NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff);
netxen_rom_unlock(adapter);
if (verbose) {
@@ -655,7 +645,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
}
}
- adapter->hw_write_wx(adapter, off, &buf[i].data, 4);
+ NXWR32(adapter, off, buf[i].data);
msleep(init_delay);
}
@@ -665,36 +655,230 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
/* unreset_net_cache */
if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
- adapter->hw_read_wx(adapter,
- NETXEN_ROMUSB_GLB_SW_RESET, &val, 4);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f));
+ val = NXRD32(adapter, NETXEN_ROMUSB_GLB_SW_RESET);
+ NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f));
}
/* p2dn replyCount */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
/* disable_peg_cache 0 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8);
/* disable_peg_cache 1 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8);
/* peg_clr_all */
/* peg_clr 0 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0);
/* peg_clr 1 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0);
/* peg_clr 2 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0);
/* peg_clr 3 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0);
+ NXWR32(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0);
+ return 0;
+}
+
+int
+netxen_load_firmware(struct netxen_adapter *adapter)
+{
+ u64 *ptr64;
+ u32 i, flashaddr, size;
+ const struct firmware *fw = adapter->fw;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1);
+
+ if (fw) {
+ __le64 data;
+
+ size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8;
+
+ ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START];
+ flashaddr = NETXEN_BOOTLD_START;
+
+ for (i = 0; i < size; i++) {
+ data = cpu_to_le64(ptr64[i]);
+ adapter->pci_mem_write(adapter, flashaddr, &data, 8);
+ flashaddr += 8;
+ }
+
+ size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET];
+ size = (__force u32)cpu_to_le32(size) / 8;
+
+ ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START];
+ flashaddr = NETXEN_IMAGE_START;
+
+ for (i = 0; i < size; i++) {
+ data = cpu_to_le64(ptr64[i]);
+
+ if (adapter->pci_mem_write(adapter,
+ flashaddr, &data, 8))
+ return -EIO;
+
+ flashaddr += 8;
+ }
+ } else {
+ u32 data;
+
+ size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4;
+ flashaddr = NETXEN_BOOTLD_START;
+
+ for (i = 0; i < size; i++) {
+ if (netxen_rom_fast_read(adapter,
+ flashaddr, (int *)&data) != 0)
+ return -EIO;
+
+ if (adapter->pci_mem_write(adapter,
+ flashaddr, &data, 4))
+ return -EIO;
+
+ flashaddr += 4;
+ }
+ }
+ msleep(1);
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d);
+ else {
+ NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff);
+ NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 0);
+ }
+
+ return 0;
+}
+
+static int
+netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname)
+{
+ __le32 val;
+ u32 major, minor, build, ver, min_ver, bios;
+ struct pci_dev *pdev = adapter->pdev;
+ const struct firmware *fw = adapter->fw;
+
+ if (fw->size < NX_FW_MIN_SIZE)
+ return -EINVAL;
+
+ val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
+ if ((__force u32)val != NETXEN_BDINFO_MAGIC)
+ return -EINVAL;
+
+ val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
+ major = (__force u32)val & 0xff;
+ minor = ((__force u32)val >> 8) & 0xff;
+ build = (__force u32)val >> 16;
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ min_ver = NETXEN_VERSION_CODE(4, 0, 216);
+ else
+ min_ver = NETXEN_VERSION_CODE(3, 4, 216);
+
+ ver = NETXEN_VERSION_CODE(major, minor, build);
+
+ if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
+ dev_err(&pdev->dev,
+ "%s: firmware version %d.%d.%d unsupported\n",
+ fwname, major, minor, build);
+ return -EINVAL;
+ }
+
+ val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
+ netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios);
+ if ((__force u32)val != bios) {
+ dev_err(&pdev->dev, "%s: firmware bios is incompatible\n",
+ fwname);
+ return -EINVAL;
+ }
+
+ /* check if flashed firmware is newer */
+ if (netxen_rom_fast_read(adapter,
+ NX_FW_VERSION_OFFSET, (int *)&val))
+ return -EIO;
+ major = (__force u32)val & 0xff;
+ minor = ((__force u32)val >> 8) & 0xff;
+ build = (__force u32)val >> 16;
+ if (NETXEN_VERSION_CODE(major, minor, build) > ver)
+ return -EINVAL;
+
+ NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
return 0;
}
+static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" };
+
+void netxen_request_firmware(struct netxen_adapter *adapter)
+{
+ u32 capability, flashed_ver;
+ int fw_type;
+ struct pci_dev *pdev = adapter->pdev;
+ int rc = 0;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+ fw_type = NX_P2_MN_ROMIMAGE;
+ goto request_fw;
+ } else {
+ fw_type = NX_P3_CT_ROMIMAGE;
+ goto request_fw;
+ }
+
+request_mn:
+ capability = 0;
+
+ netxen_rom_fast_read(adapter,
+ NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
+ if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) {
+ capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY);
+ if (capability & NX_PEG_TUNE_MN_PRESENT) {
+ fw_type = NX_P3_MN_ROMIMAGE;
+ goto request_fw;
+ }
+ }
+
+request_fw:
+ rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev);
+ if (rc != 0) {
+ if (fw_type == NX_P3_CT_ROMIMAGE) {
+ msleep(1);
+ goto request_mn;
+ }
+
+ adapter->fw = NULL;
+ goto done;
+ }
+
+ rc = netxen_validate_firmware(adapter, fw_name[fw_type]);
+ if (rc != 0) {
+ release_firmware(adapter->fw);
+
+ if (fw_type == NX_P3_CT_ROMIMAGE) {
+ msleep(1);
+ goto request_mn;
+ }
+
+ adapter->fw = NULL;
+ goto done;
+ }
+
+done:
+ if (adapter->fw)
+ dev_info(&pdev->dev, "loading firmware from file %s\n",
+ fw_name[fw_type]);
+ else
+ dev_info(&pdev->dev, "loading firmware from flash\n");
+}
+
+
+void
+netxen_release_firmware(struct netxen_adapter *adapter)
+{
+ if (adapter->fw)
+ release_firmware(adapter->fw);
+}
+
int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
{
uint64_t addr;
@@ -715,12 +899,12 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
hi = (addr >> 32) & 0xffffffff;
lo = addr & 0xffffffff;
- adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi);
- adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo);
+ NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi);
+ NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo);
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
uint32_t temp = 0;
- adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF, &temp, 4);
+ NXWR32(adapter, CRB_HOST_DUMMY_BUF, temp);
}
return 0;
@@ -762,8 +946,7 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
if (!pegtune_val) {
do {
- val = adapter->pci_read_normalize(adapter,
- CRB_CMDPEG_STATE);
+ val = NXRD32(adapter, CRB_CMDPEG_STATE);
if (val == PHAN_INITIALIZE_COMPLETE ||
val == PHAN_INITIALIZE_ACK)
@@ -774,7 +957,7 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
} while (--retries);
if (!retries) {
- pegtune_val = adapter->pci_read_normalize(adapter,
+ pegtune_val = NXRD32(adapter,
NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
printk(KERN_WARNING "netxen_phantom_init: init failed, "
"pegtune_val=%x\n", pegtune_val);
@@ -785,13 +968,14 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
return 0;
}
-int netxen_receive_peg_ready(struct netxen_adapter *adapter)
+static int
+netxen_receive_peg_ready(struct netxen_adapter *adapter)
{
u32 val = 0;
int retries = 2000;
do {
- val = adapter->pci_read_normalize(adapter, CRB_RCVPEG_STATE);
+ val = NXRD32(adapter, CRB_RCVPEG_STATE);
if (val == PHAN_PEG_RCV_INITIALIZED)
return 0;
@@ -809,6 +993,93 @@ int netxen_receive_peg_ready(struct netxen_adapter *adapter)
return 0;
}
+int netxen_init_firmware(struct netxen_adapter *adapter)
+{
+ int err;
+
+ err = netxen_receive_peg_ready(adapter);
+ if (err)
+ return err;
+
+ NXWR32(adapter, CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
+ NXWR32(adapter, CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
+ NXWR32(adapter, CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
+ NXWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
+
+ if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222)) {
+ adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
+ }
+
+ return err;
+}
+
+static void
+netxen_handle_linkevent(struct netxen_adapter *adapter, nx_fw_msg_t *msg)
+{
+ u32 cable_OUI;
+ u16 cable_len;
+ u16 link_speed;
+ u8 link_status, module, duplex, autoneg;
+ struct net_device *netdev = adapter->netdev;
+
+ adapter->has_link_events = 1;
+
+ cable_OUI = msg->body[1] & 0xffffffff;
+ cable_len = (msg->body[1] >> 32) & 0xffff;
+ link_speed = (msg->body[1] >> 48) & 0xffff;
+
+ link_status = msg->body[2] & 0xff;
+ duplex = (msg->body[2] >> 16) & 0xff;
+ autoneg = (msg->body[2] >> 24) & 0xff;
+
+ module = (msg->body[2] >> 8) & 0xff;
+ if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE) {
+ printk(KERN_INFO "%s: unsupported cable: OUI 0x%x, length %d\n",
+ netdev->name, cable_OUI, cable_len);
+ } else if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN) {
+ printk(KERN_INFO "%s: unsupported cable length %d\n",
+ netdev->name, cable_len);
+ }
+
+ netxen_advert_link_change(adapter, link_status);
+
+ /* update link parameters */
+ if (duplex == LINKEVENT_FULL_DUPLEX)
+ adapter->link_duplex = DUPLEX_FULL;
+ else
+ adapter->link_duplex = DUPLEX_HALF;
+ adapter->module_type = module;
+ adapter->link_autoneg = autoneg;
+ adapter->link_speed = link_speed;
+}
+
+static void
+netxen_handle_fw_message(int desc_cnt, int index,
+ struct nx_host_sds_ring *sds_ring)
+{
+ nx_fw_msg_t msg;
+ struct status_desc *desc;
+ int i = 0, opcode;
+
+ while (desc_cnt > 0 && i < 8) {
+ desc = &sds_ring->desc_head[index];
+ msg.words[i++] = le64_to_cpu(desc->status_desc_data[0]);
+ msg.words[i++] = le64_to_cpu(desc->status_desc_data[1]);
+
+ index = get_next_index(index, sds_ring->num_desc);
+ desc_cnt--;
+ }
+
+ opcode = netxen_get_nic_msg_opcode(msg.body[0]);
+ switch (opcode) {
+ case NX_NIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE:
+ netxen_handle_linkevent(sds_ring->adapter, &msg);
+ break;
+ default:
+ break;
+ }
+}
+
static int
netxen_alloc_rx_skb(struct netxen_adapter *adapter,
struct nx_host_rds_ring *rds_ring,
@@ -874,7 +1145,8 @@ no_skb:
static struct netxen_rx_buffer *
netxen_process_rcv(struct netxen_adapter *adapter,
- int ring, int index, int length, int cksum, int pkt_offset)
+ int ring, int index, int length, int cksum, int pkt_offset,
+ struct nx_host_sds_ring *sds_ring)
{
struct net_device *netdev = adapter->netdev;
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
@@ -902,7 +1174,7 @@ netxen_process_rcv(struct netxen_adapter *adapter,
skb->protocol = eth_type_trans(skb, netdev);
- netif_receive_skb(skb);
+ napi_gro_receive(&sds_ring->napi, skb);
adapter->stats.no_rcv++;
adapter->stats.rxbytes += length;
@@ -927,35 +1199,53 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
int count = 0;
u64 sts_data;
- int opcode, ring, index, length, cksum, pkt_offset;
+ int opcode, ring, index, length, cksum, pkt_offset, desc_cnt;
while (count < max) {
desc = &sds_ring->desc_head[consumer];
- sts_data = le64_to_cpu(desc->status_desc_data);
+ sts_data = le64_to_cpu(desc->status_desc_data[0]);
if (!(sts_data & STATUS_OWNER_HOST))
break;
+ desc_cnt = netxen_get_sts_desc_cnt(sts_data);
ring = netxen_get_sts_type(sts_data);
+
if (ring > RCV_RING_JUMBO)
- continue;
+ goto skip;
opcode = netxen_get_sts_opcode(sts_data);
+ switch (opcode) {
+ case NETXEN_NIC_RXPKT_DESC:
+ case NETXEN_OLD_RXPKT_DESC:
+ break;
+ case NETXEN_NIC_RESPONSE_DESC:
+ netxen_handle_fw_message(desc_cnt, consumer, sds_ring);
+ default:
+ goto skip;
+ }
+
+ WARN_ON(desc_cnt > 1);
+
index = netxen_get_sts_refhandle(sts_data);
length = netxen_get_sts_totallength(sts_data);
cksum = netxen_get_sts_status(sts_data);
pkt_offset = netxen_get_sts_pkt_offset(sts_data);
rxbuf = netxen_process_rcv(adapter, ring, index,
- length, cksum, pkt_offset);
+ length, cksum, pkt_offset, sds_ring);
if (rxbuf)
list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]);
- desc->status_desc_data = cpu_to_le64(STATUS_OWNER_PHANTOM);
-
- consumer = get_next_index(consumer, sds_ring->num_desc);
+skip:
+ for (; desc_cnt > 0; desc_cnt--) {
+ desc = &sds_ring->desc_head[consumer];
+ desc->status_desc_data[0] =
+ cpu_to_le64(STATUS_OWNER_PHANTOM);
+ consumer = get_next_index(consumer, sds_ring->num_desc);
+ }
count++;
}
@@ -980,8 +1270,7 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
if (count) {
sds_ring->consumer = consumer;
- adapter->pci_write_normalize(adapter,
- sds_ring->crb_sts_consumer, consumer);
+ NXWR32(adapter, sds_ring->crb_sts_consumer, consumer);
}
return count;
@@ -990,23 +1279,24 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
/* Process Command status ring */
int netxen_process_cmd_ring(struct netxen_adapter *adapter)
{
- u32 last_consumer, consumer;
+ u32 sw_consumer, hw_consumer;
int count = 0, i;
struct netxen_cmd_buffer *buffer;
struct pci_dev *pdev = adapter->pdev;
struct net_device *netdev = adapter->netdev;
struct netxen_skb_frag *frag;
int done = 0;
+ struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
if (!spin_trylock(&adapter->tx_clean_lock))
return 1;
- last_consumer = adapter->last_cmd_consumer;
- barrier(); /* cmd_consumer can change underneath */
- consumer = le32_to_cpu(*(adapter->cmd_consumer));
+ sw_consumer = tx_ring->sw_consumer;
+ barrier(); /* hw_consumer can change underneath */
+ hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
- while (last_consumer != consumer) {
- buffer = &adapter->cmd_buf_arr[last_consumer];
+ while (sw_consumer != hw_consumer) {
+ buffer = &tx_ring->cmd_buf_arr[sw_consumer];
if (buffer->skb) {
frag = &buffer->frag_array[0];
pci_unmap_single(pdev, frag->dma, frag->length,
@@ -1024,16 +1314,16 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
buffer->skb = NULL;
}
- last_consumer = get_next_index(last_consumer,
- adapter->num_txd);
+ sw_consumer = get_next_index(sw_consumer, tx_ring->num_desc);
if (++count >= MAX_STATUS_HANDLE)
break;
}
- if (count) {
- adapter->last_cmd_consumer = last_consumer;
+ tx_ring->sw_consumer = sw_consumer;
+
+ if (count && netif_running(netdev)) {
smp_mb();
- if (netif_queue_stopped(netdev) && netif_running(netdev)) {
+ if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) {
netif_tx_lock(netdev);
netif_wake_queue(netdev);
smp_mb();
@@ -1053,9 +1343,9 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
* There is still a possible race condition and the host could miss an
* interrupt. The card has to take care of this.
*/
- barrier(); /* cmd_consumer can change underneath */
- consumer = le32_to_cpu(*(adapter->cmd_consumer));
- done = (last_consumer == consumer);
+ barrier(); /* hw_consumer can change underneath */
+ hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
+ done = (sw_consumer == hw_consumer);
spin_unlock(&adapter->tx_clean_lock);
return (done);
@@ -1099,8 +1389,7 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
if (count) {
rds_ring->producer = producer;
- adapter->pci_write_normalize(adapter,
- rds_ring->crb_rcv_producer,
+ NXWR32(adapter, rds_ring->crb_rcv_producer,
(producer-1) & (rds_ring->num_desc-1));
if (adapter->fw_major < 4) {
@@ -1160,10 +1449,8 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
if (count) {
rds_ring->producer = producer;
- adapter->pci_write_normalize(adapter,
- rds_ring->crb_rcv_producer,
+ NXWR32(adapter, rds_ring->crb_rcv_producer,
(producer - 1) & (rds_ring->num_desc - 1));
- wmb();
}
spin_unlock(&rds_ring->lock);
}
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index aef77289bd3..98737ef7293 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -29,7 +29,7 @@
*/
#include <linux/vmalloc.h>
-#include <linux/highmem.h>
+#include <linux/interrupt.h>
#include "netxen_nic_hw.h"
#include "netxen_nic.h"
@@ -107,10 +107,9 @@ static uint32_t crb_cmd_producer[4] = {
void
netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
- uint32_t crb_producer)
+ struct nx_host_tx_ring *tx_ring, u32 producer)
{
- adapter->pci_write_normalize(adapter,
- adapter->crb_addr_cmd_producer, crb_producer);
+ NXWR32(adapter, tx_ring->crb_cmd_producer, producer);
}
static uint32_t crb_cmd_consumer[4] = {
@@ -120,10 +119,9 @@ static uint32_t crb_cmd_consumer[4] = {
static inline void
netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
- u32 crb_consumer)
+ struct nx_host_tx_ring *tx_ring, u32 consumer)
{
- adapter->pci_write_normalize(adapter,
- adapter->crb_addr_cmd_consumer, crb_consumer);
+ NXWR32(adapter, tx_ring->crb_cmd_consumer, consumer);
}
static uint32_t msi_tgt_status[8] = {
@@ -139,37 +137,54 @@ static inline void netxen_nic_disable_int(struct nx_host_sds_ring *sds_ring)
{
struct netxen_adapter *adapter = sds_ring->adapter;
- adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0);
+ NXWR32(adapter, sds_ring->crb_intr_mask, 0);
}
static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring)
{
struct netxen_adapter *adapter = sds_ring->adapter;
- adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0x1);
+ NXWR32(adapter, sds_ring->crb_intr_mask, 0x1);
if (!NETXEN_IS_MSI_FAMILY(adapter))
adapter->pci_write_immediate(adapter,
adapter->legacy_intr.tgt_mask_reg, 0xfbff);
}
+static int
+netxen_alloc_sds_rings(struct netxen_recv_context *recv_ctx, int count)
+{
+ int size = sizeof(struct nx_host_sds_ring) * count;
+
+ recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL);
+
+ return (recv_ctx->sds_rings == NULL);
+}
+
static void
+netxen_free_sds_rings(struct netxen_recv_context *recv_ctx)
+{
+ if (recv_ctx->sds_rings != NULL)
+ kfree(recv_ctx->sds_rings);
+}
+
+static int
netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev)
{
int ring;
struct nx_host_sds_ring *sds_ring;
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
- if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
- adapter->max_sds_rings = (num_online_cpus() >= 4) ? 4 : 2;
- else
- adapter->max_sds_rings = 1;
+ if (netxen_alloc_sds_rings(recv_ctx, adapter->max_sds_rings))
+ return 1;
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &recv_ctx->sds_rings[ring];
netif_napi_add(netdev, &sds_ring->napi,
netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
}
+
+ return 0;
}
static void
@@ -195,8 +210,9 @@ netxen_napi_disable(struct netxen_adapter *adapter)
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &recv_ctx->sds_rings[ring];
- netxen_nic_disable_int(sds_ring);
napi_disable(&sds_ring->napi);
+ netxen_nic_disable_int(sds_ring);
+ synchronize_irq(sds_ring->irq);
}
}
@@ -240,7 +256,7 @@ nx_update_dma_mask(struct netxen_adapter *adapter)
change = 0;
- shift = netxen_nic_reg_read(adapter, CRB_DMA_SHIFT);
+ shift = NXRD32(adapter, CRB_DMA_SHIFT);
if (shift >= 32)
return 0;
@@ -268,10 +284,21 @@ static void netxen_check_options(struct netxen_adapter *adapter)
else if (adapter->ahw.port_type == NETXEN_NIC_GBE)
adapter->num_rxd = MAX_RCV_DESCRIPTORS_1G;
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ adapter->msix_supported = 0;
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
adapter->msix_supported = !!use_msi_x;
- else
- adapter->msix_supported = 0;
+ adapter->rss_supported = !!use_msi_x;
+ } else if (adapter->fw_version >= NETXEN_VERSION_CODE(3, 4, 336)) {
+ switch (adapter->ahw.board_type) {
+ case NETXEN_BRDTYPE_P2_SB31_10G:
+ case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
+ adapter->msix_supported = !!use_msi_x;
+ adapter->rss_supported = !!use_msi_x;
+ break;
+ default:
+ break;
+ }
+ }
adapter->num_txd = MAX_CMD_DESCRIPTORS_HOST;
adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS;
@@ -287,43 +314,34 @@ netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot)
if (first_boot == 0x55555555) {
/* This is the first boot after power up */
- adapter->pci_write_normalize(adapter,
- NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
+ NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
if (!NX_IS_REVISION_P2(adapter->ahw.revision_id))
return 0;
/* PCI bus master workaround */
- adapter->hw_read_wx(adapter,
- NETXEN_PCIE_REG(0x4), &first_boot, 4);
+ first_boot = NXRD32(adapter, NETXEN_PCIE_REG(0x4));
if (!(first_boot & 0x4)) {
first_boot |= 0x4;
- adapter->hw_write_wx(adapter,
- NETXEN_PCIE_REG(0x4), &first_boot, 4);
- adapter->hw_read_wx(adapter,
- NETXEN_PCIE_REG(0x4), &first_boot, 4);
+ NXWR32(adapter, NETXEN_PCIE_REG(0x4), first_boot);
+ first_boot = NXRD32(adapter, NETXEN_PCIE_REG(0x4));
}
/* This is the first boot after power up */
- adapter->hw_read_wx(adapter,
- NETXEN_ROMUSB_GLB_SW_RESET, &first_boot, 4);
+ first_boot = NXRD32(adapter, NETXEN_ROMUSB_GLB_SW_RESET);
if (first_boot != 0x80000f) {
/* clear the register for future unloads/loads */
- adapter->pci_write_normalize(adapter,
- NETXEN_CAM_RAM(0x1fc), 0);
+ NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), 0);
return -EIO;
}
/* Start P2 boot loader */
- val = adapter->pci_read_normalize(adapter,
- NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
- adapter->pci_write_normalize(adapter,
- NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1);
+ val = NXRD32(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
+ NXWR32(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1);
timeout = 0;
do {
msleep(1);
- val = adapter->pci_read_normalize(adapter,
- NETXEN_CAM_RAM(0x1fc));
+ val = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc));
if (++timeout > 5000)
return -EIO;
@@ -342,24 +360,19 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter)
(val == NETXEN_BRDTYPE_P3_XG_LOM)) {
if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
data = NETXEN_PORT_MODE_802_3_AP;
- adapter->hw_write_wx(adapter,
- NETXEN_PORT_MODE_ADDR, &data, 4);
+ NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
} else if (port_mode == NETXEN_PORT_MODE_XG) {
data = NETXEN_PORT_MODE_XG;
- adapter->hw_write_wx(adapter,
- NETXEN_PORT_MODE_ADDR, &data, 4);
+ NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
} else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_1G) {
data = NETXEN_PORT_MODE_AUTO_NEG_1G;
- adapter->hw_write_wx(adapter,
- NETXEN_PORT_MODE_ADDR, &data, 4);
+ NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
} else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_XG) {
data = NETXEN_PORT_MODE_AUTO_NEG_XG;
- adapter->hw_write_wx(adapter,
- NETXEN_PORT_MODE_ADDR, &data, 4);
+ NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
} else {
data = NETXEN_PORT_MODE_AUTO_NEG;
- adapter->hw_write_wx(adapter,
- NETXEN_PORT_MODE_ADDR, &data, 4);
+ NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
}
if ((wol_port_mode != NETXEN_PORT_MODE_802_3_AP) &&
@@ -368,8 +381,7 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter)
(wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_XG)) {
wol_port_mode = NETXEN_PORT_MODE_AUTO_NEG;
}
- adapter->hw_write_wx(adapter, NETXEN_WOL_PORT_MODE,
- &wol_port_mode, 4);
+ NXWR32(adapter, NETXEN_WOL_PORT_MODE, wol_port_mode);
}
}
@@ -389,11 +401,11 @@ static void netxen_set_msix_bit(struct pci_dev *pdev, int enable)
}
}
-static void netxen_init_msix_entries(struct netxen_adapter *adapter)
+static void netxen_init_msix_entries(struct netxen_adapter *adapter, int count)
{
int i;
- for (i = 0; i < MSIX_ENTRIES_PER_ADAPTER; i++)
+ for (i = 0; i < count; i++)
adapter->msix_entries[i].entry = i;
}
@@ -424,20 +436,38 @@ netxen_read_mac_addr(struct netxen_adapter *adapter)
if (!is_valid_ether_addr(netdev->perm_addr))
dev_warn(&pdev->dev, "Bad MAC address %pM.\n", netdev->dev_addr);
- else
- adapter->macaddr_set(adapter, netdev->dev_addr);
return 0;
}
+int netxen_nic_set_mac(struct net_device *netdev, void *p)
+{
+ struct netxen_adapter *adapter = netdev_priv(netdev);
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EINVAL;
+
+ if (netif_running(netdev)) {
+ netif_device_detach(netdev);
+ netxen_napi_disable(adapter);
+ }
+
+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+ adapter->macaddr_set(adapter, addr->sa_data);
+
+ if (netif_running(netdev)) {
+ netif_device_attach(netdev);
+ netxen_napi_enable(adapter);
+ }
+ return 0;
+}
+
static void netxen_set_multicast_list(struct net_device *dev)
{
struct netxen_adapter *adapter = netdev_priv(dev);
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- netxen_p3_nic_set_multi(dev);
- else
- netxen_p2_nic_set_multi(dev);
+ adapter->set_multi(dev);
}
static const struct net_device_ops netxen_netdev_ops = {
@@ -460,10 +490,17 @@ netxen_setup_intr(struct netxen_adapter *adapter)
{
struct netxen_legacy_intr_set *legacy_intrp;
struct pci_dev *pdev = adapter->pdev;
+ int err, num_msix;
+
+ if (adapter->rss_supported) {
+ num_msix = (num_online_cpus() >= MSIX_ENTRIES_PER_ADAPTER) ?
+ MSIX_ENTRIES_PER_ADAPTER : 2;
+ } else
+ num_msix = 1;
+
+ adapter->max_sds_rings = 1;
adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
- adapter->intr_scheme = -1;
- adapter->msi_mode = -1;
if (adapter->ahw.revision_id >= NX_P3_B0)
legacy_intrp = &legacy_intr[adapter->ahw.pci_func];
@@ -478,24 +515,36 @@ netxen_setup_intr(struct netxen_adapter *adapter)
if (adapter->msix_supported) {
- netxen_init_msix_entries(adapter);
- if (pci_enable_msix(pdev, adapter->msix_entries,
- MSIX_ENTRIES_PER_ADAPTER))
- goto request_msi;
+ netxen_init_msix_entries(adapter, num_msix);
+ err = pci_enable_msix(pdev, adapter->msix_entries, num_msix);
+ if (err == 0) {
+ adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
+ netxen_set_msix_bit(pdev, 1);
- adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
- netxen_set_msix_bit(pdev, 1);
- dev_info(&pdev->dev, "using msi-x interrupts\n");
+ if (adapter->rss_supported)
+ adapter->max_sds_rings = num_msix;
- } else {
-request_msi:
- if (use_msi && !pci_enable_msi(pdev)) {
- adapter->flags |= NETXEN_NIC_MSI_ENABLED;
- dev_info(&pdev->dev, "using msi interrupts\n");
- } else
- dev_info(&pdev->dev, "using legacy interrupts\n");
+ dev_info(&pdev->dev, "using msi-x interrupts\n");
+ return;
+ }
+
+ if (err > 0)
+ pci_disable_msix(pdev);
+
+ /* fall through for msi */
+ }
+
+ if (use_msi && !pci_enable_msi(pdev)) {
+ adapter->flags |= NETXEN_NIC_MSI_ENABLED;
+ adapter->msi_tgt_status =
+ msi_tgt_status[adapter->ahw.pci_func];
+ dev_info(&pdev->dev, "using msi interrupts\n");
adapter->msix_entries[0].vector = pdev->irq;
+ return;
}
+
+ dev_info(&pdev->dev, "using legacy interrupts\n");
+ adapter->msix_entries[0].vector = pdev->irq;
}
static void
@@ -552,8 +601,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
adapter->hw_read_wx = netxen_nic_hw_read_wx_128M;
adapter->pci_read_immediate = netxen_nic_pci_read_immediate_128M;
adapter->pci_write_immediate = netxen_nic_pci_write_immediate_128M;
- adapter->pci_read_normalize = netxen_nic_pci_read_normalize_128M;
- adapter->pci_write_normalize = netxen_nic_pci_write_normalize_128M;
adapter->pci_set_window = netxen_nic_pci_set_window_128M;
adapter->pci_mem_read = netxen_nic_pci_mem_read_128M;
adapter->pci_mem_write = netxen_nic_pci_mem_write_128M;
@@ -575,9 +622,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
adapter->pci_read_immediate = netxen_nic_pci_read_immediate_2M;
adapter->pci_write_immediate =
netxen_nic_pci_write_immediate_2M;
- adapter->pci_read_normalize = netxen_nic_pci_read_normalize_2M;
- adapter->pci_write_normalize =
- netxen_nic_pci_write_normalize_2M;
adapter->pci_set_window = netxen_nic_pci_set_window_2M;
adapter->pci_mem_read = netxen_nic_pci_mem_read_2M;
adapter->pci_mem_write = netxen_nic_pci_mem_write_2M;
@@ -643,25 +687,22 @@ err_out:
}
static int
-netxen_start_firmware(struct netxen_adapter *adapter)
+netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
{
int val, err, first_boot;
struct pci_dev *pdev = adapter->pdev;
int first_driver = 0;
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
- if (adapter->ahw.pci_func == 0)
- first_driver = 1;
- } else {
- if (adapter->portnum == 0)
- first_driver = 1;
- }
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ first_driver = (adapter->portnum == 0);
+ else
+ first_driver = (adapter->ahw.pci_func == 0);
if (!first_driver)
return 0;
- first_boot = adapter->pci_read_normalize(adapter,
- NETXEN_CAM_RAM(0x1fc));
+ first_boot = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc));
err = netxen_check_hw_init(adapter, first_boot);
if (err) {
@@ -669,14 +710,16 @@ netxen_start_firmware(struct netxen_adapter *adapter)
return err;
}
+ if (request_fw)
+ netxen_request_firmware(adapter);
+
if (first_boot != 0x55555555) {
- adapter->pci_write_normalize(adapter,
- CRB_CMDPEG_STATE, 0);
+ NXWR32(adapter, CRB_CMDPEG_STATE, 0);
netxen_pinit_from_rom(adapter, 0);
msleep(1);
}
- netxen_nic_reg_write(adapter, CRB_DMA_SHIFT, 0x55555555);
+ NXWR32(adapter, CRB_DMA_SHIFT, 0x55555555);
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
netxen_set_port_mode(adapter);
@@ -688,8 +731,7 @@ netxen_start_firmware(struct netxen_adapter *adapter)
val = 0x7654;
if (adapter->ahw.port_type == NETXEN_NIC_XGBE)
val |= 0x0f000000;
- netxen_crb_writelit_adapter(adapter,
- NETXEN_MAC_ADDR_CNTL_REG, val);
+ NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
}
@@ -703,7 +745,7 @@ netxen_start_firmware(struct netxen_adapter *adapter)
val = (_NETXEN_NIC_LINUX_MAJOR << 16)
| ((_NETXEN_NIC_LINUX_MINOR << 8))
| (_NETXEN_NIC_LINUX_SUBVERSION);
- adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, val);
+ NXWR32(adapter, CRB_DRIVER_VERSION, val);
/* Handshake with the card before we register the devices. */
err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
@@ -726,15 +768,6 @@ netxen_nic_request_irq(struct netxen_adapter *adapter)
struct net_device *netdev = adapter->netdev;
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
- if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
- (adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
- printk(KERN_ERR "%s: Firmware interrupt scheme is "
- "incompatible with driver\n",
- netdev->name);
- adapter->driver_mismatch = 1;
- return -EINVAL;
- }
-
if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
handler = netxen_msix_intr;
else if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
@@ -747,7 +780,7 @@ netxen_nic_request_irq(struct netxen_adapter *adapter)
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &recv_ctx->sds_rings[ring];
- sprintf(sds_ring->name, "%16s[%d]", netdev->name, ring);
+ sprintf(sds_ring->name, "%s[%d]", netdev->name, ring);
err = request_irq(sds_ring->irq, handler,
flags, sds_ring->name, sds_ring);
if (err)
@@ -782,22 +815,26 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
netxen_nic_driver_name, adapter->portnum);
return err;
}
- adapter->macaddr_set(adapter, netdev->dev_addr);
-
- netxen_nic_set_link_parameters(adapter);
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ adapter->macaddr_set(adapter, netdev->dev_addr);
- netxen_set_multicast_list(netdev);
- if (adapter->set_mtu)
- adapter->set_mtu(adapter, netdev->mtu);
+ adapter->set_multi(netdev);
+ adapter->set_mtu(adapter, netdev->mtu);
adapter->ahw.linkup = 0;
- mod_timer(&adapter->watchdog_timer, jiffies);
netxen_napi_enable(adapter);
if (adapter->max_sds_rings > 1)
netxen_config_rss(adapter, 1);
+ if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION)
+ netxen_linkevent_request(adapter, 1);
+ else
+ netxen_nic_set_link_parameters(adapter);
+
+ mod_timer(&adapter->watchdog_timer, jiffies);
+
return 0;
}
@@ -806,11 +843,15 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
{
netif_carrier_off(netdev);
netif_stop_queue(netdev);
- netxen_napi_disable(adapter);
if (adapter->stop_port)
adapter->stop_port(adapter);
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ netxen_p3_free_mac_list(adapter);
+
+ netxen_napi_disable(adapter);
+
netxen_release_tx_buffers(adapter);
FLUSH_SCHEDULED_WORK();
@@ -825,6 +866,7 @@ netxen_nic_attach(struct netxen_adapter *adapter)
struct pci_dev *pdev = adapter->pdev;
int err, ring;
struct nx_host_rds_ring *rds_ring;
+ struct nx_host_tx_ring *tx_ring;
err = netxen_init_firmware(adapter);
if (err != 0) {
@@ -854,13 +896,12 @@ netxen_nic_attach(struct netxen_adapter *adapter)
}
if (adapter->fw_major < 4) {
- adapter->crb_addr_cmd_producer =
- crb_cmd_producer[adapter->portnum];
- adapter->crb_addr_cmd_consumer =
- crb_cmd_consumer[adapter->portnum];
+ tx_ring = adapter->tx_ring;
+ tx_ring->crb_cmd_producer = crb_cmd_producer[adapter->portnum];
+ tx_ring->crb_cmd_consumer = crb_cmd_consumer[adapter->portnum];
- netxen_nic_update_cmd_producer(adapter, 0);
- netxen_nic_update_cmd_consumer(adapter, 0);
+ netxen_nic_update_cmd_producer(adapter, tx_ring, 0);
+ netxen_nic_update_cmd_consumer(adapter, tx_ring, 0);
}
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
@@ -889,10 +930,9 @@ err_out_free_sw:
static void
netxen_nic_detach(struct netxen_adapter *adapter)
{
- netxen_nic_free_irq(adapter);
-
netxen_release_rx_buffers(adapter);
netxen_free_hw_resources(adapter);
+ netxen_nic_free_irq(adapter);
netxen_free_sw_resources(adapter);
adapter->is_up = 0;
@@ -957,6 +997,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
rwlock_init(&adapter->adapter_lock);
spin_lock_init(&adapter->tx_clean_lock);
+ INIT_LIST_HEAD(&adapter->mac_list);
err = netxen_setup_pci_map(adapter);
if (err)
@@ -979,6 +1020,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+ netdev->features |= (NETIF_F_GRO);
netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
if (NX_IS_REVISION_P3(revision_id)) {
@@ -1011,7 +1053,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
- err = netxen_start_firmware(adapter);
+ err = netxen_start_firmware(adapter, 1);
if (err)
goto err_out_iounmap;
@@ -1024,8 +1066,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
*/
adapter->physical_port = adapter->portnum;
if (adapter->fw_major < 4) {
- i = adapter->pci_read_normalize(adapter,
- CRB_V2P(adapter->portnum));
+ i = NXRD32(adapter, CRB_V2P(adapter->portnum));
if (i != 0x55555555)
adapter->physical_port = i;
}
@@ -1036,10 +1077,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->irq = adapter->msix_entries[0].vector;
- netxen_napi_add(adapter, netdev);
-
- err = netxen_receive_peg_ready(adapter);
- if (err)
+ if (netxen_napi_add(adapter, netdev))
goto err_out_disable_msi;
init_timer(&adapter->watchdog_timer);
@@ -1113,18 +1151,18 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
netxen_nic_detach(adapter);
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- netxen_p3_free_mac_list(adapter);
}
if (adapter->portnum == 0)
netxen_free_adapter_offload(adapter);
netxen_teardown_intr(adapter);
+ netxen_free_sds_rings(&adapter->recv_ctx);
netxen_cleanup_pci_map(adapter);
+ netxen_release_firmware(adapter);
+
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
@@ -1176,7 +1214,7 @@ netxen_nic_resume(struct pci_dev *pdev)
adapter->curr_window = 255;
- err = netxen_start_firmware(adapter);
+ err = netxen_start_firmware(adapter, 0);
if (err) {
dev_err(&pdev->dev, "failed to start firmware\n");
return err;
@@ -1315,7 +1353,7 @@ static int
netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
- struct netxen_hardware_context *hw = &adapter->ahw;
+ struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
unsigned int first_seg_len = skb->len - skb->data_len;
struct netxen_cmd_buffer *pbuf;
struct netxen_skb_frag *buffrag;
@@ -1326,28 +1364,26 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
u32 producer, consumer;
int frag_count, no_of_desc;
- u32 num_txd = adapter->num_txd;
+ u32 num_txd = tx_ring->num_desc;
bool is_tso = false;
frag_count = skb_shinfo(skb)->nr_frags + 1;
- /* There 4 fragments per descriptor */
+ /* 4 fragments per cmd des */
no_of_desc = (frag_count + 3) >> 2;
- producer = adapter->cmd_producer;
+ producer = tx_ring->producer;
smp_mb();
- consumer = adapter->last_cmd_consumer;
- if ((no_of_desc+2) > find_diff_among(producer, consumer, num_txd)) {
+ consumer = tx_ring->sw_consumer;
+ if ((no_of_desc+2) >= find_diff_among(producer, consumer, num_txd)) {
netif_stop_queue(netdev);
smp_mb();
return NETDEV_TX_BUSY;
}
- /* Copy the descriptors into the hardware */
- hwdesc = &hw->cmd_desc_head[producer];
+ hwdesc = &tx_ring->desc_head[producer];
netxen_clear_cmddesc((u64 *)hwdesc);
- /* Take skb->data itself */
- pbuf = &adapter->cmd_buf_arr[producer];
+ pbuf = &tx_ring->cmd_buf_arr[producer];
is_tso = netxen_tso_check(netdev, hwdesc, skb);
@@ -1376,9 +1412,9 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if ((i & 0x3) == 0) {
k = 0;
producer = get_next_index(producer, num_txd);
- hwdesc = &hw->cmd_desc_head[producer];
+ hwdesc = &tx_ring->desc_head[producer];
netxen_clear_cmddesc((u64 *)hwdesc);
- pbuf = &adapter->cmd_buf_arr[producer];
+ pbuf = &tx_ring->cmd_buf_arr[producer];
pbuf->skb = NULL;
}
frag = &skb_shinfo(skb)->frags[i - 1];
@@ -1430,8 +1466,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
more_hdr = 0;
}
/* copy the MAC/IP/TCP headers to the cmd descriptor list */
- hwdesc = &hw->cmd_desc_head[producer];
- pbuf = &adapter->cmd_buf_arr[producer];
+ hwdesc = &tx_ring->desc_head[producer];
+ pbuf = &tx_ring->cmd_buf_arr[producer];
pbuf->skb = NULL;
/* copy the first 64 bytes */
@@ -1440,8 +1476,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
producer = get_next_index(producer, num_txd);
if (more_hdr) {
- hwdesc = &hw->cmd_desc_head[producer];
- pbuf = &adapter->cmd_buf_arr[producer];
+ hwdesc = &tx_ring->desc_head[producer];
+ pbuf = &tx_ring->cmd_buf_arr[producer];
pbuf->skb = NULL;
/* copy the next 64 bytes - should be enough except
* for pathological case
@@ -1454,13 +1490,12 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
}
- adapter->cmd_producer = producer;
+ tx_ring->producer = producer;
adapter->stats.txbytes += skb->len;
- netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer);
+ netxen_nic_update_cmd_producer(adapter, tx_ring, producer);
adapter->stats.xmitcalled++;
- netdev->trans_start = jiffies;
return NETDEV_TX_OK;
@@ -1476,7 +1511,7 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter)
uint32_t temp, temp_state, temp_val;
int rv = 0;
- temp = adapter->pci_read_normalize(adapter, CRB_TEMP_STATE);
+ temp = NXRD32(adapter, CRB_TEMP_STATE);
temp_state = nx_get_temp_state(temp);
temp_val = nx_get_temp_val(temp);
@@ -1510,26 +1545,9 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter)
return rv;
}
-static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
+void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup)
{
struct net_device *netdev = adapter->netdev;
- u32 val, port, linkup;
-
- port = adapter->physical_port;
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
- val = adapter->pci_read_normalize(adapter, CRB_XG_STATE_P3);
- val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
- linkup = (val == XG_LINK_UP_P3);
- } else {
- val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
- if (adapter->ahw.port_type == NETXEN_NIC_GBE)
- linkup = (val >> port) & 1;
- else {
- val = (val >> port*8) & 0xff;
- linkup = (val == XG_LINK_UP);
- }
- }
if (adapter->ahw.linkup && !linkup) {
printk(KERN_INFO "%s: %s NIC Link is down\n",
@@ -1540,7 +1558,9 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
netif_stop_queue(netdev);
}
- netxen_nic_set_link_parameters(adapter);
+ if (!adapter->has_link_events)
+ netxen_nic_set_link_parameters(adapter);
+
} else if (!adapter->ahw.linkup && linkup) {
printk(KERN_INFO "%s: %s NIC Link is up\n",
netxen_nic_driver_name, netdev->name);
@@ -1550,8 +1570,32 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
netif_wake_queue(netdev);
}
- netxen_nic_set_link_parameters(adapter);
+ if (!adapter->has_link_events)
+ netxen_nic_set_link_parameters(adapter);
+ }
+}
+
+static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
+{
+ u32 val, port, linkup;
+
+ port = adapter->physical_port;
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+ val = NXRD32(adapter, CRB_XG_STATE_P3);
+ val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
+ linkup = (val == XG_LINK_UP_P3);
+ } else {
+ val = NXRD32(adapter, CRB_XG_STATE);
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE)
+ linkup = (val >> port) & 1;
+ else {
+ val = (val >> port*8) & 0xff;
+ linkup = (val == XG_LINK_UP);
+ }
}
+
+ netxen_advert_link_change(adapter, linkup);
}
static void netxen_watchdog(unsigned long v)
@@ -1569,7 +1613,8 @@ void netxen_watchdog_task(struct work_struct *work)
if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter))
return;
- netxen_nic_handle_phy_intr(adapter);
+ if (!adapter->has_link_events)
+ netxen_nic_handle_phy_intr(adapter);
if (netif_running(adapter->netdev))
mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
@@ -1598,10 +1643,6 @@ static void netxen_tx_timeout_task(struct work_struct *work)
netif_wake_queue(adapter->netdev);
}
-/*
- * netxen_nic_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- */
struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
@@ -1609,22 +1650,11 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
memset(stats, 0, sizeof(*stats));
- /* total packets received */
stats->rx_packets = adapter->stats.no_rcv;
- /* total packets transmitted */
- stats->tx_packets = adapter->stats.xmitedframes +
- adapter->stats.xmitfinished;
- /* total bytes received */
+ stats->tx_packets = adapter->stats.xmitfinished;
stats->rx_bytes = adapter->stats.rxbytes;
- /* total bytes transmitted */
stats->tx_bytes = adapter->stats.txbytes;
- /* bad packets received */
- stats->rx_errors = adapter->stats.rcvdbadskb;
- /* packet transmit problems */
- stats->tx_errors = adapter->stats.nocmddescriptor;
- /* no space in linux buffers */
stats->rx_dropped = adapter->stats.rxdropped;
- /* no space available in linux */
stats->tx_dropped = adapter->stats.txdropped;
return stats;
@@ -1651,15 +1681,14 @@ static irqreturn_t netxen_intr(int irq, void *data)
} else {
unsigned long our_int = 0;
- our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
+ our_int = NXRD32(adapter, CRB_INT_VECTOR);
/* not our interrupt */
if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
return IRQ_NONE;
/* claim interrupt */
- adapter->pci_write_normalize(adapter,
- CRB_INT_VECTOR, (our_int & 0xffffffff));
+ NXWR32(adapter, CRB_INT_VECTOR, (our_int & 0xffffffff));
}
/* clear interrupt */
@@ -1685,7 +1714,7 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
/* clear interrupt */
adapter->pci_write_immediate(adapter,
- msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
+ adapter->msi_tgt_status, 0xffffffff);
napi_schedule(&sds_ring->napi);
return IRQ_HANDLED;
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
index d85203203d4..5941c79be72 100644
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ b/drivers/net/netxen/netxen_nic_niu.c
@@ -43,8 +43,7 @@ static int phy_lock(struct netxen_adapter *adapter)
int done = 0, timeout = 0;
while (!done) {
- done = netxen_nic_reg_read(adapter,
- NETXEN_PCIE_REG(PCIE_SEM3_LOCK));
+ done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK));
if (done == 1)
break;
if (timeout >= phy_lock_timeout) {
@@ -59,8 +58,7 @@ static int phy_lock(struct netxen_adapter *adapter)
}
}
- netxen_crb_writelit_adapter(adapter,
- NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER);
+ NXWR32(adapter, NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER);
return 0;
}
@@ -105,9 +103,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
* so it cannot be in reset
*/
- if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
- &mac_cfg0, 4))
- return -EIO;
+ mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
if (netxen_gb_get_soft_reset(mac_cfg0)) {
__u32 temp;
temp = 0;
@@ -115,9 +111,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
netxen_gb_rx_reset_pb(temp);
netxen_gb_tx_reset_mac(temp);
netxen_gb_rx_reset_mac(temp);
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0(0),
- &temp, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
return -EIO;
restore = 1;
}
@@ -125,43 +119,32 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
address = 0;
netxen_gb_mii_mgmt_reg_addr(address, reg);
netxen_gb_mii_mgmt_phy_addr(address, phy);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
- &address, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
return -EIO;
command = 0; /* turn off any prior activity */
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
- &command, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
return -EIO;
/* send read command */
netxen_gb_mii_mgmt_set_read_cycle(command);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
- &command, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
return -EIO;
status = 0;
do {
- if (adapter->hw_read_wx(adapter,
- NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
- &status, 4))
- return -EIO;
+ status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
timeout++;
} while ((netxen_get_gb_mii_mgmt_busy(status)
|| netxen_get_gb_mii_mgmt_notvalid(status))
&& (timeout++ < NETXEN_NIU_PHY_WAITMAX));
if (timeout < NETXEN_NIU_PHY_WAITMAX) {
- if (adapter->hw_read_wx(adapter,
- NETXEN_NIU_GB_MII_MGMT_STATUS(0),
- readval, 4))
- return -EIO;
+ *readval = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_STATUS(0));
result = 0;
} else
result = -1;
if (restore)
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0(0),
- &mac_cfg0, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
return -EIO;
phy_unlock(adapter);
return result;
@@ -197,9 +180,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
* cannot be in reset
*/
- if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
- &mac_cfg0, 4))
- return -EIO;
+ mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
if (netxen_gb_get_soft_reset(mac_cfg0)) {
__u32 temp;
temp = 0;
@@ -208,35 +189,27 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
netxen_gb_tx_reset_mac(temp);
netxen_gb_rx_reset_mac(temp);
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0(0),
- &temp, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
return -EIO;
restore = 1;
}
command = 0; /* turn off any prior activity */
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
- &command, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
return -EIO;
address = 0;
netxen_gb_mii_mgmt_reg_addr(address, reg);
netxen_gb_mii_mgmt_phy_addr(address, phy);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
- &address, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
return -EIO;
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0),
- &val, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), val))
return -EIO;
status = 0;
do {
- if (adapter->hw_read_wx(adapter,
- NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
- &status, 4))
- return -EIO;
+ status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
timeout++;
} while ((netxen_get_gb_mii_mgmt_busy(status))
&& (timeout++ < NETXEN_NIU_PHY_WAITMAX));
@@ -248,9 +221,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
/* restore the state of port 0 MAC in case we tampered with it */
if (restore)
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0(0),
- &mac_cfg0, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
return -EIO;
return result;
@@ -258,7 +229,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter)
{
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x3f);
+ NXWR32(adapter, NETXEN_NIU_INT_MASK, 0x3f);
return 0;
}
@@ -281,7 +252,7 @@ int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter)
int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter)
{
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x7f);
+ NXWR32(adapter, NETXEN_NIU_INT_MASK, 0x7f);
return 0;
}
@@ -315,36 +286,27 @@ static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
int port, long enable)
{
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- 0x80000000);
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- 0x0000f0025);
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
- 0xf1ff);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB0_MII_MODE + (port << 3), 1);
- netxen_crb_writelit_adapter(adapter,
- (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
+ NXWR32(adapter, NETXEN_NIU_MODE, 0x2);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x80000000);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), 0xf1ff);
+ NXWR32(adapter, NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0);
+ NXWR32(adapter, NETXEN_NIU_GB0_MII_MODE + (port << 3), 1);
+ NXWR32(adapter, (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
+ NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
if (enable) {
/*
* Do NOT enable flow control until a suitable solution for
* shutting down pause frames is found.
*/
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0(port),
- 0x5);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x5);
}
if (netxen_niu_gbe_enable_phy_interrupts(adapter))
- printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
+ printk(KERN_ERR "ERROR enabling PHY interrupts\n");
if (netxen_niu_gbe_clear_phy_interrupts(adapter))
- printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
+ printk(KERN_ERR "ERROR clearing PHY interrupts\n");
}
/*
@@ -353,36 +315,27 @@ static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
static void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter,
int port, long enable)
{
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- 0x80000000);
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- 0x0000f0025);
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
- 0xf2ff);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB0_MII_MODE + (port << 3), 0);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1);
- netxen_crb_writelit_adapter(adapter,
- (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
+ NXWR32(adapter, NETXEN_NIU_MODE, 0x2);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x80000000);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), 0xf2ff);
+ NXWR32(adapter, NETXEN_NIU_GB0_MII_MODE + (port << 3), 0);
+ NXWR32(adapter, NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1);
+ NXWR32(adapter, (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
+ NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
if (enable) {
/*
* Do NOT enable flow control until a suitable solution for
* shutting down pause frames is found.
*/
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0(port),
- 0x5);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x5);
}
if (netxen_niu_gbe_enable_phy_interrupts(adapter))
- printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
+ printk(KERN_ERR "ERROR enabling PHY interrupts\n");
if (netxen_niu_gbe_clear_phy_interrupts(adapter))
- printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
+ printk(KERN_ERR "ERROR clearing PHY interrupts\n");
}
int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
@@ -416,25 +369,20 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
* plugged in.
*/
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0
- (port),
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
NETXEN_GB_MAC_SOFT_RESET);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_0
- (port),
- NETXEN_GB_MAC_RESET_PROT_BLK
- | NETXEN_GB_MAC_ENABLE_TX_RX
- |
- NETXEN_GB_MAC_PAUSED_FRMS);
+ NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+ NETXEN_GB_MAC_RESET_PROT_BLK |
+ NETXEN_GB_MAC_ENABLE_TX_RX |
+ NETXEN_GB_MAC_PAUSED_FRMS);
if (netxen_niu_gbe_clear_phy_interrupts(adapter))
- printk(KERN_ERR PFX
+ printk(KERN_ERR
"ERROR clearing PHY interrupts\n");
if (netxen_niu_gbe_enable_phy_interrupts(adapter))
- printk(KERN_ERR PFX
+ printk(KERN_ERR
"ERROR enabling PHY interrupts\n");
if (netxen_niu_gbe_clear_phy_interrupts(adapter))
- printk(KERN_ERR PFX
+ printk(KERN_ERR
"ERROR clearing PHY interrupts\n");
result = -1;
}
@@ -447,88 +395,10 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
{
if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
- }
-
- return 0;
-}
-
-/*
- * Return the current station MAC address.
- * Note that the passed-in value must already be in network byte order.
- */
-static int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
- netxen_ethernet_macaddr_t * addr)
-{
- u32 stationhigh;
- u32 stationlow;
- int phy = adapter->physical_port;
- u8 val[8];
-
- if (addr == NULL)
- return -EINVAL;
- if ((phy < 0) || (phy > 3))
- return -EINVAL;
-
- if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy),
- &stationhigh, 4))
- return -EIO;
- if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy),
- &stationlow, 4))
- return -EIO;
- ((__le32 *)val)[1] = cpu_to_le32(stationhigh);
- ((__le32 *)val)[0] = cpu_to_le32(stationlow);
-
- memcpy(addr, val + 2, 6);
-
- return 0;
-}
-
-/*
- * Set the station MAC address.
- * Note that the passed-in value must already be in network byte order.
- */
-int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
- netxen_ethernet_macaddr_t addr)
-{
- u8 temp[4];
- u32 val;
- int phy = adapter->physical_port;
- unsigned char mac_addr[6];
- int i;
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- return 0;
-
- for (i = 0; i < 10; i++) {
- temp[0] = temp[1] = 0;
- memcpy(temp + 2, addr, 2);
- val = le32_to_cpu(*(__le32 *)temp);
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4))
- return -EIO;
-
- memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32));
- val = le32_to_cpu(*(__le32 *)temp);
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4))
- return -2;
-
- netxen_niu_macaddr_get(adapter,
- (netxen_ethernet_macaddr_t *) mac_addr);
- if (memcmp(mac_addr, addr, 6) == 0)
- break;
+ NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
+ NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
}
- if (i == 10) {
- printk(KERN_ERR "%s: cannot set Mac addr for %s\n",
- netxen_nic_driver_name, adapter->netdev->name);
- printk(KERN_ERR "MAC address set: %pM.\n", addr);
- printk(KERN_ERR "MAC address get: %pM.\n", mac_addr);
- }
return 0;
}
@@ -545,8 +415,7 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
return -EINVAL;
mac_cfg0 = 0;
netxen_gb_soft_reset(mac_cfg0);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- &mac_cfg0, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), mac_cfg0))
return -EIO;
return 0;
}
@@ -564,8 +433,8 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
return -EINVAL;
mac_cfg = 0;
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4))
+ if (NXWR32(adapter,
+ NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg))
return -EIO;
return 0;
}
@@ -581,9 +450,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
return -EINVAL;
/* save previous contents */
- if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
- &reg, 4))
- return -EIO;
+ reg = NXRD32(adapter, NETXEN_NIU_GB_DROP_WRONGADDR);
if (mode == NETXEN_NIU_PROMISC_MODE) {
switch (port) {
case 0:
@@ -619,67 +486,11 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
return -EIO;
}
}
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
- &reg, 4))
+ if (NXWR32(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, reg))
return -EIO;
return 0;
}
-/*
- * Set the MAC address for an XG port
- * Note that the passed-in value must already be in network byte order.
- */
-int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
- netxen_ethernet_macaddr_t addr)
-{
- int phy = adapter->physical_port;
- u8 temp[4];
- u32 val;
-
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- return 0;
-
- if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS))
- return -EIO;
-
- temp[0] = temp[1] = 0;
- switch (phy) {
- case 0:
- memcpy(temp + 2, addr, 2);
- val = le32_to_cpu(*(__le32 *)temp);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
- &val, 4))
- return -EIO;
-
- memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
- val = le32_to_cpu(*(__le32 *)temp);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
- &val, 4))
- return -EIO;
- break;
-
- case 1:
- memcpy(temp + 2, addr, 2);
- val = le32_to_cpu(*(__le32 *)temp);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1,
- &val, 4))
- return -EIO;
-
- memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
- val = le32_to_cpu(*(__le32 *)temp);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI,
- &val, 4))
- return -EIO;
- break;
-
- default:
- printk(KERN_ERR "Unknown port %d\n", phy);
- break;
- }
-
- return 0;
-}
-
int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
u32 mode)
{
@@ -689,9 +500,7 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
if (port > NETXEN_NIU_MAX_XG_PORTS)
return -EINVAL;
- if (adapter->hw_read_wx(adapter,
- NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), &reg, 4))
- return -EIO;
+ reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
if (mode == NETXEN_NIU_PROMISC_MODE)
reg = (reg | 0x2000UL);
else
@@ -702,8 +511,40 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
else
reg = (reg & ~0x1000UL);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+ NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+
+ return 0;
+}
+
+int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
+{
+ u32 mac_hi, mac_lo;
+ u32 reg_hi, reg_lo;
+
+ u8 phy = adapter->physical_port;
+ u8 phy_count = (adapter->ahw.port_type == NETXEN_NIC_XGBE) ?
+ NETXEN_NIU_MAX_XG_PORTS : NETXEN_NIU_MAX_GBE_PORTS;
+
+ if (phy >= phy_count)
+ return -EINVAL;
+
+ mac_lo = ((u32)addr[0] << 16) | ((u32)addr[1] << 24);
+ mac_hi = addr[2] | ((u32)addr[3] << 8) |
+ ((u32)addr[4] << 16) | ((u32)addr[5] << 24);
+
+ if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
+ reg_lo = NETXEN_NIU_XGE_STATION_ADDR_0_1 + (0x10000 * phy);
+ reg_hi = NETXEN_NIU_XGE_STATION_ADDR_0_HI + (0x10000 * phy);
+ } else {
+ reg_lo = NETXEN_NIU_GB_STATION_ADDR_1(phy);
+ reg_hi = NETXEN_NIU_GB_STATION_ADDR_0(phy);
+ }
+
+ /* write twice to flush */
+ if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
+ return -EIO;
+ if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
+ return -EIO;
return 0;
}
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h
index 50183335e43..b73a62ca74f 100644
--- a/drivers/net/netxen/netxen_nic_phan_reg.h
+++ b/drivers/net/netxen/netxen_nic_phan_reg.h
@@ -36,23 +36,25 @@
*/
#define NIC_CRB_BASE NETXEN_CAM_RAM(0x200)
#define NETXEN_NIC_REG(X) (NIC_CRB_BASE+(X))
+#define NIC_CRB_BASE_2 NETXEN_CAM_RAM(0x700)
+#define NETXEN_NIC_REG_2(X) (NIC_CRB_BASE_2+(X))
#define CRB_PHAN_CNTRL_LO_OFFSET NETXEN_NIC_REG(0x00)
#define CRB_PHAN_CNTRL_HI_OFFSET NETXEN_NIC_REG(0x04)
#define CRB_CMD_PRODUCER_OFFSET NETXEN_NIC_REG(0x08)
#define CRB_CMD_CONSUMER_OFFSET NETXEN_NIC_REG(0x0c)
-#define CRB_PAUSE_ADDR_LO NETXEN_NIC_REG(0x10) /* C0 EPG BUG */
+#define CRB_PAUSE_ADDR_LO NETXEN_NIC_REG(0x10)
#define CRB_PAUSE_ADDR_HI NETXEN_NIC_REG(0x14)
#define NX_CDRP_CRB_OFFSET NETXEN_NIC_REG(0x18)
#define NX_ARG1_CRB_OFFSET NETXEN_NIC_REG(0x1c)
#define NX_ARG2_CRB_OFFSET NETXEN_NIC_REG(0x20)
#define NX_ARG3_CRB_OFFSET NETXEN_NIC_REG(0x24)
#define NX_SIGN_CRB_OFFSET NETXEN_NIC_REG(0x28)
-#define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x20) /* 4 regs for perf */
+#define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x20)
#define CRB_CMD_DMA_LOOP NETXEN_NIC_REG(0x24)
#define CRB_RCV_INTR_LOOP NETXEN_NIC_REG(0x28)
#define CRB_RCV_DMA_LOOP NETXEN_NIC_REG(0x2c)
-#define CRB_ENABLE_TX_INTR NETXEN_NIC_REG(0x30) /* phantom init status */
+#define CRB_ENABLE_TX_INTR NETXEN_NIC_REG(0x30)
#define CRB_MMAP_ADDR_3 NETXEN_NIC_REG(0x34)
#define CRB_CMDPEG_CMDRING NETXEN_NIC_REG(0x38)
#define CRB_HOST_DUMMY_BUF_ADDR_HI NETXEN_NIC_REG(0x3c)
@@ -65,7 +67,7 @@
#define CRB_MMAP_SIZE_1 NETXEN_NIC_REG(0x58)
#define CRB_MMAP_SIZE_2 NETXEN_NIC_REG(0x5c)
#define CRB_MMAP_SIZE_3 NETXEN_NIC_REG(0x60)
-#define CRB_GLOBAL_INT_COAL NETXEN_NIC_REG(0x64) /* interrupt coalescing */
+#define CRB_GLOBAL_INT_COAL NETXEN_NIC_REG(0x64)
#define CRB_INT_COAL_MODE NETXEN_NIC_REG(0x68)
#define CRB_MAX_RCV_BUFS NETXEN_NIC_REG(0x6c)
#define CRB_TX_INT_THRESHOLD NETXEN_NIC_REG(0x70)
@@ -83,13 +85,13 @@
#define CRB_AGENT_TX_TYPE NETXEN_NIC_REG(0xa0)
#define CRB_AGENT_TX_ADDR NETXEN_NIC_REG(0xa4)
#define CRB_AGENT_TX_MSS NETXEN_NIC_REG(0xa8)
-#define CRB_TX_STATE NETXEN_NIC_REG(0xac) /* Debug -performance */
+#define CRB_TX_STATE NETXEN_NIC_REG(0xac)
#define CRB_TX_COUNT NETXEN_NIC_REG(0xb0)
#define CRB_RX_STATE NETXEN_NIC_REG(0xb4)
#define CRB_RX_PERF_DEBUG_1 NETXEN_NIC_REG(0xb8)
-#define CRB_RX_LRO_CONTROL NETXEN_NIC_REG(0xbc) /* LRO On/OFF */
+#define CRB_RX_LRO_CONTROL NETXEN_NIC_REG(0xbc)
#define CRB_RX_LRO_START_NUM NETXEN_NIC_REG(0xc0)
-#define CRB_MPORT_MODE NETXEN_NIC_REG(0xc4) /* Multiport Mode */
+#define CRB_MPORT_MODE NETXEN_NIC_REG(0xc4)
#define CRB_CMD_RING_SIZE NETXEN_NIC_REG(0xc8)
#define CRB_DMA_SHIFT NETXEN_NIC_REG(0xcc)
#define CRB_INT_VECTOR NETXEN_NIC_REG(0xd4)
@@ -109,8 +111,6 @@
#define CRB_CMD_CONSUMER_OFFSET_1 NETXEN_NIC_REG(0x1b0)
#define CRB_CMD_PRODUCER_OFFSET_2 NETXEN_NIC_REG(0x1b8)
#define CRB_CMD_CONSUMER_OFFSET_2 NETXEN_NIC_REG(0x1bc)
-
-// 1c0 to 1cc used for signature reg
#define CRB_CMD_PRODUCER_OFFSET_3 NETXEN_NIC_REG(0x1d0)
#define CRB_CMD_CONSUMER_OFFSET_3 NETXEN_NIC_REG(0x1d4)
#define CRB_TEMP_STATE NETXEN_NIC_REG(0x1b4)
@@ -120,13 +120,13 @@
#define CRB_V2P_2 NETXEN_NIC_REG(0x298)
#define CRB_V2P_3 NETXEN_NIC_REG(0x29c)
#define CRB_V2P(port) (CRB_V2P_0+((port)*4))
-#define CRB_DRIVER_VERSION NETXEN_NIC_REG(0x2a0)
-/* sw int status/mask registers */
+#define CRB_DRIVER_VERSION NETXEN_NIC_REG(0x2a0)
#define CRB_SW_INT_MASK_0 NETXEN_NIC_REG(0x1d8)
#define CRB_SW_INT_MASK_1 NETXEN_NIC_REG(0x1e0)
#define CRB_SW_INT_MASK_2 NETXEN_NIC_REG(0x1e4)
#define CRB_SW_INT_MASK_3 NETXEN_NIC_REG(0x1e8)
+#define CRB_FW_CAPABILITIES_1 NETXEN_CAM_RAM(0x128)
#define CRB_MAC_BLOCK_START NETXEN_CAM_RAM(0x1c0)
/*
@@ -136,7 +136,7 @@
#define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8)
#define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc)
#define CRB_NIC_MSI_MODE_HOST NETXEN_NIC_REG(0x270)
-#define CRB_NIC_MSI_MODE_FW NETXEN_NIC_REG(0x274)
+#define CRB_NIC_MSI_MODE_FW NETXEN_NIC_REG(0x274)
#define INTR_SCHEME_PERPORT 0x1
#define MSI_MODE_MULTIFUNC 0x1
@@ -162,7 +162,8 @@
struct netxen_recv_crb {
u32 crb_rcv_producer[NUM_RCV_DESC_RINGS];
- u32 crb_sts_consumer;
+ u32 crb_sts_consumer[NUM_STS_DESC_RINGS];
+ u32 sw_int_mask[NUM_STS_DESC_RINGS];
};
/*
diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c
index 6474f02bf78..1f10ed603e2 100644
--- a/drivers/net/ni65.c
+++ b/drivers/net/ni65.c
@@ -1165,7 +1165,7 @@ static int ni65_send_packet(struct sk_buff *skb, struct net_device *dev)
if (test_and_set_bit(0, (void*)&p->lock)) {
printk(KERN_ERR "%s: Queue was locked.\n", dev->name);
- return 1;
+ return NETDEV_TX_BUSY;
}
{
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 2b1745328cf..fa61a12c5e1 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -22,6 +22,7 @@
#include <linux/log2.h>
#include <linux/jiffies.h>
#include <linux/crc32.h>
+#include <linux/list.h>
#include <linux/io.h>
@@ -1317,7 +1318,7 @@ static int bcm8704_reset(struct niu *np)
err = mdio_read(np, np->phy_addr,
BCM8704_PHYXS_DEV_ADDR, MII_BMCR);
- if (err < 0)
+ if (err < 0 || err == 0xffff)
return err;
err |= BMCR_RESET;
err = mdio_write(np, np->phy_addr, BCM8704_PHYXS_DEV_ADDR,
@@ -2042,7 +2043,7 @@ static int link_status_10g_bcm8706(struct niu *np, int *link_up_p)
err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR,
BCM8704_PMD_RCV_SIGDET);
- if (err < 0)
+ if (err < 0 || err == 0xffff)
goto out;
if (!(err & PMD_RCV_SIGDET_GLOBAL)) {
err = 0;
@@ -2083,8 +2084,6 @@ static int link_status_10g_bcm8706(struct niu *np, int *link_up_p)
out:
*link_up_p = link_up;
- if (np->flags & NIU_FLAGS_HOTPLUG_PHY)
- err = 0;
return err;
}
@@ -2220,10 +2219,17 @@ static int link_status_10g_hotplug(struct niu *np, int *link_up_p)
if (phy_present != phy_present_prev) {
/* state change */
if (phy_present) {
+ /* A NEM was just plugged in */
np->flags |= NIU_FLAGS_HOTPLUG_PHY_PRESENT;
if (np->phy_ops->xcvr_init)
err = np->phy_ops->xcvr_init(np);
if (err) {
+ err = mdio_read(np, np->phy_addr,
+ BCM8704_PHYXS_DEV_ADDR, MII_BMCR);
+ if (err == 0xffff) {
+ /* No mdio, back-to-back XAUI */
+ goto out;
+ }
/* debounce */
np->flags &= ~NIU_FLAGS_HOTPLUG_PHY_PRESENT;
}
@@ -2234,13 +2240,21 @@ static int link_status_10g_hotplug(struct niu *np, int *link_up_p)
np->dev->name);
}
}
- if (np->flags & NIU_FLAGS_HOTPLUG_PHY_PRESENT)
+out:
+ if (np->flags & NIU_FLAGS_HOTPLUG_PHY_PRESENT) {
err = link_status_10g_bcm8706(np, link_up_p);
+ if (err == 0xffff) {
+ /* No mdio, back-to-back XAUI: it is C10NEM */
+ *link_up_p = 1;
+ np->link_config.active_speed = SPEED_10000;
+ np->link_config.active_duplex = DUPLEX_FULL;
+ }
+ }
}
spin_unlock_irqrestore(&np->lock, flags);
- return err;
+ return 0;
}
static int niu_link_status(struct niu *np, int *link_up_p)
@@ -2312,6 +2326,12 @@ static const struct niu_phy_ops phy_ops_10g_fiber_hotplug = {
.link_status = link_status_10g_hotplug,
};
+static const struct niu_phy_ops phy_ops_niu_10g_hotplug = {
+ .serdes_init = serdes_init_niu_10g_fiber,
+ .xcvr_init = xcvr_init_10g_bcm8706,
+ .link_status = link_status_10g_hotplug,
+};
+
static const struct niu_phy_ops phy_ops_10g_copper = {
.serdes_init = serdes_init_10g,
.link_status = link_status_10g, /* XXX */
@@ -2358,6 +2378,11 @@ static const struct niu_phy_template phy_template_10g_fiber_hotplug = {
.phy_addr_base = 8,
};
+static const struct niu_phy_template phy_template_niu_10g_hotplug = {
+ .ops = &phy_ops_niu_10g_hotplug,
+ .phy_addr_base = 8,
+};
+
static const struct niu_phy_template phy_template_10g_copper = {
.ops = &phy_ops_10g_copper,
.phy_addr_base = 10,
@@ -2542,8 +2567,16 @@ static int niu_determine_phy_disposition(struct niu *np)
case NIU_FLAGS_10G | NIU_FLAGS_FIBER:
/* 10G Fiber */
default:
- tp = &phy_template_niu_10g_fiber;
- phy_addr_off += np->port;
+ if (np->flags & NIU_FLAGS_HOTPLUG_PHY) {
+ tp = &phy_template_niu_10g_hotplug;
+ if (np->port == 0)
+ phy_addr_off = 8;
+ if (np->port == 1)
+ phy_addr_off = 12;
+ } else {
+ tp = &phy_template_niu_10g_fiber;
+ phy_addr_off += np->port;
+ }
break;
}
} else {
@@ -2630,11 +2663,11 @@ static int niu_init_link(struct niu *np)
msleep(200);
}
err = niu_serdes_init(np);
- if (err)
+ if (err && !(np->flags & NIU_FLAGS_HOTPLUG_PHY))
return err;
msleep(200);
err = niu_xcvr_init(np);
- if (!err)
+ if (!err || (np->flags & NIU_FLAGS_HOTPLUG_PHY))
niu_link_status(np, &ignore);
return 0;
}
@@ -6330,6 +6363,7 @@ static void niu_set_rx_mode(struct net_device *dev)
struct niu *np = netdev_priv(dev);
int i, alt_cnt, err;
struct dev_addr_list *addr;
+ struct netdev_hw_addr *ha;
unsigned long flags;
u16 hash[16] = { 0, };
@@ -6351,9 +6385,8 @@ static void niu_set_rx_mode(struct net_device *dev)
if (alt_cnt) {
int index = 0;
- for (addr = dev->uc_list; addr; addr = addr->next) {
- err = niu_set_alt_mac(np, index,
- addr->da_addr);
+ list_for_each_entry(ha, &dev->uc_list, list) {
+ err = niu_set_alt_mac(np, index, ha->addr);
if (err)
printk(KERN_WARNING PFX "%s: Error %d "
"adding alt mac %d\n",
@@ -6745,8 +6778,6 @@ static int niu_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_tx_wake_queue(txq);
}
- dev->trans_start = jiffies;
-
out:
return NETDEV_TX_OK;
@@ -9346,6 +9377,11 @@ static int __devinit niu_get_of_props(struct niu *np)
if (model)
strcpy(np->vpd.model, model);
+ if (of_find_property(dp, "hot-swappable-phy", &prop_len)) {
+ np->flags |= (NIU_FLAGS_10G | NIU_FLAGS_FIBER |
+ NIU_FLAGS_HOTPLUG_PHY);
+ }
+
return 0;
#else
return -EINVAL;
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index d531614a90b..1576ac07216 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -1097,7 +1097,7 @@ again:
if (unlikely(dev->CFG_cache & CFG_LNKSTS)) {
netif_stop_queue(ndev);
if (unlikely(dev->CFG_cache & CFG_LNKSTS))
- return 1;
+ return NETDEV_TX_BUSY;
netif_start_queue(ndev);
}
@@ -1115,7 +1115,7 @@ again:
netif_start_queue(ndev);
goto again;
}
- return 1;
+ return NETDEV_TX_BUSY;
}
if (free_idx == dev->tx_intr_idx) {
@@ -1204,9 +1204,7 @@ again:
if (stopped && (dev->tx_done_idx != tx_done_idx) && start_tx_okay(dev))
netif_start_queue(ndev);
- /* set the transmit start time to catch transmit timeouts */
- ndev->trans_start = jiffies;
- return 0;
+ return NETDEV_TX_OK;
}
static void ns83820_update_stats(struct ns83820 *dev)
@@ -1626,7 +1624,7 @@ static void ns83820_tx_watch(unsigned long data)
);
#endif
- if (time_after(jiffies, ndev->trans_start + 1*HZ) &&
+ if (time_after(jiffies, dev_trans_start(ndev) + 1*HZ) &&
dev->tx_done_idx != dev->tx_free_idx) {
printk(KERN_DEBUG "%s: ns83820_tx_watch: %u %u %d\n",
ndev->name,
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 5eeb5a87b73..c254a7f5b9f 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -24,6 +24,7 @@
#include <linux/dmaengine.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
+#include <linux/of_mdio.h>
#include <linux/etherdevice.h>
#include <asm/dma-mapping.h>
#include <linux/in.h>
@@ -1086,34 +1087,17 @@ static int pasemi_mac_phy_init(struct net_device *dev)
struct pasemi_mac *mac = netdev_priv(dev);
struct device_node *dn, *phy_dn;
struct phy_device *phydev;
- unsigned int phy_id;
- const phandle *ph;
- const unsigned int *prop;
- struct resource r;
- int ret;
dn = pci_device_to_OF_node(mac->pdev);
- ph = of_get_property(dn, "phy-handle", NULL);
- if (!ph)
- return -ENODEV;
- phy_dn = of_find_node_by_phandle(*ph);
-
- prop = of_get_property(phy_dn, "reg", NULL);
- ret = of_address_to_resource(phy_dn->parent, 0, &r);
- if (ret)
- goto err;
-
- phy_id = *prop;
- snprintf(mac->phy_id, sizeof(mac->phy_id), "%x:%02x",
- (int)r.start, phy_id);
-
+ phy_dn = of_parse_phandle(dn, "phy-handle", 0);
of_node_put(phy_dn);
mac->link = 0;
mac->speed = 0;
mac->duplex = -1;
- phydev = phy_connect(dev, mac->phy_id, &pasemi_adjust_link, 0, PHY_INTERFACE_MODE_SGMII);
+ phydev = of_phy_connect(dev, phy_dn, &pasemi_adjust_link, 0,
+ PHY_INTERFACE_MODE_SGMII);
if (IS_ERR(phydev)) {
printk(KERN_ERR "%s: Could not attach to phy\n", dev->name);
@@ -1123,10 +1107,6 @@ static int pasemi_mac_phy_init(struct net_device *dev)
mac->phydev = phydev;
return 0;
-
-err:
- of_node_put(phy_dn);
- return -ENODEV;
}
@@ -1735,12 +1715,25 @@ out:
return ret;
}
+static const struct net_device_ops pasemi_netdev_ops = {
+ .ndo_open = pasemi_mac_open,
+ .ndo_stop = pasemi_mac_close,
+ .ndo_start_xmit = pasemi_mac_start_tx,
+ .ndo_set_multicast_list = pasemi_mac_set_rx_mode,
+ .ndo_set_mac_address = pasemi_mac_set_mac_addr,
+ .ndo_change_mtu = pasemi_mac_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = pasemi_mac_netpoll,
+#endif
+};
+
static int __devinit
pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct net_device *dev;
struct pasemi_mac *mac;
- int err;
+ int err, ret;
err = pci_enable_device(pdev);
if (err)
@@ -1798,12 +1791,13 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
memcpy(dev->dev_addr, mac->mac_addr, sizeof(mac->mac_addr));
- mac->dma_if = mac_to_intf(mac);
- if (mac->dma_if < 0) {
+ ret = mac_to_intf(mac);
+ if (ret < 0) {
dev_err(&mac->pdev->dev, "Can't map DMA interface\n");
err = -ENODEV;
goto out;
}
+ mac->dma_if = ret;
switch (pdev->device) {
case 0xa005:
@@ -1817,19 +1811,11 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto out;
}
- dev->open = pasemi_mac_open;
- dev->stop = pasemi_mac_close;
- dev->hard_start_xmit = pasemi_mac_start_tx;
- dev->set_multicast_list = pasemi_mac_set_rx_mode;
- dev->set_mac_address = pasemi_mac_set_mac_addr;
+ dev->netdev_ops = &pasemi_netdev_ops;
dev->mtu = PE_DEF_MTU;
/* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
mac->bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = pasemi_mac_netpoll;
-#endif
- dev->change_mtu = pasemi_mac_change_mtu;
dev->ethtool_ops = &pasemi_mac_ethtool_ops;
if (err)
diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h
index 1a115ec60b5..e2f4efa8ad4 100644
--- a/drivers/net/pasemi_mac.h
+++ b/drivers/net/pasemi_mac.h
@@ -100,7 +100,6 @@ struct pasemi_mac {
int duplex;
unsigned int msg_enable;
- char phy_id[BUS_ID_SIZE];
};
/* Software status descriptor (ring_info) */
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index c95fd72c3bb..8c1f6988f39 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -728,6 +728,17 @@ err_out:
return rc;
}
+static const struct net_device_ops netdrv_netdev_ops = {
+ .ndo_open = netdrv_open,
+ .ndo_stop = netdrv_close,
+ .ndo_start_xmit = netdrv_start_xmit,
+ .ndo_set_multicast_list = netdrv_set_rx_mode,
+ .ndo_do_ioctl = netdrv_ioctl,
+ .ndo_tx_timeout = netdrv_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
static int __devinit netdrv_init_one (struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -769,13 +780,7 @@ static int __devinit netdrv_init_one (struct pci_dev *pdev,
((u16 *) (dev->dev_addr))[i] =
le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len));
- /* The Rtl8139-specific entries in the device structure. */
- dev->open = netdrv_open;
- dev->hard_start_xmit = netdrv_start_xmit;
- dev->stop = netdrv_close;
- dev->set_multicast_list = netdrv_set_rx_mode;
- dev->do_ioctl = netdrv_ioctl;
- dev->tx_timeout = netdrv_tx_timeout;
+ dev->netdev_ops = &netdrv_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
dev->irq = pdev->irq;
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 8f3872b8985..f35c609ba02 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -1195,7 +1195,7 @@ static int el3_close(struct net_device *dev)
static struct pcmcia_device_id tc574_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0574),
- PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0556, "3CCFEM556.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, tc574_ids);
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index cdf661a6092..ec7cf5ac4f0 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -967,8 +967,8 @@ static struct pcmcia_device_id tc589_ids[] = {
PCMCIA_MFC_DEVICE_PROD_ID1(0, "Motorola MARQUIS", 0xf03e4e77),
PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0589),
PCMCIA_DEVICE_PROD_ID12("Farallon", "ENet", 0x58d93fc4, 0x992c2202),
- PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0035, "3CXEM556.cis"),
- PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x003d, "3CXEM556.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0035, "cis/3CXEM556.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x003d, "cis/3CXEM556.cis"),
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, tc589_ids);
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 15b8fe61695..0e38d80fd25 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -1130,7 +1130,7 @@ static int axnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
outb_p(ENISR_ALL, e8390_base + EN0_IMR);
spin_unlock_irqrestore(&ei_local->page_lock, flags);
dev->stats.tx_errors++;
- return 1;
+ return NETDEV_TX_BUSY;
}
/*
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 81e6660a433..479d5b49437 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -877,7 +877,7 @@ static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (length > ETH_FRAME_LEN) {
printk(KERN_NOTICE "%s: Attempting to send a large packet"
" (%d bytes).\n", dev->name, length);
- return 1;
+ return NETDEV_TX_BUSY;
}
DEBUG(4, "%s: Transmitting a packet of length %lu.\n",
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 48dbb35747d..37e05d3ab89 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -1388,7 +1388,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->stats.tx_aborted_errors++;
printk(KERN_DEBUG "%s: Internal error -- sent packet while busy.\n",
dev->name);
- return 1;
+ return NETDEV_TX_BUSY;
}
smc->saved_skb = skb;
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index a3685c0d22f..ef37d22c7e1 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -1399,7 +1399,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
DEBUG(2 + (okay ? 2 : 0), "%s: avail. tx space=%u%s\n",
dev->name, freespace, okay ? " (okay)":" (not enough)");
if (!okay) { /* not enough space */
- return 1; /* upper layer may decide to requeue this packet */
+ return NETDEV_TX_BUSY; /* upper layer may decide to requeue this packet */
}
/* send the packet */
PutWord(XIRCREG_EDP, (u_short)pktlen);
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 80124fac65f..1c35e1d637a 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -1227,7 +1227,6 @@ static void pcnet32_rx_entry(struct net_device *dev,
dev->stats.rx_dropped++;
return;
}
- skb->dev = dev;
if (!rx_in_place) {
skb_reserve(skb, NET_IP_ALIGN);
skb_put(skb, pkt_len); /* Make room */
@@ -1406,7 +1405,7 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
/* Set interrupt enable. */
lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN);
- mmiowb();
+
spin_unlock_irqrestore(&lp->lock, flags);
}
return work_done;
@@ -2598,7 +2597,7 @@ pcnet32_interrupt(int irq, void *dev_id)
val = lp->a.read_csr(ioaddr, CSR3);
val |= 0x5f00;
lp->a.write_csr(ioaddr, CSR3, val);
- mmiowb();
+
__napi_schedule(&lp->napi);
break;
}
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 7a3ec9d39a9..dd6f54d1b49 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -243,6 +243,7 @@ static int m88e1111_config_init(struct phy_device *phydev)
temp &= ~(MII_M1111_HWCFG_MODE_MASK);
temp |= MII_M1111_HWCFG_MODE_SGMII_NO_CLK;
+ temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO;
err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
if (err < 0)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index b754020cbe7..bd4e8d72dc0 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -113,7 +113,6 @@ int mdiobus_register(struct mii_bus *bus)
bus->reset(bus);
for (i = 0; i < PHY_MAX_ADDR; i++) {
- bus->phy_map[i] = NULL;
if ((bus->phy_mask & (1 << i)) == 0) {
struct phy_device *phydev;
@@ -150,6 +149,7 @@ void mdiobus_unregister(struct mii_bus *bus)
for (i = 0; i < PHY_MAX_ADDR; i++) {
if (bus->phy_map[i])
device_unregister(&bus->phy_map[i]->dev);
+ bus->phy_map[i] = NULL;
}
}
EXPORT_SYMBOL(mdiobus_unregister);
@@ -188,35 +188,12 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
if (IS_ERR(phydev) || phydev == NULL)
return phydev;
- /* There's a PHY at this address
- * We need to set:
- * 1) IRQ
- * 2) bus_id
- * 3) parent
- * 4) bus
- * 5) mii_bus
- * And, we need to register it */
-
- phydev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
-
- phydev->dev.parent = bus->parent;
- phydev->dev.bus = &mdio_bus_type;
- dev_set_name(&phydev->dev, PHY_ID_FMT, bus->id, addr);
-
- phydev->bus = bus;
-
- /* Run all of the fixups for this PHY */
- phy_scan_fixups(phydev);
-
- err = device_register(&phydev->dev);
+ err = phy_device_register(phydev);
if (err) {
- printk(KERN_ERR "phy %d failed to register\n", addr);
phy_device_free(phydev);
- phydev = NULL;
+ return NULL;
}
- bus->phy_map[addr] = phydev;
-
return phydev;
}
EXPORT_SYMBOL(mdiobus_scan);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 0a06e4fd37d..a2ece89622d 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -39,20 +39,21 @@ MODULE_DESCRIPTION("PHY library");
MODULE_AUTHOR("Andy Fleming");
MODULE_LICENSE("GPL");
-static struct phy_driver genphy_driver;
-extern int mdio_bus_init(void);
-extern void mdio_bus_exit(void);
-
void phy_device_free(struct phy_device *phydev)
{
kfree(phydev);
}
+EXPORT_SYMBOL(phy_device_free);
static void phy_device_release(struct device *dev)
{
phy_device_free(to_phy_device(dev));
}
+static struct phy_driver genphy_driver;
+extern int mdio_bus_init(void);
+extern void mdio_bus_exit(void);
+
static LIST_HEAD(phy_fixup_list);
static DEFINE_MUTEX(phy_fixup_lock);
@@ -166,6 +167,10 @@ struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
dev->addr = addr;
dev->phy_id = phy_id;
dev->bus = bus;
+ dev->dev.parent = bus->parent;
+ dev->dev.bus = &mdio_bus_type;
+ dev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
+ dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
dev->state = PHY_DOWN;
@@ -235,6 +240,38 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
return dev;
}
+EXPORT_SYMBOL(get_phy_device);
+
+/**
+ * phy_device_register - Register the phy device on the MDIO bus
+ * @phy_device: phy_device structure to be added to the MDIO bus
+ */
+int phy_device_register(struct phy_device *phydev)
+{
+ int err;
+
+ /* Don't register a phy if one is already registered at this
+ * address */
+ if (phydev->bus->phy_map[phydev->addr])
+ return -EINVAL;
+ phydev->bus->phy_map[phydev->addr] = phydev;
+
+ /* Run all of the fixups for this PHY */
+ phy_scan_fixups(phydev);
+
+ err = device_register(&phydev->dev);
+ if (err) {
+ pr_err("phy %d failed to register\n", phydev->addr);
+ goto out;
+ }
+
+ return 0;
+
+ out:
+ phydev->bus->phy_map[phydev->addr] = NULL;
+ return err;
+}
+EXPORT_SYMBOL(phy_device_register);
/**
* phy_prepare_link - prepares the PHY layer to monitor link status
@@ -255,6 +292,33 @@ void phy_prepare_link(struct phy_device *phydev,
}
/**
+ * phy_connect_direct - connect an ethernet device to a specific phy_device
+ * @dev: the network device to connect
+ * @phydev: the pointer to the phy device
+ * @handler: callback function for state change notifications
+ * @flags: PHY device's dev_flags
+ * @interface: PHY device's interface
+ */
+int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
+ void (*handler)(struct net_device *), u32 flags,
+ phy_interface_t interface)
+{
+ int rc;
+
+ rc = phy_attach_direct(dev, phydev, flags, interface);
+ if (rc)
+ return rc;
+
+ phy_prepare_link(phydev, handler);
+ phy_start_machine(phydev, NULL);
+ if (phydev->irq > 0)
+ phy_start_interrupts(phydev);
+
+ return 0;
+}
+EXPORT_SYMBOL(phy_connect_direct);
+
+/**
* phy_connect - connect an ethernet device to a PHY device
* @dev: the network device to connect
* @bus_id: the id string of the PHY device to connect
@@ -275,18 +339,21 @@ struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
phy_interface_t interface)
{
struct phy_device *phydev;
+ struct device *d;
+ int rc;
- phydev = phy_attach(dev, bus_id, flags, interface);
-
- if (IS_ERR(phydev))
- return phydev;
-
- phy_prepare_link(phydev, handler);
-
- phy_start_machine(phydev, NULL);
+ /* Search the list of PHY devices on the mdio bus for the
+ * PHY with the requested name */
+ d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id);
+ if (!d) {
+ pr_err("PHY %s not found\n", bus_id);
+ return ERR_PTR(-ENODEV);
+ }
+ phydev = to_phy_device(d);
- if (phydev->irq > 0)
- phy_start_interrupts(phydev);
+ rc = phy_connect_direct(dev, phydev, handler, flags, interface);
+ if (rc)
+ return ERR_PTR(rc);
return phydev;
}
@@ -310,9 +377,9 @@ void phy_disconnect(struct phy_device *phydev)
EXPORT_SYMBOL(phy_disconnect);
/**
- * phy_attach - attach a network device to a particular PHY device
+ * phy_attach_direct - attach a network device to a given PHY device pointer
* @dev: network device to attach
- * @bus_id: PHY device to attach
+ * @phydev: Pointer to phy_device to attach
* @flags: PHY device's dev_flags
* @interface: PHY device's interface
*
@@ -323,22 +390,10 @@ EXPORT_SYMBOL(phy_disconnect);
* the attaching device, and given a callback for link status
* change. The phy_device is returned to the attaching driver.
*/
-struct phy_device *phy_attach(struct net_device *dev,
- const char *bus_id, u32 flags, phy_interface_t interface)
+int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
+ u32 flags, phy_interface_t interface)
{
- struct bus_type *bus = &mdio_bus_type;
- struct phy_device *phydev;
- struct device *d;
-
- /* Search the list of PHY devices on the mdio bus for the
- * PHY with the requested name */
- d = bus_find_device_by_name(bus, NULL, bus_id);
- if (d) {
- phydev = to_phy_device(d);
- } else {
- printk(KERN_ERR "%s not found\n", bus_id);
- return ERR_PTR(-ENODEV);
- }
+ struct device *d = &phydev->dev;
/* Assume that if there is no driver, that it doesn't
* exist, and we should use the genphy driver. */
@@ -351,13 +406,12 @@ struct phy_device *phy_attach(struct net_device *dev,
err = device_bind_driver(d);
if (err)
- return ERR_PTR(err);
+ return err;
}
if (phydev->attached_dev) {
- printk(KERN_ERR "%s: %s already attached\n",
- dev->name, bus_id);
- return ERR_PTR(-EBUSY);
+ dev_err(&dev->dev, "PHY already attached\n");
+ return -EBUSY;
}
phydev->attached_dev = dev;
@@ -375,14 +429,49 @@ struct phy_device *phy_attach(struct net_device *dev,
err = phy_scan_fixups(phydev);
if (err < 0)
- return ERR_PTR(err);
+ return err;
err = phydev->drv->config_init(phydev);
if (err < 0)
- return ERR_PTR(err);
+ return err;
}
+ return 0;
+}
+EXPORT_SYMBOL(phy_attach_direct);
+
+/**
+ * phy_attach - attach a network device to a particular PHY device
+ * @dev: network device to attach
+ * @bus_id: Bus ID of PHY device to attach
+ * @flags: PHY device's dev_flags
+ * @interface: PHY device's interface
+ *
+ * Description: Same as phy_attach_direct() except that a PHY bus_id
+ * string is passed instead of a pointer to a struct phy_device.
+ */
+struct phy_device *phy_attach(struct net_device *dev,
+ const char *bus_id, u32 flags, phy_interface_t interface)
+{
+ struct bus_type *bus = &mdio_bus_type;
+ struct phy_device *phydev;
+ struct device *d;
+ int rc;
+
+ /* Search the list of PHY devices on the mdio bus for the
+ * PHY with the requested name */
+ d = bus_find_device_by_name(bus, NULL, bus_id);
+ if (!d) {
+ pr_err("PHY %s not found\n", bus_id);
+ return ERR_PTR(-ENODEV);
+ }
+ phydev = to_phy_device(d);
+
+ rc = phy_attach_direct(dev, phydev, flags, interface);
+ if (rc)
+ return ERR_PTR(rc);
+
return phydev;
}
EXPORT_SYMBOL(phy_attach);
diff --git a/drivers/net/plip.c b/drivers/net/plip.c
index 0be0f0b164f..7a62f781fef 100644
--- a/drivers/net/plip.c
+++ b/drivers/net/plip.c
@@ -955,12 +955,12 @@ plip_tx_packet(struct sk_buff *skb, struct net_device *dev)
struct plip_local *snd = &nl->snd_data;
if (netif_queue_stopped(dev))
- return 1;
+ return NETDEV_TX_BUSY;
/* We may need to grab the bus */
if (!nl->port_owner) {
if (parport_claim(nl->pardev))
- return 1;
+ return NETDEV_TX_BUSY;
nl->port_owner = 1;
}
@@ -969,7 +969,7 @@ plip_tx_packet(struct sk_buff *skb, struct net_device *dev)
if (skb->len > dev->mtu + dev->hard_header_len) {
printk(KERN_WARNING "%s: packet too big, %d.\n", dev->name, (int)skb->len);
netif_start_queue (dev);
- return 1;
+ return NETDEV_TX_BUSY;
}
if (net_debug > 2)
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 8ee91421db1..639d11bc444 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -1054,6 +1054,7 @@ static void ppp_setup(struct net_device *dev)
dev->type = ARPHRD_PPP;
dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
dev->features |= NETIF_F_NETNS_LOCAL;
+ dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
}
/*
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index 5b07dd8e5c0..e7935d09c89 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -433,8 +433,7 @@ static void pppol2tp_recv_dequeue_skb(struct pppol2tp_session *session, struct s
* to the inner packet either
*/
secpath_reset(skb);
- dst_release(skb->dst);
- skb->dst = NULL;
+ skb_dst_drop(skb);
nf_reset(skb);
po = pppox_sk(session_sock);
@@ -976,7 +975,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
/* Calculate UDP checksum if configured to do so */
if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT)
skb->ip_summed = CHECKSUM_NONE;
- else if (!(skb->dst->dev->features & NETIF_F_V4_CSUM)) {
+ else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
skb->ip_summed = CHECKSUM_COMPLETE;
csum = skb_checksum(skb, 0, udp_len, 0);
uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr,
@@ -1172,14 +1171,14 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
nf_reset(skb);
/* Get routing info from the tunnel socket */
- dst_release(skb->dst);
- skb->dst = dst_clone(__sk_dst_get(sk_tun));
+ skb_dst_drop(skb);
+ skb_dst_set(skb, dst_clone(__sk_dst_get(sk_tun)));
pppol2tp_skb_set_owner_w(skb, sk_tun);
/* Calculate UDP checksum if configured to do so */
if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT)
skb->ip_summed = CHECKSUM_NONE;
- else if (!(skb->dst->dev->features & NETIF_F_V4_CSUM)) {
+ else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
skb->ip_summed = CHECKSUM_COMPLETE;
csum = skb_checksum(skb, 0, udp_len, 0);
uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr,
@@ -1238,8 +1237,7 @@ static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel)
struct pppol2tp_session *session;
struct sock *sk;
- if (tunnel == NULL)
- BUG();
+ BUG_ON(tunnel == NULL);
PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
"%s: closing all sessions...\n", tunnel->name);
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index cadc32c94c1..8a823ecc99a 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -2617,7 +2617,6 @@ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev)
&port_regs->CommonRegs.reqQProducerIndex,
qdev->req_producer_index);
- ndev->trans_start = jiffies;
if (netif_msg_tx_queued(qdev))
printk(KERN_DEBUG PFX "%s: tx queued, slot %d, len %d\n",
ndev->name, qdev->req_producer_index, skb->len);
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index fcb159e4df5..156e02e8905 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -27,6 +27,8 @@
"%s: " fmt, __func__, ##args); \
} while (0)
+#define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */
+
#define QLGE_VENDOR_ID 0x1077
#define QLGE_DEVICE_ID_8012 0x8012
#define QLGE_DEVICE_ID_8000 0x8000
@@ -39,7 +41,18 @@
#define NUM_SMALL_BUFFERS 512
#define NUM_LARGE_BUFFERS 512
+#define DB_PAGE_SIZE 4096
+
+/* Calculate the number of (4k) pages required to
+ * contain a buffer queue of the given length.
+ */
+#define MAX_DB_PAGES_PER_BQ(x) \
+ (((x * sizeof(u64)) / DB_PAGE_SIZE) + \
+ (((x * sizeof(u64)) % DB_PAGE_SIZE) ? 1 : 0))
+#define RX_RING_SHADOW_SPACE (sizeof(u64) + \
+ MAX_DB_PAGES_PER_BQ(NUM_SMALL_BUFFERS) * sizeof(u64) + \
+ MAX_DB_PAGES_PER_BQ(NUM_LARGE_BUFFERS) * sizeof(u64))
#define SMALL_BUFFER_SIZE 256
#define LARGE_BUFFER_SIZE PAGE_SIZE
#define MAX_SPLIT_SIZE 1023
@@ -50,7 +63,7 @@
#define MAX_INTER_FRAME_WAIT 10 /* 10 usec max interframe-wait for coalescing */
#define DFLT_INTER_FRAME_WAIT (MAX_INTER_FRAME_WAIT/2)
#define UDELAY_COUNT 3
-#define UDELAY_DELAY 10
+#define UDELAY_DELAY 100
#define TX_DESC_PER_IOCB 8
@@ -63,7 +76,16 @@
#define TX_DESC_PER_OAL 0
#endif
-#define DB_PAGE_SIZE 4096
+/* MPI test register definitions. This register
+ * is used for determining alternate NIC function's
+ * PCI->func number.
+ */
+enum {
+ MPI_TEST_FUNC_PORT_CFG = 0x1002,
+ MPI_TEST_NIC1_FUNC_SHIFT = 1,
+ MPI_TEST_NIC2_FUNC_SHIFT = 5,
+ MPI_TEST_NIC_FUNC_MASK = 0x00000007,
+};
/*
* Processor Address Register (PROC_ADDR) bit definitions.
@@ -1430,7 +1452,10 @@ struct ql_adapter {
/* Hardware information */
u32 chip_rev_id;
+ u32 fw_rev_id;
u32 func; /* PCI function for this adapter */
+ u32 alt_func; /* PCI function for alternate adapter */
+ u32 port; /* Port number this adapter */
spinlock_t adapter_lock;
spinlock_t hw_lock;
@@ -1580,6 +1605,8 @@ void ql_mpi_idc_work(struct work_struct *work);
void ql_mpi_port_cfg_work(struct work_struct *work);
int ql_mb_get_fw_state(struct ql_adapter *qdev);
int ql_cam_route_initialize(struct ql_adapter *qdev);
+int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data);
+int ql_mb_about_fw(struct ql_adapter *qdev);
#if 1
#define QL_ALL_DUMP
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 913b2a5fafc..37c99fe7977 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -293,7 +293,10 @@ static void ql_get_drvinfo(struct net_device *ndev,
struct ql_adapter *qdev = netdev_priv(ndev);
strncpy(drvinfo->driver, qlge_driver_name, 32);
strncpy(drvinfo->version, qlge_driver_version, 32);
- strncpy(drvinfo->fw_version, "N/A", 32);
+ snprintf(drvinfo->fw_version, 32, "v%d.%d.%d",
+ (qdev->fw_rev_id & 0x00ff0000) >> 16,
+ (qdev->fw_rev_id & 0x0000ff00) >> 8,
+ (qdev->fw_rev_id & 0x000000ff));
strncpy(drvinfo->bus_info, pci_name(qdev->pdev), 32);
drvinfo->n_stats = 0;
drvinfo->testinfo_len = 0;
@@ -401,6 +404,7 @@ const struct ethtool_ops qlge_ethtool_ops = {
.get_rx_csum = ql_get_rx_csum,
.set_rx_csum = ql_set_rx_csum,
.get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_tso = ethtool_op_get_tso,
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 1fd5ecb2442..90d1f76c0e8 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -675,11 +675,12 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev)
int status;
__le32 *p = (__le32 *)&qdev->flash;
u32 offset;
+ u8 mac_addr[6];
/* Get flash offset for function and adjust
* for dword access.
*/
- if (!qdev->func)
+ if (!qdev->port)
offset = FUNC0_FLASH_OFFSET / sizeof(u32);
else
offset = FUNC1_FLASH_OFFSET / sizeof(u32);
@@ -705,14 +706,26 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev)
goto exit;
}
- if (!is_valid_ether_addr(qdev->flash.flash_params_8000.mac_addr)) {
+ /* Extract either manufacturer or BOFM modified
+ * MAC address.
+ */
+ if (qdev->flash.flash_params_8000.data_type1 == 2)
+ memcpy(mac_addr,
+ qdev->flash.flash_params_8000.mac_addr1,
+ qdev->ndev->addr_len);
+ else
+ memcpy(mac_addr,
+ qdev->flash.flash_params_8000.mac_addr,
+ qdev->ndev->addr_len);
+
+ if (!is_valid_ether_addr(mac_addr)) {
QPRINTK(qdev, IFUP, ERR, "Invalid MAC address.\n");
status = -EINVAL;
goto exit;
}
memcpy(qdev->ndev->dev_addr,
- qdev->flash.flash_params_8000.mac_addr,
+ mac_addr,
qdev->ndev->addr_len);
exit:
@@ -731,7 +744,7 @@ static int ql_get_8012_flash_params(struct ql_adapter *qdev)
/* Second function's parameters follow the first
* function's.
*/
- if (qdev->func)
+ if (qdev->port)
offset = size;
if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
@@ -837,6 +850,13 @@ exit:
static int ql_8000_port_initialize(struct ql_adapter *qdev)
{
int status;
+ /*
+ * Get MPI firmware version for driver banner
+ * and ethool info.
+ */
+ status = ql_mb_about_fw(qdev);
+ if (status)
+ goto exit;
status = ql_mb_get_fw_state(qdev);
if (status)
goto exit;
@@ -1518,6 +1538,22 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
return;
}
+ /* Frame error, so drop the packet. */
+ if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) {
+ QPRINTK(qdev, DRV, ERR, "Receive error, flags2 = 0x%x\n",
+ ib_mac_rsp->flags2);
+ dev_kfree_skb_any(skb);
+ return;
+ }
+
+ /* The max framesize filter on this chip is set higher than
+ * MTU since FCoE uses 2k frames.
+ */
+ if (skb->len > ndev->mtu + ETH_HLEN) {
+ dev_kfree_skb_any(skb);
+ return;
+ }
+
prefetch(skb->data);
skb->dev = ndev;
if (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) {
@@ -1540,7 +1576,6 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
* csum or frame errors.
*/
if (qdev->rx_csum &&
- !(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) &&
!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
/* TCP frame. */
if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
@@ -2108,7 +2143,6 @@ static int qlge_send(struct sk_buff *skb, struct net_device *ndev)
wmb();
ql_write_db_reg(tx_ring->prod_idx, tx_ring->prod_idx_db_reg);
- ndev->trans_start = jiffies;
QPRINTK(qdev, TX_QUEUED, DEBUG, "tx queued, slot %d, len %d\n",
tx_ring->prod_idx, skb->len);
@@ -2203,7 +2237,7 @@ static int ql_alloc_tx_resources(struct ql_adapter *qdev,
&tx_ring->wq_base_dma);
if ((tx_ring->wq_base == NULL)
- || tx_ring->wq_base_dma & (tx_ring->wq_size - 1)) {
+ || tx_ring->wq_base_dma & WQ_ADDR_ALIGN) {
QPRINTK(qdev, IFUP, ERR, "tx_ring alloc failed.\n");
return -ENOMEM;
}
@@ -2518,14 +2552,16 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
{
struct cqicb *cqicb = &rx_ring->cqicb;
void *shadow_reg = qdev->rx_ring_shadow_reg_area +
- (rx_ring->cq_id * sizeof(u64) * 4);
+ (rx_ring->cq_id * RX_RING_SHADOW_SPACE);
u64 shadow_reg_dma = qdev->rx_ring_shadow_reg_dma +
- (rx_ring->cq_id * sizeof(u64) * 4);
+ (rx_ring->cq_id * RX_RING_SHADOW_SPACE);
void __iomem *doorbell_area =
qdev->doorbell_area + (DB_PAGE_SIZE * (128 + rx_ring->cq_id));
int err = 0;
u16 bq_len;
u64 tmp;
+ __le64 *base_indirect_ptr;
+ int page_entries;
/* Set up the shadow registers for this ring. */
rx_ring->prod_idx_sh_reg = shadow_reg;
@@ -2534,8 +2570,8 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
shadow_reg_dma += sizeof(u64);
rx_ring->lbq_base_indirect = shadow_reg;
rx_ring->lbq_base_indirect_dma = shadow_reg_dma;
- shadow_reg += sizeof(u64);
- shadow_reg_dma += sizeof(u64);
+ shadow_reg += (sizeof(u64) * MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len));
+ shadow_reg_dma += (sizeof(u64) * MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len));
rx_ring->sbq_base_indirect = shadow_reg;
rx_ring->sbq_base_indirect_dma = shadow_reg_dma;
@@ -2572,7 +2608,14 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
if (rx_ring->lbq_len) {
cqicb->flags |= FLAGS_LL; /* Load lbq values */
tmp = (u64)rx_ring->lbq_base_dma;;
- *((__le64 *) rx_ring->lbq_base_indirect) = cpu_to_le64(tmp);
+ base_indirect_ptr = (__le64 *) rx_ring->lbq_base_indirect;
+ page_entries = 0;
+ do {
+ *base_indirect_ptr = cpu_to_le64(tmp);
+ tmp += DB_PAGE_SIZE;
+ base_indirect_ptr++;
+ page_entries++;
+ } while (page_entries < MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len));
cqicb->lbq_addr =
cpu_to_le64(rx_ring->lbq_base_indirect_dma);
bq_len = (rx_ring->lbq_buf_size == 65536) ? 0 :
@@ -2589,7 +2632,14 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
if (rx_ring->sbq_len) {
cqicb->flags |= FLAGS_LS; /* Load sbq values */
tmp = (u64)rx_ring->sbq_base_dma;;
- *((__le64 *) rx_ring->sbq_base_indirect) = cpu_to_le64(tmp);
+ base_indirect_ptr = (__le64 *) rx_ring->sbq_base_indirect;
+ page_entries = 0;
+ do {
+ *base_indirect_ptr = cpu_to_le64(tmp);
+ tmp += DB_PAGE_SIZE;
+ base_indirect_ptr++;
+ page_entries++;
+ } while (page_entries < MAX_DB_PAGES_PER_BQ(rx_ring->sbq_len));
cqicb->sbq_addr =
cpu_to_le64(rx_ring->sbq_base_indirect_dma);
cqicb->sbq_buf_size =
@@ -3186,9 +3236,10 @@ static void ql_display_dev_info(struct net_device *ndev)
struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
QPRINTK(qdev, PROBE, INFO,
- "Function #%d, NIC Roll %d, NIC Rev = %d, "
+ "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, "
"XG Roll = %d, XG Rev = %d.\n",
qdev->func,
+ qdev->port,
qdev->chip_rev_id & 0x0000000f,
qdev->chip_rev_id >> 4 & 0x0000000f,
qdev->chip_rev_id >> 8 & 0x0000000f,
@@ -3264,7 +3315,6 @@ static int ql_adapter_up(struct ql_adapter *qdev)
err = ql_adapter_initialize(qdev);
if (err) {
QPRINTK(qdev, IFUP, INFO, "Unable to initialize adapter.\n");
- spin_unlock(&qdev->hw_lock);
goto err_init;
}
set_bit(QL_ADAPTER_UP, &qdev->flags);
@@ -3361,7 +3411,6 @@ static int ql_configure_rings(struct ql_adapter *qdev)
* completion handler rx_rings.
*/
qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count + 1;
- netif_set_gso_max_size(qdev->ndev, 65536);
for (i = 0; i < qdev->tx_ring_count; i++) {
tx_ring = &qdev->tx_ring[i];
@@ -3644,12 +3693,53 @@ static struct nic_operations qla8000_nic_ops = {
.port_initialize = ql_8000_port_initialize,
};
+/* Find the pcie function number for the other NIC
+ * on this chip. Since both NIC functions share a
+ * common firmware we have the lowest enabled function
+ * do any common work. Examples would be resetting
+ * after a fatal firmware error, or doing a firmware
+ * coredump.
+ */
+static int ql_get_alt_pcie_func(struct ql_adapter *qdev)
+{
+ int status = 0;
+ u32 temp;
+ u32 nic_func1, nic_func2;
+
+ status = ql_read_mpi_reg(qdev, MPI_TEST_FUNC_PORT_CFG,
+ &temp);
+ if (status)
+ return status;
+
+ nic_func1 = ((temp >> MPI_TEST_NIC1_FUNC_SHIFT) &
+ MPI_TEST_NIC_FUNC_MASK);
+ nic_func2 = ((temp >> MPI_TEST_NIC2_FUNC_SHIFT) &
+ MPI_TEST_NIC_FUNC_MASK);
+
+ if (qdev->func == nic_func1)
+ qdev->alt_func = nic_func2;
+ else if (qdev->func == nic_func2)
+ qdev->alt_func = nic_func1;
+ else
+ status = -EIO;
+
+ return status;
+}
-static void ql_get_board_info(struct ql_adapter *qdev)
+static int ql_get_board_info(struct ql_adapter *qdev)
{
+ int status;
qdev->func =
(ql_read32(qdev, STS) & STS_FUNC_ID_MASK) >> STS_FUNC_ID_SHIFT;
- if (qdev->func) {
+ if (qdev->func > 3)
+ return -EIO;
+
+ status = ql_get_alt_pcie_func(qdev);
+ if (status)
+ return status;
+
+ qdev->port = (qdev->func < qdev->alt_func) ? 0 : 1;
+ if (qdev->port) {
qdev->xg_sem_mask = SEM_XGMAC1_MASK;
qdev->port_link_up = STS_PL1;
qdev->port_init = STS_PI1;
@@ -3668,6 +3758,7 @@ static void ql_get_board_info(struct ql_adapter *qdev)
qdev->nic_ops = &qla8012_nic_ops;
else if (qdev->device_id == QLGE_DEVICE_ID_8000)
qdev->nic_ops = &qla8000_nic_ops;
+ return status;
}
static void ql_release_all(struct pci_dev *pdev)
@@ -3762,7 +3853,12 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
qdev->ndev = ndev;
qdev->pdev = pdev;
- ql_get_board_info(qdev);
+ err = ql_get_board_info(qdev);
+ if (err) {
+ dev_err(&pdev->dev, "Register access failed.\n");
+ err = -EIO;
+ goto err_out;
+ }
qdev->msg_enable = netif_msg_init(debug, default_msg);
spin_lock_init(&qdev->hw_lock);
spin_lock_init(&qdev->stats_lock);
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index ac9493f6c1a..71afbf8b9c5 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -90,14 +90,14 @@ static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
*/
static int ql_wait_mbx_cmd_cmplt(struct ql_adapter *qdev)
{
- int count = 50; /* TODO: arbitrary for now. */
+ int count = 100;
u32 value;
do {
value = ql_read32(qdev, STS);
if (value & STS_PI)
return 0;
- udelay(UDELAY_DELAY); /* 10us */
+ mdelay(UDELAY_DELAY); /* 100ms */
} while (--count);
return -ETIMEDOUT;
}
@@ -453,6 +453,13 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
}
end:
ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+ /* Restore the original mailbox count to
+ * what the caller asked for. This can get
+ * changed when a mailbox command is waiting
+ * for a response and an AEN arrives and
+ * is handled.
+ * */
+ mbcp->out_count = orig_count;
return status;
}
@@ -540,6 +547,40 @@ end:
return status;
}
+
+/* Get MPI firmware version. This will be used for
+ * driver banner and for ethtool info.
+ * Returns zero on success.
+ */
+int ql_mb_about_fw(struct ql_adapter *qdev)
+{
+ struct mbox_params mbc;
+ struct mbox_params *mbcp = &mbc;
+ int status = 0;
+
+ memset(mbcp, 0, sizeof(struct mbox_params));
+
+ mbcp->in_count = 1;
+ mbcp->out_count = 3;
+
+ mbcp->mbox_in[0] = MB_CMD_ABOUT_FW;
+
+ status = ql_mailbox_command(qdev, mbcp);
+ if (status)
+ return status;
+
+ if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed about firmware command\n");
+ status = -EIO;
+ }
+
+ /* Store the firmware version */
+ qdev->fw_rev_id = mbcp->mbox_out[1];
+
+ return status;
+}
+
/* Get functional state for MPI firmware.
* Returns zero on success.
*/
@@ -754,7 +795,6 @@ void ql_mpi_port_cfg_work(struct work_struct *work)
{
struct ql_adapter *qdev =
container_of(work, struct ql_adapter, mpi_port_cfg_work.work);
- struct net_device *ndev = qdev->ndev;
int status;
status = ql_mb_get_port_cfg(qdev);
@@ -764,9 +804,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work)
goto err;
}
- if (ndev->mtu <= 2500)
- goto end;
- else if (qdev->link_config & CFG_JUMBO_FRAME_SIZE &&
+ if (qdev->link_config & CFG_JUMBO_FRAME_SIZE &&
qdev->max_frame_size ==
CFG_DEFAULT_MAX_FRAME_SIZE)
goto end;
@@ -831,13 +869,19 @@ void ql_mpi_work(struct work_struct *work)
container_of(work, struct ql_adapter, mpi_work.work);
struct mbox_params mbc;
struct mbox_params *mbcp = &mbc;
+ int err = 0;
mutex_lock(&qdev->mpi_mutex);
while (ql_read32(qdev, STS) & STS_PI) {
memset(mbcp, 0, sizeof(struct mbox_params));
mbcp->out_count = 1;
- ql_mpi_handler(qdev, mbcp);
+ /* Don't continue if an async event
+ * did not complete properly.
+ */
+ err = ql_mpi_handler(qdev, mbcp);
+ if (err)
+ break;
}
mutex_unlock(&qdev->mpi_mutex);
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 6f97b47d74a..ed63d23a645 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -49,8 +49,8 @@
#include <asm/processor.h>
#define DRV_NAME "r6040"
-#define DRV_VERSION "0.22"
-#define DRV_RELDATE "25Mar2009"
+#define DRV_VERSION "0.23"
+#define DRV_RELDATE "05May2009"
/* PHY CHIP Address */
#define PHY1_ADDR 1 /* For MAC1 */
@@ -401,6 +401,9 @@ static void r6040_init_mac_regs(struct net_device *dev)
* we may got called by r6040_tx_timeout which has left
* some unsent tx buffers */
iowrite16(0x01, ioaddr + MTPR);
+
+ /* Check media */
+ mii_check_media(&lp->mii_if, 1, 1);
}
static void r6040_tx_timeout(struct net_device *dev)
@@ -528,6 +531,8 @@ static int r6040_phy_mode_chk(struct net_device *dev)
phy_dat = 0x0000;
}
+ mii_check_media(&lp->mii_if, 0, 1);
+
return phy_dat;
};
@@ -742,6 +747,14 @@ static int r6040_up(struct net_device *dev)
struct r6040_private *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
int ret;
+ u16 val;
+
+ /* Check presence of a second PHY */
+ val = r6040_phy_read(ioaddr, lp->phy_addr, 2);
+ if (val == 0xFFFF) {
+ printk(KERN_ERR DRV_NAME " no second PHY attached\n");
+ return -EIO;
+ }
/* Initialise and alloc RX/TX buffers */
r6040_init_txbufs(dev);
@@ -802,7 +815,6 @@ static void r6040_timer(unsigned long data)
lp->phy_mode = phy_mode;
lp->mcr0 = (lp->mcr0 & 0x7fff) | phy_mode;
iowrite16(lp->mcr0, ioaddr);
- printk(KERN_INFO "Link Change %x \n", ioread16(ioaddr));
}
/* Timer active again */
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 3b19e0ce290..35196faa084 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -93,6 +93,7 @@ static const int multicast_filter_limit = 32;
#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg)))
enum mac_version {
+ RTL_GIGA_MAC_NONE = 0x00,
RTL_GIGA_MAC_VER_01 = 0x01, // 8169
RTL_GIGA_MAC_VER_02 = 0x02, // 8169S
RTL_GIGA_MAC_VER_03 = 0x03, // 8110S
@@ -478,7 +479,6 @@ struct rtl8169_private {
u16 intr_event;
u16 napi_event;
u16 intr_mask;
- int phy_auto_nego_reg;
int phy_1000_ctrl_reg;
#ifdef CONFIG_R8169_VLAN
struct vlan_group *vlgrp;
@@ -843,76 +843,81 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
- int auto_nego, giga_ctrl;
-
- auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
- auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL |
- ADVERTISE_100HALF | ADVERTISE_100FULL);
- giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
- giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
+ int giga_ctrl, bmcr;
if (autoneg == AUTONEG_ENABLE) {
+ int auto_nego;
+
+ auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL |
ADVERTISE_100HALF | ADVERTISE_100FULL);
- giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
- } else {
- if (speed == SPEED_10)
- auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL;
- else if (speed == SPEED_100)
- auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL;
- else if (speed == SPEED_1000)
- giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
-
- if (duplex == DUPLEX_HALF)
- auto_nego &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL);
-
- if (duplex == DUPLEX_FULL)
- auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_100HALF);
+ auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
- /* This tweak comes straight from Realtek's driver. */
- if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) &&
- ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_16))) {
- auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA;
- }
- }
+ giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
+ giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
- /* The 8100e/8101e/8102e do Fast Ethernet only. */
- if ((tp->mac_version == RTL_GIGA_MAC_VER_07) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_08) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_09) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_10) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_15) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
- if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) &&
- netif_msg_link(tp)) {
+ /* The 8100e/8101e/8102e do Fast Ethernet only. */
+ if ((tp->mac_version != RTL_GIGA_MAC_VER_07) &&
+ (tp->mac_version != RTL_GIGA_MAC_VER_08) &&
+ (tp->mac_version != RTL_GIGA_MAC_VER_09) &&
+ (tp->mac_version != RTL_GIGA_MAC_VER_10) &&
+ (tp->mac_version != RTL_GIGA_MAC_VER_13) &&
+ (tp->mac_version != RTL_GIGA_MAC_VER_14) &&
+ (tp->mac_version != RTL_GIGA_MAC_VER_15) &&
+ (tp->mac_version != RTL_GIGA_MAC_VER_16)) {
+ giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
+ } else if (netif_msg_link(tp)) {
printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n",
dev->name);
}
- giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
- }
- auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+ bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
+
+ if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
+ (tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
+ /*
+ * Wake up the PHY.
+ * Vendor specific (0x1f) and reserved (0x0e) MII
+ * registers.
+ */
+ mdio_write(ioaddr, 0x1f, 0x0000);
+ mdio_write(ioaddr, 0x0e, 0x0000);
+ }
+
+ mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
+ mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
+ } else {
+ giga_ctrl = 0;
+
+ if (speed == SPEED_10)
+ bmcr = 0;
+ else if (speed == SPEED_100)
+ bmcr = BMCR_SPEED100;
+ else
+ return -EINVAL;
+
+ if (duplex == DUPLEX_FULL)
+ bmcr |= BMCR_FULLDPLX;
- if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
- (tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
- /*
- * Wake up the PHY.
- * Vendor specific (0x1f) and reserved (0x0e) MII registers.
- */
mdio_write(ioaddr, 0x1f, 0x0000);
- mdio_write(ioaddr, 0x0e, 0x0000);
}
- tp->phy_auto_nego_reg = auto_nego;
tp->phy_1000_ctrl_reg = giga_ctrl;
- mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
- mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
- mdio_write(ioaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
+ mdio_write(ioaddr, MII_BMCR, bmcr);
+
+ if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
+ if ((speed == SPEED_100) && (autoneg != AUTONEG_ENABLE)) {
+ mdio_write(ioaddr, 0x17, 0x2138);
+ mdio_write(ioaddr, 0x0e, 0x0260);
+ } else {
+ mdio_write(ioaddr, 0x17, 0x2108);
+ mdio_write(ioaddr, 0x0e, 0x0000);
+ }
+ }
+
return 0;
}
@@ -1295,7 +1300,8 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
{ 0xfc800000, 0x00800000, RTL_GIGA_MAC_VER_02 },
{ 0xfc800000, 0x00000000, RTL_GIGA_MAC_VER_01 },
- { 0x00000000, 0x00000000, RTL_GIGA_MAC_VER_01 } /* Catch-all */
+ /* Catch-all */
+ { 0x00000000, 0x00000000, RTL_GIGA_MAC_NONE }
}, *p = mac_info;
u32 reg;
@@ -1303,12 +1309,6 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
while ((reg & p->mask) != p->val)
p++;
tp->mac_version = p->mac_version;
-
- if (p->mask == 0x00000000) {
- struct pci_dev *pdev = tp->pci_dev;
-
- dev_info(&pdev->dev, "unknown MAC (%08x)\n", reg);
- }
}
static void rtl8169_print_mac_version(struct rtl8169_private *tp)
@@ -1884,6 +1884,7 @@ static const struct rtl_cfg_info {
u16 intr_event;
u16 napi_event;
unsigned features;
+ u8 default_ver;
} rtl_cfg_infos [] = {
[RTL_CFG_0] = {
.hw_start = rtl_hw_start_8169,
@@ -1892,7 +1893,8 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow |
RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
.napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
- .features = RTL_FEATURE_GMII
+ .features = RTL_FEATURE_GMII,
+ .default_ver = RTL_GIGA_MAC_VER_01,
},
[RTL_CFG_1] = {
.hw_start = rtl_hw_start_8168,
@@ -1901,7 +1903,8 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow |
TxErr | TxOK | RxOK | RxErr,
.napi_event = TxErr | TxOK | RxOK | RxOverflow,
- .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI
+ .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI,
+ .default_ver = RTL_GIGA_MAC_VER_11,
},
[RTL_CFG_2] = {
.hw_start = rtl_hw_start_8101,
@@ -1910,7 +1913,8 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout |
RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
.napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
- .features = RTL_FEATURE_MSI
+ .features = RTL_FEATURE_MSI,
+ .default_ver = RTL_GIGA_MAC_VER_13,
}
};
@@ -2091,6 +2095,15 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Identify chip attached to board */
rtl8169_get_mac_version(tp, ioaddr);
+ /* Use appropriate default if unknown */
+ if (tp->mac_version == RTL_GIGA_MAC_NONE) {
+ if (netif_msg_probe(tp)) {
+ dev_notice(&pdev->dev,
+ "unknown MAC, using family default\n");
+ }
+ tp->mac_version = cfg->default_ver;
+ }
+
rtl8169_print_mac_version(tp);
for (i = 0; i < ARRAY_SIZE(rtl_chip_info); i++) {
@@ -2098,13 +2111,9 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
if (i == ARRAY_SIZE(rtl_chip_info)) {
- /* Unknown chip: assume array element #0, original RTL-8169 */
- if (netif_msg_probe(tp)) {
- dev_printk(KERN_DEBUG, &pdev->dev,
- "unknown chip version, assuming %s\n",
- rtl_chip_info[0].name);
- }
- i = 0;
+ dev_err(&pdev->dev,
+ "driver bug, MAC version not found in rtl_chip_info\n");
+ goto err_out_msi_5;
}
tp->chipset = i;
@@ -3269,8 +3278,6 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
txd->opts1 = cpu_to_le32(status);
- dev->trans_start = jiffies;
-
tp->cur_tx += frags + 1;
smp_wmb();
@@ -3371,7 +3378,7 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry);
if (status & LastFrag) {
- dev_kfree_skb_irq(tx_skb->skb);
+ dev_kfree_skb(tx_skb->skb);
tx_skb->skb = NULL;
}
dirty_tx++;
@@ -3802,16 +3809,13 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
return &dev->stats;
}
-#ifdef CONFIG_PM
-
-static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
+static void rtl8169_net_suspend(struct net_device *dev)
{
- struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
if (!netif_running(dev))
- goto out_pci_suspend;
+ return;
netif_device_detach(dev);
netif_stop_queue(dev);
@@ -3823,24 +3827,25 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
rtl8169_rx_missed(dev, ioaddr);
spin_unlock_irq(&tp->lock);
+}
-out_pci_suspend:
- pci_save_state(pdev);
- pci_enable_wake(pdev, pci_choose_state(pdev, state),
- (tp->features & RTL_FEATURE_WOL) ? 1 : 0);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
+#ifdef CONFIG_PM
+
+static int rtl8169_suspend(struct device *device)
+{
+ struct pci_dev *pdev = to_pci_dev(device);
+ struct net_device *dev = pci_get_drvdata(pdev);
+
+ rtl8169_net_suspend(dev);
return 0;
}
-static int rtl8169_resume(struct pci_dev *pdev)
+static int rtl8169_resume(struct device *device)
{
+ struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- pci_enable_wake(pdev, PCI_D0, 0);
-
if (!netif_running(dev))
goto out;
@@ -3851,23 +3856,42 @@ out:
return 0;
}
+static struct dev_pm_ops rtl8169_pm_ops = {
+ .suspend = rtl8169_suspend,
+ .resume = rtl8169_resume,
+ .freeze = rtl8169_suspend,
+ .thaw = rtl8169_resume,
+ .poweroff = rtl8169_suspend,
+ .restore = rtl8169_resume,
+};
+
+#define RTL8169_PM_OPS (&rtl8169_pm_ops)
+
+#else /* !CONFIG_PM */
+
+#define RTL8169_PM_OPS NULL
+
+#endif /* !CONFIG_PM */
+
static void rtl_shutdown(struct pci_dev *pdev)
{
- rtl8169_suspend(pdev, PMSG_SUSPEND);
-}
+ struct net_device *dev = pci_get_drvdata(pdev);
+
+ rtl8169_net_suspend(dev);
-#endif /* CONFIG_PM */
+ if (system_state == SYSTEM_POWER_OFF) {
+ pci_wake_from_d3(pdev, true);
+ pci_set_power_state(pdev, PCI_D3hot);
+ }
+}
static struct pci_driver rtl8169_pci_driver = {
.name = MODULENAME,
.id_table = rtl8169_pci_tbl,
.probe = rtl8169_init_one,
.remove = __devexit_p(rtl8169_remove_one),
-#ifdef CONFIG_PM
- .suspend = rtl8169_suspend,
- .resume = rtl8169_resume,
.shutdown = rtl_shutdown,
-#endif
+ .driver.pm = RTL8169_PM_OPS,
};
static int __init rtl8169_init_module(void)
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index ec59e29807a..8702e7acdee 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -428,6 +428,15 @@ static const struct ethtool_ops rionet_ethtool_ops = {
.get_link = ethtool_op_get_link,
};
+static const struct net_device_ops rionet_netdev_ops = {
+ .ndo_open = rionet_open,
+ .ndo_stop = rionet_close,
+ .ndo_start_xmit = rionet_start_xmit,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
static int rionet_setup_netdev(struct rio_mport *mport)
{
int rc = 0;
@@ -466,10 +475,7 @@ static int rionet_setup_netdev(struct rio_mport *mport)
ndev->dev_addr[4] = device_id >> 8;
ndev->dev_addr[5] = device_id & 0xff;
- /* Fill in the driver function table */
- ndev->open = &rionet_open;
- ndev->hard_start_xmit = &rionet_start_xmit;
- ndev->stop = &rionet_close;
+ ndev->netdev_ops = &rionet_netdev_ops;
ndev->mtu = RIO_MAX_MSG_SIZE - 14;
ndev->features = NETIF_F_LLTX;
SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops);
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index d890829a9ac..81dbcbb910f 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -1425,7 +1425,7 @@ static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (!(new_skb = dev_alloc_skb(len + 8))) {
dev_kfree_skb(skb);
netif_wake_queue(dev);
- return -EBUSY;
+ return NETDEV_TX_OK;
}
skb_reserve(new_skb, 8);
skb_put(new_skb, len);
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h
index f8274f8941e..416669fd68c 100644
--- a/drivers/net/s2io-regs.h
+++ b/drivers/net/s2io-regs.h
@@ -271,11 +271,6 @@ struct XENA_dev_config {
u64 mdio_control;
#define MDIO_MMD_INDX_ADDR(val) vBIT(val, 0, 16)
#define MDIO_MMD_DEV_ADDR(val) vBIT(val, 19, 5)
-#define MDIO_MMD_PMA_DEV_ADDR 0x1
-#define MDIO_MMD_PMD_DEV_ADDR 0x1
-#define MDIO_MMD_WIS_DEV_ADDR 0x2
-#define MDIO_MMD_PCS_DEV_ADDR 0x3
-#define MDIO_MMD_PHYXS_DEV_ADDR 0x4
#define MDIO_MMS_PRT_ADDR(val) vBIT(val, 27, 5)
#define MDIO_CTRL_START_TRANS(val) vBIT(val, 56, 4)
#define MDIO_OP(val) vBIT(val, 60, 2)
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 1a4979f27fb..458daa06ed4 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -63,6 +63,7 @@
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/mdio.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/delay.h>
@@ -1763,7 +1764,7 @@ static int init_nic(struct s2io_nic *nic)
* by then we return error.
*/
time = 0;
- while (TRUE) {
+ while (true) {
val64 = readq(&bar0->rti_command_mem);
if (!(val64 & RTI_CMD_MEM_STROBE_NEW_CMD))
break;
@@ -2136,7 +2137,7 @@ static int verify_pcc_quiescent(struct s2io_nic *sp, int flag)
herc = (sp->device_type == XFRAME_II_DEVICE);
- if (flag == FALSE) {
+ if (flag == false) {
if ((!herc && (sp->pdev->revision >= 4)) || herc) {
if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE))
ret = 1;
@@ -3328,9 +3329,9 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
struct stat_block *stat_info = sp->mac_control.stats_info;
/* Check the communication with the MDIO slave */
- addr = 0x0000;
+ addr = MDIO_CTRL1;
val64 = 0x0;
- val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev);
+ val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
if((val64 == 0xFFFF) || (val64 == 0x0000))
{
DBG_PRINT(ERR_DBG, "ERR: MDIO slave access failed - "
@@ -3338,24 +3339,24 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
return;
}
- /* Check for the expecte value of 2040 at PMA address 0x0000 */
- if(val64 != 0x2040)
+ /* Check for the expected value of control reg 1 */
+ if(val64 != MDIO_CTRL1_SPEED10G)
{
DBG_PRINT(ERR_DBG, "Incorrect value at PMA address 0x0000 - ");
- DBG_PRINT(ERR_DBG, "Returned: %llx- Expected: 0x2040\n",
- (unsigned long long)val64);
+ DBG_PRINT(ERR_DBG, "Returned: %llx- Expected: 0x%x\n",
+ (unsigned long long)val64, MDIO_CTRL1_SPEED10G);
return;
}
/* Loading the DOM register to MDIO register */
addr = 0xA100;
- s2io_mdio_write(MDIO_MMD_PMA_DEV_ADDR, addr, val16, dev);
- val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev);
+ s2io_mdio_write(MDIO_MMD_PMAPMD, addr, val16, dev);
+ val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
/* Reading the Alarm flags */
addr = 0xA070;
val64 = 0x0;
- val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev);
+ val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
flag = CHECKBIT(val64, 0x7);
type = 1;
@@ -3387,7 +3388,7 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
/* Reading the Warning flags */
addr = 0xA074;
val64 = 0x0;
- val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev);
+ val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
if(CHECKBIT(val64, 0x7))
stat_info->xpak_stat.warn_transceiver_temp_high++;
@@ -3586,7 +3587,7 @@ static void s2io_reset(struct s2io_nic * sp)
writeq(val64, &bar0->pcc_err_reg);
}
- sp->device_enabled_once = FALSE;
+ sp->device_enabled_once = false;
}
/**
@@ -4298,7 +4299,6 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
s2io_stop_tx_queue(sp, fifo->fifo_no);
}
mac_control->stats_info->sw_stat.mem_allocated += skb->truesize;
- dev->trans_start = jiffies;
spin_unlock_irqrestore(&fifo->tx_lock, flags);
if (sp->config.intr_type == MSI_X)
@@ -5572,10 +5572,10 @@ static void s2io_ethtool_getpause_data(struct net_device *dev,
val64 = readq(&bar0->rmac_pause_cfg);
if (val64 & RMAC_PAUSE_GEN_ENABLE)
- ep->tx_pause = TRUE;
+ ep->tx_pause = true;
if (val64 & RMAC_PAUSE_RX_ENABLE)
- ep->rx_pause = TRUE;
- ep->autoneg = FALSE;
+ ep->rx_pause = true;
+ ep->autoneg = false;
}
/**
@@ -6806,7 +6806,7 @@ static void s2io_set_link(struct work_struct *work)
val64 |= ADAPTER_LED_ON;
writeq(val64, &bar0->adapter_control);
}
- nic->device_enabled_once = TRUE;
+ nic->device_enabled_once = true;
} else {
DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name);
DBG_PRINT(ERR_DBG, "device is not Quiescent\n");
@@ -7754,7 +7754,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
struct s2io_nic *sp;
struct net_device *dev;
int i, j, ret;
- int dma_flag = FALSE;
+ int dma_flag = false;
u32 mac_up, mac_down;
u64 val64 = 0, tmp64 = 0;
struct XENA_dev_config __iomem *bar0 = NULL;
@@ -7777,7 +7777,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n");
- dma_flag = TRUE;
+ dma_flag = true;
if (pci_set_consistent_dma_mask
(pdev, DMA_BIT_MASK(64))) {
DBG_PRINT(ERR_DBG,
@@ -7818,7 +7818,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
sp->dev = dev;
sp->pdev = pdev;
sp->high_dma_flag = dma_flag;
- sp->device_enabled_once = FALSE;
+ sp->device_enabled_once = false;
if (rx_ring_mode == 1)
sp->rxd_mode = RXD_MODE_1;
if (rx_ring_mode == 2)
@@ -7964,7 +7964,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
- if (sp->high_dma_flag == TRUE)
+ if (sp->high_dma_flag == true)
dev->features |= NETIF_F_HIGHDMA;
dev->features |= NETIF_F_TSO;
dev->features |= NETIF_F_TSO6;
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 55cb943f23f..d5c5be6c07b 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -18,15 +18,6 @@
#define vBIT(val, loc, sz) (((u64)val) << (64-loc-sz))
#define INV(d) ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff)
-#ifndef BOOL
-#define BOOL int
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-
#undef SUCCESS
#define SUCCESS 0
#define FAILURE -1
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index ce7551e17ba..d8c9cf1b901 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -2084,7 +2084,7 @@ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
spin_unlock_irqrestore(&sc->sbm_lock, flags);
- return 1;
+ return NETDEV_TX_BUSY;
}
dev->trans_start = jiffies;
@@ -2271,6 +2271,21 @@ static int sb1250_change_mtu(struct net_device *_dev, int new_mtu)
return 0;
}
+static const struct net_device_ops sbmac_netdev_ops = {
+ .ndo_open = sbmac_open,
+ .ndo_stop = sbmac_close,
+ .ndo_start_xmit = sbmac_start_tx,
+ .ndo_set_multicast_list = sbmac_set_rx_mode,
+ .ndo_tx_timeout = sbmac_tx_timeout,
+ .ndo_do_ioctl = sbmac_mii_ioctl,
+ .ndo_change_mtu = sb1250_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = sbmac_netpoll,
+#endif
+};
+
/**********************************************************************
* SBMAC_INIT(dev)
*
@@ -2285,7 +2300,7 @@ static int sb1250_change_mtu(struct net_device *_dev, int new_mtu)
static int sbmac_init(struct platform_device *pldev, long long base)
{
- struct net_device *dev = pldev->dev.driver_data;
+ struct net_device *dev = dev_get_drvdata(&pldev->dev);
int idx = pldev->id;
struct sbmac_softc *sc = netdev_priv(dev);
unsigned char *eaddr;
@@ -2327,21 +2342,11 @@ static int sbmac_init(struct platform_device *pldev, long long base)
spin_lock_init(&(sc->sbm_lock));
- dev->open = sbmac_open;
- dev->hard_start_xmit = sbmac_start_tx;
- dev->stop = sbmac_close;
- dev->set_multicast_list = sbmac_set_rx_mode;
- dev->do_ioctl = sbmac_mii_ioctl;
- dev->tx_timeout = sbmac_tx_timeout;
- dev->watchdog_timeo = TX_TIMEOUT;
+ dev->netdev_ops = &sbmac_netdev_ops;
+ dev->watchdog_timeo = TX_TIMEOUT;
netif_napi_add(dev, &sc->napi, sbmac_poll, 16);
- dev->change_mtu = sb1250_change_mtu;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = sbmac_netpoll;
-#endif
-
dev->irq = UNIT_INT(idx);
/* This is needed for PASS2 for Rx H/W checksum feature */
@@ -2726,7 +2731,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
goto out_unmap;
}
- pldev->dev.driver_data = dev;
+ dev_set_drvdata(&pldev->dev, dev);
SET_NETDEV_DEV(dev, &pldev->dev);
sc = netdev_priv(dev);
@@ -2751,7 +2756,7 @@ out_out:
static int __exit sbmac_remove(struct platform_device *pldev)
{
- struct net_device *dev = pldev->dev.driver_data;
+ struct net_device *dev = dev_get_drvdata(&pldev->dev);
struct sbmac_softc *sc = netdev_priv(dev);
unregister_netdev(dev);
diff --git a/drivers/net/sfc/Kconfig b/drivers/net/sfc/Kconfig
index 12a82966b57..260aafaac23 100644
--- a/drivers/net/sfc/Kconfig
+++ b/drivers/net/sfc/Kconfig
@@ -1,7 +1,7 @@
config SFC
tristate "Solarflare Solarstorm SFC4000 support"
depends on PCI && INET
- select MII
+ select MDIO
select CRC32
select I2C
select I2C_ALGOBIT
diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c
index 5182ac5a103..4a4c74c891b 100644
--- a/drivers/net/sfc/boards.c
+++ b/drivers/net/sfc/boards.c
@@ -172,7 +172,6 @@ static const u8 sfe4002_lm87_regs[] = {
static struct i2c_board_info sfe4002_hwmon_info = {
I2C_BOARD_INFO("lm87", 0x2e),
.platform_data = &sfe4002_lm87_channel,
- .irq = -1,
};
/****************************************************************************/
@@ -247,7 +246,6 @@ static const u8 sfn4112f_lm87_regs[] = {
static struct i2c_board_info sfn4112f_hwmon_info = {
I2C_BOARD_INFO("lm87", 0x2e),
.platform_data = &sfn4112f_lm87_channel,
- .irq = -1,
};
#define SFN4112F_ACT_LED 0
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 7269a426051..343e8da1fa3 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -50,16 +50,6 @@ static struct workqueue_struct *reset_workqueue;
*************************************************************************/
/*
- * Enable large receive offload (LRO) aka soft segment reassembly (SSR)
- *
- * This sets the default for new devices. It can be controlled later
- * using ethtool.
- */
-static int lro = true;
-module_param(lro, int, 0644);
-MODULE_PARM_DESC(lro, "Large receive offload acceleration");
-
-/*
* Use separate channels for TX and RX events
*
* Set this to 1 to use separate channels for TX and RX. It allows us
@@ -894,9 +884,9 @@ static int efx_wanted_rx_queues(void)
int count;
int cpu;
- if (!alloc_cpumask_var(&core_mask, GFP_KERNEL)) {
+ if (unlikely(!alloc_cpumask_var(&core_mask, GFP_KERNEL))) {
printk(KERN_WARNING
- "efx.c: allocation failure, irq balancing hobbled\n");
+ "sfc: RSS disabled due to allocation failure\n");
return 1;
}
@@ -1300,10 +1290,16 @@ out_requeue:
static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
{
struct efx_nic *efx = netdev_priv(net_dev);
+ struct mii_ioctl_data *data = if_mii(ifr);
EFX_ASSERT_RESET_SERIALISED(efx);
- return generic_mii_ioctl(&efx->mii, if_mii(ifr), cmd, NULL);
+ /* Convert phy_id from older PRTAD/DEVAD format */
+ if ((cmd == SIOCGMIIREG || cmd == SIOCSMIIREG) &&
+ (data->phy_id & 0xfc00) == 0x0400)
+ data->phy_id ^= MDIO_PHY_ID_C45 | 0x0400;
+
+ return mdio_mii_ioctl(&efx->mdio, data, cmd);
}
/**************************************************************************
@@ -1945,7 +1941,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
mutex_init(&efx->mac_lock);
efx->mac_op = &efx_dummy_mac_operations;
efx->phy_op = &efx_dummy_phy_operations;
- efx->mii.dev = net_dev;
+ efx->mdio.dev = net_dev;
INIT_WORK(&efx->phy_work, efx_phy_work);
INIT_WORK(&efx->mac_work, efx_mac_work);
atomic_set(&efx->netif_stop_count, 1);
@@ -2161,9 +2157,8 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
if (!net_dev)
return -ENOMEM;
net_dev->features |= (NETIF_F_IP_CSUM | NETIF_F_SG |
- NETIF_F_HIGHDMA | NETIF_F_TSO);
- if (lro)
- net_dev->features |= NETIF_F_GRO;
+ NETIF_F_HIGHDMA | NETIF_F_TSO |
+ NETIF_F_GRO);
/* Mask for features that also apply to VLAN devices */
net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG |
NETIF_F_HIGHDMA | NETIF_F_TSO);
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 64309f4e8b1..997ea2a3d53 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -10,6 +10,7 @@
#include <linux/netdevice.h>
#include <linux/ethtool.h>
+#include <linux/mdio.h>
#include <linux/rtnetlink.h>
#include "net_driver.h"
#include "workarounds.h"
@@ -345,8 +346,8 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
unsigned int n = 0, i;
enum efx_loopback_mode mode;
- efx_fill_test(n++, strings, data, &tests->mii,
- "core", 0, "mii", NULL);
+ efx_fill_test(n++, strings, data, &tests->mdio,
+ "core", 0, "mdio", NULL);
efx_fill_test(n++, strings, data, &tests->nvram,
"core", 0, "nvram", NULL);
efx_fill_test(n++, strings, data, &tests->interrupt,
@@ -529,14 +530,7 @@ static int efx_ethtool_nway_reset(struct net_device *net_dev)
{
struct efx_nic *efx = netdev_priv(net_dev);
- if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
- mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_CTRL1,
- __ffs(BMCR_ANRESTART), true);
- return 0;
- }
-
- return -EOPNOTSUPP;
+ return mdio45_nway_restart(&efx->mdio);
}
static u32 efx_ethtool_get_link(struct net_device *net_dev)
@@ -689,7 +683,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
return -EINVAL;
}
- if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) &&
+ if (!(efx->phy_op->mmds & MDIO_DEVS_AN) &&
(wanted_fc & EFX_FC_AUTO)) {
EFX_LOG(efx, "PHY does not support flow control "
"autonegotiation\n");
@@ -717,7 +711,8 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
mutex_lock(&efx->mac_lock);
efx->wanted_fc = wanted_fc;
- mdio_clause45_set_pause(efx);
+ if (efx->phy_op->mmds & MDIO_DEVS_AN)
+ mdio45_ethtool_spauseparam_an(&efx->mdio, pause);
__efx_reconfigure_port(efx);
mutex_unlock(&efx->mac_lock);
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 466a8abb005..c049364aec4 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -2063,26 +2063,6 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset)
**************************************************************************
*/
-/* Use the top bit of the MII PHY id to indicate the PHY type
- * (1G/10G), with the remaining bits as the actual PHY id.
- *
- * This allows us to avoid leaking information from the mii_if_info
- * structure into other data structures.
- */
-#define FALCON_PHY_ID_ID_WIDTH EFX_WIDTH(MD_PRT_DEV_ADR)
-#define FALCON_PHY_ID_ID_MASK ((1 << FALCON_PHY_ID_ID_WIDTH) - 1)
-#define FALCON_PHY_ID_WIDTH (FALCON_PHY_ID_ID_WIDTH + 1)
-#define FALCON_PHY_ID_MASK ((1 << FALCON_PHY_ID_WIDTH) - 1)
-#define FALCON_PHY_ID_10G (1 << (FALCON_PHY_ID_WIDTH - 1))
-
-
-/* Packing the clause 45 port and device fields into a single value */
-#define MD_PRT_ADR_COMP_LBN (MD_PRT_ADR_LBN - MD_DEV_ADR_LBN)
-#define MD_PRT_ADR_COMP_WIDTH MD_PRT_ADR_WIDTH
-#define MD_DEV_ADR_COMP_LBN 0
-#define MD_DEV_ADR_COMP_WIDTH MD_DEV_ADR_WIDTH
-
-
/* Wait for GMII access to complete */
static int falcon_gmii_wait(struct efx_nic *efx)
{
@@ -2108,49 +2088,29 @@ static int falcon_gmii_wait(struct efx_nic *efx)
return -ETIMEDOUT;
}
-/* Writes a GMII register of a PHY connected to Falcon using MDIO. */
-static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
- int addr, int value)
+/* Write an MDIO register of a PHY connected to Falcon. */
+static int falcon_mdio_write(struct net_device *net_dev,
+ int prtad, int devad, u16 addr, u16 value)
{
struct efx_nic *efx = netdev_priv(net_dev);
- unsigned int phy_id2 = phy_id & FALCON_PHY_ID_ID_MASK;
efx_oword_t reg;
+ int rc;
- /* The 'generic' prt/dev packing in mdio_10g.h is conveniently
- * chosen so that the only current user, Falcon, can take the
- * packed value and use them directly.
- * Fail to build if this assumption is broken.
- */
- BUILD_BUG_ON(FALCON_PHY_ID_10G != MDIO45_XPRT_ID_IS10G);
- BUILD_BUG_ON(FALCON_PHY_ID_ID_WIDTH != MDIO45_PRT_DEV_WIDTH);
- BUILD_BUG_ON(MD_PRT_ADR_COMP_LBN != MDIO45_PRT_ID_COMP_LBN);
- BUILD_BUG_ON(MD_DEV_ADR_COMP_LBN != MDIO45_DEV_ID_COMP_LBN);
-
- if (phy_id2 == PHY_ADDR_INVALID)
- return;
-
- /* See falcon_mdio_read for an explanation. */
- if (!(phy_id & FALCON_PHY_ID_10G)) {
- int mmd = ffs(efx->phy_op->mmds) - 1;
- EFX_TRACE(efx, "Fixing erroneous clause22 write\n");
- phy_id2 = mdio_clause45_pack(phy_id2, mmd)
- & FALCON_PHY_ID_ID_MASK;
- }
-
- EFX_REGDUMP(efx, "writing GMII %d register %02x with %04x\n", phy_id,
- addr, value);
+ EFX_REGDUMP(efx, "writing MDIO %d register %d.%d with 0x%04x\n",
+ prtad, devad, addr, value);
spin_lock_bh(&efx->phy_lock);
- /* Check MII not currently being accessed */
- if (falcon_gmii_wait(efx) != 0)
+ /* Check MDIO not currently being accessed */
+ rc = falcon_gmii_wait(efx);
+ if (rc)
goto out;
/* Write the address/ID register */
EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr);
falcon_write(efx, &reg, MD_PHY_ADR_REG_KER);
- EFX_POPULATE_OWORD_1(reg, MD_PRT_DEV_ADR, phy_id2);
+ EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad);
falcon_write(efx, &reg, MD_ID_REG_KER);
/* Write data */
@@ -2163,7 +2123,8 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
falcon_write(efx, &reg, MD_CS_REG_KER);
/* Wait for data to be written */
- if (falcon_gmii_wait(efx) != 0) {
+ rc = falcon_gmii_wait(efx);
+ if (rc) {
/* Abort the write operation */
EFX_POPULATE_OWORD_2(reg,
MD_WRC, 0,
@@ -2174,45 +2135,28 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
out:
spin_unlock_bh(&efx->phy_lock);
+ return rc;
}
-/* Reads a GMII register from a PHY connected to Falcon. If no value
- * could be read, -1 will be returned. */
-static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
+/* Read an MDIO register of a PHY connected to Falcon. */
+static int falcon_mdio_read(struct net_device *net_dev,
+ int prtad, int devad, u16 addr)
{
struct efx_nic *efx = netdev_priv(net_dev);
- unsigned int phy_addr = phy_id & FALCON_PHY_ID_ID_MASK;
efx_oword_t reg;
- int value = -1;
-
- if (phy_addr == PHY_ADDR_INVALID)
- return -1;
-
- /* Our PHY code knows whether it needs to talk clause 22(1G) or 45(10G)
- * but the generic Linux code does not make any distinction or have
- * any state for this.
- * We spot the case where someone tried to talk 22 to a 45 PHY and
- * redirect the request to the lowest numbered MMD as a clause45
- * request. This is enough to allow simple queries like id and link
- * state to succeed. TODO: We may need to do more in future.
- */
- if (!(phy_id & FALCON_PHY_ID_10G)) {
- int mmd = ffs(efx->phy_op->mmds) - 1;
- EFX_TRACE(efx, "Fixing erroneous clause22 read\n");
- phy_addr = mdio_clause45_pack(phy_addr, mmd)
- & FALCON_PHY_ID_ID_MASK;
- }
+ int rc;
spin_lock_bh(&efx->phy_lock);
- /* Check MII not currently being accessed */
- if (falcon_gmii_wait(efx) != 0)
+ /* Check MDIO not currently being accessed */
+ rc = falcon_gmii_wait(efx);
+ if (rc)
goto out;
EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr);
falcon_write(efx, &reg, MD_PHY_ADR_REG_KER);
- EFX_POPULATE_OWORD_1(reg, MD_PRT_DEV_ADR, phy_addr);
+ EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad);
falcon_write(efx, &reg, MD_ID_REG_KER);
/* Request data to be read */
@@ -2220,12 +2164,12 @@ static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
falcon_write(efx, &reg, MD_CS_REG_KER);
/* Wait for data to become available */
- value = falcon_gmii_wait(efx);
- if (value == 0) {
+ rc = falcon_gmii_wait(efx);
+ if (rc == 0) {
falcon_read(efx, &reg, MD_RXD_REG_KER);
- value = EFX_OWORD_FIELD(reg, MD_RXD);
- EFX_REGDUMP(efx, "read from GMII %d register %02x, got %04x\n",
- phy_id, addr, value);
+ rc = EFX_OWORD_FIELD(reg, MD_RXD);
+ EFX_REGDUMP(efx, "read from MDIO %d register %d.%d, got %04x\n",
+ prtad, devad, addr, rc);
} else {
/* Abort the read operation */
EFX_POPULATE_OWORD_2(reg,
@@ -2233,22 +2177,13 @@ static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
MD_GC, 1);
falcon_write(efx, &reg, MD_CS_REG_KER);
- EFX_LOG(efx, "read from GMII 0x%x register %02x, got "
- "error %d\n", phy_id, addr, value);
+ EFX_LOG(efx, "read from MDIO %d register %d.%d, got error %d\n",
+ prtad, devad, addr, rc);
}
out:
spin_unlock_bh(&efx->phy_lock);
-
- return value;
-}
-
-static void falcon_init_mdio(struct mii_if_info *gmii)
-{
- gmii->mdio_read = falcon_mdio_read;
- gmii->mdio_write = falcon_mdio_write;
- gmii->phy_id_mask = FALCON_PHY_ID_MASK;
- gmii->reg_num_mask = ((1 << EFX_WIDTH(MD_PHY_ADR)) - 1);
+ return rc;
}
static int falcon_probe_phy(struct efx_nic *efx)
@@ -2342,9 +2277,11 @@ int falcon_probe_port(struct efx_nic *efx)
if (rc)
return rc;
- /* Set up GMII structure for PHY */
- efx->mii.supports_gmii = true;
- falcon_init_mdio(&efx->mii);
+ /* Set up MDIO structure for PHY */
+ efx->mdio.mmds = efx->phy_op->mmds;
+ efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+ efx->mdio.mdio_read = falcon_mdio_read;
+ efx->mdio.mdio_write = falcon_mdio_write;
/* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */
if (falcon_rev(efx) >= FALCON_REV_B0)
@@ -2761,7 +2698,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
if (rc == -EINVAL) {
EFX_ERR(efx, "NVRAM is invalid therefore using defaults\n");
efx->phy_type = PHY_TYPE_NONE;
- efx->mii.phy_id = PHY_ADDR_INVALID;
+ efx->mdio.prtad = MDIO_PRTAD_NONE;
board_rev = 0;
rc = 0;
} else if (rc) {
@@ -2771,7 +2708,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
struct falcon_nvconfig_board_v3 *v3 = &nvconfig->board_v3;
efx->phy_type = v2->port0_phy_type;
- efx->mii.phy_id = v2->port0_phy_addr;
+ efx->mdio.prtad = v2->port0_phy_addr;
board_rev = le16_to_cpu(v2->board_revision);
if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) {
@@ -2793,7 +2730,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
/* Read the MAC addresses */
memcpy(efx->mac_address, nvconfig->mac_address[0], ETH_ALEN);
- EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mii.phy_id);
+ EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad);
efx_set_board_info(efx, board_rev);
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h
index bda8d5bb72e..375e2a5961e 100644
--- a/drivers/net/sfc/falcon_hwdefs.h
+++ b/drivers/net/sfc/falcon_hwdefs.h
@@ -456,9 +456,6 @@
#define MD_PRT_ADR_WIDTH 5
#define MD_DEV_ADR_LBN 6
#define MD_DEV_ADR_WIDTH 5
-/* Used for writing both at once */
-#define MD_PRT_DEV_ADR_LBN 6
-#define MD_PRT_DEV_ADR_WIDTH 10
/* PHY management status & mask register (DWORD read only) */
#define MD_STAT_REG_KER 0xc50
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index 5a03713685a..2b3269c0326 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -133,7 +133,7 @@ bool falcon_xaui_link_ok(struct efx_nic *efx)
/* If the link is up, then check the phy side of the xaui link */
if (efx->link_up && link_ok)
if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS))
- link_ok = mdio_clause45_phyxgxs_lane_sync(efx);
+ link_ok = efx_mdio_phyxgxs_lane_sync(efx);
return link_ok;
}
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 9f5ec3eb341..6c33459f9ea 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -17,7 +17,7 @@
#include "boards.h"
#include "workarounds.h"
-unsigned mdio_id_oui(u32 id)
+unsigned efx_mdio_id_oui(u32 id)
{
unsigned oui = 0;
int i;
@@ -32,52 +32,45 @@ unsigned mdio_id_oui(u32 id)
return oui;
}
-int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
+int efx_mdio_reset_mmd(struct efx_nic *port, int mmd,
int spins, int spintime)
{
u32 ctrl;
- int phy_id = port->mii.phy_id;
/* Catch callers passing values in the wrong units (or just silly) */
EFX_BUG_ON_PARANOID(spins * spintime >= 5000);
- mdio_clause45_write(port, phy_id, mmd, MDIO_MMDREG_CTRL1,
- (1 << MDIO_MMDREG_CTRL1_RESET_LBN));
+ efx_mdio_write(port, mmd, MDIO_CTRL1, MDIO_CTRL1_RESET);
/* Wait for the reset bit to clear. */
do {
msleep(spintime);
- ctrl = mdio_clause45_read(port, phy_id, mmd, MDIO_MMDREG_CTRL1);
+ ctrl = efx_mdio_read(port, mmd, MDIO_CTRL1);
spins--;
- } while (spins && (ctrl & (1 << MDIO_MMDREG_CTRL1_RESET_LBN)));
+ } while (spins && (ctrl & MDIO_CTRL1_RESET));
return spins ? spins : -ETIMEDOUT;
}
-static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd,
- int fault_fatal)
+static int efx_mdio_check_mmd(struct efx_nic *efx, int mmd, int fault_fatal)
{
int status;
- int phy_id = efx->mii.phy_id;
if (LOOPBACK_INTERNAL(efx))
return 0;
if (mmd != MDIO_MMD_AN) {
/* Read MMD STATUS2 to check it is responding. */
- status = mdio_clause45_read(efx, phy_id, mmd,
- MDIO_MMDREG_STAT2);
- if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) &
- ((1 << MDIO_MMDREG_STAT2_PRESENT_WIDTH) - 1)) !=
- MDIO_MMDREG_STAT2_PRESENT_VAL) {
+ status = efx_mdio_read(efx, mmd, MDIO_STAT2);
+ if ((status & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL) {
EFX_ERR(efx, "PHY MMD %d not responding.\n", mmd);
return -EIO;
}
}
/* Read MMD STATUS 1 to check for fault. */
- status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT1);
- if ((status & (1 << MDIO_MMDREG_STAT1_FAULT_LBN)) != 0) {
+ status = efx_mdio_read(efx, mmd, MDIO_STAT1);
+ if (status & MDIO_STAT1_FAULT) {
if (fault_fatal) {
EFX_ERR(efx, "PHY MMD %d reporting fatal"
" fault: status %x\n", mmd, status);
@@ -94,8 +87,7 @@ static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd,
#define MDIO45_RESET_TIME 1000 /* ms */
#define MDIO45_RESET_ITERS 100
-int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
- unsigned int mmd_mask)
+int efx_mdio_wait_reset_mmds(struct efx_nic *efx, unsigned int mmd_mask)
{
const int spintime = MDIO45_RESET_TIME / MDIO45_RESET_ITERS;
int tries = MDIO45_RESET_ITERS;
@@ -109,16 +101,13 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
in_reset = 0;
while (mask) {
if (mask & 1) {
- stat = mdio_clause45_read(efx,
- efx->mii.phy_id,
- mmd,
- MDIO_MMDREG_CTRL1);
+ stat = efx_mdio_read(efx, mmd, MDIO_CTRL1);
if (stat < 0) {
EFX_ERR(efx, "failed to read status of"
" MMD %d\n", mmd);
return -EIO;
}
- if (stat & (1 << MDIO_MMDREG_CTRL1_RESET_LBN))
+ if (stat & MDIO_CTRL1_RESET)
in_reset |= (1 << mmd);
}
mask = mask >> 1;
@@ -137,28 +126,26 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
return rc;
}
-int mdio_clause45_check_mmds(struct efx_nic *efx,
- unsigned int mmd_mask, unsigned int fatal_mask)
+int efx_mdio_check_mmds(struct efx_nic *efx,
+ unsigned int mmd_mask, unsigned int fatal_mask)
{
- int mmd = 0, probe_mmd, devs0, devs1;
+ int mmd = 0, probe_mmd, devs1, devs2;
u32 devices;
/* Historically we have probed the PHYXS to find out what devices are
* present,but that doesn't work so well if the PHYXS isn't expected
* to exist, if so just find the first item in the list supplied. */
- probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS_PHYXS) ? MDIO_MMD_PHYXS :
+ probe_mmd = (mmd_mask & MDIO_DEVS_PHYXS) ? MDIO_MMD_PHYXS :
__ffs(mmd_mask);
/* Check all the expected MMDs are present */
- devs0 = mdio_clause45_read(efx, efx->mii.phy_id,
- probe_mmd, MDIO_MMDREG_DEVS0);
- devs1 = mdio_clause45_read(efx, efx->mii.phy_id,
- probe_mmd, MDIO_MMDREG_DEVS1);
- if (devs0 < 0 || devs1 < 0) {
+ devs1 = efx_mdio_read(efx, probe_mmd, MDIO_DEVS1);
+ devs2 = efx_mdio_read(efx, probe_mmd, MDIO_DEVS2);
+ if (devs1 < 0 || devs2 < 0) {
EFX_ERR(efx, "failed to read devices present\n");
return -EIO;
}
- devices = devs0 | (devs1 << 16);
+ devices = devs1 | (devs2 << 16);
if ((devices & mmd_mask) != mmd_mask) {
EFX_ERR(efx, "required MMDs not present: got %x, "
"wanted %x\n", devices, mmd_mask);
@@ -170,7 +157,7 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,
while (mmd_mask) {
if (mmd_mask & 1) {
int fault_fatal = fatal_mask & 1;
- if (mdio_clause45_check_mmd(efx, mmd, fault_fatal))
+ if (efx_mdio_check_mmd(efx, mmd, fault_fatal))
return -EIO;
}
mmd_mask = mmd_mask >> 1;
@@ -181,13 +168,8 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,
return 0;
}
-bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
+bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
{
- int phy_id = efx->mii.phy_id;
- u32 reg;
- bool ok = true;
- int mmd = 0;
-
/* If the port is in loopback, then we should only consider a subset
* of mmd's */
if (LOOPBACK_INTERNAL(efx))
@@ -197,241 +179,75 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
else if (efx_phy_mode_disabled(efx->phy_mode))
return false;
else if (efx->loopback_mode == LOOPBACK_PHYXS)
- mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS |
- MDIO_MMDREG_DEVS_PCS |
- MDIO_MMDREG_DEVS_PMAPMD |
- MDIO_MMDREG_DEVS_AN);
+ mmd_mask &= ~(MDIO_DEVS_PHYXS |
+ MDIO_DEVS_PCS |
+ MDIO_DEVS_PMAPMD |
+ MDIO_DEVS_AN);
else if (efx->loopback_mode == LOOPBACK_PCS)
- mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS |
- MDIO_MMDREG_DEVS_PMAPMD |
- MDIO_MMDREG_DEVS_AN);
+ mmd_mask &= ~(MDIO_DEVS_PCS |
+ MDIO_DEVS_PMAPMD |
+ MDIO_DEVS_AN);
else if (efx->loopback_mode == LOOPBACK_PMAPMD)
- mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD |
- MDIO_MMDREG_DEVS_AN);
-
- if (!mmd_mask) {
- /* Use presence of XGMII faults in leui of link state */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
- MDIO_PHYXS_STATUS2);
- return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
- }
+ mmd_mask &= ~(MDIO_DEVS_PMAPMD |
+ MDIO_DEVS_AN);
- while (mmd_mask) {
- if (mmd_mask & 1) {
- /* Double reads because link state is latched, and a
- * read moves the current state into the register */
- reg = mdio_clause45_read(efx, phy_id,
- mmd, MDIO_MMDREG_STAT1);
- reg = mdio_clause45_read(efx, phy_id,
- mmd, MDIO_MMDREG_STAT1);
- ok = ok && (reg & (1 << MDIO_MMDREG_STAT1_LINK_LBN));
- }
- mmd_mask = (mmd_mask >> 1);
- mmd++;
- }
- return ok;
+ return mdio45_links_ok(&efx->mdio, mmd_mask);
}
-void mdio_clause45_transmit_disable(struct efx_nic *efx)
+void efx_mdio_transmit_disable(struct efx_nic *efx)
{
- mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_TXDIS, MDIO_MMDREG_TXDIS_GLOBAL_LBN,
- efx->phy_mode & PHY_MODE_TX_DISABLED);
+ efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD,
+ MDIO_PMA_TXDIS, MDIO_PMD_TXDIS_GLOBAL,
+ efx->phy_mode & PHY_MODE_TX_DISABLED);
}
-void mdio_clause45_phy_reconfigure(struct efx_nic *efx)
+void efx_mdio_phy_reconfigure(struct efx_nic *efx)
{
- int phy_id = efx->mii.phy_id;
-
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_CTRL1, MDIO_PMAPMD_CTRL1_LBACK_LBN,
- efx->loopback_mode == LOOPBACK_PMAPMD);
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PCS,
- MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
- efx->loopback_mode == LOOPBACK_PCS);
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS,
- MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
- efx->loopback_mode == LOOPBACK_NETWORK);
+ efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD,
+ MDIO_CTRL1, MDIO_PMA_CTRL1_LOOPBACK,
+ efx->loopback_mode == LOOPBACK_PMAPMD);
+ efx_mdio_set_flag(efx, MDIO_MMD_PCS,
+ MDIO_CTRL1, MDIO_PCS_CTRL1_LOOPBACK,
+ efx->loopback_mode == LOOPBACK_PCS);
+ efx_mdio_set_flag(efx, MDIO_MMD_PHYXS,
+ MDIO_CTRL1, MDIO_PHYXS_CTRL1_LOOPBACK,
+ efx->loopback_mode == LOOPBACK_NETWORK);
}
-static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx,
- int lpower, int mmd)
+static void efx_mdio_set_mmd_lpower(struct efx_nic *efx,
+ int lpower, int mmd)
{
- int phy = efx->mii.phy_id;
- int stat = mdio_clause45_read(efx, phy, mmd, MDIO_MMDREG_STAT1);
+ int stat = efx_mdio_read(efx, mmd, MDIO_STAT1);
EFX_TRACE(efx, "Setting low power mode for MMD %d to %d\n",
mmd, lpower);
- if (stat & (1 << MDIO_MMDREG_STAT1_LPABLE_LBN)) {
- mdio_clause45_set_flag(efx, phy, mmd, MDIO_MMDREG_CTRL1,
- MDIO_MMDREG_CTRL1_LPOWER_LBN, lpower);
+ if (stat & MDIO_STAT1_LPOWERABLE) {
+ efx_mdio_set_flag(efx, mmd, MDIO_CTRL1,
+ MDIO_CTRL1_LPOWER, lpower);
}
}
-void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
- int low_power, unsigned int mmd_mask)
+void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
+ int low_power, unsigned int mmd_mask)
{
int mmd = 0;
- mmd_mask &= ~MDIO_MMDREG_DEVS_AN;
+ mmd_mask &= ~MDIO_DEVS_AN;
while (mmd_mask) {
if (mmd_mask & 1)
- mdio_clause45_set_mmd_lpower(efx, low_power, mmd);
+ efx_mdio_set_mmd_lpower(efx, low_power, mmd);
mmd_mask = (mmd_mask >> 1);
mmd++;
}
}
-static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr)
-{
- int phy_id = efx->mii.phy_id;
- u32 result = 0;
- int reg;
-
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, addr);
- if (reg & ADVERTISE_10HALF)
- result |= ADVERTISED_10baseT_Half;
- if (reg & ADVERTISE_10FULL)
- result |= ADVERTISED_10baseT_Full;
- if (reg & ADVERTISE_100HALF)
- result |= ADVERTISED_100baseT_Half;
- if (reg & ADVERTISE_100FULL)
- result |= ADVERTISED_100baseT_Full;
- return result;
-}
-
-/**
- * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO.
- * @efx: Efx NIC
- * @ecmd: Buffer for settings
- *
- * On return the 'port', 'speed', 'supported' and 'advertising' fields of
- * ecmd have been filled out.
- */
-void mdio_clause45_get_settings(struct efx_nic *efx,
- struct ethtool_cmd *ecmd)
-{
- mdio_clause45_get_settings_ext(efx, ecmd, 0, 0);
-}
-
-/**
- * mdio_clause45_get_settings_ext - Read (some of) the PHY settings over MDIO.
- * @efx: Efx NIC
- * @ecmd: Buffer for settings
- * @xnp: Advertised Extended Next Page state
- * @xnp_lpa: Link Partner's advertised XNP state
- *
- * On return the 'port', 'speed', 'supported' and 'advertising' fields of
- * ecmd have been filled out.
- */
-void mdio_clause45_get_settings_ext(struct efx_nic *efx,
- struct ethtool_cmd *ecmd,
- u32 npage_adv, u32 npage_lpa)
-{
- int phy_id = efx->mii.phy_id;
- int reg;
-
- ecmd->transceiver = XCVR_INTERNAL;
- ecmd->phy_address = phy_id;
-
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_CTRL2);
- switch (reg & MDIO_PMAPMD_CTRL2_TYPE_MASK) {
- case MDIO_PMAPMD_CTRL2_10G_BT:
- case MDIO_PMAPMD_CTRL2_1G_BT:
- case MDIO_PMAPMD_CTRL2_100_BT:
- case MDIO_PMAPMD_CTRL2_10_BT:
- ecmd->port = PORT_TP;
- ecmd->supported = SUPPORTED_TP;
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_SPEED);
- if (reg & (1 << MDIO_MMDREG_SPEED_10G_LBN))
- ecmd->supported |= SUPPORTED_10000baseT_Full;
- if (reg & (1 << MDIO_MMDREG_SPEED_1000M_LBN))
- ecmd->supported |= (SUPPORTED_1000baseT_Full |
- SUPPORTED_1000baseT_Half);
- if (reg & (1 << MDIO_MMDREG_SPEED_100M_LBN))
- ecmd->supported |= (SUPPORTED_100baseT_Full |
- SUPPORTED_100baseT_Half);
- if (reg & (1 << MDIO_MMDREG_SPEED_10M_LBN))
- ecmd->supported |= (SUPPORTED_10baseT_Full |
- SUPPORTED_10baseT_Half);
- ecmd->advertising = ADVERTISED_TP;
- break;
-
- /* We represent CX4 as fibre in the absence of anything better */
- case MDIO_PMAPMD_CTRL2_10G_CX4:
- /* All the other defined modes are flavours of optical */
- default:
- ecmd->port = PORT_FIBRE;
- ecmd->supported = SUPPORTED_FIBRE;
- ecmd->advertising = ADVERTISED_FIBRE;
- break;
- }
-
- if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
- ecmd->supported |= SUPPORTED_Autoneg;
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_CTRL1);
- if (reg & BMCR_ANENABLE) {
- ecmd->autoneg = AUTONEG_ENABLE;
- ecmd->advertising |=
- ADVERTISED_Autoneg |
- mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) |
- npage_adv;
- } else
- ecmd->autoneg = AUTONEG_DISABLE;
- } else
- ecmd->autoneg = AUTONEG_DISABLE;
-
- if (ecmd->autoneg) {
- /* If AN is complete, report best common mode,
- * otherwise report best advertised mode. */
- u32 modes = 0;
- if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_STAT1) &
- (1 << MDIO_AN_STATUS_AN_DONE_LBN))
- modes = (ecmd->advertising &
- (mdio_clause45_get_an(efx, MDIO_AN_LPA) |
- npage_lpa));
- if (modes == 0)
- modes = ecmd->advertising;
-
- if (modes & ADVERTISED_10000baseT_Full) {
- ecmd->speed = SPEED_10000;
- ecmd->duplex = DUPLEX_FULL;
- } else if (modes & (ADVERTISED_1000baseT_Full |
- ADVERTISED_1000baseT_Half)) {
- ecmd->speed = SPEED_1000;
- ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full);
- } else if (modes & (ADVERTISED_100baseT_Full |
- ADVERTISED_100baseT_Half)) {
- ecmd->speed = SPEED_100;
- ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
- } else {
- ecmd->speed = SPEED_10;
- ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
- }
- } else {
- /* Report forced settings */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_CTRL1);
- ecmd->speed = (((reg & BMCR_SPEED1000) ? 100 : 1) *
- ((reg & BMCR_SPEED100) ? 100 : 10));
- ecmd->duplex = (reg & BMCR_FULLDPLX ||
- ecmd->speed == SPEED_10000);
- }
-}
-
/**
- * mdio_clause45_set_settings - Set (some of) the PHY settings over MDIO.
+ * efx_mdio_set_settings - Set (some of) the PHY settings over MDIO.
* @efx: Efx NIC
* @ecmd: New settings
*/
-int mdio_clause45_set_settings(struct efx_nic *efx,
- struct ethtool_cmd *ecmd)
+int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- int phy_id = efx->mii.phy_id;
struct ethtool_cmd prev;
u32 required;
int reg;
@@ -488,95 +304,48 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
else if (ecmd->advertising & (ADVERTISED_1000baseT_Half |
ADVERTISED_1000baseT_Full))
reg |= ADVERTISE_NPAGE;
- reg |= efx_fc_advertise(efx->wanted_fc);
- mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_ADVERTISE, reg);
+ reg |= mii_advertise_flowctrl(efx->wanted_fc);
+ efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
/* Set up the (extended) next page if necessary */
if (efx->phy_op->set_npage_adv)
efx->phy_op->set_npage_adv(efx, ecmd->advertising);
/* Enable and restart AN */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_CTRL1);
- reg |= BMCR_ANENABLE;
+ reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1);
+ reg |= MDIO_AN_CTRL1_ENABLE;
if (!(EFX_WORKAROUND_15195(efx) &&
LOOPBACK_MASK(efx) & efx->phy_op->loopbacks))
- reg |= BMCR_ANRESTART;
+ reg |= MDIO_AN_CTRL1_RESTART;
if (xnp)
- reg |= 1 << MDIO_AN_CTRL_XNP_LBN;
+ reg |= MDIO_AN_CTRL1_XNP;
else
- reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN);
- mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_CTRL1, reg);
+ reg &= ~MDIO_AN_CTRL1_XNP;
+ efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg);
} else {
/* Disable AN */
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_CTRL1,
- __ffs(BMCR_ANENABLE), false);
+ efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_CTRL1,
+ MDIO_AN_CTRL1_ENABLE, false);
/* Set the basic control bits */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_CTRL1);
- reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX |
- 0x003c);
+ reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1);
+ reg &= ~(MDIO_CTRL1_SPEEDSEL | MDIO_CTRL1_FULLDPLX);
if (ecmd->speed == SPEED_100)
- reg |= BMCR_SPEED100;
+ reg |= MDIO_PMA_CTRL1_SPEED100;
if (ecmd->duplex)
- reg |= BMCR_FULLDPLX;
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_CTRL1, reg);
+ reg |= MDIO_CTRL1_FULLDPLX;
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1, reg);
}
return 0;
}
-void mdio_clause45_set_pause(struct efx_nic *efx)
-{
- int phy_id = efx->mii.phy_id;
- int reg;
-
- if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
- /* Set pause capability advertising */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_ADVERTISE);
- reg &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
- reg |= efx_fc_advertise(efx->wanted_fc);
- mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_ADVERTISE, reg);
-
- /* Restart auto-negotiation */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_CTRL1);
- if (reg & BMCR_ANENABLE) {
- reg |= BMCR_ANRESTART;
- mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
- MDIO_MMDREG_CTRL1, reg);
- }
- }
-}
-
-enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx)
+enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx)
{
- int phy_id = efx->mii.phy_id;
int lpa;
- if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)))
+ if (!(efx->phy_op->mmds & MDIO_DEVS_AN))
return efx->wanted_fc;
- lpa = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, MDIO_AN_LPA);
+ lpa = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_LPA);
return efx_fc_resolve(efx->wanted_fc, lpa);
}
-
-void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev,
- u16 addr, int bit, bool sense)
-{
- int old_val = mdio_clause45_read(efx, prt, dev, addr);
- int new_val;
-
- if (sense)
- new_val = old_val | (1 << bit);
- else
- new_val = old_val & ~(1 << bit);
- if (old_val != new_val)
- mdio_clause45_write(efx, prt, dev, addr, new_val);
-}
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 7014d2279c2..6b14421a744 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -10,247 +10,53 @@
#ifndef EFX_MDIO_10G_H
#define EFX_MDIO_10G_H
+#include <linux/mdio.h>
+
/*
- * Definitions needed for doing 10G MDIO as specified in clause 45
- * MDIO, which do not appear in Linux yet. Also some helper functions.
+ * Helper functions for doing 10G MDIO as specified in IEEE 802.3 clause 45.
*/
#include "efx.h"
#include "boards.h"
-/* Numbering of the MDIO Manageable Devices (MMDs) */
-/* Physical Medium Attachment/ Physical Medium Dependent sublayer */
-#define MDIO_MMD_PMAPMD (1)
-/* WAN Interface Sublayer */
-#define MDIO_MMD_WIS (2)
-/* Physical Coding Sublayer */
-#define MDIO_MMD_PCS (3)
-/* PHY Extender Sublayer */
-#define MDIO_MMD_PHYXS (4)
-/* Extender Sublayer */
-#define MDIO_MMD_DTEXS (5)
-/* Transmission convergence */
-#define MDIO_MMD_TC (6)
-/* Auto negotiation */
-#define MDIO_MMD_AN (7)
-/* Clause 22 extension */
-#define MDIO_MMD_C22EXT 29
-
-/* Generic register locations */
-#define MDIO_MMDREG_CTRL1 (0)
-#define MDIO_MMDREG_STAT1 (1)
-#define MDIO_MMDREG_IDHI (2)
-#define MDIO_MMDREG_IDLOW (3)
-#define MDIO_MMDREG_SPEED (4)
-#define MDIO_MMDREG_DEVS0 (5)
-#define MDIO_MMDREG_DEVS1 (6)
-#define MDIO_MMDREG_CTRL2 (7)
-#define MDIO_MMDREG_STAT2 (8)
-#define MDIO_MMDREG_TXDIS (9)
-
-/* Bits in MMDREG_CTRL1 */
-/* Reset */
-#define MDIO_MMDREG_CTRL1_RESET_LBN (15)
-#define MDIO_MMDREG_CTRL1_RESET_WIDTH (1)
-/* Loopback */
-/* Loopback bit for WIS, PCS, PHYSX and DTEXS */
-#define MDIO_MMDREG_CTRL1_LBACK_LBN (14)
-#define MDIO_MMDREG_CTRL1_LBACK_WIDTH (1)
-/* Low power */
-#define MDIO_MMDREG_CTRL1_LPOWER_LBN (11)
-#define MDIO_MMDREG_CTRL1_LPOWER_WIDTH (1)
-
-/* Bits in MMDREG_STAT1 */
-#define MDIO_MMDREG_STAT1_FAULT_LBN (7)
-#define MDIO_MMDREG_STAT1_FAULT_WIDTH (1)
-/* Link state */
-#define MDIO_MMDREG_STAT1_LINK_LBN (2)
-#define MDIO_MMDREG_STAT1_LINK_WIDTH (1)
-/* Low power ability */
-#define MDIO_MMDREG_STAT1_LPABLE_LBN (1)
-#define MDIO_MMDREG_STAT1_LPABLE_WIDTH (1)
-
-/* Bits in combined ID regs */
-static inline unsigned mdio_id_rev(u32 id) { return id & 0xf; }
-static inline unsigned mdio_id_model(u32 id) { return (id >> 4) & 0x3f; }
-extern unsigned mdio_id_oui(u32 id);
-
-/* Bits in MMDREG_DEVS0/1. Someone thoughtfully layed things out
- * so the 'bit present' bit number of an MMD is the number of
- * that MMD */
-#define DEV_PRESENT_BIT(_b) (1 << _b)
-
-#define MDIO_MMDREG_DEVS_PHYXS DEV_PRESENT_BIT(MDIO_MMD_PHYXS)
-#define MDIO_MMDREG_DEVS_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS)
-#define MDIO_MMDREG_DEVS_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD)
-#define MDIO_MMDREG_DEVS_AN DEV_PRESENT_BIT(MDIO_MMD_AN)
-#define MDIO_MMDREG_DEVS_C22EXT DEV_PRESENT_BIT(MDIO_MMD_C22EXT)
-
-/* Bits in MMDREG_SPEED */
-#define MDIO_MMDREG_SPEED_10G_LBN 0
-#define MDIO_MMDREG_SPEED_10G_WIDTH 1
-#define MDIO_MMDREG_SPEED_1000M_LBN 4
-#define MDIO_MMDREG_SPEED_1000M_WIDTH 1
-#define MDIO_MMDREG_SPEED_100M_LBN 5
-#define MDIO_MMDREG_SPEED_100M_WIDTH 1
-#define MDIO_MMDREG_SPEED_10M_LBN 6
-#define MDIO_MMDREG_SPEED_10M_WIDTH 1
-
-/* Bits in MMDREG_STAT2 */
-#define MDIO_MMDREG_STAT2_PRESENT_VAL (2)
-#define MDIO_MMDREG_STAT2_PRESENT_LBN (14)
-#define MDIO_MMDREG_STAT2_PRESENT_WIDTH (2)
-
-/* Bits in MMDREG_TXDIS */
-#define MDIO_MMDREG_TXDIS_GLOBAL_LBN (0)
-#define MDIO_MMDREG_TXDIS_GLOBAL_WIDTH (1)
-
-/* MMD-specific bits, ordered by MMD, then register */
-#define MDIO_PMAPMD_CTRL1_LBACK_LBN (0)
-#define MDIO_PMAPMD_CTRL1_LBACK_WIDTH (1)
-
-/* PMA type (4 bits) */
-#define MDIO_PMAPMD_CTRL2_10G_CX4 (0x0)
-#define MDIO_PMAPMD_CTRL2_10G_EW (0x1)
-#define MDIO_PMAPMD_CTRL2_10G_LW (0x2)
-#define MDIO_PMAPMD_CTRL2_10G_SW (0x3)
-#define MDIO_PMAPMD_CTRL2_10G_LX4 (0x4)
-#define MDIO_PMAPMD_CTRL2_10G_ER (0x5)
-#define MDIO_PMAPMD_CTRL2_10G_LR (0x6)
-#define MDIO_PMAPMD_CTRL2_10G_SR (0x7)
-/* Reserved */
-#define MDIO_PMAPMD_CTRL2_10G_BT (0x9)
-/* Reserved */
-/* Reserved */
-#define MDIO_PMAPMD_CTRL2_1G_BT (0xc)
-/* Reserved */
-#define MDIO_PMAPMD_CTRL2_100_BT (0xe)
-#define MDIO_PMAPMD_CTRL2_10_BT (0xf)
-#define MDIO_PMAPMD_CTRL2_TYPE_MASK (0xf)
-
-/* PMA 10GBT registers */
-#define MDIO_PMAPMD_10GBT_TXPWR (131)
-#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN (0)
-#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_WIDTH (1)
-
-/* PHY XGXS Status 2 */
-#define MDIO_PHYXS_STATUS2 (8)
-#define MDIO_PHYXS_STATUS2_RX_FAULT_LBN 10
-
-/* PHY XGXS lane state */
-#define MDIO_PHYXS_LANE_STATE (0x18)
-#define MDIO_PHYXS_LANE_ALIGNED_LBN (12)
-
-/* AN registers */
-#define MDIO_AN_CTRL_XNP_LBN 13
-#define MDIO_AN_STATUS (1)
-#define MDIO_AN_STATUS_XNP_LBN (7)
-#define MDIO_AN_STATUS_PAGE_LBN (6)
-#define MDIO_AN_STATUS_AN_DONE_LBN (5)
-#define MDIO_AN_STATUS_LP_AN_CAP_LBN (0)
-
-#define MDIO_AN_ADVERTISE 16
-#define MDIO_AN_ADVERTISE_XNP_LBN 12
-#define MDIO_AN_LPA 19
-#define MDIO_AN_XNP 22
-#define MDIO_AN_LPA_XNP 25
-
-#define MDIO_AN_10GBT_CTRL 32
-#define MDIO_AN_10GBT_CTRL_ADV_10G_LBN 12
-#define MDIO_AN_10GBT_STATUS (33)
-#define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */
-#define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */
-#define MDIO_AN_10GBT_STATUS_LOC_OK_LBN (13) /* Local OK */
-#define MDIO_AN_10GBT_STATUS_REM_OK_LBN (12) /* Remote OK */
-#define MDIO_AN_10GBT_STATUS_LP_10G_LBN (11) /* Link partner is 10GBT capable */
-#define MDIO_AN_10GBT_STATUS_LP_LTA_LBN (10) /* LP loop timing ability */
-#define MDIO_AN_10GBT_STATUS_LP_TRR_LBN (9) /* LP Training Reset Request */
-
+static inline unsigned efx_mdio_id_rev(u32 id) { return id & 0xf; }
+static inline unsigned efx_mdio_id_model(u32 id) { return (id >> 4) & 0x3f; }
+extern unsigned efx_mdio_id_oui(u32 id);
-/* Packing of the prt and dev arguments of clause 45 style MDIO into a
- * single int so they can be passed into the mdio_read/write functions
- * that currently exist. Note that as Falcon is the only current user,
- * the packed form is chosen to match what Falcon needs to write into
- * a register. This is checked at compile-time so do not change it. If
- * your target chip needs things layed out differently you will need
- * to unpack the arguments in your chip-specific mdio functions.
- */
- /* These are defined by the standard. */
-#define MDIO45_PRT_ID_WIDTH (5)
-#define MDIO45_DEV_ID_WIDTH (5)
-
-/* The prt ID is just packed in immediately to the left of the dev ID */
-#define MDIO45_PRT_DEV_WIDTH (MDIO45_PRT_ID_WIDTH + MDIO45_DEV_ID_WIDTH)
-
-#define MDIO45_PRT_ID_MASK ((1 << MDIO45_PRT_DEV_WIDTH) - 1)
-/* This is the prt + dev extended by 1 bit to hold the 'is clause 45' flag. */
-#define MDIO45_XPRT_ID_WIDTH (MDIO45_PRT_DEV_WIDTH + 1)
-#define MDIO45_XPRT_ID_MASK ((1 << MDIO45_XPRT_ID_WIDTH) - 1)
-#define MDIO45_XPRT_ID_IS10G (1 << (MDIO45_XPRT_ID_WIDTH - 1))
-
-
-#define MDIO45_PRT_ID_COMP_LBN MDIO45_DEV_ID_WIDTH
-#define MDIO45_PRT_ID_COMP_WIDTH MDIO45_PRT_ID_WIDTH
-#define MDIO45_DEV_ID_COMP_LBN 0
-#define MDIO45_DEV_ID_COMP_WIDTH MDIO45_DEV_ID_WIDTH
-
-/* Compose port and device into a phy_id */
-static inline int mdio_clause45_pack(u8 prt, u8 dev)
-{
- efx_dword_t phy_id;
- EFX_POPULATE_DWORD_2(phy_id, MDIO45_PRT_ID_COMP, prt,
- MDIO45_DEV_ID_COMP, dev);
- return MDIO45_XPRT_ID_IS10G | EFX_DWORD_VAL(phy_id);
-}
-
-static inline void mdio_clause45_unpack(u32 val, u8 *prt, u8 *dev)
+static inline int efx_mdio_read(struct efx_nic *efx, int devad, int addr)
{
- efx_dword_t phy_id;
- EFX_POPULATE_DWORD_1(phy_id, EFX_DWORD_0, val);
- *prt = EFX_DWORD_FIELD(phy_id, MDIO45_PRT_ID_COMP);
- *dev = EFX_DWORD_FIELD(phy_id, MDIO45_DEV_ID_COMP);
+ return efx->mdio.mdio_read(efx->net_dev, efx->mdio.prtad, devad, addr);
}
-static inline int mdio_clause45_read(struct efx_nic *efx,
- u8 prt, u8 dev, u16 addr)
+static inline void
+efx_mdio_write(struct efx_nic *efx, int devad, int addr, int value)
{
- return efx->mii.mdio_read(efx->net_dev,
- mdio_clause45_pack(prt, dev), addr);
+ efx->mdio.mdio_write(efx->net_dev, efx->mdio.prtad, devad, addr, value);
}
-static inline void mdio_clause45_write(struct efx_nic *efx,
- u8 prt, u8 dev, u16 addr, int value)
+static inline u32 efx_mdio_read_id(struct efx_nic *efx, int mmd)
{
- efx->mii.mdio_write(efx->net_dev,
- mdio_clause45_pack(prt, dev), addr, value);
-}
-
-
-static inline u32 mdio_clause45_read_id(struct efx_nic *efx, int mmd)
-{
- int phy_id = efx->mii.phy_id;
- u16 id_low = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_IDLOW);
- u16 id_hi = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_IDHI);
+ u16 id_low = efx_mdio_read(efx, mmd, MDIO_DEVID2);
+ u16 id_hi = efx_mdio_read(efx, mmd, MDIO_DEVID1);
return (id_hi << 16) | (id_low);
}
-static inline bool mdio_clause45_phyxgxs_lane_sync(struct efx_nic *efx)
+static inline bool efx_mdio_phyxgxs_lane_sync(struct efx_nic *efx)
{
int i, lane_status;
bool sync;
for (i = 0; i < 2; ++i)
- lane_status = mdio_clause45_read(efx, efx->mii.phy_id,
- MDIO_MMD_PHYXS,
- MDIO_PHYXS_LANE_STATE);
+ lane_status = efx_mdio_read(efx, MDIO_MMD_PHYXS,
+ MDIO_PHYXS_LNSTAT);
- sync = !!(lane_status & (1 << MDIO_PHYXS_LANE_ALIGNED_LBN));
+ sync = !!(lane_status & MDIO_PHYXS_LNSTAT_ALIGN);
if (!sync)
EFX_LOG(efx, "XGXS lane status: %x\n", lane_status);
return sync;
}
-extern const char *mdio_clause45_mmd_name(int mmd);
+extern const char *efx_mdio_mmd_name(int mmd);
/*
* Reset a specific MMD and wait for reset to clear.
@@ -258,54 +64,44 @@ extern const char *mdio_clause45_mmd_name(int mmd);
*
* This function will sleep
*/
-extern int mdio_clause45_reset_mmd(struct efx_nic *efx, int mmd,
- int spins, int spintime);
+extern int efx_mdio_reset_mmd(struct efx_nic *efx, int mmd,
+ int spins, int spintime);
-/* As mdio_clause45_check_mmd but for multiple MMDs */
-int mdio_clause45_check_mmds(struct efx_nic *efx,
- unsigned int mmd_mask, unsigned int fatal_mask);
+/* As efx_mdio_check_mmd but for multiple MMDs */
+int efx_mdio_check_mmds(struct efx_nic *efx,
+ unsigned int mmd_mask, unsigned int fatal_mask);
/* Check the link status of specified mmds in bit mask */
-extern bool mdio_clause45_links_ok(struct efx_nic *efx,
- unsigned int mmd_mask);
+extern bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask);
/* Generic transmit disable support though PMAPMD */
-extern void mdio_clause45_transmit_disable(struct efx_nic *efx);
+extern void efx_mdio_transmit_disable(struct efx_nic *efx);
/* Generic part of reconfigure: set/clear loopback bits */
-extern void mdio_clause45_phy_reconfigure(struct efx_nic *efx);
+extern void efx_mdio_phy_reconfigure(struct efx_nic *efx);
/* Set the power state of the specified MMDs */
-extern void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
- int low_power, unsigned int mmd_mask);
-
-/* Read (some of) the PHY settings over MDIO */
-extern void mdio_clause45_get_settings(struct efx_nic *efx,
- struct ethtool_cmd *ecmd);
-
-/* Read (some of) the PHY settings over MDIO */
-extern void
-mdio_clause45_get_settings_ext(struct efx_nic *efx, struct ethtool_cmd *ecmd,
- u32 xnp, u32 xnp_lpa);
+extern void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
+ int low_power, unsigned int mmd_mask);
/* Set (some of) the PHY settings over MDIO */
-extern int mdio_clause45_set_settings(struct efx_nic *efx,
- struct ethtool_cmd *ecmd);
-
-/* Set pause parameters to be advertised through AN (if available) */
-extern void mdio_clause45_set_pause(struct efx_nic *efx);
+extern int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd);
/* Get pause parameters from AN if available (otherwise return
* requested pause parameters)
*/
-enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx);
+enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx);
/* Wait for specified MMDs to exit reset within a timeout */
-extern int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
- unsigned int mmd_mask);
+extern int efx_mdio_wait_reset_mmds(struct efx_nic *efx,
+ unsigned int mmd_mask);
/* Set or clear flag, debouncing */
-extern void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev,
- u16 addr, int bit, bool sense);
+static inline void
+efx_mdio_set_flag(struct efx_nic *efx, int devad, int addr,
+ int mask, bool state)
+{
+ mdio_set_flag(&efx->mdio, efx->mdio.prtad, devad, addr, mask, state);
+}
#endif /* EFX_MDIO_10G_H */
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index e169e5dcd1e..5eabede9ac1 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -19,7 +19,7 @@
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/timer.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/device.h>
@@ -458,8 +458,6 @@ enum phy_type {
PHY_TYPE_MAX /* Insert any new items before this */
};
-#define PHY_ADDR_INVALID 0xff
-
#define EFX_IS10G(efx) ((efx)->link_speed == 10000)
enum nic_state {
@@ -497,8 +495,8 @@ struct efx_nic;
/* Pseudo bit-mask flow control field */
enum efx_fc_type {
- EFX_FC_RX = 1,
- EFX_FC_TX = 2,
+ EFX_FC_RX = FLOW_CTRL_RX,
+ EFX_FC_TX = FLOW_CTRL_TX,
EFX_FC_AUTO = 4,
};
@@ -508,33 +506,15 @@ enum efx_mac_type {
EFX_XMAC = 2,
};
-static inline unsigned int efx_fc_advertise(enum efx_fc_type wanted_fc)
-{
- unsigned int adv = 0;
- if (wanted_fc & EFX_FC_RX)
- adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
- if (wanted_fc & EFX_FC_TX)
- adv ^= ADVERTISE_PAUSE_ASYM;
- return adv;
-}
-
static inline enum efx_fc_type efx_fc_resolve(enum efx_fc_type wanted_fc,
unsigned int lpa)
{
- unsigned int adv = efx_fc_advertise(wanted_fc);
+ BUILD_BUG_ON(EFX_FC_AUTO & (EFX_FC_RX | EFX_FC_TX));
if (!(wanted_fc & EFX_FC_AUTO))
return wanted_fc;
- if (adv & lpa & ADVERTISE_PAUSE_CAP)
- return EFX_FC_RX | EFX_FC_TX;
- if (adv & lpa & ADVERTISE_PAUSE_ASYM) {
- if (adv & ADVERTISE_PAUSE_CAP)
- return EFX_FC_RX;
- if (lpa & ADVERTISE_PAUSE_CAP)
- return EFX_FC_TX;
- }
- return 0;
+ return mii_resolve_flowctrl_fdx(mii_advertise_flowctrl(wanted_fc), lpa);
}
/**
@@ -758,7 +738,7 @@ union efx_multicast_hash {
* @phy_lock: PHY access lock
* @phy_op: PHY interface
* @phy_data: PHY private data (including PHY-specific stats)
- * @mii: PHY interface
+ * @mdio: PHY MDIO interface
* @phy_mode: PHY operating mode. Serialised by @mac_lock.
* @mac_up: MAC link state
* @link_up: Link status
@@ -845,7 +825,7 @@ struct efx_nic {
struct work_struct phy_work;
struct efx_phy_operations *phy_op;
void *phy_data;
- struct mii_if_info mii;
+ struct mdio_if_info mdio;
enum efx_phy_mode phy_mode;
bool mac_up;
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index 66d7fe3db3e..01f9432c31e 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -450,17 +450,27 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
/* Pass the skb/page into the LRO engine */
if (rx_buf->page) {
- struct napi_gro_fraginfo info;
+ struct sk_buff *skb = napi_get_frags(napi);
- info.frags[0].page = rx_buf->page;
- info.frags[0].page_offset = efx_rx_buf_offset(rx_buf);
- info.frags[0].size = rx_buf->len;
- info.nr_frags = 1;
- info.ip_summed = CHECKSUM_UNNECESSARY;
- info.len = rx_buf->len;
+ if (!skb) {
+ put_page(rx_buf->page);
+ goto out;
+ }
+
+ skb_shinfo(skb)->frags[0].page = rx_buf->page;
+ skb_shinfo(skb)->frags[0].page_offset =
+ efx_rx_buf_offset(rx_buf);
+ skb_shinfo(skb)->frags[0].size = rx_buf->len;
+ skb_shinfo(skb)->nr_frags = 1;
+
+ skb->len = rx_buf->len;
+ skb->data_len = rx_buf->len;
+ skb->truesize += rx_buf->len;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
- napi_gro_frags(napi, &info);
+ napi_gro_frags(napi);
+out:
EFX_BUG_ON_PARANOID(rx_buf->skb);
rx_buf->page = NULL;
} else {
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 0a598084c51..b67ccca3fc1 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -80,39 +80,38 @@ struct efx_loopback_state {
*
**************************************************************************/
-static int efx_test_mii(struct efx_nic *efx, struct efx_self_tests *tests)
+static int efx_test_mdio(struct efx_nic *efx, struct efx_self_tests *tests)
{
int rc = 0;
+ int devad = __ffs(efx->mdio.mmds);
u16 physid1, physid2;
- struct mii_if_info *mii = &efx->mii;
- struct net_device *net_dev = efx->net_dev;
if (efx->phy_type == PHY_TYPE_NONE)
return 0;
mutex_lock(&efx->mac_lock);
- tests->mii = -1;
+ tests->mdio = -1;
- physid1 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID1);
- physid2 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID2);
+ physid1 = efx_mdio_read(efx, devad, MDIO_DEVID1);
+ physid2 = efx_mdio_read(efx, devad, MDIO_DEVID2);
if ((physid1 == 0x0000) || (physid1 == 0xffff) ||
(physid2 == 0x0000) || (physid2 == 0xffff)) {
- EFX_ERR(efx, "no MII PHY present with ID %d\n",
- mii->phy_id);
+ EFX_ERR(efx, "no MDIO PHY present with ID %d\n",
+ efx->mdio.prtad);
rc = -EINVAL;
goto out;
}
if (EFX_IS10G(efx)) {
- rc = mdio_clause45_check_mmds(efx, efx->phy_op->mmds, 0);
+ rc = efx_mdio_check_mmds(efx, efx->phy_op->mmds, 0);
if (rc)
goto out;
}
out:
mutex_unlock(&efx->mac_lock);
- tests->mii = rc ? -1 : 1;
+ tests->mdio = rc ? -1 : 1;
return rc;
}
@@ -439,6 +438,7 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
kfree_skb(skb);
return -EPIPE;
}
+ efx->net_dev->trans_start = jiffies;
}
return 0;
@@ -673,7 +673,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
/* Online (i.e. non-disruptive) testing
* This checks interrupt generation, event delivery and PHY presence. */
- rc = efx_test_mii(efx, tests);
+ rc = efx_test_mdio(efx, tests);
if (rc && !rc_test)
rc_test = rc;
diff --git a/drivers/net/sfc/selftest.h b/drivers/net/sfc/selftest.h
index 39451cf938c..f6feee04c96 100644
--- a/drivers/net/sfc/selftest.h
+++ b/drivers/net/sfc/selftest.h
@@ -32,7 +32,7 @@ struct efx_loopback_self_tests {
*/
struct efx_self_tests {
/* online tests */
- int mii;
+ int mdio;
int nvram;
int interrupt;
int eventq_dma[EFX_MAX_CHANNELS];
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index 4eac5da81e5..cee00ad49b5 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -296,7 +296,6 @@ static int sfe4001_check_hw(struct efx_nic *efx)
static struct i2c_board_info sfe4001_hwmon_info = {
I2C_BOARD_INFO("max6647", 0x4e),
- .irq = -1,
};
/* This board uses an I2C expander to provider power to the PHY, which needs to
@@ -389,12 +388,10 @@ static void sfn4111t_fini(struct efx_nic *efx)
static struct i2c_board_info sfn4111t_a0_hwmon_info = {
I2C_BOARD_INFO("max6647", 0x4e),
- .irq = -1,
};
static struct i2c_board_info sfn4111t_r5_hwmon_info = {
I2C_BOARD_INFO("max6646", 0x4d),
- .irq = -1,
};
int sfn4111t_init(struct efx_nic *efx)
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index e61dc4d4741..f4d509015f7 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -23,10 +23,10 @@
* clause 22 extension MMD, but since it doesn't have all the generic
* MMD registers it is pointless to include it here.
*/
-#define TENXPRESS_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PMAPMD | \
- MDIO_MMDREG_DEVS_PCS | \
- MDIO_MMDREG_DEVS_PHYXS | \
- MDIO_MMDREG_DEVS_AN)
+#define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD | \
+ MDIO_DEVS_PCS | \
+ MDIO_DEVS_PHYXS | \
+ MDIO_DEVS_AN)
#define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \
(1 << LOOPBACK_PCS) | \
@@ -44,18 +44,6 @@
*/
#define MAX_BAD_LP_TRIES (5)
-/* LASI Control */
-#define PMA_PMD_LASI_CTRL 36866
-#define PMA_PMD_LASI_STATUS 36869
-#define PMA_PMD_LS_ALARM_LBN 0
-#define PMA_PMD_LS_ALARM_WIDTH 1
-#define PMA_PMD_TX_ALARM_LBN 1
-#define PMA_PMD_TX_ALARM_WIDTH 1
-#define PMA_PMD_RX_ALARM_LBN 2
-#define PMA_PMD_RX_ALARM_WIDTH 1
-#define PMA_PMD_AN_ALARM_LBN 3
-#define PMA_PMD_AN_ALARM_WIDTH 1
-
/* Extended control register */
#define PMA_PMD_XCONTROL_REG 49152
#define PMA_PMD_EXT_GMII_EN_LBN 1
@@ -75,6 +63,7 @@
/* extended status register */
#define PMA_PMD_XSTATUS_REG 49153
+#define PMA_PMD_XSTAT_MDIX_LBN 14
#define PMA_PMD_XSTAT_FLP_LBN (12)
/* LED control register */
@@ -153,10 +142,6 @@
#define LOOPBACK_NEAR_LBN (8)
#define LOOPBACK_NEAR_WIDTH (1)
-#define PCS_10GBASET_STAT1 32
-#define PCS_10GBASET_BLKLK_LBN 0
-#define PCS_10GBASET_BLKLK_WIDTH 1
-
/* Boot status register */
#define PCS_BOOT_STATUS_REG 53248
#define PCS_BOOT_FATAL_ERROR_LBN 0
@@ -206,10 +191,8 @@ static ssize_t show_phy_short_reach(struct device *dev,
struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
int reg;
- reg = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- MDIO_PMAPMD_10GBT_TXPWR);
- return sprintf(buf, "%d\n",
- !!(reg & (1 << MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN)));
+ reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR);
+ return sprintf(buf, "%d\n", !!(reg & MDIO_PMA_10GBT_TXPWR_SHORT));
}
static ssize_t set_phy_short_reach(struct device *dev,
@@ -219,10 +202,9 @@ static ssize_t set_phy_short_reach(struct device *dev,
struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
rtnl_lock();
- mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- MDIO_PMAPMD_10GBT_TXPWR,
- MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN,
- count != 0 && *buf != '0');
+ efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR,
+ MDIO_PMA_10GBT_TXPWR_SHORT,
+ count != 0 && *buf != '0');
efx_reconfigure_port(efx);
rtnl_unlock();
@@ -238,9 +220,8 @@ int sft9001_wait_boot(struct efx_nic *efx)
int boot_stat;
for (;;) {
- boot_stat = mdio_clause45_read(efx, efx->mii.phy_id,
- MDIO_MMD_PCS,
- PCS_BOOT_STATUS_REG);
+ boot_stat = efx_mdio_read(efx, MDIO_MMD_PCS,
+ PCS_BOOT_STATUS_REG);
if (boot_stat >= 0) {
EFX_LOG(efx, "PHY boot status = %#x\n", boot_stat);
switch (boot_stat &
@@ -286,38 +267,32 @@ int sft9001_wait_boot(struct efx_nic *efx)
static int tenxpress_init(struct efx_nic *efx)
{
- int phy_id = efx->mii.phy_id;
int reg;
if (efx->phy_type == PHY_TYPE_SFX7101) {
/* Enable 312.5 MHz clock */
- mdio_clause45_write(efx, phy_id,
- MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
- 1 << CLK312_EN_LBN);
+ efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
+ 1 << CLK312_EN_LBN);
} else {
/* Enable 312.5 MHz clock and GMII */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG);
+ reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) |
(1 << PMA_PMD_EXT_CLK_OUT_LBN) |
(1 << PMA_PMD_EXT_CLK312_LBN) |
(1 << PMA_PMD_EXT_ROBUST_LBN));
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG, reg);
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
- GPHY_XCONTROL_REG, GPHY_ISOLATE_LBN,
- false);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
+ efx_mdio_set_flag(efx, MDIO_MMD_C22EXT,
+ GPHY_XCONTROL_REG, 1 << GPHY_ISOLATE_LBN,
+ false);
}
/* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
if (efx->phy_type == PHY_TYPE_SFX7101) {
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_LED_CTRL_REG,
- PMA_PMA_LED_ACTIVITY_LBN,
- true);
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_LED_OVERR_REG, PMA_PMD_LED_DEFAULT);
+ efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG,
+ 1 << PMA_PMA_LED_ACTIVITY_LBN, true);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG,
+ PMA_PMD_LED_DEFAULT);
}
return 0;
@@ -337,22 +312,19 @@ static int tenxpress_phy_init(struct efx_nic *efx)
if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
if (efx->phy_type == PHY_TYPE_SFT9001A) {
int reg;
- reg = mdio_clause45_read(efx, efx->mii.phy_id,
- MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG);
+ reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+ PMA_PMD_XCONTROL_REG);
reg |= (1 << PMA_PMD_EXT_SSR_LBN);
- mdio_clause45_write(efx, efx->mii.phy_id,
- MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG, reg);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD,
+ PMA_PMD_XCONTROL_REG, reg);
mdelay(200);
}
- rc = mdio_clause45_wait_reset_mmds(efx,
- TENXPRESS_REQUIRED_DEVS);
+ rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
if (rc < 0)
goto fail;
- rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
+ rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
if (rc < 0)
goto fail;
}
@@ -360,7 +332,6 @@ static int tenxpress_phy_init(struct efx_nic *efx)
rc = tenxpress_init(efx);
if (rc < 0)
goto fail;
- mdio_clause45_set_pause(efx);
if (efx->phy_type == PHY_TYPE_SFT9001B) {
rc = device_create_file(&efx->pci_dev->dev,
@@ -395,17 +366,14 @@ static int tenxpress_special_reset(struct efx_nic *efx)
efx_stats_disable(efx);
/* Initiate reset */
- reg = mdio_clause45_read(efx, efx->mii.phy_id,
- MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
+ reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
reg |= (1 << PMA_PMD_EXT_SSR_LBN);
- mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG, reg);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
mdelay(200);
/* Wait for the blocks to come out of reset */
- rc = mdio_clause45_wait_reset_mmds(efx,
- TENXPRESS_REQUIRED_DEVS);
+ rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
if (rc < 0)
goto out;
@@ -424,7 +392,6 @@ out:
static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
{
struct tenxpress_phy_data *pd = efx->phy_data;
- int phy_id = efx->mii.phy_id;
bool bad_lp;
int reg;
@@ -432,11 +399,10 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
bad_lp = false;
} else {
/* Check that AN has started but not completed. */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_STATUS);
- if (!(reg & (1 << MDIO_AN_STATUS_LP_AN_CAP_LBN)))
+ reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_STAT1);
+ if (!(reg & MDIO_AN_STAT1_LPABLE))
return; /* LP status is unknown */
- bad_lp = !(reg & (1 << MDIO_AN_STATUS_AN_DONE_LBN));
+ bad_lp = !(reg & MDIO_AN_STAT1_COMPLETE);
if (bad_lp)
pd->bad_lp_tries++;
}
@@ -448,8 +414,8 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
/* Use the RX (red) LED as an error indicator once we've seen AN
* failure several times in a row, and also log a message. */
if (!bad_lp || pd->bad_lp_tries == MAX_BAD_LP_TRIES) {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_LED_OVERR_REG);
+ reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+ PMA_PMD_LED_OVERR_REG);
reg &= ~(PMA_PMD_LED_MASK << PMA_PMD_LED_RX_LBN);
if (!bad_lp) {
reg |= PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN;
@@ -460,23 +426,22 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
" supports 10GBASE-T ONLY, so no link can"
" be established\n");
}
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_LED_OVERR_REG, reg);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD,
+ PMA_PMD_LED_OVERR_REG, reg);
pd->bad_lp_tries = bad_lp;
}
}
static bool sfx7101_link_ok(struct efx_nic *efx)
{
- return mdio_clause45_links_ok(efx,
- MDIO_MMDREG_DEVS_PMAPMD |
- MDIO_MMDREG_DEVS_PCS |
- MDIO_MMDREG_DEVS_PHYXS);
+ return efx_mdio_links_ok(efx,
+ MDIO_DEVS_PMAPMD |
+ MDIO_DEVS_PCS |
+ MDIO_DEVS_PHYXS);
}
static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- int phy_id = efx->mii.phy_id;
u32 reg;
if (efx_phy_mode_disabled(efx->phy_mode))
@@ -484,50 +449,43 @@ static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd)
else if (efx->loopback_mode == LOOPBACK_GPHY)
return true;
else if (efx->loopback_mode)
- return mdio_clause45_links_ok(efx,
- MDIO_MMDREG_DEVS_PMAPMD |
- MDIO_MMDREG_DEVS_PHYXS);
+ return efx_mdio_links_ok(efx,
+ MDIO_DEVS_PMAPMD |
+ MDIO_DEVS_PHYXS);
/* We must use the same definition of link state as LASI,
* otherwise we can miss a link state transition
*/
if (ecmd->speed == 10000) {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
- PCS_10GBASET_STAT1);
- return reg & (1 << PCS_10GBASET_BLKLK_LBN);
+ reg = efx_mdio_read(efx, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1);
+ return reg & MDIO_PCS_10GBRT_STAT1_BLKLK;
} else {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
- C22EXT_STATUS_REG);
+ reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_STATUS_REG);
return reg & (1 << C22EXT_STATUS_LINK_LBN);
}
}
static void tenxpress_ext_loopback(struct efx_nic *efx)
{
- int phy_id = efx->mii.phy_id;
-
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS,
- PHYXS_TEST1, LOOPBACK_NEAR_LBN,
- efx->loopback_mode == LOOPBACK_PHYXS);
+ efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, PHYXS_TEST1,
+ 1 << LOOPBACK_NEAR_LBN,
+ efx->loopback_mode == LOOPBACK_PHYXS);
if (efx->phy_type != PHY_TYPE_SFX7101)
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
- GPHY_XCONTROL_REG,
- GPHY_LOOPBACK_NEAR_LBN,
- efx->loopback_mode == LOOPBACK_GPHY);
+ efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, GPHY_XCONTROL_REG,
+ 1 << GPHY_LOOPBACK_NEAR_LBN,
+ efx->loopback_mode == LOOPBACK_GPHY);
}
static void tenxpress_low_power(struct efx_nic *efx)
{
- int phy_id = efx->mii.phy_id;
-
if (efx->phy_type == PHY_TYPE_SFX7101)
- mdio_clause45_set_mmds_lpower(
+ efx_mdio_set_mmds_lpower(
efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER),
TENXPRESS_REQUIRED_DEVS);
else
- mdio_clause45_set_flag(
- efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG, PMA_PMD_EXT_LPOWER_LBN,
+ efx_mdio_set_flag(
+ efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG,
+ 1 << PMA_PMD_EXT_LPOWER_LBN,
!!(efx->phy_mode & PHY_MODE_LOW_POWER));
}
@@ -568,8 +526,8 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
WARN_ON(rc);
}
- mdio_clause45_transmit_disable(efx);
- mdio_clause45_phy_reconfigure(efx);
+ efx_mdio_transmit_disable(efx);
+ efx_mdio_phy_reconfigure(efx);
tenxpress_ext_loopback(efx);
phy_data->loopback_mode = efx->loopback_mode;
@@ -585,7 +543,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
efx->link_fd = ecmd.duplex == DUPLEX_FULL;
efx->link_up = sft9001_link_ok(efx, &ecmd);
}
- efx->link_fc = mdio_clause45_get_pause(efx);
+ efx->link_fc = efx_mdio_get_pause(efx);
}
/* Poll PHY for interrupt */
@@ -599,7 +557,7 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
if (link_ok != efx->link_up) {
change = true;
} else {
- unsigned int link_fc = mdio_clause45_get_pause(efx);
+ unsigned int link_fc = efx_mdio_get_pause(efx);
if (link_fc != efx->link_fc)
change = true;
}
@@ -609,10 +567,9 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
if (link_ok != efx->link_up)
change = true;
} else {
- u32 status = mdio_clause45_read(efx, efx->mii.phy_id,
- MDIO_MMD_PMAPMD,
- PMA_PMD_LASI_STATUS);
- if (status & (1 << PMA_PMD_LS_ALARM_LBN))
+ int status = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+ MDIO_PMA_LASI_STAT);
+ if (status & MDIO_PMA_LASI_LSALARM)
change = true;
}
@@ -634,8 +591,7 @@ static void tenxpress_phy_fini(struct efx_nic *efx)
if (efx->phy_type == PHY_TYPE_SFX7101) {
/* Power down the LNPGA */
reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN);
- mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG, reg);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
/* Waiting here ensures that the board fini, which can turn
* off the power to the PHY, won't get run until the LNPGA
@@ -661,8 +617,7 @@ void tenxpress_phy_blink(struct efx_nic *efx, bool blink)
else
reg = PMA_PMD_LED_DEFAULT;
- mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_LED_OVERR_REG, reg);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg);
}
static const char *const sfx7101_test_names[] = {
@@ -698,7 +653,6 @@ static const char *const sft9001_test_names[] = {
static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
{
struct ethtool_cmd ecmd;
- int phy_id = efx->mii.phy_id;
int rc = 0, rc2, i, ctrl_reg, res_reg;
if (flags & ETH_TEST_FL_OFFLINE)
@@ -717,11 +671,10 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
* must reset the PHY to resume normal service. */
ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN);
}
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_CDIAG_CTRL_REG, ctrl_reg);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG,
+ ctrl_reg);
i = 0;
- while (mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_CDIAG_CTRL_REG) &
+ while (efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG) &
(1 << CDIAG_CTRL_IN_PROG_LBN)) {
if (++i == 50) {
rc = -ETIMEDOUT;
@@ -729,15 +682,13 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
}
msleep(100);
}
- res_reg = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_CDIAG_RES_REG);
+ res_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_RES_REG);
for (i = 0; i < 4; i++) {
int pair_res =
(res_reg >> (CDIAG_RES_A_LBN - i * CDIAG_RES_WIDTH))
& ((1 << CDIAG_RES_WIDTH) - 1);
- int len_reg = mdio_clause45_read(efx, efx->mii.phy_id,
- MDIO_MMD_PMAPMD,
- PMA_PMD_CDIAG_LEN_REG + i);
+ int len_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+ PMA_PMD_CDIAG_LEN_REG + i);
if (pair_res == CDIAG_RES_OK)
results[1 + i] = 1;
else if (pair_res == CDIAG_RES_INVALID)
@@ -769,36 +720,39 @@ out:
static void
tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- int phy_id = efx->mii.phy_id;
u32 adv = 0, lpa = 0;
int reg;
if (efx->phy_type != PHY_TYPE_SFX7101) {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
- C22EXT_MSTSLV_CTRL);
+ reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL);
if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN))
adv |= ADVERTISED_1000baseT_Full;
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
- C22EXT_MSTSLV_STATUS);
+ reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_STATUS);
if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN))
lpa |= ADVERTISED_1000baseT_Half;
if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN))
lpa |= ADVERTISED_1000baseT_Full;
}
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_10GBT_CTRL);
- if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN))
+ reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL);
+ if (reg & MDIO_AN_10GBT_CTRL_ADV10G)
adv |= ADVERTISED_10000baseT_Full;
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_10GBT_STATUS);
- if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN))
+ reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
+ if (reg & MDIO_AN_10GBT_STAT_LP10G)
lpa |= ADVERTISED_10000baseT_Full;
- mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa);
+ mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa);
- if (efx->phy_type != PHY_TYPE_SFX7101)
+ if (efx->phy_type != PHY_TYPE_SFX7101) {
ecmd->supported |= (SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full);
+ if (ecmd->speed != SPEED_10000) {
+ ecmd->eth_tp_mdix =
+ (efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+ PMA_PMD_XSTATUS_REG) &
+ (1 << PMA_PMD_XSTAT_MDIX_LBN))
+ ? ETH_TP_MDI_X : ETH_TP_MDI;
+ }
+ }
/* In loopback, the PHY automatically brings up the correct interface,
* but doesn't advertise the correct speed. So override it */
@@ -813,29 +767,24 @@ static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
if (!ecmd->autoneg)
return -EINVAL;
- return mdio_clause45_set_settings(efx, ecmd);
+ return efx_mdio_set_settings(efx, ecmd);
}
static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
{
- mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
- MDIO_AN_10GBT_CTRL,
- MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
- advertising & ADVERTISED_10000baseT_Full);
+ efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
+ MDIO_AN_10GBT_CTRL_ADV10G,
+ advertising & ADVERTISED_10000baseT_Full);
}
static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising)
{
- int phy_id = efx->mii.phy_id;
-
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
- C22EXT_MSTSLV_CTRL,
- C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
- advertising & ADVERTISED_1000baseT_Full);
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_10GBT_CTRL,
- MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
- advertising & ADVERTISED_10000baseT_Full);
+ efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL,
+ 1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
+ advertising & ADVERTISED_1000baseT_Full);
+ efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
+ MDIO_AN_10GBT_CTRL_ADV10G,
+ advertising & ADVERTISED_10000baseT_Full);
}
struct efx_phy_operations falcon_sfx7101_phy_ops = {
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index d6681edb701..14a14788566 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -360,13 +360,6 @@ inline int efx_xmit(struct efx_nic *efx,
/* Map fragments for DMA and add to TX queue */
rc = efx_enqueue_skb(tx_queue, skb);
- if (unlikely(rc != NETDEV_TX_OK))
- goto out;
-
- /* Update last TX timer */
- efx->net_dev->trans_start = jiffies;
-
- out:
return rc;
}
diff --git a/drivers/net/sfc/xenpack.h b/drivers/net/sfc/xenpack.h
deleted file mode 100644
index b0d1f225b70..00000000000
--- a/drivers/net/sfc/xenpack.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2006 Solarflare Communications Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation, incorporated herein by reference.
- */
-
-#ifndef EFX_XENPACK_H
-#define EFX_XENPACK_H
-
-/* Exported functions from Xenpack standard PHY control */
-
-#include "mdio_10g.h"
-
-/****************************************************************************/
-/* XENPACK MDIO register extensions */
-#define MDIO_XP_LASI_RX_CTRL (0x9000)
-#define MDIO_XP_LASI_TX_CTRL (0x9001)
-#define MDIO_XP_LASI_CTRL (0x9002)
-#define MDIO_XP_LASI_RX_STAT (0x9003)
-#define MDIO_XP_LASI_TX_STAT (0x9004)
-#define MDIO_XP_LASI_STAT (0x9005)
-
-/* Control/Status bits */
-#define XP_LASI_LS_ALARM (1 << 0)
-#define XP_LASI_TX_ALARM (1 << 1)
-#define XP_LASI_RX_ALARM (1 << 2)
-/* These two are Quake vendor extensions to the standard XENPACK defines */
-#define XP_LASI_LS_INTB (1 << 3)
-#define XP_LASI_TEST (1 << 7)
-
-/* Enable LASI interrupts for PHY */
-static inline void xenpack_enable_lasi_irqs(struct efx_nic *efx)
-{
- int reg;
- int phy_id = efx->mii.phy_id;
- /* Read to clear LASI status register */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_XP_LASI_STAT);
-
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_XP_LASI_CTRL, XP_LASI_LS_ALARM);
-}
-
-/* Read the LASI interrupt status to clear the interrupt. */
-static inline int xenpack_clear_lasi_irqs(struct efx_nic *efx)
-{
- /* Read to clear link status alarm */
- return mdio_clause45_read(efx, efx->mii.phy_id,
- MDIO_MMD_PMAPMD, MDIO_XP_LASI_STAT);
-}
-
-/* Turn off LASI interrupts */
-static inline void xenpack_disable_lasi_irqs(struct efx_nic *efx)
-{
- mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- MDIO_XP_LASI_CTRL, 0);
-}
-
-#endif /* EFX_XENPACK_H */
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index bb1ef77d5f5..bb2e6afd082 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -15,13 +15,12 @@
#include <linux/delay.h>
#include "efx.h"
#include "mdio_10g.h"
-#include "xenpack.h"
#include "phy.h"
#include "falcon.h"
-#define XFP_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PCS | \
- MDIO_MMDREG_DEVS_PMAPMD | \
- MDIO_MMDREG_DEVS_PHYXS)
+#define XFP_REQUIRED_DEVS (MDIO_DEVS_PCS | \
+ MDIO_DEVS_PMAPMD | \
+ MDIO_DEVS_PHYXS)
#define XFP_LOOPBACKS ((1 << LOOPBACK_PCS) | \
(1 << LOOPBACK_PMAPMD) | \
@@ -49,8 +48,7 @@
void xfp_set_led(struct efx_nic *p, int led, int mode)
{
int addr = MDIO_QUAKE_LED0_REG + led;
- mdio_clause45_write(p, p->mii.phy_id, MDIO_MMD_PMAPMD, addr,
- mode);
+ efx_mdio_write(p, MDIO_MMD_PMAPMD, addr, mode);
}
struct xfp_phy_data {
@@ -63,14 +61,12 @@ struct xfp_phy_data {
static int qt2025c_wait_reset(struct efx_nic *efx)
{
unsigned long timeout = jiffies + 10 * HZ;
- int phy_id = efx->mii.phy_id;
int reg, old_counter = 0;
/* Wait for firmware heartbeat to start */
for (;;) {
int counter;
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
- PCS_FW_HEARTBEAT_REG);
+ reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_FW_HEARTBEAT_REG);
if (reg < 0)
return reg;
counter = ((reg >> PCS_FW_HEARTB_LBN) &
@@ -86,8 +82,7 @@ static int qt2025c_wait_reset(struct efx_nic *efx)
/* Wait for firmware status to look good */
for (;;) {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
- PCS_UC8051_STATUS_REG);
+ reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG);
if (reg < 0)
return reg;
if ((reg &
@@ -109,9 +104,9 @@ static int xfp_reset_phy(struct efx_nic *efx)
{
int rc;
- rc = mdio_clause45_reset_mmd(efx, MDIO_MMD_PHYXS,
- XFP_MAX_RESET_TIME / XFP_RESET_WAIT,
- XFP_RESET_WAIT);
+ rc = efx_mdio_reset_mmd(efx, MDIO_MMD_PHYXS,
+ XFP_MAX_RESET_TIME / XFP_RESET_WAIT,
+ XFP_RESET_WAIT);
if (rc < 0)
goto fail;
@@ -126,8 +121,7 @@ static int xfp_reset_phy(struct efx_nic *efx)
/* Check that all the MMDs we expect are present and responding. We
* expect faults on some if the link is down, but not on the PHY XS */
- rc = mdio_clause45_check_mmds(efx, XFP_REQUIRED_DEVS,
- MDIO_MMDREG_DEVS_PHYXS);
+ rc = efx_mdio_check_mmds(efx, XFP_REQUIRED_DEVS, MDIO_DEVS_PHYXS);
if (rc < 0)
goto fail;
@@ -143,7 +137,7 @@ static int xfp_reset_phy(struct efx_nic *efx)
static int xfp_phy_init(struct efx_nic *efx)
{
struct xfp_phy_data *phy_data;
- u32 devid = mdio_clause45_read_id(efx, MDIO_MMD_PHYXS);
+ u32 devid = efx_mdio_read_id(efx, MDIO_MMD_PHYXS);
int rc;
phy_data = kzalloc(sizeof(struct xfp_phy_data), GFP_KERNEL);
@@ -152,8 +146,8 @@ static int xfp_phy_init(struct efx_nic *efx)
efx->phy_data = phy_data;
EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n",
- devid, mdio_id_oui(devid), mdio_id_model(devid),
- mdio_id_rev(devid));
+ devid, efx_mdio_id_oui(devid), efx_mdio_id_model(devid),
+ efx_mdio_id_rev(devid));
phy_data->phy_mode = efx->phy_mode;
@@ -174,12 +168,13 @@ static int xfp_phy_init(struct efx_nic *efx)
static void xfp_phy_clear_interrupt(struct efx_nic *efx)
{
- xenpack_clear_lasi_irqs(efx);
+ /* Read to clear link status alarm */
+ efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT);
}
static int xfp_link_ok(struct efx_nic *efx)
{
- return mdio_clause45_links_ok(efx, XFP_REQUIRED_DEVS);
+ return efx_mdio_links_ok(efx, XFP_REQUIRED_DEVS);
}
static void xfp_phy_poll(struct efx_nic *efx)
@@ -200,9 +195,9 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
* or optical transceivers, varying somewhat between
* firmware versions. Only 'static mode' appears to
* cover everything. */
- mdio_clause45_set_flag(
- efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_FTX_CTRL2_REG, PMA_PMD_FTX_STATIC_LBN,
+ mdio_set_flag(
+ &efx->mdio, efx->mdio.prtad, MDIO_MMD_PMAPMD,
+ PMA_PMD_FTX_CTRL2_REG, 1 << PMA_PMD_FTX_STATIC_LBN,
efx->phy_mode & PHY_MODE_TX_DISABLED ||
efx->phy_mode & PHY_MODE_LOW_POWER ||
efx->loopback_mode == LOOPBACK_PCS ||
@@ -213,10 +208,10 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
(phy_data->phy_mode & PHY_MODE_TX_DISABLED))
xfp_reset_phy(efx);
- mdio_clause45_transmit_disable(efx);
+ efx_mdio_transmit_disable(efx);
}
- mdio_clause45_phy_reconfigure(efx);
+ efx_mdio_phy_reconfigure(efx);
phy_data->phy_mode = efx->phy_mode;
efx->link_up = xfp_link_ok(efx);
@@ -225,6 +220,10 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
efx->link_fc = efx->wanted_fc;
}
+static void xfp_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+{
+ mdio45_ethtool_gset(&efx->mdio, ecmd);
+}
static void xfp_phy_fini(struct efx_nic *efx)
{
@@ -243,8 +242,8 @@ struct efx_phy_operations falcon_xfp_phy_ops = {
.poll = xfp_phy_poll,
.fini = xfp_phy_fini,
.clear_interrupt = xfp_phy_clear_interrupt,
- .get_settings = mdio_clause45_get_settings,
- .set_settings = mdio_clause45_set_settings,
+ .get_settings = xfp_phy_get_settings,
+ .set_settings = efx_mdio_set_settings,
.mmds = XFP_REQUIRED_DEVS,
.loopbacks = XFP_LOOPBACKS,
};
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index 97d68560067..5fb88ca6dd7 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -709,6 +709,17 @@ static inline void setup_rx_ring(struct net_device *dev,
dma_sync_desc_dev(dev, &buf[i]);
}
+static const struct net_device_ops sgiseeq_netdev_ops = {
+ .ndo_open = sgiseeq_open,
+ .ndo_stop = sgiseeq_close,
+ .ndo_start_xmit = sgiseeq_start_xmit,
+ .ndo_tx_timeout = timeout,
+ .ndo_set_multicast_list = sgiseeq_set_multicast,
+ .ndo_set_mac_address = sgiseeq_set_mac_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __init sgiseeq_probe(struct platform_device *pdev)
{
struct sgiseeq_platform_data *pd = pdev->dev.platform_data;
@@ -775,13 +786,8 @@ static int __init sgiseeq_probe(struct platform_device *pdev)
SEEQ_CTRL_SFLAG | SEEQ_CTRL_ESHORT |
SEEQ_CTRL_ENCARR;
- dev->open = sgiseeq_open;
- dev->stop = sgiseeq_close;
- dev->hard_start_xmit = sgiseeq_start_xmit;
- dev->tx_timeout = timeout;
+ dev->netdev_ops = &sgiseeq_netdev_ops;
dev->watchdog_timeo = (200 * HZ) / 1000;
- dev->set_multicast_list = sgiseeq_set_multicast;
- dev->set_mac_address = sgiseeq_set_mac_address;
dev->irq = irq;
if (register_netdev(dev)) {
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 3ab28bb00c1..341882f959f 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -2,7 +2,7 @@
* SuperH Ethernet device driver
*
* Copyright (C) 2006-2008 Nobuhiro Iwamatsu
- * Copyright (C) 2008 Renesas Solutions Corp.
+ * Copyright (C) 2008-2009 Renesas Solutions Corp.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -33,6 +33,226 @@
#include "sh_eth.h"
+/* There is CPU dependent code */
+#if defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define SH_ETH_RESET_DEFAULT 1
+static void sh_eth_set_duplex(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ u32 ioaddr = ndev->base_addr;
+
+ if (mdp->duplex) /* Full */
+ ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
+ else /* Half */
+ ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
+}
+
+static void sh_eth_set_rate(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ u32 ioaddr = ndev->base_addr;
+
+ switch (mdp->speed) {
+ case 10: /* 10BASE */
+ ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_RTM, ioaddr + ECMR);
+ break;
+ case 100:/* 100BASE */
+ ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_RTM, ioaddr + ECMR);
+ break;
+ default:
+ break;
+ }
+}
+
+/* SH7724 */
+static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+ .set_duplex = sh_eth_set_duplex,
+ .set_rate = sh_eth_set_rate,
+
+ .ecsr_value = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
+ .ecsipr_value = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
+ .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x01ff009f,
+
+ .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
+ .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE |
+ EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI,
+ .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,
+
+ .apr = 1,
+ .mpr = 1,
+ .tpauser = 1,
+ .hw_swap = 1,
+};
+
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
+#define SH_ETH_HAS_TSU 1
+static void sh_eth_chip_reset(struct net_device *ndev)
+{
+ /* reset device */
+ ctrl_outl(ARSTR_ARSTR, ARSTR);
+ mdelay(1);
+}
+
+static void sh_eth_reset(struct net_device *ndev)
+{
+ u32 ioaddr = ndev->base_addr;
+ int cnt = 100;
+
+ ctrl_outl(EDSR_ENALL, ioaddr + EDSR);
+ ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
+ while (cnt > 0) {
+ if (!(ctrl_inl(ioaddr + EDMR) & 0x3))
+ break;
+ mdelay(1);
+ cnt--;
+ }
+ if (cnt < 0)
+ printk(KERN_ERR "Device reset fail\n");
+
+ /* Table Init */
+ ctrl_outl(0x0, ioaddr + TDLAR);
+ ctrl_outl(0x0, ioaddr + TDFAR);
+ ctrl_outl(0x0, ioaddr + TDFXR);
+ ctrl_outl(0x0, ioaddr + TDFFR);
+ ctrl_outl(0x0, ioaddr + RDLAR);
+ ctrl_outl(0x0, ioaddr + RDFAR);
+ ctrl_outl(0x0, ioaddr + RDFXR);
+ ctrl_outl(0x0, ioaddr + RDFFR);
+}
+
+static void sh_eth_set_duplex(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ u32 ioaddr = ndev->base_addr;
+
+ if (mdp->duplex) /* Full */
+ ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
+ else /* Half */
+ ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
+}
+
+static void sh_eth_set_rate(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ u32 ioaddr = ndev->base_addr;
+
+ switch (mdp->speed) {
+ case 10: /* 10BASE */
+ ctrl_outl(GECMR_10, ioaddr + GECMR);
+ break;
+ case 100:/* 100BASE */
+ ctrl_outl(GECMR_100, ioaddr + GECMR);
+ break;
+ case 1000: /* 1000BASE */
+ ctrl_outl(GECMR_1000, ioaddr + GECMR);
+ break;
+ default:
+ break;
+ }
+}
+
+/* sh7763 */
+static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+ .chip_reset = sh_eth_chip_reset,
+ .set_duplex = sh_eth_set_duplex,
+ .set_rate = sh_eth_set_rate,
+
+ .ecsr_value = ECSR_ICD | ECSR_MPD,
+ .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
+ .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
+
+ .tx_check = EESR_TC1 | EESR_FTC,
+ .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
+ EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
+ EESR_ECI,
+ .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
+ EESR_TFE,
+
+ .apr = 1,
+ .mpr = 1,
+ .tpauser = 1,
+ .bculr = 1,
+ .hw_swap = 1,
+ .rpadir = 1,
+ .no_trimd = 1,
+ .no_ade = 1,
+};
+
+#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
+#define SH_ETH_RESET_DEFAULT 1
+static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+ .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
+
+ .apr = 1,
+ .mpr = 1,
+ .tpauser = 1,
+ .hw_swap = 1,
+};
+#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
+#define SH_ETH_RESET_DEFAULT 1
+#define SH_ETH_HAS_TSU 1
+static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+ .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
+};
+#endif
+
+static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
+{
+ if (!cd->ecsr_value)
+ cd->ecsr_value = DEFAULT_ECSR_INIT;
+
+ if (!cd->ecsipr_value)
+ cd->ecsipr_value = DEFAULT_ECSIPR_INIT;
+
+ if (!cd->fcftr_value)
+ cd->fcftr_value = DEFAULT_FIFO_F_D_RFF | \
+ DEFAULT_FIFO_F_D_RFD;
+
+ if (!cd->fdr_value)
+ cd->fdr_value = DEFAULT_FDR_INIT;
+
+ if (!cd->rmcr_value)
+ cd->rmcr_value = DEFAULT_RMCR_VALUE;
+
+ if (!cd->tx_check)
+ cd->tx_check = DEFAULT_TX_CHECK;
+
+ if (!cd->eesr_err_check)
+ cd->eesr_err_check = DEFAULT_EESR_ERR_CHECK;
+
+ if (!cd->tx_error_check)
+ cd->tx_error_check = DEFAULT_TX_ERROR_CHECK;
+}
+
+#if defined(SH_ETH_RESET_DEFAULT)
+/* Chip Reset */
+static void sh_eth_reset(struct net_device *ndev)
+{
+ u32 ioaddr = ndev->base_addr;
+
+ ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
+ mdelay(3);
+ ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR);
+}
+#endif
+
+#if defined(CONFIG_CPU_SH4)
+static void sh_eth_set_receive_align(struct sk_buff *skb)
+{
+ int reserve;
+
+ reserve = SH4_SKB_RX_ALIGN - ((u32)skb->data & (SH4_SKB_RX_ALIGN - 1));
+ if (reserve)
+ skb_reserve(skb, reserve);
+}
+#else
+static void sh_eth_set_receive_align(struct sk_buff *skb)
+{
+ skb_reserve(skb, SH2_SH3_SKB_RX_ALIGN);
+}
+#endif
+
+
/* CPU <-> EDMAC endian convert */
static inline __u32 cpu_to_edmac(struct sh_eth_private *mdp, u32 x)
{
@@ -165,41 +385,6 @@ static struct mdiobb_ops bb_ops = {
.get_mdio_data = sh_get_mdio,
};
-/* Chip Reset */
-static void sh_eth_reset(struct net_device *ndev)
-{
- u32 ioaddr = ndev->base_addr;
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- int cnt = 100;
-
- ctrl_outl(EDSR_ENALL, ioaddr + EDSR);
- ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
- while (cnt > 0) {
- if (!(ctrl_inl(ioaddr + EDMR) & 0x3))
- break;
- mdelay(1);
- cnt--;
- }
- if (cnt < 0)
- printk(KERN_ERR "Device reset fail\n");
-
- /* Table Init */
- ctrl_outl(0x0, ioaddr + TDLAR);
- ctrl_outl(0x0, ioaddr + TDFAR);
- ctrl_outl(0x0, ioaddr + TDFXR);
- ctrl_outl(0x0, ioaddr + TDFFR);
- ctrl_outl(0x0, ioaddr + RDLAR);
- ctrl_outl(0x0, ioaddr + RDFAR);
- ctrl_outl(0x0, ioaddr + RDFXR);
- ctrl_outl(0x0, ioaddr + RDFFR);
-#else
- ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
- mdelay(3);
- ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR);
-#endif
-}
-
/* free skb and descriptor buffer */
static void sh_eth_ring_free(struct net_device *ndev)
{
@@ -228,7 +413,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
/* format skb and descriptor buffer */
static void sh_eth_ring_format(struct net_device *ndev)
{
- u32 ioaddr = ndev->base_addr, reserve = 0;
+ u32 ioaddr = ndev->base_addr;
struct sh_eth_private *mdp = netdev_priv(ndev);
int i;
struct sk_buff *skb;
@@ -250,37 +435,27 @@ static void sh_eth_ring_format(struct net_device *ndev)
mdp->rx_skbuff[i] = skb;
if (skb == NULL)
break;
+ dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz,
+ DMA_FROM_DEVICE);
skb->dev = ndev; /* Mark as being used by this device. */
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- reserve = SH7763_SKB_ALIGN
- - ((uint32_t)skb->data & (SH7763_SKB_ALIGN-1));
- if (reserve)
- skb_reserve(skb, reserve);
-#else
- skb_reserve(skb, RX_OFFSET);
-#endif
+ sh_eth_set_receive_align(skb);
+
/* RX descriptor */
rxdesc = &mdp->rx_ring[i];
- rxdesc->addr = (u32)skb->data & ~0x3UL;
+ rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP);
/* The size of the buffer is 16 byte boundary. */
- rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;
+ rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
/* Rx descriptor address set */
if (i == 0) {
- ctrl_outl((u32)rxdesc, ioaddr + RDLAR);
+ ctrl_outl(mdp->rx_desc_dma, ioaddr + RDLAR);
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- ctrl_outl((u32)rxdesc, ioaddr + RDFAR);
+ ctrl_outl(mdp->rx_desc_dma, ioaddr + RDFAR);
#endif
}
}
- /* Rx descriptor address set */
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- ctrl_outl((u32)rxdesc, ioaddr + RDFXR);
- ctrl_outl(0x1, ioaddr + RDFFR);
-#endif
-
mdp->dirty_rx = (u32) (i - RX_RING_SIZE);
/* Mark the last entry as wrapping the ring. */
@@ -296,19 +471,13 @@ static void sh_eth_ring_format(struct net_device *ndev)
txdesc->buffer_length = 0;
if (i == 0) {
/* Tx descriptor address set */
- ctrl_outl((u32)txdesc, ioaddr + TDLAR);
+ ctrl_outl(mdp->tx_desc_dma, ioaddr + TDLAR);
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- ctrl_outl((u32)txdesc, ioaddr + TDFAR);
+ ctrl_outl(mdp->tx_desc_dma, ioaddr + TDFAR);
#endif
}
}
- /* Tx descriptor address set */
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- ctrl_outl((u32)txdesc, ioaddr + TDFXR);
- ctrl_outl(0x1, ioaddr + TDFFR);
-#endif
-
txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
}
@@ -331,7 +500,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE,
GFP_KERNEL);
if (!mdp->rx_skbuff) {
- printk(KERN_ERR "%s: Cannot allocate Rx skb\n", ndev->name);
+ dev_err(&ndev->dev, "Cannot allocate Rx skb\n");
ret = -ENOMEM;
return ret;
}
@@ -339,7 +508,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * TX_RING_SIZE,
GFP_KERNEL);
if (!mdp->tx_skbuff) {
- printk(KERN_ERR "%s: Cannot allocate Tx skb\n", ndev->name);
+ dev_err(&ndev->dev, "Cannot allocate Tx skb\n");
ret = -ENOMEM;
goto skb_ring_free;
}
@@ -350,8 +519,8 @@ static int sh_eth_ring_init(struct net_device *ndev)
GFP_KERNEL);
if (!mdp->rx_ring) {
- printk(KERN_ERR "%s: Cannot allocate Rx Ring (size %d bytes)\n",
- ndev->name, rx_ringsize);
+ dev_err(&ndev->dev, "Cannot allocate Rx Ring (size %d bytes)\n",
+ rx_ringsize);
ret = -ENOMEM;
goto desc_ring_free;
}
@@ -363,8 +532,8 @@ static int sh_eth_ring_init(struct net_device *ndev)
mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma,
GFP_KERNEL);
if (!mdp->tx_ring) {
- printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n",
- ndev->name, tx_ringsize);
+ dev_err(&ndev->dev, "Cannot allocate Tx Ring (size %d bytes)\n",
+ tx_ringsize);
ret = -ENOMEM;
goto desc_ring_free;
}
@@ -394,44 +563,43 @@ static int sh_eth_dev_init(struct net_device *ndev)
/* Descriptor format */
sh_eth_ring_format(ndev);
- ctrl_outl(RPADIR_INIT, ioaddr + RPADIR);
+ if (mdp->cd->rpadir)
+ ctrl_outl(mdp->cd->rpadir_value, ioaddr + RPADIR);
/* all sh_eth int mask */
ctrl_outl(0, ioaddr + EESIPR);
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- ctrl_outl(EDMR_EL, ioaddr + EDMR);
-#else
- ctrl_outl(0, ioaddr + EDMR); /* Endian change */
+#if defined(__LITTLE_ENDIAN__)
+ if (mdp->cd->hw_swap)
+ ctrl_outl(EDMR_EL, ioaddr + EDMR);
+ else
#endif
+ ctrl_outl(0, ioaddr + EDMR);
/* FIFO size set */
- ctrl_outl((FIFO_SIZE_T | FIFO_SIZE_R), ioaddr + FDR);
+ ctrl_outl(mdp->cd->fdr_value, ioaddr + FDR);
ctrl_outl(0, ioaddr + TFTR);
/* Frame recv control */
- ctrl_outl(0, ioaddr + RMCR);
+ ctrl_outl(mdp->cd->rmcr_value, ioaddr + RMCR);
rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5;
tx_int_var = mdp->tx_int_var = DESC_I_TINT2;
ctrl_outl(rx_int_var | tx_int_var, ioaddr + TRSCER);
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- /* Burst sycle set */
- ctrl_outl(0x800, ioaddr + BCULR);
-#endif
+ if (mdp->cd->bculr)
+ ctrl_outl(0x800, ioaddr + BCULR); /* Burst sycle set */
- ctrl_outl((FIFO_F_D_RFF | FIFO_F_D_RFD), ioaddr + FCFTR);
+ ctrl_outl(mdp->cd->fcftr_value, ioaddr + FCFTR);
-#if !defined(CONFIG_CPU_SUBTYPE_SH7763)
- ctrl_outl(0, ioaddr + TRIMD);
-#endif
+ if (!mdp->cd->no_trimd)
+ ctrl_outl(0, ioaddr + TRIMD);
/* Recv frame limit set register */
ctrl_outl(RFLR_VALUE, ioaddr + RFLR);
ctrl_outl(ctrl_inl(ioaddr + EESR), ioaddr + EESR);
- ctrl_outl((DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff), ioaddr + EESIPR);
+ ctrl_outl(mdp->cd->eesipr_value, ioaddr + EESIPR);
/* PAUSE Prohibition */
val = (ctrl_inl(ioaddr + ECMR) & ECMR_DM) |
@@ -439,24 +607,25 @@ static int sh_eth_dev_init(struct net_device *ndev)
ctrl_outl(val, ioaddr + ECMR);
+ if (mdp->cd->set_rate)
+ mdp->cd->set_rate(ndev);
+
/* E-MAC Status Register clear */
- ctrl_outl(ECSR_INIT, ioaddr + ECSR);
+ ctrl_outl(mdp->cd->ecsr_value, ioaddr + ECSR);
/* E-MAC Interrupt Enable register */
- ctrl_outl(ECSIPR_INIT, ioaddr + ECSIPR);
+ ctrl_outl(mdp->cd->ecsipr_value, ioaddr + ECSIPR);
/* Set MAC address */
update_mac_address(ndev);
/* mask reset */
-#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7763)
- ctrl_outl(APR_AP, ioaddr + APR);
- ctrl_outl(MPR_MP, ioaddr + MPR);
- ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER);
-#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7710)
- ctrl_outl(BCFR_UNLIMITED, ioaddr + BCFR);
-#endif
+ if (mdp->cd->apr)
+ ctrl_outl(APR_AP, ioaddr + APR);
+ if (mdp->cd->mpr)
+ ctrl_outl(MPR_MP, ioaddr + MPR);
+ if (mdp->cd->tpauser)
+ ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER);
/* Setting the Rx mode will start the Rx process. */
ctrl_outl(EDRRR_R, ioaddr + EDRRR);
@@ -505,7 +674,7 @@ static int sh_eth_rx(struct net_device *ndev)
int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx;
struct sk_buff *skb;
u16 pkt_len = 0;
- u32 desc_status, reserve = 0;
+ u32 desc_status;
rxdesc = &mdp->rx_ring[entry];
while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) {
@@ -534,7 +703,10 @@ static int sh_eth_rx(struct net_device *ndev)
if (desc_status & RD_RFS10)
mdp->stats.rx_over_errors++;
} else {
- swaps((char *)(rxdesc->addr & ~0x3), pkt_len + 2);
+ if (!mdp->cd->hw_swap)
+ sh_eth_soft_swap(
+ phys_to_virt(ALIGN(rxdesc->addr, 4)),
+ pkt_len + 2);
skb = mdp->rx_skbuff[entry];
mdp->rx_skbuff[entry] = NULL;
skb_put(skb, pkt_len);
@@ -545,6 +717,7 @@ static int sh_eth_rx(struct net_device *ndev)
}
rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
entry = (++mdp->cur_rx) % RX_RING_SIZE;
+ rxdesc = &mdp->rx_ring[entry];
}
/* Refill the Rx ring buffers. */
@@ -552,24 +725,20 @@ static int sh_eth_rx(struct net_device *ndev)
entry = mdp->dirty_rx % RX_RING_SIZE;
rxdesc = &mdp->rx_ring[entry];
/* The size of the buffer is 16 byte boundary. */
- rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;
+ rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
if (mdp->rx_skbuff[entry] == NULL) {
skb = dev_alloc_skb(mdp->rx_buf_sz);
mdp->rx_skbuff[entry] = skb;
if (skb == NULL)
break; /* Better luck next round. */
+ dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz,
+ DMA_FROM_DEVICE);
skb->dev = ndev;
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- reserve = SH7763_SKB_ALIGN
- - ((uint32_t)skb->data & (SH7763_SKB_ALIGN-1));
- if (reserve)
- skb_reserve(skb, reserve);
-#else
- skb_reserve(skb, RX_OFFSET);
-#endif
+ sh_eth_set_receive_align(skb);
+
skb->ip_summed = CHECKSUM_NONE;
- rxdesc->addr = (u32)skb->data & ~0x3UL;
+ rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
}
if (entry >= RX_RING_SIZE - 1)
rxdesc->status |=
@@ -593,6 +762,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
struct sh_eth_private *mdp = netdev_priv(ndev);
u32 ioaddr = ndev->base_addr;
u32 felic_stat;
+ u32 link_stat;
+ u32 mask;
if (intr_status & EESR_ECI) {
felic_stat = ctrl_inl(ioaddr + ECSR);
@@ -601,7 +772,14 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
mdp->stats.tx_carrier_errors++;
if (felic_stat & ECSR_LCHNG) {
/* Link Changed */
- u32 link_stat = (ctrl_inl(ioaddr + PSR));
+ if (mdp->cd->no_psr) {
+ if (mdp->link == PHY_DOWN)
+ link_stat = 0;
+ else
+ link_stat = PHY_ST_LINK;
+ } else {
+ link_stat = (ctrl_inl(ioaddr + PSR));
+ }
if (!(link_stat & PHY_ST_LINK)) {
/* Link Down : disable tx and rx */
ctrl_outl(ctrl_inl(ioaddr + ECMR) &
@@ -633,17 +811,15 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
if (intr_status & EESR_RFRMER) {
/* Receive Frame Overflow int */
mdp->stats.rx_frame_errors++;
- printk(KERN_ERR "Receive Frame Overflow\n");
+ dev_err(&ndev->dev, "Receive Frame Overflow\n");
}
}
-#if !defined(CONFIG_CPU_SUBTYPE_SH7763)
- if (intr_status & EESR_ADE) {
- if (intr_status & EESR_TDE) {
- if (intr_status & EESR_TFE)
- mdp->stats.tx_fifo_errors++;
- }
+
+ if (!mdp->cd->no_ade) {
+ if (intr_status & EESR_ADE && intr_status & EESR_TDE &&
+ intr_status & EESR_TFE)
+ mdp->stats.tx_fifo_errors++;
}
-#endif
if (intr_status & EESR_RDE) {
/* Receive Descriptor Empty int */
@@ -651,24 +827,24 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
if (ctrl_inl(ioaddr + EDRRR) ^ EDRRR_R)
ctrl_outl(EDRRR_R, ioaddr + EDRRR);
- printk(KERN_ERR "Receive Descriptor Empty\n");
+ dev_err(&ndev->dev, "Receive Descriptor Empty\n");
}
if (intr_status & EESR_RFE) {
/* Receive FIFO Overflow int */
mdp->stats.rx_fifo_errors++;
- printk(KERN_ERR "Receive FIFO Overflow\n");
+ dev_err(&ndev->dev, "Receive FIFO Overflow\n");
}
- if (intr_status & (EESR_TWB | EESR_TABT |
-#if !defined(CONFIG_CPU_SUBTYPE_SH7763)
- EESR_ADE |
-#endif
- EESR_TDE | EESR_TFE)) {
+
+ mask = EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE;
+ if (mdp->cd->no_ade)
+ mask &= ~EESR_ADE;
+ if (intr_status & mask) {
/* Tx error */
u32 edtrr = ctrl_inl(ndev->base_addr + EDTRR);
/* dmesg */
- printk(KERN_ERR "%s:TX error. status=%8.8x cur_tx=%8.8x ",
- ndev->name, intr_status, mdp->cur_tx);
- printk(KERN_ERR "dirty_tx=%8.8x state=%8.8x EDTRR=%8.8x.\n",
+ dev_err(&ndev->dev, "TX error. status=%8.8x cur_tx=%8.8x ",
+ intr_status, mdp->cur_tx);
+ dev_err(&ndev->dev, "dirty_tx=%8.8x state=%8.8x EDTRR=%8.8x.\n",
mdp->dirty_tx, (u32) ndev->state, edtrr);
/* dirty buffer free */
sh_eth_txfree(ndev);
@@ -687,6 +863,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
{
struct net_device *ndev = netdev;
struct sh_eth_private *mdp = netdev_priv(ndev);
+ struct sh_eth_cpu_data *cd = mdp->cd;
irqreturn_t ret = IRQ_NONE;
u32 ioaddr, boguscnt = RX_RING_SIZE;
u32 intr_status = 0;
@@ -699,7 +876,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
/* Clear interrupt */
if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
- TX_CHECK | EESR_ERR_CHECK)) {
+ cd->tx_check | cd->eesr_err_check)) {
ctrl_outl(intr_status, ioaddr + EESR);
ret = IRQ_HANDLED;
} else
@@ -716,12 +893,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
}
/* Tx Check */
- if (intr_status & TX_CHECK) {
+ if (intr_status & cd->tx_check) {
sh_eth_txfree(ndev);
netif_wake_queue(ndev);
}
- if (intr_status & EESR_ERR_CHECK)
+ if (intr_status & cd->eesr_err_check)
sh_eth_error(ndev, intr_status);
if (--boguscnt < 0) {
@@ -756,32 +933,15 @@ static void sh_eth_adjust_link(struct net_device *ndev)
if (phydev->duplex != mdp->duplex) {
new_state = 1;
mdp->duplex = phydev->duplex;
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- if (mdp->duplex) { /* FULL */
- ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM,
- ioaddr + ECMR);
- } else { /* Half */
- ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM,
- ioaddr + ECMR);
- }
-#endif
+ if (mdp->cd->set_duplex)
+ mdp->cd->set_duplex(ndev);
}
if (phydev->speed != mdp->speed) {
new_state = 1;
mdp->speed = phydev->speed;
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- switch (mdp->speed) {
- case 10: /* 10BASE */
- ctrl_outl(GECMR_10, ioaddr + GECMR); break;
- case 100:/* 100BASE */
- ctrl_outl(GECMR_100, ioaddr + GECMR); break;
- case 1000: /* 1000BASE */
- ctrl_outl(GECMR_1000, ioaddr + GECMR); break;
- default:
- break;
- }
-#endif
+ if (mdp->cd->set_rate)
+ mdp->cd->set_rate(ndev);
}
if (mdp->link == PHY_DOWN) {
ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_TXF)
@@ -804,7 +964,7 @@ static void sh_eth_adjust_link(struct net_device *ndev)
static int sh_eth_phy_init(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- char phy_id[BUS_ID_SIZE];
+ char phy_id[MII_BUS_ID_SIZE + 3];
struct phy_device *phydev = NULL;
snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
@@ -821,8 +981,9 @@ static int sh_eth_phy_init(struct net_device *ndev)
dev_err(&ndev->dev, "phy_connect failed\n");
return PTR_ERR(phydev);
}
+
dev_info(&ndev->dev, "attached phy %i to driver %s\n",
- phydev->addr, phydev->drv->name);
+ phydev->addr, phydev->drv->name);
mdp->phydev = phydev;
@@ -860,7 +1021,7 @@ static int sh_eth_open(struct net_device *ndev)
#endif
ndev->name, ndev);
if (ret) {
- printk(KERN_ERR "Can not assign IRQ number to %s\n", CARDNAME);
+ dev_err(&ndev->dev, "Can not assign IRQ number\n");
return ret;
}
@@ -947,7 +1108,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
if (!sh_eth_txfree(ndev)) {
netif_stop_queue(ndev);
spin_unlock_irqrestore(&mdp->lock, flags);
- return 1;
+ return NETDEV_TX_BUSY;
}
}
spin_unlock_irqrestore(&mdp->lock, flags);
@@ -955,9 +1116,11 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
entry = mdp->cur_tx % TX_RING_SIZE;
mdp->tx_skbuff[entry] = skb;
txdesc = &mdp->tx_ring[entry];
- txdesc->addr = (u32)(skb->data);
+ txdesc->addr = virt_to_phys(skb->data);
/* soft swap. */
- swaps((char *)(txdesc->addr & ~0x3), skb->len + 2);
+ if (!mdp->cd->hw_swap)
+ sh_eth_soft_swap(phys_to_virt(ALIGN(txdesc->addr, 4)),
+ skb->len + 2);
/* write back */
__flush_purge_region(skb->data, skb->len);
if (skb->len < ETHERSMALL)
@@ -1059,7 +1222,7 @@ static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq,
return phy_mii_ioctl(phydev, if_mii(rq), cmd);
}
-
+#if defined(SH_ETH_HAS_TSU)
/* Multicast reception directions set */
static void sh_eth_set_multicast_list(struct net_device *ndev)
{
@@ -1104,6 +1267,7 @@ static void sh_eth_tsu_init(u32 ioaddr)
ctrl_outl(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */
ctrl_outl(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */
}
+#endif /* SH_ETH_HAS_TSU */
/* MDIO bus release function */
static int sh_mdio_release(struct net_device *ndev)
@@ -1193,7 +1357,9 @@ static const struct net_device_ops sh_eth_netdev_ops = {
.ndo_stop = sh_eth_close,
.ndo_start_xmit = sh_eth_start_xmit,
.ndo_get_stats = sh_eth_get_stats,
+#if defined(SH_ETH_HAS_TSU)
.ndo_set_multicast_list = sh_eth_set_multicast_list,
+#endif
.ndo_tx_timeout = sh_eth_tx_timeout,
.ndo_do_ioctl = sh_eth_do_ioctl,
.ndo_validate_addr = eth_validate_addr,
@@ -1219,7 +1385,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
ndev = alloc_etherdev(sizeof(struct sh_eth_private));
if (!ndev) {
- printk(KERN_ERR "%s: could not allocate device.\n", CARDNAME);
+ dev_err(&pdev->dev, "Could not allocate device.\n");
ret = -ENOMEM;
goto out;
}
@@ -1252,6 +1418,10 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
/* EDMAC endian */
mdp->edmac_endian = pd->edmac_endian;
+ /* set cpu data */
+ mdp->cd = &sh_eth_my_cpu_data;
+ sh_eth_set_default_cpu_data(mdp->cd);
+
/* set function */
ndev->netdev_ops = &sh_eth_netdev_ops;
ndev->watchdog_timeo = TX_TIMEOUT;
@@ -1264,13 +1434,10 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
/* First device only init */
if (!devno) {
-#if defined(ARSTR)
- /* reset device */
- ctrl_outl(ARSTR_ARSTR, ARSTR);
- mdelay(1);
-#endif
+ if (mdp->cd->chip_reset)
+ mdp->cd->chip_reset(ndev);
-#if defined(SH_TSU_ADDR)
+#if defined(SH_ETH_HAS_TSU)
/* TSU init (Init only)*/
sh_eth_tsu_init(SH_TSU_ADDR);
#endif
@@ -1287,8 +1454,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
goto out_unregister;
/* pritnt device infomation */
- printk(KERN_INFO "%s: %s at 0x%x, ",
- ndev->name, CARDNAME, (u32) ndev->base_addr);
+ pr_info("Base address at 0x%x, ",
+ (u32)ndev->base_addr);
for (i = 0; i < 5; i++)
printk("%02X:", ndev->dev_addr[i]);
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index 1537e13e623..9afe5b4c855 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -2,7 +2,7 @@
* SuperH Ethernet device driver
*
* Copyright (C) 2006-2008 Nobuhiro Iwamatsu
- * Copyright (C) 2008 Renesas Solutions Corp.
+ * Copyright (C) 2008-2009 Renesas Solutions Corp.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -39,12 +39,12 @@
#define ETHERSMALL 60
#define PKT_BUF_SZ 1538
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+/* This CPU register maps is very difference by other SH4 CPU */
-#define SH7763_SKB_ALIGN 32
/* Chip Base Address */
# define SH_TSU_ADDR 0xFEE01800
-# define ARSTR SH_TSU_ADDR
+# define ARSTR SH_TSU_ADDR
/* Chip Registers */
/* E-DMAC */
@@ -143,8 +143,60 @@
# define FWNLCR1 0xB0
# define FWALCR1 0x40
-#else /* CONFIG_CPU_SUBTYPE_SH7763 */
-# define RX_OFFSET 2 /* skb offset */
+#elif defined(CONFIG_CPU_SH4) /* #if defined(CONFIG_CPU_SUBTYPE_SH7763) */
+/* EtherC */
+#define ECMR 0x100
+#define RFLR 0x108
+#define ECSR 0x110
+#define ECSIPR 0x118
+#define PIR 0x120
+#define PSR 0x128
+#define RDMLR 0x140
+#define IPGR 0x150
+#define APR 0x154
+#define MPR 0x158
+#define TPAUSER 0x164
+#define RFCF 0x160
+#define TPAUSECR 0x168
+#define BCFRR 0x16c
+#define MAHR 0x1c0
+#define MALR 0x1c8
+#define TROCR 0x1d0
+#define CDCR 0x1d4
+#define LCCR 0x1d8
+#define CNDCR 0x1dc
+#define CEFCR 0x1e4
+#define FRECR 0x1e8
+#define TSFRCR 0x1ec
+#define TLFRCR 0x1f0
+#define RFCR 0x1f4
+#define MAFCR 0x1f8
+#define RTRATE 0x1fc
+
+/* E-DMAC */
+#define EDMR 0x000
+#define EDTRR 0x008
+#define EDRRR 0x010
+#define TDLAR 0x018
+#define RDLAR 0x020
+#define EESR 0x028
+#define EESIPR 0x030
+#define TRSCER 0x038
+#define RMFCR 0x040
+#define TFTR 0x048
+#define FDR 0x050
+#define RMCR 0x058
+#define TFUCR 0x064
+#define RFOCR 0x068
+#define FCFTR 0x070
+#define RPADIR 0x078
+#define TRIMD 0x07c
+#define RBWAR 0x0c8
+#define RDFAR 0x0cc
+#define TBRAR 0x0d4
+#define TDFAR 0x0d8
+#else /* #elif defined(CONFIG_CPU_SH4) */
+/* This section is SH3 or SH2 */
#ifndef CONFIG_CPU_SUBTYPE_SH7619
/* Chip base address */
# define SH_TSU_ADDR 0xA7000804
@@ -243,6 +295,30 @@
#endif /* CONFIG_CPU_SUBTYPE_SH7763 */
+/* There are avoid compile error... */
+#if !defined(BCULR)
+#define BCULR 0x0fc
+#endif
+#if !defined(TRIMD)
+#define TRIMD 0x0fc
+#endif
+#if !defined(APR)
+#define APR 0x0fc
+#endif
+#if !defined(MPR)
+#define MPR 0x0fc
+#endif
+#if !defined(TPAUSER)
+#define TPAUSER 0x0fc
+#endif
+
+/* Driver's parameters */
+#if defined(CONFIG_CPU_SH4)
+#define SH4_SKB_RX_ALIGN 32
+#else
+#define SH2_SH3_SKB_RX_ALIGN 2
+#endif
+
/*
* Register's bits
*/
@@ -261,11 +337,10 @@ enum GECMR_BIT {
/* EDMR */
enum DMAC_M_BIT {
+ EDMR_EL = 0x40, /* Litte endian */
EDMR_DL1 = 0x20, EDMR_DL0 = 0x10,
#ifdef CONFIG_CPU_SUBTYPE_SH7763
- EDMR_SRST = 0x03,
- EMDR_DESC_R = 0x30, /* Descriptor reserve size */
- EDMR_EL = 0x40, /* Litte endian */
+ EDMR_SRST = 0x03,
#else /* CONFIG_CPU_SUBTYPE_SH7763 */
EDMR_SRST = 0x01,
#endif
@@ -307,47 +382,43 @@ enum PHY_STATUS_BIT { PHY_ST_LINK = 0x01, };
/* EESR */
enum EESR_BIT {
-#ifndef CONFIG_CPU_SUBTYPE_SH7763
- EESR_TWB = 0x40000000,
-#else
- EESR_TWB = 0xC0000000,
- EESR_TC1 = 0x20000000,
- EESR_TUC = 0x10000000,
- EESR_ROC = 0x80000000,
-#endif
- EESR_TABT = 0x04000000,
- EESR_RABT = 0x02000000, EESR_RFRMER = 0x01000000,
-#ifndef CONFIG_CPU_SUBTYPE_SH7763
- EESR_ADE = 0x00800000,
-#endif
- EESR_ECI = 0x00400000,
- EESR_FTC = 0x00200000, EESR_TDE = 0x00100000,
- EESR_TFE = 0x00080000, EESR_FRC = 0x00040000,
- EESR_RDE = 0x00020000, EESR_RFE = 0x00010000,
-#ifndef CONFIG_CPU_SUBTYPE_SH7763
- EESR_CND = 0x00000800,
-#endif
- EESR_DLC = 0x00000400,
- EESR_CD = 0x00000200, EESR_RTO = 0x00000100,
- EESR_RMAF = 0x00000080, EESR_CEEF = 0x00000040,
- EESR_CELF = 0x00000020, EESR_RRF = 0x00000010,
- EESR_RTLF = 0x00000008, EESR_RTSF = 0x00000004,
- EESR_PRE = 0x00000002, EESR_CERF = 0x00000001,
-};
-
-
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
-# define TX_CHECK (EESR_TC1 | EESR_FTC)
-# define EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
- | EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI)
-# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE)
-
-#else
-# define TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO)
-# define EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
- | EESR_RFRMER | EESR_ADE | EESR_TFE | EESR_TDE | EESR_ECI)
-# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE)
-#endif
+ EESR_TWB1 = 0x80000000,
+ EESR_TWB = 0x40000000, /* same as TWB0 */
+ EESR_TC1 = 0x20000000,
+ EESR_TUC = 0x10000000,
+ EESR_ROC = 0x08000000,
+ EESR_TABT = 0x04000000,
+ EESR_RABT = 0x02000000,
+ EESR_RFRMER = 0x01000000, /* same as RFCOF */
+ EESR_ADE = 0x00800000,
+ EESR_ECI = 0x00400000,
+ EESR_FTC = 0x00200000, /* same as TC or TC0 */
+ EESR_TDE = 0x00100000,
+ EESR_TFE = 0x00080000, /* same as TFUF */
+ EESR_FRC = 0x00040000, /* same as FR */
+ EESR_RDE = 0x00020000,
+ EESR_RFE = 0x00010000,
+ EESR_CND = 0x00000800,
+ EESR_DLC = 0x00000400,
+ EESR_CD = 0x00000200,
+ EESR_RTO = 0x00000100,
+ EESR_RMAF = 0x00000080,
+ EESR_CEEF = 0x00000040,
+ EESR_CELF = 0x00000020,
+ EESR_RRF = 0x00000010,
+ EESR_RTLF = 0x00000008,
+ EESR_RTSF = 0x00000004,
+ EESR_PRE = 0x00000002,
+ EESR_CERF = 0x00000001,
+};
+
+#define DEFAULT_TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | \
+ EESR_RTO)
+#define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | \
+ EESR_RDE | EESR_RFRMER | EESR_ADE | \
+ EESR_TFE | EESR_TDE | EESR_ECI)
+#define DEFAULT_TX_ERROR_CHECK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | \
+ EESR_TFE)
/* EESIPR */
enum DMAC_IM_BIT {
@@ -386,12 +457,8 @@ enum FCFTR_BIT {
FCFTR_RFF0 = 0x00010000, FCFTR_RFD2 = 0x00000004,
FCFTR_RFD1 = 0x00000002, FCFTR_RFD0 = 0x00000001,
};
-#define FIFO_F_D_RFF (FCFTR_RFF2|FCFTR_RFF1|FCFTR_RFF0)
-#ifndef CONFIG_CPU_SUBTYPE_SH7619
-#define FIFO_F_D_RFD (FCFTR_RFD2|FCFTR_RFD1|FCFTR_RFD0)
-#else
-#define FIFO_F_D_RFD (FCFTR_RFD0)
-#endif
+#define DEFAULT_FIFO_F_D_RFF (FCFTR_RFF2 | FCFTR_RFF1 | FCFTR_RFF0)
+#define DEFAULT_FIFO_F_D_RFD (FCFTR_RFD2 | FCFTR_RFD1 | FCFTR_RFD0)
/* Transfer descriptor bit */
enum TD_STS_BIT {
@@ -404,60 +471,38 @@ enum TD_STS_BIT {
#define TD_TFP (TD_TFP1|TD_TFP0)
/* RMCR */
-enum RECV_RST_BIT { RMCR_RST = 0x01, };
+#define DEFAULT_RMCR_VALUE 0x00000000
+
/* ECMR */
enum FELIC_MODE_BIT {
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
ECMR_TRCCM = 0x04000000, ECMR_RCSC = 0x00800000,
ECMR_DPAD = 0x00200000, ECMR_RZPF = 0x00100000,
-#endif
ECMR_ZPF = 0x00080000, ECMR_PFR = 0x00040000, ECMR_RXF = 0x00020000,
ECMR_TXF = 0x00010000, ECMR_MCT = 0x00002000, ECMR_PRCEF = 0x00001000,
ECMR_PMDE = 0x00000200, ECMR_RE = 0x00000040, ECMR_TE = 0x00000020,
- ECMR_ILB = 0x00000008, ECMR_ELB = 0x00000004, ECMR_DM = 0x00000002,
- ECMR_PRM = 0x00000001,
+ ECMR_RTM = 0x00000010, ECMR_ILB = 0x00000008, ECMR_ELB = 0x00000004,
+ ECMR_DM = 0x00000002, ECMR_PRM = 0x00000001,
};
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
-#define ECMR_CHG_DM (ECMR_TRCCM | ECMR_RZPF | ECMR_ZPF |\
- ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT)
-#elif CONFIG_CPU_SUBTYPE_SH7619
-#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF)
-#else
-#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT)
-#endif
-
/* ECSR */
enum ECSR_STATUS_BIT {
-#ifndef CONFIG_CPU_SUBTYPE_SH7763
ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10,
-#endif
ECSR_LCHNG = 0x04,
ECSR_MPD = 0x02, ECSR_ICD = 0x01,
};
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
-# define ECSR_INIT (ECSR_ICD | ECSIPR_MPDIP)
-#else
-# define ECSR_INIT (ECSR_BRCRX | ECSR_PSRTO | \
- ECSR_LCHNG | ECSR_ICD | ECSIPR_MPDIP)
-#endif
+#define DEFAULT_ECSR_INIT (ECSR_BRCRX | ECSR_PSRTO | ECSR_LCHNG | \
+ ECSR_ICD | ECSIPR_MPDIP)
/* ECSIPR */
enum ECSIPR_STATUS_MASK_BIT {
-#ifndef CONFIG_CPU_SUBTYPE_SH7763
ECSIPR_BRCRXIP = 0x20, ECSIPR_PSRTOIP = 0x10,
-#endif
ECSIPR_LCHNGIP = 0x04,
ECSIPR_MPDIP = 0x02, ECSIPR_ICDIP = 0x01,
};
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
-# define ECSIPR_INIT (ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP)
-#else
-# define ECSIPR_INIT (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | \
- ECSIPR_ICDIP | ECSIPR_MPDIP)
-#endif
+#define DEFAULT_ECSIPR_INIT (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | \
+ ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP)
/* APR */
enum APR_BIT {
@@ -483,23 +528,12 @@ enum RPADIR_BIT {
RPADIR_PADR = 0x0003f,
};
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-# define RPADIR_INIT (0x00)
-#else
-# define RPADIR_INIT (RPADIR_PADS1)
-#endif
-
/* RFLR */
#define RFLR_VALUE 0x1000
/* FDR */
-enum FIFO_SIZE_BIT {
-#ifndef CONFIG_CPU_SUBTYPE_SH7619
- FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007,
-#else
- FIFO_SIZE_T = 0x00000100, FIFO_SIZE_R = 0x00000001,
-#endif
-};
+#define DEFAULT_FDR_INIT 0x00000707
+
enum phy_offsets {
PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3,
PHY_ANA = 4, PHY_ANL = 5, PHY_ANE = 6,
@@ -633,7 +667,43 @@ struct sh_eth_rxdesc {
u32 pad0; /* padding data */
} __attribute__((aligned(2), packed));
+/* This structure is used by each CPU dependency handling. */
+struct sh_eth_cpu_data {
+ /* optional functions */
+ void (*chip_reset)(struct net_device *ndev);
+ void (*set_duplex)(struct net_device *ndev);
+ void (*set_rate)(struct net_device *ndev);
+
+ /* mandatory initialize value */
+ unsigned long eesipr_value;
+
+ /* optional initialize value */
+ unsigned long ecsr_value;
+ unsigned long ecsipr_value;
+ unsigned long fdr_value;
+ unsigned long fcftr_value;
+ unsigned long rpadir_value;
+ unsigned long rmcr_value;
+
+ /* interrupt checking mask */
+ unsigned long tx_check;
+ unsigned long eesr_err_check;
+ unsigned long tx_error_check;
+
+ /* hardware features */
+ unsigned no_psr:1; /* EtherC DO NOT have PSR */
+ unsigned apr:1; /* EtherC have APR */
+ unsigned mpr:1; /* EtherC have MPR */
+ unsigned tpauser:1; /* EtherC have TPAUSER */
+ unsigned bculr:1; /* EtherC have BCULR */
+ unsigned hw_swap:1; /* E-DMAC have DE bit in EDMR */
+ unsigned rpadir:1; /* E-DMAC have RPADIR */
+ unsigned no_trimd:1; /* E-DMAC DO NOT have TRIMD */
+ unsigned no_ade:1; /* E-DMAC DO NOT have ADE bit in EESR */
+};
+
struct sh_eth_private {
+ struct sh_eth_cpu_data *cd;
dma_addr_t rx_desc_dma;
dma_addr_t tx_desc_dma;
struct sh_eth_rxdesc *rx_ring;
@@ -661,11 +731,7 @@ struct sh_eth_private {
struct net_device_stats tsu_stats; /* TSU forward status */
};
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
-/* SH7763 has endian control register */
-#define swaps(x, y)
-#else
-static void swaps(char *src, int len)
+static inline void sh_eth_soft_swap(char *src, int len)
{
#ifdef __LITTLE_ENDIAN__
u32 *p = (u32 *)src;
@@ -676,5 +742,5 @@ static void swaps(char *src, int len)
*p = swab32(*p);
#endif
}
-#endif /* CONFIG_CPU_SUBTYPE_SH7763 */
-#endif
+
+#endif /* #ifndef __SH_ETH_H__ */
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 55ccd51d247..e2247669a49 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -47,7 +47,7 @@
#define PHY_ID_ANY 0x1f
#define MII_REG_ANY 0x1f
-#define DRV_VERSION "1.2"
+#define DRV_VERSION "1.3"
#define DRV_NAME "sis190"
#define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION
#define PFX DRV_NAME ": "
@@ -317,6 +317,7 @@ static struct mii_chip_info {
unsigned int type;
u32 feature;
} mii_chip_table[] = {
+ { "Atheros PHY", { 0x004d, 0xd010 }, LAN, 0 },
{ "Atheros PHY AR8012", { 0x004d, 0xd020 }, LAN, 0 },
{ "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 },
{ "Broadcom PHY AC131", { 0x0143, 0xbc70 }, LAN, 0 },
@@ -347,7 +348,7 @@ static struct {
u32 msg_enable;
} debug = { -1 };
-MODULE_DESCRIPTION("SiS sis190 Gigabit Ethernet driver");
+MODULE_DESCRIPTION("SiS sis190/191 Gigabit Ethernet driver");
module_param(rx_copybreak, int, 0);
MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
module_param_named(debug, debug.msg_enable, int, 0);
@@ -539,8 +540,8 @@ static bool sis190_try_rx_copy(struct sis190_private *tp,
if (!skb)
goto out;
- pci_dma_sync_single_for_device(tp->pci_dev, addr, pkt_size,
- PCI_DMA_FROMDEVICE);
+ pci_dma_sync_single_for_cpu(tp->pci_dev, addr, tp->rx_buf_sz,
+ PCI_DMA_FROMDEVICE);
skb_reserve(skb, 2);
skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size);
*sk_buff = skb;
@@ -942,9 +943,9 @@ static void sis190_phy_task(struct work_struct *work)
u32 ctl;
const char *msg;
} reg31[] = {
- { LPA_1000XFULL | LPA_SLCT, 0x07000c00 | 0x00001000,
+ { LPA_1000FULL, 0x07000c00 | 0x00001000,
"1000 Mbps Full Duplex" },
- { LPA_1000XHALF | LPA_SLCT, 0x07000c00,
+ { LPA_1000HALF, 0x07000c00,
"1000 Mbps Half Duplex" },
{ LPA_100FULL, 0x04000800 | 0x00001000,
"100 Mbps Full Duplex" },
@@ -955,22 +956,35 @@ static void sis190_phy_task(struct work_struct *work)
{ LPA_10HALF, 0x04000400,
"10 Mbps Half Duplex" },
{ 0, 0x04000400, "unknown" }
- }, *p;
- u16 adv;
+ }, *p = NULL;
+ u16 adv, autoexp, gigadv, gigrec;
val = mdio_read(ioaddr, phy_id, 0x1f);
net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val);
val = mdio_read(ioaddr, phy_id, MII_LPA);
adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
- net_link(tp, KERN_INFO "%s: mii lpa = %04x adv = %04x.\n",
- dev->name, val, adv);
-
- val &= adv;
+ autoexp = mdio_read(ioaddr, phy_id, MII_EXPANSION);
+ net_link(tp, KERN_INFO "%s: mii lpa=%04x adv=%04x exp=%04x.\n",
+ dev->name, val, adv, autoexp);
+
+ if (val & LPA_NPAGE && autoexp & EXPANSION_NWAY) {
+ /* check for gigabit speed */
+ gigadv = mdio_read(ioaddr, phy_id, MII_CTRL1000);
+ gigrec = mdio_read(ioaddr, phy_id, MII_STAT1000);
+ val = (gigadv & (gigrec >> 2));
+ if (val & ADVERTISE_1000FULL)
+ p = reg31;
+ else if (val & ADVERTISE_1000HALF)
+ p = reg31 + 1;
+ }
+ if (!p) {
+ val &= adv;
- for (p = reg31; p->val; p++) {
- if ((val & p->val) == p->val)
- break;
+ for (p = reg31; p->val; p++) {
+ if ((val & p->val) == p->val)
+ break;
+ }
}
p->ctl |= SIS_R32(StationControl) & ~0x0f001c00;
@@ -1204,8 +1218,6 @@ static int sis190_start_xmit(struct sk_buff *skb, struct net_device *dev)
SIS_W32(TxControl, 0x1a00 | CmdReset | CmdTxEnb);
- dev->trans_start = jiffies;
-
dirty_tx = tp->dirty_tx;
if ((tp->cur_tx - NUM_TX_DESC) == dirty_tx) {
netif_stop_queue(dev);
@@ -1315,12 +1327,15 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp,
((mii_status & (BMSR_100FULL | BMSR_100HALF)) ?
LAN : HOME) : p->type;
tp->features |= p->feature;
- } else
+ net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n",
+ pci_name(tp->pci_dev), p->name, phy_id);
+ } else {
phy->type = UNKNOWN;
-
- net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n",
- pci_name(tp->pci_dev),
- (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id);
+ net_probe(tp, KERN_INFO
+ "%s: unknown PHY 0x%x:0x%x transceiver at address %d\n",
+ pci_name(tp->pci_dev),
+ phy->id[0], (phy->id[1] & 0xfff0), phy_id);
+ }
}
static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp)
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 2d4617b3e20..a9a897bb42d 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -1584,7 +1584,7 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
/* Don't transmit data before the complete of auto-negotiation */
if(!sis_priv->autong_complete){
netif_stop_queue(net_dev);
- return 1;
+ return NETDEV_TX_BUSY;
}
spin_lock_irqsave(&sis_priv->lock, flags);
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index e14aec0a733..088fe26484e 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -159,12 +159,6 @@ MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
static int num_boards; /* total number of adapters configured */
-#ifdef DRIVERDEBUG
-#define PRINTK(s, args...) printk(s, ## args)
-#else
-#define PRINTK(s, args...)
-#endif // DRIVERDEBUG
-
static const struct net_device_ops skfp_netdev_ops = {
.ndo_open = skfp_open,
.ndo_stop = skfp_close,
@@ -213,7 +207,7 @@ static int skfp_init_one(struct pci_dev *pdev,
void __iomem *mem;
int err;
- PRINTK(KERN_INFO "entering skfp_init_one\n");
+ pr_debug(KERN_INFO "entering skfp_init_one\n");
if (num_boards == 0)
printk("%s\n", boot_msg);
@@ -389,7 +383,7 @@ static int skfp_driver_init(struct net_device *dev)
skfddi_priv *bp = &smc->os;
int err = -EIO;
- PRINTK(KERN_INFO "entering skfp_driver_init\n");
+ pr_debug(KERN_INFO "entering skfp_driver_init\n");
// set the io address in private structures
bp->base_addr = dev->base_addr;
@@ -409,7 +403,7 @@ static int skfp_driver_init(struct net_device *dev)
// Determine the required size of the 'shared' memory area.
bp->SharedMemSize = mac_drv_check_space();
- PRINTK(KERN_INFO "Memory for HWM: %ld\n", bp->SharedMemSize);
+ pr_debug(KERN_INFO "Memory for HWM: %ld\n", bp->SharedMemSize);
if (bp->SharedMemSize > 0) {
bp->SharedMemSize += 16; // for descriptor alignment
@@ -433,13 +427,13 @@ static int skfp_driver_init(struct net_device *dev)
card_stop(smc); // Reset adapter.
- PRINTK(KERN_INFO "mac_drv_init()..\n");
+ pr_debug(KERN_INFO "mac_drv_init()..\n");
if (mac_drv_init(smc) != 0) {
- PRINTK(KERN_INFO "mac_drv_init() failed.\n");
+ pr_debug(KERN_INFO "mac_drv_init() failed.\n");
goto fail;
}
read_address(smc, NULL);
- PRINTK(KERN_INFO "HW-Addr: %02x %02x %02x %02x %02x %02x\n",
+ pr_debug(KERN_INFO "HW-Addr: %02x %02x %02x %02x %02x %02x\n",
smc->hw.fddi_canon_addr.a[0],
smc->hw.fddi_canon_addr.a[1],
smc->hw.fddi_canon_addr.a[2],
@@ -495,7 +489,7 @@ static int skfp_open(struct net_device *dev)
struct s_smc *smc = netdev_priv(dev);
int err;
- PRINTK(KERN_INFO "entering skfp_open\n");
+ pr_debug(KERN_INFO "entering skfp_open\n");
/* Register IRQ - support shared interrupts by passing device ptr */
err = request_irq(dev->irq, skfp_interrupt, IRQF_SHARED,
dev->name, dev);
@@ -868,12 +862,12 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
/* Enable promiscuous mode, if necessary */
if (dev->flags & IFF_PROMISC) {
mac_drv_rx_mode(smc, RX_ENABLE_PROMISC);
- PRINTK(KERN_INFO "PROMISCUOUS MODE ENABLED\n");
+ pr_debug(KERN_INFO "PROMISCUOUS MODE ENABLED\n");
}
/* Else, update multicast address table */
else {
mac_drv_rx_mode(smc, RX_DISABLE_PROMISC);
- PRINTK(KERN_INFO "PROMISCUOUS MODE DISABLED\n");
+ pr_debug(KERN_INFO "PROMISCUOUS MODE DISABLED\n");
// Reset all MC addresses
mac_clear_multicast(smc);
@@ -881,7 +875,7 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
if (dev->flags & IFF_ALLMULTI) {
mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI);
- PRINTK(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
+ pr_debug(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
} else if (dev->mc_count > 0) {
if (dev->mc_count <= FPMAX_MULTICAST) {
/* use exact filtering */
@@ -894,12 +888,12 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
(struct fddi_addr *)dmi->dmi_addr,
1);
- PRINTK(KERN_INFO "ENABLE MC ADDRESS:");
- PRINTK(" %02x %02x %02x ",
+ pr_debug(KERN_INFO "ENABLE MC ADDRESS:");
+ pr_debug(" %02x %02x %02x ",
dmi->dmi_addr[0],
dmi->dmi_addr[1],
dmi->dmi_addr[2]);
- PRINTK("%02x %02x %02x\n",
+ pr_debug("%02x %02x %02x\n",
dmi->dmi_addr[3],
dmi->dmi_addr[4],
dmi->dmi_addr[5]);
@@ -909,11 +903,11 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
} else { // more MC addresses than HW supports
mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI);
- PRINTK(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
+ pr_debug(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
}
} else { // no MC addresses
- PRINTK(KERN_INFO "DISABLE ALL MC ADDRESSES\n");
+ pr_debug(KERN_INFO "DISABLE ALL MC ADDRESSES\n");
}
/* Update adapter filters */
@@ -1067,7 +1061,7 @@ static int skfp_send_pkt(struct sk_buff *skb, struct net_device *dev)
struct s_smc *smc = netdev_priv(dev);
skfddi_priv *bp = &smc->os;
- PRINTK(KERN_INFO "skfp_send_pkt\n");
+ pr_debug(KERN_INFO "skfp_send_pkt\n");
/*
* Verify that incoming transmit request is OK
@@ -1088,7 +1082,7 @@ static int skfp_send_pkt(struct sk_buff *skb, struct net_device *dev)
if (bp->QueueSkb == 0) { // return with tbusy set: queue full
netif_stop_queue(dev);
- return 1;
+ return NETDEV_TX_BUSY;
}
bp->QueueSkb--;
skb_queue_tail(&bp->SendSkbQueue, skb);
@@ -1137,13 +1131,13 @@ static void send_queued_packets(struct s_smc *smc)
int frame_status; // HWM tx frame status.
- PRINTK(KERN_INFO "send queued packets\n");
+ pr_debug(KERN_INFO "send queued packets\n");
for (;;) {
// send first buffer from queue
skb = skb_dequeue(&bp->SendSkbQueue);
if (!skb) {
- PRINTK(KERN_INFO "queue empty\n");
+ pr_debug(KERN_INFO "queue empty\n");
return;
} // queue empty !
@@ -1174,11 +1168,11 @@ static void send_queued_packets(struct s_smc *smc)
if ((frame_status & RING_DOWN) != 0) {
// Ring is down.
- PRINTK("Tx attempt while ring down.\n");
+ pr_debug("Tx attempt while ring down.\n");
} else if ((frame_status & OUT_OF_TXD) != 0) {
- PRINTK("%s: out of TXDs.\n", bp->dev->name);
+ pr_debug("%s: out of TXDs.\n", bp->dev->name);
} else {
- PRINTK("%s: out of transmit resources",
+ pr_debug("%s: out of transmit resources",
bp->dev->name);
}
@@ -1255,7 +1249,7 @@ static void CheckSourceAddress(unsigned char *frame, unsigned char *hw_addr)
static void ResetAdapter(struct s_smc *smc)
{
- PRINTK(KERN_INFO "[fddi: ResetAdapter]\n");
+ pr_debug(KERN_INFO "[fddi: ResetAdapter]\n");
// Stop the adapter.
@@ -1301,7 +1295,7 @@ void llc_restart_tx(struct s_smc *smc)
{
skfddi_priv *bp = &smc->os;
- PRINTK(KERN_INFO "[llc_restart_tx]\n");
+ pr_debug(KERN_INFO "[llc_restart_tx]\n");
// Try to send queued packets
spin_unlock(&bp->DriverLock);
@@ -1331,7 +1325,7 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size)
{
void *virt;
- PRINTK(KERN_INFO "mac_drv_get_space (%d bytes), ", size);
+ pr_debug(KERN_INFO "mac_drv_get_space (%d bytes), ", size);
virt = (void *) (smc->os.SharedMemAddr + smc->os.SharedMemHeap);
if ((smc->os.SharedMemHeap + size) > smc->os.SharedMemSize) {
@@ -1340,9 +1334,9 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size)
}
smc->os.SharedMemHeap += size; // Move heap pointer.
- PRINTK(KERN_INFO "mac_drv_get_space end\n");
- PRINTK(KERN_INFO "virt addr: %lx\n", (ulong) virt);
- PRINTK(KERN_INFO "bus addr: %lx\n", (ulong)
+ pr_debug(KERN_INFO "mac_drv_get_space end\n");
+ pr_debug(KERN_INFO "virt addr: %lx\n", (ulong) virt);
+ pr_debug(KERN_INFO "bus addr: %lx\n", (ulong)
(smc->os.SharedMemDMA +
((char *) virt - (char *)smc->os.SharedMemAddr)));
return (virt);
@@ -1372,7 +1366,7 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size)
char *virt;
- PRINTK(KERN_INFO "mac_drv_get_desc_mem\n");
+ pr_debug(KERN_INFO "mac_drv_get_desc_mem\n");
// Descriptor memory must be aligned on 16-byte boundary.
@@ -1381,8 +1375,8 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size)
size = (u_int) (16 - (((unsigned long) virt) & 15UL));
size = size % 16;
- PRINTK("Allocate %u bytes alignment gap ", size);
- PRINTK("for descriptor memory.\n");
+ pr_debug("Allocate %u bytes alignment gap ", size);
+ pr_debug("for descriptor memory.\n");
if (!mac_drv_get_space(smc, size)) {
printk("fddi: Unable to align descriptor memory.\n");
@@ -1516,11 +1510,11 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd)
{
struct sk_buff *skb;
- PRINTK(KERN_INFO "entering mac_drv_tx_complete\n");
+ pr_debug(KERN_INFO "entering mac_drv_tx_complete\n");
// Check if this TxD points to a skb
if (!(skb = txd->txd_os.skb)) {
- PRINTK("TXD with no skb assigned.\n");
+ pr_debug("TXD with no skb assigned.\n");
return;
}
txd->txd_os.skb = NULL;
@@ -1536,7 +1530,7 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd)
// free the skb
dev_kfree_skb_irq(skb);
- PRINTK(KERN_INFO "leaving mac_drv_tx_complete\n");
+ pr_debug(KERN_INFO "leaving mac_drv_tx_complete\n");
} // mac_drv_tx_complete
@@ -1603,7 +1597,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
unsigned short ri;
u_int RifLength;
- PRINTK(KERN_INFO "entering mac_drv_rx_complete (len=%d)\n", len);
+ pr_debug(KERN_INFO "entering mac_drv_rx_complete (len=%d)\n", len);
if (frag_count != 1) { // This is not allowed to happen.
printk("fddi: Multi-fragment receive!\n");
@@ -1612,7 +1606,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
}
skb = rxd->rxd_os.skb;
if (!skb) {
- PRINTK(KERN_INFO "No skb in rxd\n");
+ pr_debug(KERN_INFO "No skb in rxd\n");
smc->os.MacStat.gen.rx_errors++;
goto RequeueRxd;
}
@@ -1642,7 +1636,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
else {
int n;
// goos: RIF removal has still to be tested
- PRINTK(KERN_INFO "RIF found\n");
+ pr_debug(KERN_INFO "RIF found\n");
// Get RIF length from Routing Control (RC) field.
cp = virt + FDDI_MAC_HDR_LEN; // Point behind MAC header.
@@ -1687,7 +1681,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
return;
RequeueRxd:
- PRINTK(KERN_INFO "Rx: re-queue RXD.\n");
+ pr_debug(KERN_INFO "Rx: re-queue RXD.\n");
mac_drv_requeue_rxd(smc, rxd, frag_count);
smc->os.MacStat.gen.rx_errors++; // Count receive packets
// not indicated.
@@ -1736,7 +1730,7 @@ void mac_drv_requeue_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
skb = src_rxd->rxd_os.skb;
if (skb == NULL) { // this should not happen
- PRINTK("Requeue with no skb in rxd!\n");
+ pr_debug("Requeue with no skb in rxd!\n");
skb = alloc_skb(MaxFrameSize + 3, GFP_ATOMIC);
if (skb) {
// we got a skb
@@ -1751,7 +1745,7 @@ void mac_drv_requeue_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
rxd->rxd_os.dma_addr = b_addr;
} else {
// no skb available, use local buffer
- PRINTK("Queueing invalid buffer!\n");
+ pr_debug("Queueing invalid buffer!\n");
rxd->rxd_os.skb = NULL;
v_addr = smc->os.LocalRxBuffer;
b_addr = smc->os.LocalRxBufferDMA;
@@ -1798,7 +1792,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
struct sk_buff *skb;
volatile struct s_smt_fp_rxd *rxd;
- PRINTK(KERN_INFO "entering mac_drv_fill_rxd\n");
+ pr_debug(KERN_INFO "entering mac_drv_fill_rxd\n");
// Walk through the list of free receive buffers, passing receive
// buffers to the HWM as long as RXDs are available.
@@ -1806,7 +1800,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
MaxFrameSize = smc->os.MaxFrameSize;
// Check if there is any RXD left.
while (HWM_GET_RX_FREE(smc) > 0) {
- PRINTK(KERN_INFO ".\n");
+ pr_debug(KERN_INFO ".\n");
rxd = HWM_GET_CURR_RXD(smc);
skb = alloc_skb(MaxFrameSize + 3, GFP_ATOMIC);
@@ -1826,7 +1820,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
// keep the receiver running in hope of better times.
// Multiple descriptors may point to this local buffer,
// so data in it must be considered invalid.
- PRINTK("Queueing invalid buffer!\n");
+ pr_debug("Queueing invalid buffer!\n");
v_addr = smc->os.LocalRxBuffer;
b_addr = smc->os.LocalRxBufferDMA;
}
@@ -1837,7 +1831,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
hwm_rx_frag(smc, v_addr, b_addr, MaxFrameSize,
FIRST_FRAG | LAST_FRAG);
}
- PRINTK(KERN_INFO "leaving mac_drv_fill_rxd\n");
+ pr_debug(KERN_INFO "leaving mac_drv_fill_rxd\n");
} // mac_drv_fill_rxd
@@ -1863,7 +1857,7 @@ void mac_drv_clear_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
struct sk_buff *skb;
- PRINTK("entering mac_drv_clear_rxd\n");
+ pr_debug("entering mac_drv_clear_rxd\n");
if (frag_count != 1) // This is not allowed to happen.
@@ -1919,19 +1913,19 @@ int mac_drv_rx_init(struct s_smc *smc, int len, int fc,
{
struct sk_buff *skb;
- PRINTK("entering mac_drv_rx_init(len=%d)\n", len);
+ pr_debug("entering mac_drv_rx_init(len=%d)\n", len);
// "Received" a SMT or NSA frame of the local SMT.
if (len != la_len || len < FDDI_MAC_HDR_LEN || !look_ahead) {
- PRINTK("fddi: Discard invalid local SMT frame\n");
- PRINTK(" len=%d, la_len=%d, (ULONG) look_ahead=%08lXh.\n",
+ pr_debug("fddi: Discard invalid local SMT frame\n");
+ pr_debug(" len=%d, la_len=%d, (ULONG) look_ahead=%08lXh.\n",
len, la_len, (unsigned long) look_ahead);
return (0);
}
skb = alloc_skb(len + 3, GFP_ATOMIC);
if (!skb) {
- PRINTK("fddi: Local SMT: skb memory exhausted.\n");
+ pr_debug("fddi: Local SMT: skb memory exhausted.\n");
return (0);
}
skb_reserve(skb, 3);
@@ -1981,40 +1975,40 @@ void smt_timer_poll(struct s_smc *smc)
************************/
void ring_status_indication(struct s_smc *smc, u_long status)
{
- PRINTK("ring_status_indication( ");
+ pr_debug("ring_status_indication( ");
if (status & RS_RES15)
- PRINTK("RS_RES15 ");
+ pr_debug("RS_RES15 ");
if (status & RS_HARDERROR)
- PRINTK("RS_HARDERROR ");
+ pr_debug("RS_HARDERROR ");
if (status & RS_SOFTERROR)
- PRINTK("RS_SOFTERROR ");
+ pr_debug("RS_SOFTERROR ");
if (status & RS_BEACON)
- PRINTK("RS_BEACON ");
+ pr_debug("RS_BEACON ");
if (status & RS_PATHTEST)
- PRINTK("RS_PATHTEST ");
+ pr_debug("RS_PATHTEST ");
if (status & RS_SELFTEST)
- PRINTK("RS_SELFTEST ");
+ pr_debug("RS_SELFTEST ");
if (status & RS_RES9)
- PRINTK("RS_RES9 ");
+ pr_debug("RS_RES9 ");
if (status & RS_DISCONNECT)
- PRINTK("RS_DISCONNECT ");
+ pr_debug("RS_DISCONNECT ");
if (status & RS_RES7)
- PRINTK("RS_RES7 ");
+ pr_debug("RS_RES7 ");
if (status & RS_DUPADDR)
- PRINTK("RS_DUPADDR ");
+ pr_debug("RS_DUPADDR ");
if (status & RS_NORINGOP)
- PRINTK("RS_NORINGOP ");
+ pr_debug("RS_NORINGOP ");
if (status & RS_VERSION)
- PRINTK("RS_VERSION ");
+ pr_debug("RS_VERSION ");
if (status & RS_STUCKBYPASSS)
- PRINTK("RS_STUCKBYPASSS ");
+ pr_debug("RS_STUCKBYPASSS ");
if (status & RS_EVENT)
- PRINTK("RS_EVENT ");
+ pr_debug("RS_EVENT ");
if (status & RS_RINGOPCHANGE)
- PRINTK("RS_RINGOPCHANGE ");
+ pr_debug("RS_RINGOPCHANGE ");
if (status & RS_RES0)
- PRINTK("RS_RES0 ");
- PRINTK("]\n");
+ pr_debug("RS_RES0 ");
+ pr_debug("]\n");
} // ring_status_indication
@@ -2057,17 +2051,17 @@ void smt_stat_counter(struct s_smc *smc, int stat)
{
// BOOLEAN RingIsUp ;
- PRINTK(KERN_INFO "smt_stat_counter\n");
+ pr_debug(KERN_INFO "smt_stat_counter\n");
switch (stat) {
case 0:
- PRINTK(KERN_INFO "Ring operational change.\n");
+ pr_debug(KERN_INFO "Ring operational change.\n");
break;
case 1:
- PRINTK(KERN_INFO "Receive fifo overflow.\n");
+ pr_debug(KERN_INFO "Receive fifo overflow.\n");
smc->os.MacStat.gen.rx_errors++;
break;
default:
- PRINTK(KERN_INFO "Unknown status (%d).\n", stat);
+ pr_debug(KERN_INFO "Unknown status (%d).\n", stat);
break;
}
} // smt_stat_counter
@@ -2123,10 +2117,10 @@ void cfm_state_change(struct s_smc *smc, int c_state)
s = "SC11_C_WRAP_S";
break;
default:
- PRINTK(KERN_INFO "cfm_state_change: unknown %d\n", c_state);
+ pr_debug(KERN_INFO "cfm_state_change: unknown %d\n", c_state);
return;
}
- PRINTK(KERN_INFO "cfm_state_change: %s\n", s);
+ pr_debug(KERN_INFO "cfm_state_change: %s\n", s);
#endif // DRIVERDEBUG
} // cfm_state_change
@@ -2181,7 +2175,7 @@ void ecm_state_change(struct s_smc *smc, int e_state)
s = "unknown";
break;
}
- PRINTK(KERN_INFO "ecm_state_change: %s\n", s);
+ pr_debug(KERN_INFO "ecm_state_change: %s\n", s);
#endif //DRIVERDEBUG
} // ecm_state_change
@@ -2236,7 +2230,7 @@ void rmt_state_change(struct s_smc *smc, int r_state)
s = "unknown";
break;
}
- PRINTK(KERN_INFO "[rmt_state_change: %s]\n", s);
+ pr_debug(KERN_INFO "[rmt_state_change: %s]\n", s);
#endif // DRIVERDEBUG
} // rmt_state_change
@@ -2256,7 +2250,7 @@ void rmt_state_change(struct s_smc *smc, int r_state)
************************/
void drv_reset_indication(struct s_smc *smc)
{
- PRINTK(KERN_INFO "entering drv_reset_indication\n");
+ pr_debug(KERN_INFO "entering drv_reset_indication\n");
smc->os.ResetRequested = TRUE; // Set flag.
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index c11cdd08ec5..60d502eef4f 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -2837,8 +2837,6 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
}
- dev->trans_start = jiffies;
-
return NETDEV_TX_OK;
}
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index a2ff9cb1e7a..6b5946fe8ae 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1690,7 +1690,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
- dev->trans_start = jiffies;
return NETDEV_TX_OK;
mapping_unwind:
diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c
index 8d36d40649e..c791ef76c1d 100644
--- a/drivers/net/smc-mca.c
+++ b/drivers/net/smc-mca.c
@@ -370,7 +370,7 @@ static int __init ultramca_probe(struct device *gen_dev)
outb(reg4, ioaddr + 4);
- gen_dev->driver_data = dev;
+ dev_set_drvdata(gen_dev, dev);
/* The 8390 isn't at the base address, so fake the offset
*/
@@ -531,7 +531,7 @@ static int ultramca_close_card(struct net_device *dev)
static int ultramca_remove(struct device *gen_dev)
{
struct mca_device *mca_dev = to_mca_device(gen_dev);
- struct net_device *dev = (struct net_device *)gen_dev->driver_data;
+ struct net_device *dev = dev_get_drvdata(gen_dev);
if (dev) {
/* NB: ultra_close_card() does free_irq */
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 293610334a7..bc4976ac871 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -1774,6 +1774,20 @@ static int __devinit smc911x_findirq(struct net_device *dev)
return probe_irq_off(cookie);
}
+static const struct net_device_ops smc911x_netdev_ops = {
+ .ndo_open = smc911x_open,
+ .ndo_stop = smc911x_close,
+ .ndo_start_xmit = smc911x_hard_start_xmit,
+ .ndo_tx_timeout = smc911x_timeout,
+ .ndo_set_multicast_list = smc911x_set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = smc911x_poll_controller,
+#endif
+};
+
/*
* Function: smc911x_probe(unsigned long ioaddr)
*
@@ -1940,16 +1954,9 @@ static int __devinit smc911x_probe(struct net_device *dev)
/* Fill in the fields of the device structure with ethernet values. */
ether_setup(dev);
- dev->open = smc911x_open;
- dev->stop = smc911x_close;
- dev->hard_start_xmit = smc911x_hard_start_xmit;
- dev->tx_timeout = smc911x_timeout;
+ dev->netdev_ops = &smc911x_netdev_ops;
dev->watchdog_timeo = msecs_to_jiffies(watchdog);
- dev->set_multicast_list = smc911x_set_multicast_list;
dev->ethtool_ops = &smc911x_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = smc911x_poll_controller;
-#endif
INIT_WORK(&lp->phy_configure, smc911x_phy_configure);
lp->mii.phy_id_mask = 0x1f;
diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c
index 9a7973a5411..e02471b2f2b 100644
--- a/drivers/net/smc9194.c
+++ b/drivers/net/smc9194.c
@@ -503,7 +503,7 @@ static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * de
/* THIS SHOULD NEVER HAPPEN. */
dev->stats.tx_aborted_errors++;
printk(CARDNAME": Bad Craziness - sent packet while busy.\n" );
- return 1;
+ return NETDEV_TX_BUSY;
}
lp->saved_skb = skb;
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index eb7db032a78..b60639bd181 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -47,6 +47,7 @@
#include <linux/bitops.h>
#include <linux/irq.h>
#include <linux/io.h>
+#include <linux/swab.h>
#include <linux/phy.h>
#include <linux/smsc911x.h>
#include "smsc911x.h"
@@ -175,6 +176,12 @@ static inline void
smsc911x_tx_writefifo(struct smsc911x_data *pdata, unsigned int *buf,
unsigned int wordcount)
{
+ if (pdata->config.flags & SMSC911X_SWAP_FIFO) {
+ while (wordcount--)
+ smsc911x_reg_write(pdata, TX_DATA_FIFO, swab32(*buf++));
+ return;
+ }
+
if (pdata->config.flags & SMSC911X_USE_32BIT) {
writesl(pdata->ioaddr + TX_DATA_FIFO, buf, wordcount);
return;
@@ -194,6 +201,12 @@ static inline void
smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf,
unsigned int wordcount)
{
+ if (pdata->config.flags & SMSC911X_SWAP_FIFO) {
+ while (wordcount--)
+ *buf++ = swab32(smsc911x_reg_read(pdata, RX_DATA_FIFO));
+ return;
+ }
+
if (pdata->config.flags & SMSC911X_USE_32BIT) {
readsl(pdata->ioaddr + RX_DATA_FIFO, buf, wordcount);
return;
@@ -1963,7 +1976,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
retval = -ENODEV;
goto out_0;
}
- res_size = res->end - res->start;
+ res_size = res->end - res->start + 1;
irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq_res) {
@@ -2096,12 +2109,58 @@ out_0:
return retval;
}
+#ifdef CONFIG_PM
+/* This implementation assumes the devices remains powered on its VDDVARIO
+ * pins during suspend. */
+
+static int smsc911x_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct smsc911x_data *pdata = netdev_priv(dev);
+
+ /* enable wake on LAN, energy detection and the external PME
+ * signal. */
+ smsc911x_reg_write(pdata, PMT_CTRL,
+ PMT_CTRL_PM_MODE_D1_ | PMT_CTRL_WOL_EN_ |
+ PMT_CTRL_ED_EN_ | PMT_CTRL_PME_EN_);
+
+ return 0;
+}
+
+static int smsc911x_resume(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct smsc911x_data *pdata = netdev_priv(dev);
+ unsigned int to = 100;
+
+ /* Note 3.11 from the datasheet:
+ * "When the LAN9220 is in a power saving state, a write of any
+ * data to the BYTE_TEST register will wake-up the device."
+ */
+ smsc911x_reg_write(pdata, BYTE_TEST, 0);
+
+ /* poll the READY bit in PMT_CTRL. Any other access to the device is
+ * forbidden while this bit isn't set. Try for 100ms and return -EIO
+ * if it failed. */
+ while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to)
+ udelay(1000);
+
+ return (to == 0) ? -EIO : 0;
+}
+
+#else
+#define smsc911x_suspend NULL
+#define smsc911x_resume NULL
+#endif
+
static struct platform_driver smsc911x_driver = {
.probe = smsc911x_drv_probe,
- .remove = smsc911x_drv_remove,
+ .remove = __devexit_p(smsc911x_drv_remove),
.driver = {
.name = SMSC_CHIPNAME,
},
+ .suspend = smsc911x_suspend,
+ .resume = smsc911x_resume,
};
/* Entry point for loading the module */
diff --git a/drivers/net/sonic.c b/drivers/net/sonic.c
index 211e805c122..e4255d82938 100644
--- a/drivers/net/sonic.c
+++ b/drivers/net/sonic.c
@@ -223,7 +223,7 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
if (!laddr) {
printk(KERN_ERR "%s: failed to map tx DMA buffer.\n", dev->name);
dev_kfree_skb(skb);
- return 1;
+ return NETDEV_TX_BUSY
}
sonic_tda_put(dev, entry, SONIC_TD_STATUS, 0); /* clear status */
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index fcb943fca4f..838cce8b8ff 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -1236,7 +1236,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
*/
if ((np->cur_tx - np->dirty_tx) + skb_num_frags(skb) * 2 > TX_RING_SIZE) {
netif_stop_queue(dev);
- return 1;
+ return NETDEV_TX_BUSY;
}
#if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE)
diff --git a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c
index a39c0b9ba8b..7bb27426dbd 100644
--- a/drivers/net/sun3_82586.c
+++ b/drivers/net/sun3_82586.c
@@ -1023,7 +1023,7 @@ static int sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
#if(NUM_XMIT_BUFFS > 1)
if(test_and_set_bit(0,(void *) &p->lock)) {
printk("%s: Queue was locked\n",dev->name);
- return 1;
+ return NETDEV_TX_BUSY;
}
else
#endif
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index e5beb299cbd..534dfe3eef6 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -294,6 +294,16 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops lance_netdev_ops = {
+ .ndo_open = lance_open,
+ .ndo_stop = lance_close,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_set_mac_address = NULL,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __init lance_probe( struct net_device *dev)
{
unsigned long ioaddr;
@@ -397,12 +407,7 @@ static int __init lance_probe( struct net_device *dev)
if (did_version++ == 0)
printk( version );
- /* The LANCE-specific entries in the device structure. */
- dev->open = &lance_open;
- dev->hard_start_xmit = &lance_start_xmit;
- dev->stop = &lance_close;
- dev->set_multicast_list = &set_multicast_list;
- dev->set_mac_address = NULL;
+ dev->netdev_ops = &lance_netdev_ops;
// KLUDGE -- REMOVE ME
set_bit(__LINK_STATE_PRESENT, &dev->state);
@@ -521,7 +526,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
if (netif_queue_stopped(dev)) {
int tickssofar = jiffies - dev->trans_start;
if (tickssofar < 20)
- return( 1 );
+ return NETDEV_TX_BUSY;
DPRINTK( 1, ( "%s: transmit timed out, status %04x, resetting.\n",
dev->name, DREG ));
@@ -572,7 +577,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
if (test_and_set_bit( 0, (void*)&lp->lock ) != 0) {
printk( "%s: tx queue lock!.\n", dev->name);
/* don't clear dev->tbusy flag. */
- return 1;
+ return NETDEV_TX_BUSY;
}
AREG = CSR0;
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index c399b1955c1..545f81b34ad 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -369,7 +369,6 @@ struct netdev_private {
struct sk_buff* tx_skbuff[TX_RING_SIZE];
dma_addr_t tx_ring_dma;
dma_addr_t rx_ring_dma;
- struct net_device_stats stats;
struct timer_list timer; /* Media monitoring timer. */
/* Frequently used values: keep some adjacent for cache effect. */
spinlock_t lock;
@@ -975,7 +974,7 @@ static void tx_timeout(struct net_device *dev)
dev->if_port = 0;
dev->trans_start = jiffies;
- np->stats.tx_errors++;
+ dev->stats.tx_errors++;
if (np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
netif_wake_queue(dev);
}
@@ -1123,7 +1122,7 @@ reset_tx (struct net_device *dev)
else
dev_kfree_skb (skb);
np->tx_skbuff[i] = NULL;
- np->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
}
}
np->cur_tx = np->dirty_tx = 0;
@@ -1181,15 +1180,15 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
if (netif_msg_tx_err(np))
printk("%s: Transmit error status %4.4x.\n",
dev->name, tx_status);
- np->stats.tx_errors++;
+ dev->stats.tx_errors++;
if (tx_status & 0x10)
- np->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
if (tx_status & 0x08)
- np->stats.collisions++;
+ dev->stats.collisions++;
if (tx_status & 0x04)
- np->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
if (tx_status & 0x02)
- np->stats.tx_window_errors++;
+ dev->stats.tx_window_errors++;
/*
** This reset has been verified on
@@ -1313,11 +1312,15 @@ static void rx_poll(unsigned long data)
if (netif_msg_rx_err(np))
printk(KERN_DEBUG " netdev_rx() Rx error was %8.8x.\n",
frame_status);
- np->stats.rx_errors++;
- if (frame_status & 0x00100000) np->stats.rx_length_errors++;
- if (frame_status & 0x00010000) np->stats.rx_fifo_errors++;
- if (frame_status & 0x00060000) np->stats.rx_frame_errors++;
- if (frame_status & 0x00080000) np->stats.rx_crc_errors++;
+ dev->stats.rx_errors++;
+ if (frame_status & 0x00100000)
+ dev->stats.rx_length_errors++;
+ if (frame_status & 0x00010000)
+ dev->stats.rx_fifo_errors++;
+ if (frame_status & 0x00060000)
+ dev->stats.rx_frame_errors++;
+ if (frame_status & 0x00080000)
+ dev->stats.rx_crc_errors++;
if (frame_status & 0x00100000) {
printk(KERN_WARNING "%s: Oversized Ethernet frame,"
" status %8.8x.\n",
@@ -1485,22 +1488,22 @@ static struct net_device_stats *get_stats(struct net_device *dev)
the vulnerability window is very small and statistics are
non-critical. */
/* The chip only need report frame silently dropped. */
- np->stats.rx_missed_errors += ioread8(ioaddr + RxMissed);
- np->stats.tx_packets += ioread16(ioaddr + TxFramesOK);
- np->stats.rx_packets += ioread16(ioaddr + RxFramesOK);
- np->stats.collisions += ioread8(ioaddr + StatsLateColl);
- np->stats.collisions += ioread8(ioaddr + StatsMultiColl);
- np->stats.collisions += ioread8(ioaddr + StatsOneColl);
- np->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError);
+ dev->stats.rx_missed_errors += ioread8(ioaddr + RxMissed);
+ dev->stats.tx_packets += ioread16(ioaddr + TxFramesOK);
+ dev->stats.rx_packets += ioread16(ioaddr + RxFramesOK);
+ dev->stats.collisions += ioread8(ioaddr + StatsLateColl);
+ dev->stats.collisions += ioread8(ioaddr + StatsMultiColl);
+ dev->stats.collisions += ioread8(ioaddr + StatsOneColl);
+ dev->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError);
ioread8(ioaddr + StatsTxDefer);
for (i = StatsTxDefer; i <= StatsMcastRx; i++)
ioread8(ioaddr + i);
- np->stats.tx_bytes += ioread16(ioaddr + TxOctetsLow);
- np->stats.tx_bytes += ioread16(ioaddr + TxOctetsHigh) << 16;
- np->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow);
- np->stats.rx_bytes += ioread16(ioaddr + RxOctetsHigh) << 16;
+ dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsLow);
+ dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsHigh) << 16;
+ dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow);
+ dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsHigh) << 16;
- return &np->stats;
+ return &dev->stats;
}
static void set_rx_mode(struct net_device *dev)
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 4e9bd380a5c..4ef729198e1 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2275,7 +2275,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irq(&hp->happy_lock);
printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
dev->name);
- return 1;
+ return NETDEV_TX_BUSY;
}
entry = hp->tx_new;
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index 0ce2db6ce2b..d737f6b8f87 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -688,14 +688,11 @@ static void tc_handle_link_change(struct net_device *dev)
if (status_change && netif_msg_link(lp)) {
phy_print_status(phydev);
-#ifdef DEBUG
- printk(KERN_DEBUG
- "%s: MII BMCR %04x BMSR %04x LPA %04x\n",
- dev->name,
- phy_read(phydev, MII_BMCR),
- phy_read(phydev, MII_BMSR),
- phy_read(phydev, MII_LPA));
-#endif
+ pr_debug("%s: MII BMCR %04x BMSR %04x LPA %04x\n",
+ dev->name,
+ phy_read(phydev, MII_BMCR),
+ phy_read(phydev, MII_BMSR),
+ phy_read(phydev, MII_LPA));
}
}
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 7f4a9683ba1..3c2679cd196 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -948,8 +948,7 @@ static void print_rxfd(struct rxf_desc *rxfd);
static void bdx_rxdb_destroy(struct rxdb *db)
{
- if (db)
- vfree(db);
+ vfree(db);
}
static struct rxdb *bdx_rxdb_create(int nelem)
@@ -1482,10 +1481,8 @@ static void bdx_tx_db_close(struct txdb *d)
{
BDX_ASSERT(d == NULL);
- if (d->start) {
- vfree(d->start);
- d->start = NULL;
- }
+ vfree(d->start);
+ d->start = NULL;
}
/*************************************************************************
@@ -1718,8 +1715,9 @@ static int bdx_tx_transmit(struct sk_buff *skb, struct net_device *ndev)
WRITE_REG(priv, f->m.reg_WPTR, f->m.wptr & TXF_WPTR_WR_PTR);
#endif
- ndev->trans_start = jiffies;
-
+#ifdef BDX_LLTX
+ ndev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
+#endif
priv->net_stats.tx_packets++;
priv->net_stats.tx_bytes += skb->len;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 201be425643..46a3f86125b 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -68,8 +68,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.98"
-#define DRV_MODULE_RELDATE "February 25, 2009"
+#define DRV_MODULE_VERSION "3.99"
+#define DRV_MODULE_RELDATE "April 20, 2009"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -1950,7 +1950,8 @@ static void tg3_frob_aux_power(struct tg3 *tp)
GRC_LCLCTRL_GPIO_OUTPUT0 |
GRC_LCLCTRL_GPIO_OUTPUT1),
100);
- } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
+ } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
/* The 5761 non-e device swaps GPIO 0 and GPIO 2. */
u32 grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 |
GRC_LCLCTRL_GPIO_OE1 |
@@ -2455,8 +2456,6 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
}
}
- __tg3_set_mac_addr(tp, 0);
-
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
u32 val;
@@ -4656,6 +4655,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
* so we must read it before checking for more work.
*/
tp->last_tag = sblk->status_tag;
+ tp->last_irq_tag = tp->last_tag;
rmb();
} else
sblk->status &= ~SD_STATUS_UPDATED;
@@ -4811,7 +4811,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
* Reading the PCI State register will confirm whether the
* interrupt is ours and will flush the status block.
*/
- if (unlikely(sblk->status_tag == tp->last_tag)) {
+ if (unlikely(sblk->status_tag == tp->last_irq_tag)) {
if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
handled = 0;
@@ -4831,18 +4831,22 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
* excessive spurious interrupts can be worse in some cases.
*/
tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+
+ /*
+ * In a shared interrupt configuration, sometimes other devices'
+ * interrupts will scream. We record the current status tag here
+ * so that the above check can report that the screaming interrupts
+ * are unhandled. Eventually they will be silenced.
+ */
+ tp->last_irq_tag = sblk->status_tag;
+
if (tg3_irq_sync(tp))
goto out;
- if (napi_schedule_prep(&tp->napi)) {
- prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
- /* Update last_tag to mark that this status has been
- * seen. Because interrupt may be shared, we may be
- * racing with tg3_poll(), so only update last_tag
- * if tg3_poll() is not scheduled.
- */
- tp->last_tag = sblk->status_tag;
- __napi_schedule(&tp->napi);
- }
+
+ prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+
+ napi_schedule(&tp->napi);
+
out:
return IRQ_RETVAL(handled);
}
@@ -5017,7 +5021,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
/* New SKB is guaranteed to be linear. */
entry = *start;
ret = skb_dma_map(&tp->pdev->dev, new_skb, DMA_TO_DEVICE);
- new_addr = skb_shinfo(new_skb)->dma_maps[0];
+ new_addr = skb_shinfo(new_skb)->dma_head;
/* Make sure new skb does not cross any 4G boundaries.
* Drop the packet if it does.
@@ -5151,7 +5155,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
sp = skb_shinfo(skb);
- mapping = sp->dma_maps[0];
+ mapping = sp->dma_head;
tp->tx_buffers[entry].skb = skb;
@@ -5169,7 +5173,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
len = frag->size;
- mapping = sp->dma_maps[i + 1];
+ mapping = sp->dma_maps[i];
tp->tx_buffers[entry].skb = NULL;
tg3_set_txd(tp, entry, mapping, len,
@@ -5190,9 +5194,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
out_unlock:
- mmiowb();
-
- dev->trans_start = jiffies;
+ mmiowb();
return NETDEV_TX_OK;
}
@@ -5329,7 +5331,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
sp = skb_shinfo(skb);
- mapping = sp->dma_maps[0];
+ mapping = sp->dma_head;
tp->tx_buffers[entry].skb = skb;
@@ -5354,7 +5356,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
len = frag->size;
- mapping = sp->dma_maps[i + 1];
+ mapping = sp->dma_maps[i];
tp->tx_buffers[entry].skb = NULL;
@@ -5403,9 +5405,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
}
out_unlock:
- mmiowb();
-
- dev->trans_start = jiffies;
+ mmiowb();
return NETDEV_TX_OK;
}
@@ -6156,6 +6156,7 @@ static int tg3_chip_reset(struct tg3 *tp)
tp->hw_status->status_tag = 0;
}
tp->last_tag = 0;
+ tp->last_irq_tag = 0;
smp_mb();
synchronize_irq(tp->pdev->irq);
@@ -6350,6 +6351,8 @@ static int tg3_halt(struct tg3 *tp, int kind, int silent)
tg3_abort_hw(tp, silent);
err = tg3_chip_reset(tp);
+ __tg3_set_mac_addr(tp, 0);
+
tg3_write_sig_legacy(tp, kind);
tg3_write_sig_post_reset(tp, kind);
@@ -6711,6 +6714,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(TG3_CPMU_HST_ACC, val);
}
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
+ val = tr32(PCIE_PWR_MGMT_THRESH) & ~PCIE_PWR_MGMT_L1_THRESH_MSK;
+ val |= PCIE_PWR_MGMT_EXT_ASPM_TMR_EN |
+ PCIE_PWR_MGMT_L1_THRESH_4MS;
+ tw32(PCIE_PWR_MGMT_THRESH, val);
+ }
+
/* This works around an issue with Athlon chipsets on
* B3 tigon3 silicon. This bit has no effect on any
* other revision. But do not set this on PCI Express
@@ -7138,7 +7148,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
udelay(100);
tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0);
- tp->last_tag = 0;
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
tw32_f(DMAC_MODE, DMAC_MODE_ENABLE);
@@ -8539,6 +8548,9 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
u32 i, offset, len, b_offset, b_count;
__be32 val;
+ if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
+ return -EINVAL;
+
if (tp->link_config.phy_is_low_power)
return -EAGAIN;
@@ -8604,7 +8616,8 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
if (tp->link_config.phy_is_low_power)
return -EAGAIN;
- if (eeprom->magic != TG3_EEPROM_MAGIC)
+ if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+ eeprom->magic != TG3_EEPROM_MAGIC)
return -EINVAL;
offset = eeprom->offset;
@@ -9201,6 +9214,9 @@ static int tg3_test_nvram(struct tg3 *tp)
__be32 *buf;
int i, j, k, err = 0, size;
+ if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
+ return 0;
+
if (tg3_nvram_read(tp, 0, &magic) != 0)
return -EIO;
@@ -10183,7 +10199,8 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp)
{
u32 val;
- if (tg3_nvram_read(tp, 0, &val) != 0)
+ if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+ tg3_nvram_read(tp, 0, &val) != 0)
return;
/* Selfboot format */
@@ -10565,6 +10582,7 @@ static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp)
}
break;
default:
+ tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM;
return;
}
@@ -11365,7 +11383,8 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
unsigned int i;
u32 magic;
- if (tg3_nvram_read(tp, 0x0, &magic))
+ if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+ tg3_nvram_read(tp, 0x0, &magic))
goto out_not_found;
if (magic == TG3_EEPROM_MAGIC) {
@@ -11457,6 +11476,15 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
out_not_found:
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
strcpy(tp->board_part_number, "BCM95906");
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57780)
+ strcpy(tp->board_part_number, "BCM57780");
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57760)
+ strcpy(tp->board_part_number, "BCM57760");
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790)
+ strcpy(tp->board_part_number, "BCM57790");
else
strcpy(tp->board_part_number, "none");
}
@@ -11667,6 +11695,14 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
{
u32 val;
+ if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) {
+ tp->fw_ver[0] = 's';
+ tp->fw_ver[1] = 'b';
+ tp->fw_ver[2] = '\0';
+
+ return;
+ }
+
if (tg3_nvram_read(tp, 0, &val))
return;
@@ -11952,7 +11988,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+ tp->pci_chip_rev_id == CHIPREV_ID_57780_A0 ||
+ tp->pci_chip_rev_id == CHIPREV_ID_57780_A1)
tp->tg3_flags3 |= TG3_FLG3_CLKREQ_BUG;
}
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
@@ -12144,7 +12181,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
- if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
+ if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
/* Turn off the debug UART. */
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
@@ -12454,7 +12492,8 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
}
if (!addr_ok) {
/* Next, try NVRAM. */
- if (!tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
+ if (!(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) &&
+ !tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
!tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) {
memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2);
memcpy(&dev->dev_addr[2], (char *)&lo, sizeof(lo));
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index cb4c62abdd2..b3347c41a1a 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -95,6 +95,8 @@
#define CHIPREV_ID_5752_A1 0x6001
#define CHIPREV_ID_5714_A2 0x9002
#define CHIPREV_ID_5906_A1 0xc001
+#define CHIPREV_ID_57780_A0 0x57780000
+#define CHIPREV_ID_57780_A1 0x57780001
#define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12)
#define ASIC_REV_5700 0x07
#define ASIC_REV_5701 0x00
@@ -1697,6 +1699,8 @@
#define PCIE_PWR_MGMT_THRESH 0x00007d28
#define PCIE_PWR_MGMT_L1_THRESH_MSK 0x0000ff00
+#define PCIE_PWR_MGMT_L1_THRESH_4MS 0x0000ff00
+#define PCIE_PWR_MGMT_EXT_ASPM_TMR_EN 0x01000000
/* OTP bit definitions */
@@ -2501,6 +2505,7 @@ struct tg3 {
struct tg3_hw_status *hw_status;
dma_addr_t status_mapping;
u32 last_tag;
+ u32 last_irq_tag;
u32 msg_enable;
@@ -2635,6 +2640,7 @@ struct tg3 {
#define TG3_FLG3_CLKREQ_BUG 0x00000800
#define TG3_FLG3_PHY_ENABLE_APD 0x00001000
#define TG3_FLG3_5755_PLUS 0x00002000
+#define TG3_FLG3_NO_NVRAM 0x00004000
struct timer_list timer;
u16 timer_counter;
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index aa6964922d5..384cb5e2839 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -1111,7 +1111,7 @@ static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
dev->name, priv->txHead, priv->txTail );
netif_stop_queue(dev);
priv->txBusyCount++;
- return 1;
+ return NETDEV_TX_BUSY;
}
tail_list->forward = 0;
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index 0337b9d673f..b40b6de2d08 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -1243,7 +1243,7 @@ static int xl_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
} else {
spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ;
- return 1;
+ return NETDEV_TX_BUSY;
}
}
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
index 46a2cc92d97..b3715efdce5 100644
--- a/drivers/net/tokenring/lanstreamer.c
+++ b/drivers/net/tokenring/lanstreamer.c
@@ -1187,7 +1187,7 @@ static int streamer_xmit(struct sk_buff *skb, struct net_device *dev)
} else {
netif_stop_queue(dev);
spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags);
- return 1;
+ return NETDEV_TX_BUSY;
}
}
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
index 2d819fc8558..451b54136ed 100644
--- a/drivers/net/tokenring/olympic.c
+++ b/drivers/net/tokenring/olympic.c
@@ -1055,7 +1055,7 @@ static int olympic_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
} else {
spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
- return 1;
+ return NETDEV_TX_BUSY;
}
}
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
index a91d9c55d78..54ad4ed0337 100644
--- a/drivers/net/tokenring/smctr.c
+++ b/drivers/net/tokenring/smctr.c
@@ -4601,7 +4601,7 @@ static int smctr_send_packet(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
if(tp->QueueSkb == 0)
- return (1); /* Return with tbusy set: queue full */
+ return NETDEV_TX_BUSY; /* Return with tbusy set: queue full */
tp->QueueSkb--;
skb_queue_tail(&tp->SendSkbQueue, skb);
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
index b11bb72dc7a..a2eab72b507 100644
--- a/drivers/net/tokenring/tms380tr.c
+++ b/drivers/net/tokenring/tms380tr.c
@@ -633,7 +633,7 @@ static int tms380tr_hardware_send_packet(struct sk_buff *skb, struct net_device
if (tms380tr_debug > 0)
printk(KERN_DEBUG "%s: No free TPL\n", dev->name);
spin_unlock_irqrestore(&tp->lock, flags);
- return 1;
+ return NETDEV_TX_BUSY;
}
dmabuf = 0;
diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig
index d913405bc39..1cc8cf4425d 100644
--- a/drivers/net/tulip/Kconfig
+++ b/drivers/net/tulip/Kconfig
@@ -27,6 +27,18 @@ config DE2104X
To compile this driver as a module, choose M here. The module will
be called de2104x.
+config DE2104X_DSL
+ int "Descriptor Skip Length in 32 bit longwords"
+ depends on DE2104X
+ range 0 31
+ default 0
+ help
+ Setting this value allows to align ring buffer descriptors into their
+ own cache lines. Value of 4 corresponds to the typical 32 byte line
+ (the descriptor is 16 bytes). This is necessary on systems that lack
+ cache coherence, an example is PowerMac 5500. Otherwise 0 is safe.
+ Default is 0, and range is 0 to 31.
+
config TULIP
tristate "DECchip Tulip (dc2114x) PCI support"
depends on PCI
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index d4c5ecc51f7..81f054dbb88 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -82,6 +82,13 @@ MODULE_PARM_DESC (rx_copybreak, "de2104x Breakpoint at which Rx packets are copi
NETIF_MSG_RX_ERR | \
NETIF_MSG_TX_ERR)
+/* Descriptor skip length in 32 bit longwords. */
+#ifndef CONFIG_DE2104X_DSL
+#define DSL 0
+#else
+#define DSL CONFIG_DE2104X_DSL
+#endif
+
#define DE_RX_RING_SIZE 64
#define DE_TX_RING_SIZE 64
#define DE_RING_BYTES \
@@ -153,6 +160,7 @@ enum {
CmdReset = (1 << 0),
CacheAlign16 = 0x00008000,
BurstLen4 = 0x00000400,
+ DescSkipLen = (DSL << 2),
/* Rx/TxPoll bits */
NormalTxPoll = (1 << 0),
@@ -246,7 +254,7 @@ static const u32 de_intr_mask =
* Set the programmable burst length to 4 longwords for all:
* DMA errors result without these values. Cache align 16 long.
*/
-static const u32 de_bus_mode = CacheAlign16 | BurstLen4;
+static const u32 de_bus_mode = CacheAlign16 | BurstLen4 | DescSkipLen;
struct de_srom_media_block {
u8 opts;
@@ -266,6 +274,9 @@ struct de_desc {
__le32 opts2;
__le32 addr1;
__le32 addr2;
+#if DSL
+ __le32 skip[DSL];
+#endif
};
struct media_info {
@@ -601,7 +612,7 @@ static int de_start_xmit (struct sk_buff *skb, struct net_device *dev)
if (tx_free == 0) {
netif_stop_queue(dev);
spin_unlock_irq(&de->lock);
- return 1;
+ return NETDEV_TX_BUSY;
}
tx_free--;
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index f9491bd787d..eb72d2e9ab3 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -1099,7 +1099,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev)
struct pci_dev *pdev = NULL;
int i, status=0;
- gendev->driver_data = dev;
+ dev_set_drvdata(gendev, dev);
/* Ensure we're not sleeping */
if (lp->bus == EISA) {
@@ -1461,12 +1461,12 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev)
{
struct de4x5_private *lp = netdev_priv(dev);
u_long iobase = dev->base_addr;
- int status = 0;
+ int status = NETDEV_TX_OK;
u_long flags = 0;
netif_stop_queue(dev);
if (!lp->tx_enable) { /* Cannot send for now */
- return -1;
+ return NETDEV_TX_LOCKED;
}
/*
@@ -1480,7 +1480,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev)
/* Test if cache is already locked - requeue skb if so */
if (test_and_set_bit(0, (void *)&lp->cache.lock) && !lp->interrupt)
- return -1;
+ return NETDEV_TX_LOCKED;
/* Transmit descriptor ring full or stale skb */
if (netif_queue_stopped(dev) || (u_long) lp->tx_skb[lp->tx_new] > 1) {
@@ -2094,7 +2094,7 @@ static int __devexit de4x5_eisa_remove (struct device *device)
struct net_device *dev;
u_long iobase;
- dev = device->driver_data;
+ dev = dev_get_drvdata(device);
iobase = dev->base_addr;
unregister_netdev (dev);
@@ -2338,7 +2338,7 @@ static void __devexit de4x5_pci_remove (struct pci_dev *pdev)
struct net_device *dev;
u_long iobase;
- dev = pdev->dev.driver_data;
+ dev = dev_get_drvdata(&pdev->dev);
iobase = dev->base_addr;
unregister_netdev (dev);
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index f2e669974c7..8e78f003f08 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -686,7 +686,7 @@ static int dmfe_start_xmit(struct sk_buff *skb, struct DEVICE *dev)
spin_unlock_irqrestore(&db->lock, flags);
printk(KERN_ERR DRV_NAME ": No Tx resource %ld\n",
db->tx_queue_cnt);
- return 1;
+ return NETDEV_TX_BUSY;
}
/* Disable NIC interrupt */
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 8761a5a5bd7..9277ce8febe 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -591,7 +591,7 @@ static int uli526x_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) {
spin_unlock_irqrestore(&db->lock, flags);
printk(KERN_ERR DRV_NAME ": No Tx resource %ld\n", db->tx_packet_cnt);
- return 1;
+ return NETDEV_TX_BUSY;
}
/* Disable NIC interrupt */
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 264e61404f3..842b1a2c40d 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -1601,8 +1601,7 @@ static int w840_suspend (struct pci_dev *pdev, pm_message_t state)
/* no more hardware accesses behind this line. */
- BUG_ON(np->csr6);
- if (ioread32(ioaddr + IntrEnable)) BUG();
+ BUG_ON(np->csr6 || ioread32(ioaddr + IntrEnable));
/* pci_power_off(pdev, -1); */
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 735bf41c654..811d3517fce 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -540,31 +540,38 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun,
/* Get packet from user space buffer */
static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
- struct iovec *iv, size_t count,
+ const struct iovec *iv, size_t count,
int noblock)
{
struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
struct sk_buff *skb;
size_t len = count, align = 0;
struct virtio_net_hdr gso = { 0 };
+ int offset = 0;
if (!(tun->flags & TUN_NO_PI)) {
if ((len -= sizeof(pi)) > count)
return -EINVAL;
- if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi)))
+ if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
return -EFAULT;
+ offset += sizeof(pi);
}
if (tun->flags & TUN_VNET_HDR) {
if ((len -= sizeof(gso)) > count)
return -EINVAL;
- if (memcpy_fromiovec((void *)&gso, iv, sizeof(gso)))
+ if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
return -EFAULT;
+ if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
+ gso.csum_start + gso.csum_offset + 2 > gso.hdr_len)
+ gso.hdr_len = gso.csum_start + gso.csum_offset + 2;
+
if (gso.hdr_len > len)
return -EINVAL;
+ offset += sizeof(gso);
}
if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
@@ -581,7 +588,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
return PTR_ERR(skb);
}
- if (skb_copy_datagram_from_iovec(skb, 0, iv, len)) {
+ if (skb_copy_datagram_from_iovec(skb, 0, iv, offset, len)) {
tun->dev->stats.rx_dropped++;
kfree_skb(skb);
return -EFAULT;
@@ -673,7 +680,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count);
- result = tun_get_user(tun, (struct iovec *)iv, iov_length(iv, count),
+ result = tun_get_user(tun, iv, iov_length(iv, count),
file->f_flags & O_NONBLOCK);
tun_put(tun);
@@ -683,7 +690,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
/* Put packet to the user space buffer */
static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
struct sk_buff *skb,
- struct iovec *iv, int len)
+ const struct iovec *iv, int len)
{
struct tun_pi pi = { 0, skb->protocol };
ssize_t total = 0;
@@ -697,7 +704,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
pi.flags |= TUN_PKT_STRIP;
}
- if (memcpy_toiovec(iv, (void *) &pi, sizeof(pi)))
+ if (memcpy_toiovecend(iv, (void *) &pi, 0, sizeof(pi)))
return -EFAULT;
total += sizeof(pi);
}
@@ -730,14 +737,15 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
gso.csum_offset = skb->csum_offset;
} /* else everything is zero */
- if (unlikely(memcpy_toiovec(iv, (void *)&gso, sizeof(gso))))
+ if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total,
+ sizeof(gso))))
return -EFAULT;
total += sizeof(gso);
}
len = min_t(int, skb->len, len);
- skb_copy_datagram_iovec(skb, 0, iv, len);
+ skb_copy_datagram_const_iovec(skb, 0, iv, total, len);
total += len;
tun->dev->stats.tx_packets++;
@@ -792,7 +800,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
}
netif_wake_queue(tun->dev);
- ret = tun_put_user(tun, skb, (struct iovec *) iv, len);
+ ret = tun_put_user(tun, skb, iv, len);
kfree_skb(skb);
break;
}
@@ -840,12 +848,12 @@ static void tun_sock_write_space(struct sock *sk)
if (!sock_writeable(sk))
return;
- if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
- wake_up_interruptible_sync(sk->sk_sleep);
-
if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags))
return;
+ if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+ wake_up_interruptible_sync(sk->sk_sleep);
+
tun = container_of(sk, struct tun_sock, sk)->tun;
kill_fasync(&tun->fasync, SIGIO, POLL_OUT);
}
@@ -861,6 +869,52 @@ static struct proto tun_proto = {
.obj_size = sizeof(struct tun_sock),
};
+static int tun_flags(struct tun_struct *tun)
+{
+ int flags = 0;
+
+ if (tun->flags & TUN_TUN_DEV)
+ flags |= IFF_TUN;
+ else
+ flags |= IFF_TAP;
+
+ if (tun->flags & TUN_NO_PI)
+ flags |= IFF_NO_PI;
+
+ if (tun->flags & TUN_ONE_QUEUE)
+ flags |= IFF_ONE_QUEUE;
+
+ if (tun->flags & TUN_VNET_HDR)
+ flags |= IFF_VNET_HDR;
+
+ return flags;
+}
+
+static ssize_t tun_show_flags(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct tun_struct *tun = netdev_priv(to_net_dev(dev));
+ return sprintf(buf, "0x%x\n", tun_flags(tun));
+}
+
+static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct tun_struct *tun = netdev_priv(to_net_dev(dev));
+ return sprintf(buf, "%d\n", tun->owner);
+}
+
+static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct tun_struct *tun = netdev_priv(to_net_dev(dev));
+ return sprintf(buf, "%d\n", tun->group);
+}
+
+static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL);
+static DEVICE_ATTR(owner, 0444, tun_show_owner, NULL);
+static DEVICE_ATTR(group, 0444, tun_show_group, NULL);
+
static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
{
struct sock *sk;
@@ -870,6 +924,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
dev = __dev_get_by_name(net, ifr->ifr_name);
if (dev) {
+ if (ifr->ifr_flags & IFF_TUN_EXCL)
+ return -EBUSY;
if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops)
tun = netdev_priv(dev);
else if ((ifr->ifr_flags & IFF_TAP) && dev->netdev_ops == &tap_netdev_ops)
@@ -944,6 +1000,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
if (err < 0)
goto err_free_sk;
+ if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) ||
+ device_create_file(&tun->dev->dev, &dev_attr_owner) ||
+ device_create_file(&tun->dev->dev, &dev_attr_group))
+ printk(KERN_ERR "Failed to create tun sysfs files\n");
+
sk->sk_destruct = tun_sock_destruct;
err = tun_attach(tun, file);
@@ -996,21 +1057,7 @@ static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
strcpy(ifr->ifr_name, tun->dev->name);
- ifr->ifr_flags = 0;
-
- if (ifr->ifr_flags & TUN_TUN_DEV)
- ifr->ifr_flags |= IFF_TUN;
- else
- ifr->ifr_flags |= IFF_TAP;
-
- if (tun->flags & TUN_NO_PI)
- ifr->ifr_flags |= IFF_NO_PI;
-
- if (tun->flags & TUN_ONE_QUEUE)
- ifr->ifr_flags |= IFF_ONE_QUEUE;
-
- if (tun->flags & TUN_VNET_HDR)
- ifr->ifr_flags |= IFF_VNET_HDR;
+ ifr->ifr_flags = tun_flags(tun);
tun_put(tun);
return 0;
@@ -1275,21 +1322,22 @@ static int tun_chr_open(struct inode *inode, struct file * file)
static int tun_chr_close(struct inode *inode, struct file *file)
{
struct tun_file *tfile = file->private_data;
- struct tun_struct *tun = __tun_get(tfile);
+ struct tun_struct *tun;
+ rtnl_lock();
+ tun = __tun_get(tfile);
if (tun) {
DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
- rtnl_lock();
__tun_detach(tun);
/* If desireable, unregister the netdevice. */
if (!(tun->flags & TUN_PERSIST))
unregister_netdevice(tun->dev);
- rtnl_unlock();
}
+ rtnl_unlock();
tun = tfile->tun;
if (tun)
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 9dd16c9b1a1..e2f2e91cfdd 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2007 Freescale Semicondutor, Inc. All rights reserved.
+ * Copyright (C) 2006-2009 Freescale Semicondutor, Inc. All rights reserved.
*
* Author: Shlomi Gridish <gridish@freescale.com>
* Li Yang <leoli@freescale.com>
@@ -27,6 +27,7 @@
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/workqueue.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <asm/uaccess.h>
@@ -64,6 +65,8 @@
static DEFINE_SPINLOCK(ugeth_lock);
+static void uec_configure_serdes(struct net_device *dev);
+
static struct {
u32 msg_enable;
} debug = { -1 };
@@ -1409,6 +1412,9 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
(ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
upsmr |= UCC_GETH_UPSMR_TBIM;
}
+ if ((ugeth->phy_interface == PHY_INTERFACE_MODE_SGMII))
+ upsmr |= UCC_GETH_UPSMR_SGMM;
+
out_be32(&uf_regs->upsmr, upsmr);
/* Disable autonegotiation in tbi mode, because by default it
@@ -1543,14 +1549,19 @@ static int init_phy(struct net_device *dev)
priv->oldspeed = 0;
priv->oldduplex = -1;
- phydev = phy_connect(dev, ug_info->phy_bus_id, &adjust_link, 0,
- priv->phy_interface);
+ if (!ug_info->phy_node)
+ return 0;
- if (IS_ERR(phydev)) {
+ phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0,
+ priv->phy_interface);
+ if (!phydev) {
printk("%s: Could not attach to PHY\n", dev->name);
- return PTR_ERR(phydev);
+ return -ENODEV;
}
+ if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII)
+ uec_configure_serdes(dev);
+
phydev->supported &= (ADVERTISED_10baseT_Half |
ADVERTISED_10baseT_Full |
ADVERTISED_100baseT_Half |
@@ -1566,7 +1577,41 @@ static int init_phy(struct net_device *dev)
return 0;
}
+/* Initialize TBI PHY interface for communicating with the
+ * SERDES lynx PHY on the chip. We communicate with this PHY
+ * through the MDIO bus on each controller, treating it as a
+ * "normal" PHY at the address found in the UTBIPA register. We assume
+ * that the UTBIPA register is valid. Either the MDIO bus code will set
+ * it to a value that doesn't conflict with other PHYs on the bus, or the
+ * value doesn't matter, as there are no other PHYs on the bus.
+ */
+static void uec_configure_serdes(struct net_device *dev)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(dev);
+
+ if (!ugeth->tbiphy) {
+ printk(KERN_WARNING "SGMII mode requires that the device "
+ "tree specify a tbi-handle\n");
+ return;
+ }
+
+ /*
+ * If the link is already up, we must already be ok, and don't need to
+ * configure and reset the TBI<->SerDes link. Maybe U-Boot configured
+ * everything for us? Resetting it takes the link down and requires
+ * several seconds for it to come back.
+ */
+ if (phy_read(ugeth->tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS)
+ return;
+ /* Single clk mode, mii mode off(for serdes communication) */
+ phy_write(ugeth->tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS);
+
+ phy_write(ugeth->tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT);
+
+ phy_write(ugeth->tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS);
+
+}
static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
{
@@ -3225,7 +3270,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
dev->stats.tx_packets++;
/* Free the sk buffer associated with this TxBD */
- dev_kfree_skb_irq(ugeth->
+ dev_kfree_skb(ugeth->
tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]);
ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL;
ugeth->skb_dirtytx[txQ] =
@@ -3259,9 +3304,15 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget)
for (i = 0; i < ug_info->numQueuesRx; i++)
howmany += ucc_geth_rx(ugeth, i, budget - howmany);
+ /* Tx event processing */
+ spin_lock(&ugeth->lock);
+ for (i = 0; i < ug_info->numQueuesTx; i++)
+ ucc_geth_tx(ugeth->ndev, i);
+ spin_unlock(&ugeth->lock);
+
if (howmany < budget) {
napi_complete(napi);
- setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS);
+ setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS | UCCE_TX_EVENTS);
}
return howmany;
@@ -3275,8 +3326,6 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
struct ucc_geth_info *ug_info;
register u32 ucce;
register u32 uccm;
- register u32 tx_mask;
- u8 i;
ugeth_vdbg("%s: IN", __func__);
@@ -3290,27 +3339,14 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
out_be32(uccf->p_ucce, ucce);
/* check for receive events that require processing */
- if (ucce & UCCE_RX_EVENTS) {
+ if (ucce & (UCCE_RX_EVENTS | UCCE_TX_EVENTS)) {
if (napi_schedule_prep(&ugeth->napi)) {
- uccm &= ~UCCE_RX_EVENTS;
+ uccm &= ~(UCCE_RX_EVENTS | UCCE_TX_EVENTS);
out_be32(uccf->p_uccm, uccm);
__napi_schedule(&ugeth->napi);
}
}
- /* Tx event processing */
- if (ucce & UCCE_TX_EVENTS) {
- spin_lock(&ugeth->lock);
- tx_mask = UCC_GETH_UCCE_TXB0;
- for (i = 0; i < ug_info->numQueuesTx; i++) {
- if (ucce & tx_mask)
- ucc_geth_tx(dev, i);
- ucce &= ~tx_mask;
- tx_mask <<= 1;
- }
- spin_unlock(&ugeth->lock);
- }
-
/* Errors and other events */
if (ucce & UCCE_OTHER) {
if (ucce & UCC_GETH_UCCE_BSY)
@@ -3339,6 +3375,37 @@ static void ucc_netpoll(struct net_device *dev)
}
#endif /* CONFIG_NET_POLL_CONTROLLER */
+static int ucc_geth_set_mac_addr(struct net_device *dev, void *p)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(dev);
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+ /*
+ * If device is not running, we will set mac addr register
+ * when opening the device.
+ */
+ if (!netif_running(dev))
+ return 0;
+
+ spin_lock_irq(&ugeth->lock);
+ init_mac_station_addr_regs(dev->dev_addr[0],
+ dev->dev_addr[1],
+ dev->dev_addr[2],
+ dev->dev_addr[3],
+ dev->dev_addr[4],
+ dev->dev_addr[5],
+ &ugeth->ug_regs->macstnaddr1,
+ &ugeth->ug_regs->macstnaddr2);
+ spin_unlock_irq(&ugeth->lock);
+
+ return 0;
+}
+
/* Called when something needs to use the ethernet device */
/* Returns 0 for success. */
static int ucc_geth_open(struct net_device *dev)
@@ -3506,6 +3573,8 @@ static phy_interface_t to_phy_interface(const char *phy_connection_type)
return PHY_INTERFACE_MODE_RGMII_RXID;
if (strcasecmp(phy_connection_type, "rtbi") == 0)
return PHY_INTERFACE_MODE_RTBI;
+ if (strcasecmp(phy_connection_type, "sgmii") == 0)
+ return PHY_INTERFACE_MODE_SGMII;
return PHY_INTERFACE_MODE_MII;
}
@@ -3515,7 +3584,7 @@ static const struct net_device_ops ucc_geth_netdev_ops = {
.ndo_stop = ucc_geth_close,
.ndo_start_xmit = ucc_geth_start_xmit,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = ucc_geth_set_mac_addr,
.ndo_change_mtu = eth_change_mtu,
.ndo_set_multicast_list = ucc_geth_set_multi,
.ndo_tx_timeout = ucc_geth_timeout,
@@ -3528,14 +3597,12 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
{
struct device *device = &ofdev->dev;
struct device_node *np = ofdev->node;
- struct device_node *mdio;
struct net_device *dev = NULL;
struct ucc_geth_private *ugeth = NULL;
struct ucc_geth_info *ug_info;
struct resource res;
struct device_node *phy;
int err, ucc_num, max_speed = 0;
- const phandle *ph;
const u32 *fixed_link;
const unsigned int *prop;
const char *sprop;
@@ -3552,6 +3619,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
PHY_INTERFACE_MODE_RMII, PHY_INTERFACE_MODE_RGMII,
PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_RGMII,
PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI,
+ PHY_INTERFACE_MODE_SGMII,
};
ugeth_vdbg("%s: IN", __func__);
@@ -3635,40 +3703,13 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
fixed_link = of_get_property(np, "fixed-link", NULL);
if (fixed_link) {
- snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id),
- PHY_ID_FMT, "0", fixed_link[0]);
phy = NULL;
} else {
- char bus_name[MII_BUS_ID_SIZE];
-
- ph = of_get_property(np, "phy-handle", NULL);
- phy = of_find_node_by_phandle(*ph);
-
+ phy = of_parse_phandle(np, "phy-handle", 0);
if (phy == NULL)
return -ENODEV;
-
- /* set the PHY address */
- prop = of_get_property(phy, "reg", NULL);
- if (prop == NULL)
- return -1;
-
- /* Set the bus id */
- mdio = of_get_parent(phy);
-
- if (mdio == NULL)
- return -ENODEV;
-
- err = of_address_to_resource(mdio, 0, &res);
-
- if (err) {
- of_node_put(mdio);
- return err;
- }
- fsl_pq_mdio_bus_name(bus_name, mdio);
- of_node_put(mdio);
- snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id),
- "%s:%02x", bus_name, *prop);
}
+ ug_info->phy_node = phy;
/* get the phy interface type, or default to MII */
prop = of_get_property(np, "phy-connection-type", NULL);
@@ -3694,6 +3735,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
case PHY_INTERFACE_MODE_RGMII_TXID:
case PHY_INTERFACE_MODE_TBI:
case PHY_INTERFACE_MODE_RTBI:
+ case PHY_INTERFACE_MODE_SGMII:
max_speed = SPEED_1000;
break;
default:
@@ -3751,7 +3793,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
dev->netdev_ops = &ucc_geth_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work);
- netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT);
+ netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, 64);
dev->mtu = 1500;
ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT);
@@ -3776,6 +3818,37 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
ugeth->ndev = dev;
ugeth->node = np;
+ /* Find the TBI PHY. If it's not there, we don't support SGMII */
+ ph = of_get_property(np, "tbi-handle", NULL);
+ if (ph) {
+ struct device_node *tbi = of_find_node_by_phandle(*ph);
+ struct of_device *ofdev;
+ struct mii_bus *bus;
+ const unsigned int *id;
+
+ if (!tbi)
+ return 0;
+
+ mdio = of_get_parent(tbi);
+ if (!mdio)
+ return 0;
+
+ ofdev = of_find_device_by_node(mdio);
+
+ of_node_put(mdio);
+
+ id = of_get_property(tbi, "reg", NULL);
+ if (!id)
+ return 0;
+ of_node_put(tbi);
+
+ bus = dev_get_drvdata(&ofdev->dev);
+ if (!bus)
+ return 0;
+
+ ugeth->tbiphy = bus->phy_map[*id];
+ }
+
return 0;
}
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index 46bb1d23359..5beba4c1453 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ * Copyright (C) Freescale Semicondutor, Inc. 2006-2009. All rights reserved.
*
* Author: Shlomi Gridish <gridish@freescale.com>
*
@@ -193,6 +193,31 @@ struct ucc_geth {
#define ENET_TBI_MII_JD 0x10 /* Jitter diagnostics */
#define ENET_TBI_MII_TBICON 0x11 /* TBI control */
+/* TBI MDIO register bit fields*/
+#define TBISR_LSTATUS 0x0004
+#define TBICON_CLK_SELECT 0x0020
+#define TBIANA_ASYMMETRIC_PAUSE 0x0100
+#define TBIANA_SYMMETRIC_PAUSE 0x0080
+#define TBIANA_HALF_DUPLEX 0x0040
+#define TBIANA_FULL_DUPLEX 0x0020
+#define TBICR_PHY_RESET 0x8000
+#define TBICR_ANEG_ENABLE 0x1000
+#define TBICR_RESTART_ANEG 0x0200
+#define TBICR_FULL_DUPLEX 0x0100
+#define TBICR_SPEED1_SET 0x0040
+
+#define TBIANA_SETTINGS ( \
+ TBIANA_ASYMMETRIC_PAUSE \
+ | TBIANA_SYMMETRIC_PAUSE \
+ | TBIANA_FULL_DUPLEX \
+ )
+#define TBICR_SETTINGS ( \
+ TBICR_PHY_RESET \
+ | TBICR_ANEG_ENABLE \
+ | TBICR_FULL_DUPLEX \
+ | TBICR_SPEED1_SET \
+ )
+
/* UCC GETH MACCFG1 (MAC Configuration 1 Register) */
#define MACCFG1_FLOW_RX 0x00000020 /* Flow Control
Rx */
@@ -852,7 +877,6 @@ struct ucc_geth_hardware_statistics {
/* Driver definitions */
#define TX_BD_RING_LEN 0x10
#define RX_BD_RING_LEN 0x10
-#define UCC_GETH_DEV_WEIGHT TX_BD_RING_LEN
#define TX_RING_MOD_MASK(size) (size-1)
#define RX_RING_MOD_MASK(size) (size-1)
@@ -1100,7 +1124,7 @@ struct ucc_geth_info {
u32 eventRegMask;
u16 pausePeriod;
u16 extensionField;
- char phy_bus_id[BUS_ID_SIZE];
+ struct device_node *phy_node;
u8 weightfactor[NUM_TX_QUEUES];
u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES];
u8 l2qt[UCC_GETH_VLAN_PRIORITY_MAX];
@@ -1189,6 +1213,7 @@ struct ucc_geth_private {
struct ugeth_mii_info *mii_info;
struct phy_device *phydev;
+ struct phy_device *tbiphy;
phy_interface_t phy_interface;
int max_speed;
uint32_t msg_enable;
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index dfc6cf765fb..3717569828b 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -359,4 +359,12 @@ config USB_HSO
To compile this driver as a module, choose M here: the
module will be called hso.
+config USB_NET_INT51X1
+ tristate "Intellon PLC based usb adapter"
+ depends on USB_USBNET
+ help
+ Choose this option if you're using a 14Mb USB-based PLC
+ (Powerline Communications) solution with an Intellon
+ INT51x1/INT5200 chip, like the "devolo dLan duo".
+
endmenu
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index c8aef62cf2b..b870b0b1cbe 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -20,4 +20,5 @@ obj-$(CONFIG_USB_NET_CDC_SUBSET) += cdc_subset.o
obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o
obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o
obj-$(CONFIG_USB_USBNET) += usbnet.o
+obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 55e8ecc3a9e..01fd528306e 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -25,7 +25,6 @@
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
-#include <linux/ctype.h>
#include <linux/ethtool.h>
#include <linux/workqueue.h>
#include <linux/mii.h>
@@ -389,36 +388,6 @@ static void cdc_status(struct usbnet *dev, struct urb *urb)
}
}
-static u8 nibble(unsigned char c)
-{
- if (likely(isdigit(c)))
- return c - '0';
- c = toupper(c);
- if (likely(isxdigit(c)))
- return 10 + c - 'A';
- return 0;
-}
-
-static inline int
-get_ethernet_addr(struct usbnet *dev, struct usb_cdc_ether_desc *e)
-{
- int tmp, i;
- unsigned char buf [13];
-
- tmp = usb_string(dev->udev, e->iMACAddress, buf, sizeof buf);
- if (tmp != 12) {
- dev_dbg(&dev->udev->dev,
- "bad MAC string %d fetch, %d\n", e->iMACAddress, tmp);
- if (tmp >= 0)
- tmp = -EINVAL;
- return tmp;
- }
- for (i = tmp = 0; i < 6; i++, tmp += 2)
- dev->net->dev_addr [i] =
- (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]);
- return 0;
-}
-
static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
{
int status;
@@ -428,7 +397,7 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
if (status < 0)
return status;
- status = get_ethernet_addr(dev, info->ether);
+ status = usbnet_get_ethernet_addr(dev, info->ether->iMACAddress);
if (status < 0) {
usb_set_intfdata(info->data, NULL);
usb_driver_release_interface(driver_of(intf), info->data);
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 6fc4f82b0be..7ae82446b93 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -497,10 +497,10 @@ static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
int len;
/* format:
- b0: rx status
- b1: packet length (incl crc) low
- b2: packet length (incl crc) high
- b3..n-4: packet data
+ b1: rx status
+ b2: packet length (incl crc) low
+ b3: packet length (incl crc) high
+ b4..n-4: packet data
bn-3..bn: ethernet crc
*/
@@ -533,8 +533,8 @@ static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
int len;
/* format:
- b0: packet length low
- b1: packet length high
+ b1: packet length low
+ b2: packet length high
b3..n: packet data
*/
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index f84b78d94c4..f8c6d7ea726 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -482,7 +482,7 @@ static ssize_t hso_sysfs_show_porttype(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct hso_device *hso_dev = dev->driver_data;
+ struct hso_device *hso_dev = dev_get_drvdata(dev);
char *port_name;
if (!hso_dev)
@@ -816,7 +816,7 @@ static int hso_net_start_xmit(struct sk_buff *skb, struct net_device *net)
}
dev_kfree_skb(skb);
/* we're done */
- return result;
+ return NETDEV_TX_OK;
}
static void hso_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
@@ -899,15 +899,14 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
continue;
}
/* Allocate an sk_buff */
- odev->skb_rx_buf = dev_alloc_skb(frame_len);
+ odev->skb_rx_buf = netdev_alloc_skb(odev->net,
+ frame_len);
if (!odev->skb_rx_buf) {
/* We got no receive buffer. */
D1("could not allocate memory");
odev->rx_parse_state = WAIT_SYNC;
return;
}
- /* Here's where it came from */
- odev->skb_rx_buf->dev = odev->net;
/* Copy what we got so far. make room for iphdr
* after tail. */
@@ -2313,7 +2312,7 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
serial->parent->dev = tty_register_device(tty_drv, minor,
&serial->parent->interface->dev);
dev = serial->parent->dev;
- dev->driver_data = serial->parent;
+ dev_set_drvdata(dev, serial->parent);
i = device_create_file(dev, &dev_attr_hsotype);
/* fill in specific data for later use */
@@ -2481,10 +2480,10 @@ static int add_net_device(struct hso_device *hso_dev)
return 0;
}
-static int hso_radio_toggle(void *data, enum rfkill_state state)
+static int hso_rfkill_set_block(void *data, bool blocked)
{
struct hso_device *hso_dev = data;
- int enabled = (state == RFKILL_STATE_ON);
+ int enabled = !blocked;
int rv;
mutex_lock(&hso_dev->mutex);
@@ -2498,6 +2497,10 @@ static int hso_radio_toggle(void *data, enum rfkill_state state)
return rv;
}
+static const struct rfkill_ops hso_rfkill_ops = {
+ .set_block = hso_rfkill_set_block,
+};
+
/* Creates and sets up everything for rfkill */
static void hso_create_rfkill(struct hso_device *hso_dev,
struct usb_interface *interface)
@@ -2506,29 +2509,25 @@ static void hso_create_rfkill(struct hso_device *hso_dev,
struct device *dev = &hso_net->net->dev;
char *rfkn;
- hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev,
- RFKILL_TYPE_WWAN);
- if (!hso_net->rfkill) {
- dev_err(dev, "%s - Out of memory\n", __func__);
- return;
- }
rfkn = kzalloc(20, GFP_KERNEL);
- if (!rfkn) {
- rfkill_free(hso_net->rfkill);
- hso_net->rfkill = NULL;
+ if (!rfkn)
dev_err(dev, "%s - Out of memory\n", __func__);
- return;
- }
+
snprintf(rfkn, 20, "hso-%d",
interface->altsetting->desc.bInterfaceNumber);
- hso_net->rfkill->name = rfkn;
- hso_net->rfkill->state = RFKILL_STATE_ON;
- hso_net->rfkill->data = hso_dev;
- hso_net->rfkill->toggle_radio = hso_radio_toggle;
+
+ hso_net->rfkill = rfkill_alloc(rfkn,
+ &interface_to_usbdev(interface)->dev,
+ RFKILL_TYPE_WWAN,
+ &hso_rfkill_ops, hso_dev);
+ if (!hso_net->rfkill) {
+ dev_err(dev, "%s - Out of memory\n", __func__);
+ kfree(rfkn);
+ return;
+ }
if (rfkill_register(hso_net->rfkill) < 0) {
+ rfkill_destroy(hso_net->rfkill);
kfree(rfkn);
- hso_net->rfkill->name = NULL;
- rfkill_free(hso_net->rfkill);
hso_net->rfkill = NULL;
dev_err(dev, "%s - Failed to register rfkill\n", __func__);
return;
@@ -3165,8 +3164,10 @@ static void hso_free_interface(struct usb_interface *interface)
hso_stop_net_device(network_table[i]);
cancel_work_sync(&network_table[i]->async_put_intf);
cancel_work_sync(&network_table[i]->async_get_intf);
- if (rfk)
+ if (rfk) {
rfkill_unregister(rfk);
+ rfkill_destroy(rfk);
+ }
hso_free_net_device(network_table[i]);
}
}
diff --git a/drivers/net/usb/int51x1.c b/drivers/net/usb/int51x1.c
new file mode 100644
index 00000000000..55cf7081de1
--- /dev/null
+++ b/drivers/net/usb/int51x1.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2009 Peter Holik
+ *
+ * Intellon usb PLC (Powerline Communications) usb net driver
+ *
+ * http://www.tandel.be/downloads/INT51X1_Datasheet.pdf
+ *
+ * Based on the work of Jan 'RedBully' Seiffert
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or.
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb/usbnet.h>
+
+#define INT51X1_VENDOR_ID 0x09e1
+#define INT51X1_PRODUCT_ID 0x5121
+
+#define INT51X1_HEADER_SIZE 2 /* 2 byte header */
+
+#define PACKET_TYPE_PROMISCUOUS (1 << 0)
+#define PACKET_TYPE_ALL_MULTICAST (1 << 1) /* no filter */
+#define PACKET_TYPE_DIRECTED (1 << 2)
+#define PACKET_TYPE_BROADCAST (1 << 3)
+#define PACKET_TYPE_MULTICAST (1 << 4) /* filtered */
+
+#define SET_ETHERNET_PACKET_FILTER 0x43
+
+static int int51x1_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ int len;
+
+ if (!(pskb_may_pull(skb, INT51X1_HEADER_SIZE))) {
+ deverr(dev, "unexpected tiny rx frame");
+ return 0;
+ }
+
+ len = le16_to_cpu(*(__le16 *)&skb->data[skb->len - 2]);
+
+ skb_trim(skb, len);
+
+ return 1;
+}
+
+static struct sk_buff *int51x1_tx_fixup(struct usbnet *dev,
+ struct sk_buff *skb, gfp_t flags)
+{
+ int pack_len = skb->len;
+ int pack_with_header_len = pack_len + INT51X1_HEADER_SIZE;
+ int headroom = skb_headroom(skb);
+ int tailroom = skb_tailroom(skb);
+ int need_tail = 0;
+ __le16 *len;
+
+ /* if packet and our header is smaler than 64 pad to 64 (+ ZLP) */
+ if ((pack_with_header_len) < dev->maxpacket)
+ need_tail = dev->maxpacket - pack_with_header_len + 1;
+ /*
+ * usbnet would send a ZLP if packetlength mod urbsize == 0 for us,
+ * but we need to know ourself, because this would add to the length
+ * we send down to the device...
+ */
+ else if (!(pack_with_header_len % dev->maxpacket))
+ need_tail = 1;
+
+ if (!skb_cloned(skb) &&
+ (headroom + tailroom >= need_tail + INT51X1_HEADER_SIZE)) {
+ if (headroom < INT51X1_HEADER_SIZE || tailroom < need_tail) {
+ skb->data = memmove(skb->head + INT51X1_HEADER_SIZE,
+ skb->data, skb->len);
+ skb_set_tail_pointer(skb, skb->len);
+ }
+ } else {
+ struct sk_buff *skb2;
+
+ skb2 = skb_copy_expand(skb,
+ INT51X1_HEADER_SIZE,
+ need_tail,
+ flags);
+ dev_kfree_skb_any(skb);
+ if (!skb2)
+ return NULL;
+ skb = skb2;
+ }
+
+ pack_len += need_tail;
+ pack_len &= 0x07ff;
+
+ len = (__le16 *) __skb_push(skb, INT51X1_HEADER_SIZE);
+ *len = cpu_to_le16(pack_len);
+
+ if(need_tail)
+ memset(__skb_put(skb, need_tail), 0, need_tail);
+
+ return skb;
+}
+
+static void int51x1_async_cmd_callback(struct urb *urb)
+{
+ struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+ int status = urb->status;
+
+ if (status < 0)
+ dev_warn(&urb->dev->dev, "async callback failed with %d\n", status);
+
+ kfree(req);
+ usb_free_urb(urb);
+}
+
+static void int51x1_set_multicast(struct net_device *netdev)
+{
+ struct usb_ctrlrequest *req;
+ int status;
+ struct urb *urb;
+ struct usbnet *dev = netdev_priv(netdev);
+ u16 filter = PACKET_TYPE_DIRECTED | PACKET_TYPE_BROADCAST;
+
+ if (netdev->flags & IFF_PROMISC) {
+ /* do not expect to see traffic of other PLCs */
+ filter |= PACKET_TYPE_PROMISCUOUS;
+ devinfo(dev, "promiscuous mode enabled");
+ } else if (netdev->mc_count ||
+ (netdev->flags & IFF_ALLMULTI)) {
+ filter |= PACKET_TYPE_ALL_MULTICAST;
+ devdbg(dev, "receive all multicast enabled");
+ } else {
+ /* ~PROMISCUOUS, ~MULTICAST */
+ devdbg(dev, "receive own packets only");
+ }
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ devwarn(dev, "Error allocating URB");
+ return;
+ }
+
+ req = kmalloc(sizeof(*req), GFP_ATOMIC);
+ if (!req) {
+ devwarn(dev, "Error allocating control msg");
+ goto out;
+ }
+
+ req->bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
+ req->bRequest = SET_ETHERNET_PACKET_FILTER;
+ req->wValue = cpu_to_le16(filter);
+ req->wIndex = 0;
+ req->wLength = 0;
+
+ usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0),
+ (void *)req, NULL, 0,
+ int51x1_async_cmd_callback,
+ (void *)req);
+
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status < 0) {
+ devwarn(dev, "Error submitting control msg, sts=%d", status);
+ goto out1;
+ }
+ return;
+out1:
+ kfree(req);
+out:
+ usb_free_urb(urb);
+}
+
+static const struct net_device_ops int51x1_netdev_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_change_mtu = usbnet_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = int51x1_set_multicast,
+};
+
+static int int51x1_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ int status = usbnet_get_ethernet_addr(dev, 3);
+
+ if (status)
+ return status;
+
+ dev->net->hard_header_len += INT51X1_HEADER_SIZE;
+ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+ dev->net->netdev_ops = &int51x1_netdev_ops;
+
+ return usbnet_get_endpoints(dev, intf);
+}
+
+static const struct driver_info int51x1_info = {
+ .description = "Intellon usb powerline adapter",
+ .bind = int51x1_bind,
+ .rx_fixup = int51x1_rx_fixup,
+ .tx_fixup = int51x1_tx_fixup,
+ .in = 1,
+ .out = 2,
+ .flags = FLAG_ETHER,
+};
+
+static const struct usb_device_id products[] = {
+ {
+ USB_DEVICE(INT51X1_VENDOR_ID, INT51X1_PRODUCT_ID),
+ .driver_info = (unsigned long) &int51x1_info,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver int51x1_driver = {
+ .name = "int51x1",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+};
+
+static int __init int51x1_init(void)
+{
+ return usb_register(&int51x1_driver);
+}
+module_init(int51x1_init);
+
+static void __exit int51x1_exit(void)
+{
+ usb_deregister(&int51x1_driver);
+}
+module_exit(int51x1_exit);
+
+MODULE_AUTHOR("Peter Holik");
+MODULE_DESCRIPTION("Intellon usb powerline adapter");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index 3d0d0b0b37c..e0131478971 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -31,7 +31,6 @@
****************************************************************/
/* TODO:
- * Fix in_interrupt() problem
* Develop test procedures for USB net interfaces
* Run test procedures
* Fix bugs from previous two steps
@@ -606,14 +605,30 @@ static void kaweth_usb_receive(struct urb *urb)
struct sk_buff *skb;
- if(unlikely(status == -ECONNRESET || status == -ESHUTDOWN))
- /* we are killed - set a flag and wake the disconnect handler */
- {
+ if (unlikely(status == -EPIPE)) {
+ kaweth->stats.rx_errors++;
kaweth->end = 1;
wake_up(&kaweth->term_wait);
+ dbg("Status was -EPIPE.");
return;
}
-
+ if (unlikely(status == -ECONNRESET || status == -ESHUTDOWN)) {
+ /* we are killed - set a flag and wake the disconnect handler */
+ kaweth->end = 1;
+ wake_up(&kaweth->term_wait);
+ dbg("Status was -ECONNRESET or -ESHUTDOWN.");
+ return;
+ }
+ if (unlikely(status == -EPROTO || status == -ETIME ||
+ status == -EILSEQ)) {
+ kaweth->stats.rx_errors++;
+ dbg("Status was -EPROTO, -ETIME, or -EILSEQ.");
+ return;
+ }
+ if (unlikely(status == -EOVERFLOW)) {
+ kaweth->stats.rx_errors++;
+ dbg("Status was -EOVERFLOW.");
+ }
spin_lock(&kaweth->device_lock);
if (IS_BLOCKED(kaweth->status)) {
spin_unlock(&kaweth->device_lock);
@@ -883,13 +898,16 @@ static void kaweth_set_rx_mode(struct net_device *net)
****************************************************************/
static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth)
{
+ int result;
__u16 packet_filter_bitmap = kaweth->packet_filter_bitmap;
+
kaweth->packet_filter_bitmap = 0;
if (packet_filter_bitmap == 0)
return;
- {
- int result;
+ if (in_interrupt())
+ return;
+
result = kaweth_control(kaweth,
usb_sndctrlpipe(kaweth->dev, 0),
KAWETH_COMMAND_SET_PACKET_FILTER,
@@ -906,7 +924,6 @@ static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth)
else {
dbg("Set Rx mode to %d", packet_filter_bitmap);
}
- }
}
/****************************************************************
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index f9fb454ffa8..fcc6fa0905d 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -221,7 +221,8 @@ static void ctrl_callback(struct urb *urb)
case -ENOENT:
break;
default:
- dev_warn(&urb->dev->dev, "ctrl urb status %d\n", status);
+ if (printk_ratelimit())
+ dev_warn(&urb->dev->dev, "ctrl urb status %d\n", status);
}
dev = urb->context;
clear_bit(RX_REG_SET, &dev->flags);
@@ -442,10 +443,12 @@ static void read_bulk_callback(struct urb *urb)
case -ENOENT:
return; /* the urb is in unlink state */
case -ETIME:
- dev_warn(&urb->dev->dev, "may be reset is needed?..\n");
+ if (printk_ratelimit())
+ dev_warn(&urb->dev->dev, "may be reset is needed?..\n");
goto goon;
default:
- dev_warn(&urb->dev->dev, "Rx status %d\n", status);
+ if (printk_ratelimit())
+ dev_warn(&urb->dev->dev, "Rx status %d\n", status);
goto goon;
}
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 5a7283372b5..89a91f8c22d 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1134,7 +1134,7 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
if (skb->len == size) {
if (pdata->use_rx_csum)
smsc95xx_rx_csum_offload(skb);
-
+ skb_trim(skb, skb->len - 4); /* remove fcs */
skb->truesize = size + sizeof(struct sk_buff);
return 1;
@@ -1152,7 +1152,7 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
if (pdata->use_rx_csum)
smsc95xx_rx_csum_offload(ax_skb);
-
+ skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
ax_skb->truesize = size + sizeof(struct sk_buff);
usbnet_skb_return(dev, ax_skb);
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 47f68cfa7e2..22c0585a031 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -37,6 +37,7 @@
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/ctype.h>
#include <linux/ethtool.h>
#include <linux/workqueue.h>
#include <linux/mii.h>
@@ -156,6 +157,36 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
}
EXPORT_SYMBOL_GPL(usbnet_get_endpoints);
+static u8 nibble(unsigned char c)
+{
+ if (likely(isdigit(c)))
+ return c - '0';
+ c = toupper(c);
+ if (likely(isxdigit(c)))
+ return 10 + c - 'A';
+ return 0;
+}
+
+int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress)
+{
+ int tmp, i;
+ unsigned char buf [13];
+
+ tmp = usb_string(dev->udev, iMACAddress, buf, sizeof buf);
+ if (tmp != 12) {
+ dev_dbg(&dev->udev->dev,
+ "bad MAC string %d fetch, %d\n", iMACAddress, tmp);
+ if (tmp >= 0)
+ tmp = -EINVAL;
+ return tmp;
+ }
+ for (i = tmp = 0; i < 6; i++, tmp += 2)
+ dev->net->dev_addr [i] =
+ (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr);
+
static void intr_complete (struct urb *urb);
static int init_status (struct usbnet *dev, struct usb_interface *intf)
@@ -1185,12 +1216,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
#endif
net->netdev_ops = &usbnet_netdev_ops;
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
- net->hard_start_xmit = usbnet_start_xmit;
- net->open = usbnet_open;
- net->stop = usbnet_stop;
- net->tx_timeout = usbnet_tx_timeout;
-#endif
net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
net->ethtool_ops = &usbnet_ethtool_ops;
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 8e56fcf0a0e..87197dd9c78 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -176,8 +176,6 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev)
if (dev->features & NETIF_F_NO_CSUM)
skb->ip_summed = rcv_priv->ip_summed;
- dst_release(skb->dst);
- skb->dst = NULL;
skb->mark = 0;
secpath_reset(skb);
nf_reset(skb);
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 45daba726b6..d3489a3c4c0 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -388,7 +388,6 @@ struct rhine_private {
long pioaddr;
struct net_device *dev;
struct napi_struct napi;
- struct net_device_stats stats;
spinlock_t lock;
/* Frequently used values: keep some adjacent for cache effect. */
@@ -1209,7 +1208,7 @@ static void rhine_tx_timeout(struct net_device *dev)
enable_irq(rp->pdev->irq);
dev->trans_start = jiffies;
- rp->stats.tx_errors++;
+ dev->stats.tx_errors++;
netif_wake_queue(dev);
}
@@ -1237,7 +1236,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
/* packet too long, drop it */
dev_kfree_skb(skb);
rp->tx_skbuff[entry] = NULL;
- rp->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
return 0;
}
@@ -1378,29 +1377,33 @@ static void rhine_tx(struct net_device *dev)
printk(KERN_DEBUG "%s: Transmit error, "
"Tx status %8.8x.\n",
dev->name, txstatus);
- rp->stats.tx_errors++;
- if (txstatus & 0x0400) rp->stats.tx_carrier_errors++;
- if (txstatus & 0x0200) rp->stats.tx_window_errors++;
- if (txstatus & 0x0100) rp->stats.tx_aborted_errors++;
- if (txstatus & 0x0080) rp->stats.tx_heartbeat_errors++;
+ dev->stats.tx_errors++;
+ if (txstatus & 0x0400)
+ dev->stats.tx_carrier_errors++;
+ if (txstatus & 0x0200)
+ dev->stats.tx_window_errors++;
+ if (txstatus & 0x0100)
+ dev->stats.tx_aborted_errors++;
+ if (txstatus & 0x0080)
+ dev->stats.tx_heartbeat_errors++;
if (((rp->quirks & rqRhineI) && txstatus & 0x0002) ||
(txstatus & 0x0800) || (txstatus & 0x1000)) {
- rp->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
rp->tx_ring[entry].tx_status = cpu_to_le32(DescOwn);
break; /* Keep the skb - we try again */
}
/* Transmitter restarted in 'abnormal' handler. */
} else {
if (rp->quirks & rqRhineI)
- rp->stats.collisions += (txstatus >> 3) & 0x0F;
+ dev->stats.collisions += (txstatus >> 3) & 0x0F;
else
- rp->stats.collisions += txstatus & 0x0F;
+ dev->stats.collisions += txstatus & 0x0F;
if (debug > 6)
printk(KERN_DEBUG "collisions: %1.1x:%1.1x\n",
(txstatus >> 3) & 0xF,
txstatus & 0xF);
- rp->stats.tx_bytes += rp->tx_skbuff[entry]->len;
- rp->stats.tx_packets++;
+ dev->stats.tx_bytes += rp->tx_skbuff[entry]->len;
+ dev->stats.tx_packets++;
}
/* Free the original skb. */
if (rp->tx_skbuff_dma[entry]) {
@@ -1455,21 +1458,24 @@ static int rhine_rx(struct net_device *dev, int limit)
printk(KERN_WARNING "%s: Oversized Ethernet "
"frame %p vs %p.\n", dev->name,
rp->rx_head_desc, &rp->rx_ring[entry]);
- rp->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
} else if (desc_status & RxErr) {
/* There was a error. */
if (debug > 2)
printk(KERN_DEBUG "rhine_rx() Rx "
"error was %8.8x.\n",
desc_status);
- rp->stats.rx_errors++;
- if (desc_status & 0x0030) rp->stats.rx_length_errors++;
- if (desc_status & 0x0048) rp->stats.rx_fifo_errors++;
- if (desc_status & 0x0004) rp->stats.rx_frame_errors++;
+ dev->stats.rx_errors++;
+ if (desc_status & 0x0030)
+ dev->stats.rx_length_errors++;
+ if (desc_status & 0x0048)
+ dev->stats.rx_fifo_errors++;
+ if (desc_status & 0x0004)
+ dev->stats.rx_frame_errors++;
if (desc_status & 0x0002) {
/* this can also be updated outside the interrupt handler */
spin_lock(&rp->lock);
- rp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
spin_unlock(&rp->lock);
}
}
@@ -1513,8 +1519,8 @@ static int rhine_rx(struct net_device *dev, int limit)
}
skb->protocol = eth_type_trans(skb, dev);
netif_receive_skb(skb);
- rp->stats.rx_bytes += pkt_len;
- rp->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
}
entry = (++rp->cur_rx) % RX_RING_SIZE;
rp->rx_head_desc = &rp->rx_ring[entry];
@@ -1599,8 +1605,8 @@ static void rhine_error(struct net_device *dev, int intr_status)
if (intr_status & IntrLinkChange)
rhine_check_media(dev, 0);
if (intr_status & IntrStatsMax) {
- rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
- rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
+ dev->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
+ dev->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
clear_tally_counters(ioaddr);
}
if (intr_status & IntrTxAborted) {
@@ -1654,12 +1660,12 @@ static struct net_device_stats *rhine_get_stats(struct net_device *dev)
unsigned long flags;
spin_lock_irqsave(&rp->lock, flags);
- rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
- rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
+ dev->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
+ dev->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
clear_tally_counters(ioaddr);
spin_unlock_irqrestore(&rp->lock, flags);
- return &rp->stats;
+ return &dev->stats;
}
static void rhine_set_rx_mode(struct net_device *dev)
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 754a4b182c1..e2a7725e567 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1385,7 +1385,7 @@ static void velocity_free_td_ring(struct velocity_info *vptr)
static int velocity_rx_srv(struct velocity_info *vptr, int status)
{
- struct net_device_stats *stats = &vptr->stats;
+ struct net_device_stats *stats = &vptr->dev->stats;
int rd_curr = vptr->rx.curr;
int works = 0;
@@ -1519,7 +1519,7 @@ static inline void velocity_iph_realign(struct velocity_info *vptr,
static int velocity_receive_frame(struct velocity_info *vptr, int idx)
{
void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
- struct net_device_stats *stats = &vptr->stats;
+ struct net_device_stats *stats = &vptr->dev->stats;
struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
struct rx_desc *rd = &(vptr->rx.ring[idx]);
int pkt_len = le16_to_cpu(rd->rdesc0.len) & 0x3fff;
@@ -1532,7 +1532,7 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
}
if (rd->rdesc0.RSR & RSR_MAR)
- vptr->stats.multicast++;
+ stats->multicast++;
skb = rd_info->skb;
@@ -1634,7 +1634,7 @@ static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
int idx;
int works = 0;
struct velocity_td_info *tdinfo;
- struct net_device_stats *stats = &vptr->stats;
+ struct net_device_stats *stats = &vptr->dev->stats;
for (qnum = 0; qnum < vptr->tx.numq; qnum++) {
for (idx = vptr->tx.tail[qnum]; vptr->tx.used[qnum] > 0;
@@ -2324,22 +2324,22 @@ static struct net_device_stats *velocity_get_stats(struct net_device *dev)
/* If the hardware is down, don't touch MII */
if(!netif_running(dev))
- return &vptr->stats;
+ return &dev->stats;
spin_lock_irq(&vptr->lock);
velocity_update_hw_mibs(vptr);
spin_unlock_irq(&vptr->lock);
- vptr->stats.rx_packets = vptr->mib_counter[HW_MIB_ifRxAllPkts];
- vptr->stats.rx_errors = vptr->mib_counter[HW_MIB_ifRxErrorPkts];
- vptr->stats.rx_length_errors = vptr->mib_counter[HW_MIB_ifInRangeLengthErrors];
+ dev->stats.rx_packets = vptr->mib_counter[HW_MIB_ifRxAllPkts];
+ dev->stats.rx_errors = vptr->mib_counter[HW_MIB_ifRxErrorPkts];
+ dev->stats.rx_length_errors = vptr->mib_counter[HW_MIB_ifInRangeLengthErrors];
// unsigned long rx_dropped; /* no space in linux buffers */
- vptr->stats.collisions = vptr->mib_counter[HW_MIB_ifTxEtherCollisions];
+ dev->stats.collisions = vptr->mib_counter[HW_MIB_ifTxEtherCollisions];
/* detailed rx_errors: */
// unsigned long rx_length_errors;
// unsigned long rx_over_errors; /* receiver ring buff overflow */
- vptr->stats.rx_crc_errors = vptr->mib_counter[HW_MIB_ifRxPktCRCE];
+ dev->stats.rx_crc_errors = vptr->mib_counter[HW_MIB_ifRxPktCRCE];
// unsigned long rx_frame_errors; /* recv'd frame alignment error */
// unsigned long rx_fifo_errors; /* recv'r fifo overrun */
// unsigned long rx_missed_errors; /* receiver missed packet */
@@ -2347,7 +2347,7 @@ static struct net_device_stats *velocity_get_stats(struct net_device *dev)
/* detailed tx_errors */
// unsigned long tx_fifo_errors;
- return &vptr->stats;
+ return &dev->stats;
}
diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h
index ea43e1832af..4cd3f6c9737 100644
--- a/drivers/net/via-velocity.h
+++ b/drivers/net/via-velocity.h
@@ -1503,7 +1503,6 @@ struct velocity_info {
struct pci_dev *pdev;
struct net_device *dev;
- struct net_device_stats stats;
struct vlan_group *vlgrp;
u8 ip_addr[4];
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 7fa620ddeb2..52198f6797a 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -283,10 +283,11 @@ static void try_fill_recv_maxbufs(struct virtnet_info *vi)
for (;;) {
struct virtio_net_hdr *hdr;
- skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN);
+ skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN + NET_IP_ALIGN);
if (unlikely(!skb))
break;
+ skb_reserve(skb, NET_IP_ALIGN);
skb_put(skb, MAX_PACKET_LEN);
hdr = skb_vnet_hdr(skb);
@@ -470,7 +471,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
}
if (skb_is_gso(skb)) {
- hdr->hdr_len = skb_transport_header(skb) - skb->data;
+ hdr->hdr_len = skb_headlen(skb);
hdr->gso_size = skb_shinfo(skb)->gso_size;
if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
@@ -622,12 +623,9 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
unsigned int tmp;
int i;
- if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
- BUG(); /* Caller should know better */
- return false;
- }
-
- BUG_ON(out + in > VIRTNET_SEND_COMMAND_SG_MAX);
+ /* Caller should know better */
+ BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) ||
+ (out + in > VIRTNET_SEND_COMMAND_SG_MAX));
out++; /* Add header */
in++; /* Add return status */
@@ -642,8 +640,7 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
sg_set_buf(&sg[i + 1], sg_virt(s), s->length);
sg_set_buf(&sg[out + in - 1], &status, sizeof(status));
- if (vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi) != 0)
- BUG();
+ BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi));
vi->cvq->vq_ops->kick(vi->cvq);
@@ -684,6 +681,7 @@ static void virtnet_set_rx_mode(struct net_device *dev)
u8 promisc, allmulti;
struct virtio_net_ctrl_mac *mac_data;
struct dev_addr_list *addr;
+ struct netdev_hw_addr *ha;
void *buf;
int i;
@@ -722,9 +720,9 @@ static void virtnet_set_rx_mode(struct net_device *dev)
/* Store the unicast list and count in the front of the buffer */
mac_data->entries = dev->uc_count;
- addr = dev->uc_list;
- for (i = 0; i < dev->uc_count; i++, addr = addr->next)
- memcpy(&mac_data->macs[i][0], addr->da_addr, ETH_ALEN);
+ i = 0;
+ list_for_each_entry(ha, &dev->uc_list, list)
+ memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN);
sg_set_buf(&sg[0], mac_data,
sizeof(mac_data->entries) + (dev->uc_count * ETH_ALEN));
diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c
index 6b41c884a33..26cde573af4 100644
--- a/drivers/net/vxge/vxge-config.c
+++ b/drivers/net/vxge/vxge-config.c
@@ -1884,17 +1884,13 @@ void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool)
mempool->memblock_size, dma_object);
}
- if (mempool->items_arr)
- vfree(mempool->items_arr);
+ vfree(mempool->items_arr);
- if (mempool->memblocks_dma_arr)
- vfree(mempool->memblocks_dma_arr);
+ vfree(mempool->memblocks_dma_arr);
- if (mempool->memblocks_priv_arr)
- vfree(mempool->memblocks_priv_arr);
+ vfree(mempool->memblocks_priv_arr);
- if (mempool->memblocks_arr)
- vfree(mempool->memblocks_arr);
+ vfree(mempool->memblocks_arr);
vfree(mempool);
}
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index b7f08f3e524..6c838b3e063 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -677,7 +677,7 @@ vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
return VXGE_HW_OK;
}
-/* select a vpath to trasmit the packet */
+/* select a vpath to transmit the packet */
static u32 vxge_get_vpath_no(struct vxgedev *vdev, struct sk_buff *skb,
int *do_lock)
{
@@ -992,7 +992,9 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
VXGE_HW_FIFO_TXD_TX_CKO_UDP_EN);
vxge_hw_fifo_txdl_post(fifo_hw, dtr);
- dev->trans_start = jiffies;
+#ifdef NETIF_F_LLTX
+ dev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
+#endif
spin_unlock_irqrestore(&fifo->tx_lock, flags);
VXGE_COMPLETE_VPATH_TX(fifo);
diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c
index c2eeac4125f..370f55cbbad 100644
--- a/drivers/net/vxge/vxge-traffic.c
+++ b/drivers/net/vxge/vxge-traffic.c
@@ -1923,7 +1923,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process(
if (vpath == NULL) {
alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN,
alarm_event);
- goto out;
+ goto out2;
}
hldev = vpath->hldev;
@@ -2161,7 +2161,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process(
}
out:
hldev->stats.sw_dev_err_stats.vpath_alarms++;
-
+out2:
if ((alarm_event == VXGE_HW_EVENT_ALARM_CLEARED) ||
(alarm_event == VXGE_HW_EVENT_UNKNOWN))
return VXGE_HW_OK;
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index 35dea3bea95..f525f9fe74d 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -615,7 +615,7 @@ static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
case WAN_DISCONNECTED:
if (cycx_x25_chan_connect(dev)) {
netif_stop_queue(dev);
- return -EBUSY;
+ return NETDEV_TX_BUSY;
}
/* fall thru */
case WAN_CONNECTED:
@@ -624,7 +624,7 @@ static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
netif_stop_queue(dev);
if (cycx_x25_chan_send(dev, skb))
- return -EBUSY;
+ return NETDEV_TX_BUSY;
break;
default:
@@ -656,7 +656,7 @@ static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
if (cycx_x25_chan_send(dev, skb)) {
/* prepare for future retransmissions */
skb_push(skb, 1);
- return -EBUSY;
+ return NETDEV_TX_BUSY;
}
}
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c
index e8d155c3e59..2fa275a58f9 100644
--- a/drivers/net/wan/dlci.c
+++ b/drivers/net/wan/dlci.c
@@ -205,15 +205,15 @@ static int dlci_transmit(struct sk_buff *skb, struct net_device *dev)
{
case DLCI_RET_OK:
dev->stats.tx_packets++;
- ret = 0;
+ ret = NETDEV_TX_OK;
break;
case DLCI_RET_ERR:
dev->stats.tx_errors++;
- ret = 0;
+ ret = NETDEV_TX_OK;
break;
case DLCI_RET_DROP:
dev->stats.tx_dropped++;
- ret = 1;
+ ret = NETDEV_TX_BUSY;
break;
}
/* Alan Cox recommends always returning 0, and always freeing the packet */
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 80053010109..bfa0161a02d 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -1054,6 +1054,7 @@ static void pvc_setup(struct net_device *dev)
dev->flags = IFF_POINTOPOINT;
dev->hard_header_len = 10;
dev->addr_len = 2;
+ dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
}
static const struct net_device_ops pvc_ops = {
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index a6dc317083d..bb719b6114c 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -732,8 +732,8 @@ static int hss_hdlc_poll(struct napi_struct *napi, int budget)
dma_unmap_single(&dev->dev, desc->data,
RX_SIZE, DMA_FROM_DEVICE);
#else
- dma_sync_single(&dev->dev, desc->data,
- RX_SIZE, DMA_FROM_DEVICE);
+ dma_sync_single_for_cpu(&dev->dev, desc->data,
+ RX_SIZE, DMA_FROM_DEVICE);
memcpy_swab32((u32 *)skb->data, (u32 *)port->rx_buff_tab[n],
ALIGN(desc->pkt_len, 4) / 4);
#endif
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index c23fde0c034..79dabc557bd 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -225,6 +225,7 @@ static char rcsid[] =
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <linux/spinlock.h>
#include <linux/if.h>
#include <net/arp.h>
@@ -3246,6 +3247,16 @@ static inline void show_version(void)
rcsvers, rcsdate, __DATE__, __TIME__);
} /* show_version */
+static const struct net_device_ops cpc_netdev_ops = {
+ .ndo_open = cpc_open,
+ .ndo_stop = cpc_close,
+ .ndo_tx_timeout = cpc_tx_timeout,
+ .ndo_set_mac_address = NULL,
+ .ndo_change_mtu = cpc_change_mtu,
+ .ndo_do_ioctl = cpc_ioctl,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static void cpc_init_card(pc300_t * card)
{
int i, devcount = 0;
@@ -3357,18 +3368,11 @@ static void cpc_init_card(pc300_t * card)
dev->mem_start = card->hw.ramphys;
dev->mem_end = card->hw.ramphys + card->hw.ramsize - 1;
dev->irq = card->hw.irq;
- dev->init = NULL;
dev->tx_queue_len = PC300_TX_QUEUE_LEN;
dev->mtu = PC300_DEF_MTU;
- dev->open = cpc_open;
- dev->stop = cpc_close;
- dev->tx_timeout = cpc_tx_timeout;
+ dev->netdev_ops = &cpc_netdev_ops;
dev->watchdog_timeo = PC300_TX_TIMEOUT;
- dev->set_multicast_list = NULL;
- dev->set_mac_address = NULL;
- dev->change_mtu = cpc_change_mtu;
- dev->do_ioctl = cpc_ioctl;
if (register_hdlc_device(dev) == 0) {
printk("%s: Cyclades-PC300/", dev->name);
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index f4211fe0f44..3fb9dbc88a1 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -469,7 +469,7 @@ sbni_start_xmit( struct sk_buff *skb, struct net_device *dev )
}
}
- return 1;
+ return NETDEV_TX_BUSY;
}
#else /* CONFIG_SBNI_MULTILINE */
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index 8130b79a8a9..e4ad7b6b52e 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -283,7 +283,7 @@ static int wanxl_xmit(struct sk_buff *skb, struct net_device *dev)
#endif
netif_stop_queue(dev);
spin_unlock_irq(&port->lock);
- return 1; /* request packet to be queued */
+ return NETDEV_TX_BUSY; /* request packet to be queued */
}
#ifdef DEBUG_PKT
diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c
index b3cadb626fe..07308686dbc 100644
--- a/drivers/net/wimax/i2400m/control.c
+++ b/drivers/net/wimax/i2400m/control.c
@@ -292,8 +292,6 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m,
d_fnstart(3, dev, "(i2400m %p ss %p [%u])\n", i2400m, ss, i2400m_state);
- if (unlikely(i2400m->ready == 0)) /* act if up */
- goto out;
if (i2400m->state != i2400m_state) {
i2400m->state = i2400m_state;
wake_up_all(&i2400m->state_wq);
@@ -341,7 +339,6 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m,
i2400m->bus_reset(i2400m, I2400M_RT_WARM);
break;
};
-out:
d_fnend(3, dev, "(i2400m %p ss %p [%u]) = void\n",
i2400m, ss, i2400m_state);
}
@@ -372,8 +369,6 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m,
d_fnstart(3, dev, "(i2400m %p ms %p [%u])\n", i2400m, ms, status);
- if (unlikely(i2400m->ready == 0)) /* act if up */
- goto out;
switch (status) {
case I2400M_MEDIA_STATUS_LINK_UP:
netif_carrier_on(net_dev);
@@ -393,14 +388,59 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m,
dev_err(dev, "HW BUG? unknown media status %u\n",
status);
};
-out:
d_fnend(3, dev, "(i2400m %p ms %p [%u]) = void\n",
i2400m, ms, status);
}
/*
- * Parse a 'state report' and extract carrier on/off information
+ * Process a TLV from a 'state report'
+ *
+ * @i2400m: device descriptor
+ * @tlv: pointer to the TLV header; it has been already validated for
+ * consistent size.
+ * @tag: for error messages
+ *
+ * Act on the TLVs from a 'state report'.
+ */
+static
+void i2400m_report_state_parse_tlv(struct i2400m *i2400m,
+ const struct i2400m_tlv_hdr *tlv,
+ const char *tag)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ const struct i2400m_tlv_media_status *ms;
+ const struct i2400m_tlv_system_state *ss;
+ const struct i2400m_tlv_rf_switches_status *rfss;
+
+ if (0 == i2400m_tlv_match(tlv, I2400M_TLV_SYSTEM_STATE, sizeof(*ss))) {
+ ss = container_of(tlv, typeof(*ss), hdr);
+ d_printf(2, dev, "%s: system state TLV "
+ "found (0x%04x), state 0x%08x\n",
+ tag, I2400M_TLV_SYSTEM_STATE,
+ le32_to_cpu(ss->state));
+ i2400m_report_tlv_system_state(i2400m, ss);
+ }
+ if (0 == i2400m_tlv_match(tlv, I2400M_TLV_RF_STATUS, sizeof(*rfss))) {
+ rfss = container_of(tlv, typeof(*rfss), hdr);
+ d_printf(2, dev, "%s: RF status TLV "
+ "found (0x%04x), sw 0x%02x hw 0x%02x\n",
+ tag, I2400M_TLV_RF_STATUS,
+ le32_to_cpu(rfss->sw_rf_switch),
+ le32_to_cpu(rfss->hw_rf_switch));
+ i2400m_report_tlv_rf_switches_status(i2400m, rfss);
+ }
+ if (0 == i2400m_tlv_match(tlv, I2400M_TLV_MEDIA_STATUS, sizeof(*ms))) {
+ ms = container_of(tlv, typeof(*ms), hdr);
+ d_printf(2, dev, "%s: Media Status TLV: %u\n",
+ tag, le32_to_cpu(ms->media_status));
+ i2400m_report_tlv_media_status(i2400m, ms);
+ }
+}
+
+
+/*
+ * Parse a 'state report' and extract information
*
* @i2400m: device descriptor
* @l3l4_hdr: pointer to message; it has been already validated for
@@ -409,13 +449,7 @@ out:
* declaration is assumed to be congruent with @size (as in
* sizeof(*l3l4_hdr) + l3l4_hdr->length == size)
*
- * Extract from the report state the system state TLV and infer from
- * there if we have a carrier or not. Update our local state and tell
- * netdev.
- *
- * When setting the carrier, it's fine to set OFF twice (for example),
- * as netif_carrier_off() will not generate two OFF events (just on
- * the transitions).
+ * Walk over the TLVs in a report state and act on them.
*/
static
void i2400m_report_state_hook(struct i2400m *i2400m,
@@ -424,9 +458,6 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
{
struct device *dev = i2400m_dev(i2400m);
const struct i2400m_tlv_hdr *tlv;
- const struct i2400m_tlv_system_state *ss;
- const struct i2400m_tlv_rf_switches_status *rfss;
- const struct i2400m_tlv_media_status *ms;
size_t tlv_size = le16_to_cpu(l3l4_hdr->length);
d_fnstart(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s)\n",
@@ -434,34 +465,8 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
tlv = NULL;
while ((tlv = i2400m_tlv_buffer_walk(i2400m, &l3l4_hdr->pl,
- tlv_size, tlv))) {
- if (0 == i2400m_tlv_match(tlv, I2400M_TLV_SYSTEM_STATE,
- sizeof(*ss))) {
- ss = container_of(tlv, typeof(*ss), hdr);
- d_printf(2, dev, "%s: system state TLV "
- "found (0x%04x), state 0x%08x\n",
- tag, I2400M_TLV_SYSTEM_STATE,
- le32_to_cpu(ss->state));
- i2400m_report_tlv_system_state(i2400m, ss);
- }
- if (0 == i2400m_tlv_match(tlv, I2400M_TLV_RF_STATUS,
- sizeof(*rfss))) {
- rfss = container_of(tlv, typeof(*rfss), hdr);
- d_printf(2, dev, "%s: RF status TLV "
- "found (0x%04x), sw 0x%02x hw 0x%02x\n",
- tag, I2400M_TLV_RF_STATUS,
- le32_to_cpu(rfss->sw_rf_switch),
- le32_to_cpu(rfss->hw_rf_switch));
- i2400m_report_tlv_rf_switches_status(i2400m, rfss);
- }
- if (0 == i2400m_tlv_match(tlv, I2400M_TLV_MEDIA_STATUS,
- sizeof(*ms))) {
- ms = container_of(tlv, typeof(*ms), hdr);
- d_printf(2, dev, "%s: Media Status TLV: %u\n",
- tag, le32_to_cpu(ms->media_status));
- i2400m_report_tlv_media_status(i2400m, ms);
- }
- }
+ tlv_size, tlv)))
+ i2400m_report_state_parse_tlv(i2400m, tlv, tag);
d_fnend(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s) = void\n",
i2400m, l3l4_hdr, size, tag);
}
@@ -500,8 +505,15 @@ void i2400m_report_hook(struct i2400m *i2400m,
* it. */
case I2400M_MT_REPORT_POWERSAVE_READY: /* zzzzz */
if (l3l4_hdr->status == cpu_to_le16(I2400M_MS_DONE_OK)) {
- d_printf(1, dev, "ready for powersave, requesting\n");
- i2400m_cmd_enter_powersave(i2400m);
+ if (i2400m_power_save_disabled)
+ d_printf(1, dev, "ready for powersave, "
+ "not requesting (disabled by module "
+ "parameter)\n");
+ else {
+ d_printf(1, dev, "ready for powersave, "
+ "requesting\n");
+ i2400m_cmd_enter_powersave(i2400m);
+ }
}
break;
};
@@ -683,8 +695,9 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
d_fnstart(3, dev, "(i2400m %p buf %p len %zu)\n",
i2400m, buf, buf_len);
+ rmb(); /* Make sure we see what i2400m_dev_reset_handle() */
if (i2400m->boot_mode)
- return ERR_PTR(-ENODEV);
+ return ERR_PTR(-EL3RST);
msg_l3l4_hdr = buf;
/* Check msg & payload consistency */
@@ -721,6 +734,8 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
ack_timeout = HZ;
};
+ if (unlikely(i2400m->trace_msg_from_user))
+ wimax_msg(&i2400m->wimax_dev, "echo", buf, buf_len, GFP_KERNEL);
/* The RX path in rx.c will put any response for this message
* in i2400m->ack_skb and wake us up. If we cancel the wait,
* we need to change the value of i2400m->ack_skb to something
@@ -755,6 +770,9 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
ack_l3l4_hdr = wimax_msg_data_len(ack_skb, &ack_len);
/* Check the ack and deliver it if it is ok */
+ if (unlikely(i2400m->trace_msg_from_user))
+ wimax_msg(&i2400m->wimax_dev, "echo",
+ ack_l3l4_hdr, ack_len, GFP_KERNEL);
result = i2400m_msg_size_check(i2400m, ack_l3l4_hdr, ack_len);
if (result < 0) {
dev_err(dev, "HW BUG? reply to message 0x%04x: %d\n",
@@ -1379,16 +1397,16 @@ error:
*
* @i2400m: device descriptor
*
- * Gracefully stops the device, moving it to the lowest power
- * consumption state possible.
+ * Release resources acquired during the running of the device; in
+ * theory, should also tell the device to go to sleep, switch off the
+ * radio, all that, but at this point, in most cases (driver
+ * disconnection, reset handling) we can't even talk to the device.
*/
void i2400m_dev_shutdown(struct i2400m *i2400m)
{
- int result = -ENODEV;
struct device *dev = i2400m_dev(i2400m);
d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
- result = i2400m->bus_reset(i2400m, I2400M_RT_WARM);
- d_fnend(3, dev, "(i2400m %p) = void [%d]\n", i2400m, result);
+ d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
return;
}
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index 07a54bad237..304f0443ca4 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -62,6 +62,7 @@
* unregister_netdev()
*/
#include "i2400m.h"
+#include <linux/etherdevice.h>
#include <linux/wimax/i2400m.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -81,6 +82,14 @@ module_param_named(rx_reorder_disabled, i2400m_rx_reorder_disabled, int, 0644);
MODULE_PARM_DESC(rx_reorder_disabled,
"If true, RX reordering will be disabled.");
+int i2400m_power_save_disabled; /* 0 (power saving enabled) by default */
+module_param_named(power_save_disabled, i2400m_power_save_disabled, int, 0644);
+MODULE_PARM_DESC(power_save_disabled,
+ "If true, the driver will not tell the device to enter "
+ "power saving mode when it reports it is ready for it. "
+ "False by default (so the device is told to do power "
+ "saving).");
+
/**
* i2400m_queue_work - schedule work on a i2400m's queue
*
@@ -171,7 +180,6 @@ int i2400m_schedule_work(struct i2400m *i2400m,
int result;
struct i2400m_work *iw;
- BUG_ON(i2400m->work_queue == NULL);
result = -ENOMEM;
iw = kzalloc(sizeof(*iw), gfp_flags);
if (iw == NULL)
@@ -234,9 +242,6 @@ int i2400m_op_msg_from_user(struct wimax_dev *wimax_dev,
result = PTR_ERR(ack_skb);
if (IS_ERR(ack_skb))
goto error_msg_to_dev;
- if (unlikely(i2400m->trace_msg_from_user))
- wimax_msg(&i2400m->wimax_dev, "trace",
- msg_buf, msg_len, GFP_KERNEL);
result = wimax_msg_send(&i2400m->wimax_dev, ack_skb);
error_msg_to_dev:
d_fnend(4, dev, "(wimax_dev %p [i2400m %p] msg_buf %p msg_len %zu "
@@ -379,6 +384,11 @@ error:
* Uploads firmware and brings up all the resources needed to be able
* to communicate with the device.
*
+ * The workqueue has to be setup early, at least before RX handling
+ * (it's only real user for now) so it can process reports as they
+ * arrive. We also want to destroy it if we retry, to make sure it is
+ * flushed...easier like this.
+ *
* TX needs to be setup before the bus-specific code (otherwise on
* shutdown, the bus-tx code could try to access it).
*/
@@ -389,7 +399,7 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags)
struct wimax_dev *wimax_dev = &i2400m->wimax_dev;
struct net_device *net_dev = wimax_dev->net_dev;
struct device *dev = i2400m_dev(i2400m);
- int times = 3;
+ int times = i2400m->bus_bm_retries;
d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
retry:
@@ -404,15 +414,15 @@ retry:
result = i2400m_rx_setup(i2400m);
if (result < 0)
goto error_rx_setup;
- result = i2400m->bus_dev_start(i2400m);
- if (result < 0)
- goto error_bus_dev_start;
i2400m->work_queue = create_singlethread_workqueue(wimax_dev->name);
if (i2400m->work_queue == NULL) {
result = -ENOMEM;
dev_err(dev, "cannot create workqueue\n");
goto error_create_workqueue;
}
+ result = i2400m->bus_dev_start(i2400m);
+ if (result < 0)
+ goto error_bus_dev_start;
result = i2400m_firmware_check(i2400m); /* fw versions ok? */
if (result < 0)
goto error_fw_check;
@@ -434,17 +444,17 @@ retry:
error_dev_initialize:
error_check_mac_addr:
error_fw_check:
- destroy_workqueue(i2400m->work_queue);
-error_create_workqueue:
i2400m->bus_dev_stop(i2400m);
error_bus_dev_start:
+ destroy_workqueue(i2400m->work_queue);
+error_create_workqueue:
i2400m_rx_release(i2400m);
error_rx_setup:
i2400m_tx_release(i2400m);
error_tx_setup:
error_bootstrap:
- if (result == -ERESTARTSYS && times-- > 0) {
- flags = I2400M_BRI_SOFT;
+ if (result == -EL3RST && times-- > 0) {
+ flags = I2400M_BRI_SOFT|I2400M_BRI_MAC_REINIT;
goto retry;
}
d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n",
@@ -473,7 +483,9 @@ int i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri bm_flags)
*
* Returns: 0 if ok, < 0 errno code on error.
*
- * Releases all the resources allocated to communicate with the device.
+ * Releases all the resources allocated to communicate with the
+ * device. Note we cannot destroy the workqueue earlier as until RX is
+ * fully destroyed, it could still try to schedule jobs.
*/
static
void __i2400m_dev_stop(struct i2400m *i2400m)
@@ -485,8 +497,8 @@ void __i2400m_dev_stop(struct i2400m *i2400m)
wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING);
i2400m_dev_shutdown(i2400m);
i2400m->ready = 0;
- destroy_workqueue(i2400m->work_queue);
i2400m->bus_dev_stop(i2400m);
+ destroy_workqueue(i2400m->work_queue);
i2400m_rx_release(i2400m);
i2400m_tx_release(i2400m);
wimax_state_change(wimax_dev, WIMAX_ST_DOWN);
@@ -548,7 +560,7 @@ void __i2400m_dev_reset_handle(struct work_struct *ws)
* i2400m_dev_stop() [we are shutting down anyway, so
* ignore it] or we are resetting somewhere else. */
dev_err(dev, "device rebooted\n");
- i2400m_msg_to_dev_cancel_wait(i2400m, -ERESTARTSYS);
+ i2400m_msg_to_dev_cancel_wait(i2400m, -EL3RST);
complete(&i2400m->msg_completion);
goto out;
}
@@ -598,6 +610,8 @@ out:
*/
int i2400m_dev_reset_handle(struct i2400m *i2400m)
{
+ i2400m->boot_mode = 1;
+ wmb(); /* Make sure i2400m_msg_to_dev() sees boot_mode */
return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle,
GFP_ATOMIC);
}
@@ -650,6 +664,7 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
result = i2400m_read_mac_addr(i2400m);
if (result < 0)
goto error_read_mac_addr;
+ random_ether_addr(i2400m->src_mac_addr);
result = register_netdev(net_dev); /* Okey dokey, bring it up */
if (result < 0) {
diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c
index 675c6ce810c..e81750e5445 100644
--- a/drivers/net/wimax/i2400m/fw.c
+++ b/drivers/net/wimax/i2400m/fw.c
@@ -397,7 +397,7 @@ static int i2400m_download_chunk(struct i2400m *i2400m, const void *chunk,
unsigned int direct, unsigned int do_csum)
{
int ret;
- size_t chunk_len = ALIGN(__chunk_len, I2400M_PL_PAD);
+ size_t chunk_len = ALIGN(__chunk_len, I2400M_PL_ALIGN);
struct device *dev = i2400m_dev(i2400m);
struct {
struct i2400m_bootrom_header cmd;
@@ -532,14 +532,14 @@ int i2400m_dnload_finalize(struct i2400m *i2400m,
cmd = (void *) bcf + offset;
if (i2400m->sboot == 0) {
struct i2400m_bootrom_header jump_ack;
- d_printf(3, dev, "unsecure boot, jumping to 0x%08x\n",
+ d_printf(1, dev, "unsecure boot, jumping to 0x%08x\n",
le32_to_cpu(cmd->target_addr));
i2400m_brh_set_opcode(cmd, I2400M_BRH_JUMP);
cmd->data_size = 0;
ret = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd),
&jump_ack, sizeof(jump_ack), 0);
} else {
- d_printf(3, dev, "secure boot, jumping to 0x%08x\n",
+ d_printf(1, dev, "secure boot, jumping to 0x%08x\n",
le32_to_cpu(cmd->target_addr));
cmd_buf = i2400m->bm_cmd_buf;
memcpy(&cmd_buf->cmd, cmd, sizeof(*cmd));
@@ -696,8 +696,7 @@ error_dev_gone:
return result;
error_timeout:
- dev_err(dev, "Timed out waiting for reboot ack, resetting\n");
- i2400m->bus_reset(i2400m, I2400M_RT_BUS);
+ dev_err(dev, "Timed out waiting for reboot ack\n");
result = -ETIMEDOUT;
goto exit_timeout;
}
@@ -770,40 +769,21 @@ error_read_mac:
static
int i2400m_dnload_init_nonsigned(struct i2400m *i2400m)
{
-#define POKE(a, d) { \
- .address = cpu_to_le32(a), \
- .data = cpu_to_le32(d) \
-}
- static const struct {
- __le32 address;
- __le32 data;
- } i2400m_pokes[] = {
- POKE(0x081A58, 0xA7810230),
- POKE(0x080040, 0x00000000),
- POKE(0x080048, 0x00000082),
- POKE(0x08004C, 0x0000081F),
- POKE(0x080054, 0x00000085),
- POKE(0x080058, 0x00000180),
- POKE(0x08005C, 0x00000018),
- POKE(0x080060, 0x00000010),
- POKE(0x080574, 0x00000001),
- POKE(0x080550, 0x00000005),
- POKE(0xAE0000, 0x00000000),
- };
-#undef POKE
- unsigned i;
- int ret;
+ unsigned i = 0;
+ int ret = 0;
struct device *dev = i2400m_dev(i2400m);
-
- dev_warn(dev, "WARNING!!! non-signed boot UNTESTED PATH!\n");
-
d_fnstart(5, dev, "(i2400m %p)\n", i2400m);
- for (i = 0; i < ARRAY_SIZE(i2400m_pokes); i++) {
- ret = i2400m_download_chunk(i2400m, &i2400m_pokes[i].data,
- sizeof(i2400m_pokes[i].data),
- i2400m_pokes[i].address, 1, 1);
- if (ret < 0)
- break;
+ if (i2400m->bus_bm_pokes_table) {
+ while (i2400m->bus_bm_pokes_table[i].address) {
+ ret = i2400m_download_chunk(
+ i2400m,
+ &i2400m->bus_bm_pokes_table[i].data,
+ sizeof(i2400m->bus_bm_pokes_table[i].data),
+ i2400m->bus_bm_pokes_table[i].address, 1, 1);
+ if (ret < 0)
+ break;
+ i++;
+ }
}
d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret);
return ret;
@@ -980,11 +960,12 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf,
{
int ret = 0;
struct device *dev = i2400m_dev(i2400m);
- int count = I2400M_BOOT_RETRIES;
+ int count = i2400m->bus_bm_retries;
d_fnstart(5, dev, "(i2400m %p bcf %p size %zu)\n",
i2400m, bcf, bcf_size);
i2400m->boot_mode = 1;
+ wmb(); /* Make sure other readers see it */
hw_reboot:
if (count-- == 0) {
ret = -ERESTARTSYS;
@@ -1033,6 +1014,7 @@ hw_reboot:
d_printf(2, dev, "fw %s successfully uploaded\n",
i2400m->fw_name);
i2400m->boot_mode = 0;
+ wmb(); /* Make sure i2400m_msg_to_dev() sees boot_mode */
error_dnload_finalize:
error_dnload_bcf:
error_dnload_init:
diff --git a/drivers/net/wimax/i2400m/i2400m-sdio.h b/drivers/net/wimax/i2400m/i2400m-sdio.h
index 08c2fb73923..9c4e3189f7b 100644
--- a/drivers/net/wimax/i2400m/i2400m-sdio.h
+++ b/drivers/net/wimax/i2400m/i2400m-sdio.h
@@ -78,6 +78,8 @@ enum {
/* The number of ticks to wait for the device to signal that
* it is ready */
I2400MS_INIT_SLEEP_INTERVAL = 10,
+ /* How long to wait for the device to settle after reset */
+ I2400MS_SETTLE_TIME = 40,
};
@@ -105,6 +107,10 @@ struct i2400ms {
char tx_wq_name[32];
struct dentry *debugfs_dentry;
+
+ wait_queue_head_t bm_wfa_wq;
+ int bm_wait_result;
+ size_t bm_ack_size;
};
@@ -129,4 +135,7 @@ extern ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *,
extern ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *,
struct i2400m_bootrom_header *,
size_t);
+extern void i2400ms_bus_bm_release(struct i2400m *);
+extern int i2400ms_bus_bm_setup(struct i2400m *);
+
#endif /* #ifndef __I2400M_SDIO_H__ */
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index 3ae2df38b59..1fe5da4cf0a 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -150,11 +150,33 @@
enum {
/* Firmware uploading */
I2400M_BOOT_RETRIES = 3,
+ I3200_BOOT_RETRIES = 3,
/* Size of the Boot Mode Command buffer */
I2400M_BM_CMD_BUF_SIZE = 16 * 1024,
I2400M_BM_ACK_BUF_SIZE = 256,
};
+/**
+ * struct i2400m_poke_table - Hardware poke table for the Intel 2400m
+ *
+ * This structure will be used to create a device specific poke table
+ * to put the device in a consistant state at boot time.
+ *
+ * @address: The device address to poke
+ *
+ * @data: The data value to poke to the device address
+ *
+ */
+struct i2400m_poke_table{
+ __le32 address;
+ __le32 data;
+};
+
+#define I2400M_FW_POKE(a, d) { \
+ .address = cpu_to_le32(a), \
+ .data = cpu_to_le32(d) \
+}
+
/**
* i2400m_reset_type - methods to reset a device
@@ -224,6 +246,17 @@ struct i2400m_roq;
* process, so it cannot rely on common infrastructure being laid
* out.
*
+ * @bus_bm_retries: [fill] How many times shall a firmware upload /
+ * device initialization be retried? Different models of the same
+ * device might need different values, hence it is set by the
+ * bus-specific driver. Note this value is used in two places,
+ * i2400m_fw_dnload() and __i2400m_dev_start(); they won't become
+ * multiplicative (__i2400m_dev_start() calling N times
+ * i2400m_fw_dnload() and this trying N times to download the
+ * firmware), as if __i2400m_dev_start() only retries if the
+ * firmware crashed while initializing the device (not in a
+ * general case).
+ *
* @bus_bm_cmd_send: [fill] Function called to send a boot-mode
* command. Flags are defined in 'enum i2400m_bm_cmd_flags'. This
* is synchronous and has to return 0 if ok or < 0 errno code in
@@ -252,6 +285,12 @@ struct i2400m_roq;
* address provided in boot mode is kind of broken and needs to
* be re-read later on.
*
+ * @bus_bm_pokes_table: [fill/optional] A table of device addresses
+ * and values that will be poked at device init time to move the
+ * device to the correct state for the type of boot/firmware being
+ * used. This table MUST be terminated with (0x000000,
+ * 0x00000000) or bad things will happen.
+ *
*
* @wimax_dev: WiMAX generic device for linkage into the kernel WiMAX
* stack. Due to the way a net_device is allocated, we need to
@@ -323,6 +362,10 @@ struct i2400m_roq;
* delivered. Then the driver can release them to the host. See
* drivers/net/i2400m/rx.c for details.
*
+ * @src_mac_addr: MAC address used to make ethernet packets be coming
+ * from. This is generated at i2400m_setup() time and used during
+ * the life cycle of the instance. See i2400m_fake_eth_header().
+ *
* @init_mutex: Mutex used for serializing the device bringup
* sequence; this way if the device reboots in the middle, we
* don't try to do a bringup again while we are tearing down the
@@ -395,6 +438,8 @@ struct i2400m {
size_t bus_tx_block_size;
size_t bus_pl_size_max;
+ unsigned bus_bm_retries;
+
int (*bus_dev_start)(struct i2400m *);
void (*bus_dev_stop)(struct i2400m *);
void (*bus_tx_kick)(struct i2400m *);
@@ -406,6 +451,7 @@ struct i2400m {
struct i2400m_bootrom_header *, size_t);
const char **bus_fw_names;
unsigned bus_bm_mac_addr_impaired:1;
+ const struct i2400m_poke_table *bus_bm_pokes_table;
spinlock_t tx_lock; /* protect TX state */
void *tx_buf;
@@ -421,6 +467,7 @@ struct i2400m {
unsigned rx_pl_num, rx_pl_max, rx_pl_min,
rx_num, rx_size_acc, rx_size_min, rx_size_max;
struct i2400m_roq *rx_roq; /* not under rx_lock! */
+ u8 src_mac_addr[ETH_HLEN];
struct mutex msg_mutex; /* serialize command execution */
struct completion msg_completion;
@@ -704,6 +751,7 @@ static const __le32 i2400m_SBOOT_BARKER[4] = {
cpu_to_le32(I2400M_SBOOT_BARKER)
};
+extern int i2400m_power_save_disabled;
/*
* Utility functions
diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c
index 6b1fe7a81f2..9653f478b38 100644
--- a/drivers/net/wimax/i2400m/netdev.c
+++ b/drivers/net/wimax/i2400m/netdev.c
@@ -404,10 +404,12 @@ static
void i2400m_rx_fake_eth_header(struct net_device *net_dev,
void *_eth_hdr, __be16 protocol)
{
+ struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
struct ethhdr *eth_hdr = _eth_hdr;
memcpy(eth_hdr->h_dest, net_dev->dev_addr, sizeof(eth_hdr->h_dest));
- memset(eth_hdr->h_source, 0, sizeof(eth_hdr->h_dest));
+ memcpy(eth_hdr->h_source, i2400m->src_mac_addr,
+ sizeof(eth_hdr->h_source));
eth_hdr->h_proto = protocol;
}
diff --git a/drivers/net/wimax/i2400m/op-rfkill.c b/drivers/net/wimax/i2400m/op-rfkill.c
index 487ec58cea4..43927b5d7ad 100644
--- a/drivers/net/wimax/i2400m/op-rfkill.c
+++ b/drivers/net/wimax/i2400m/op-rfkill.c
@@ -54,8 +54,10 @@ int i2400m_radio_is(struct i2400m *i2400m, enum wimax_rf_state state)
/* state == WIMAX_RF_ON */
return i2400m->state != I2400M_SS_RF_OFF
&& i2400m->state != I2400M_SS_RF_SHUTDOWN;
- else
+ else {
BUG();
+ return -EINVAL; /* shut gcc warnings on certain arches */
+ }
}
diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c
index f9fc3890232..07c32e68909 100644
--- a/drivers/net/wimax/i2400m/rx.c
+++ b/drivers/net/wimax/i2400m/rx.c
@@ -177,7 +177,8 @@ void i2400m_report_hook_work(struct work_struct *ws)
struct i2400m_work *iw =
container_of(ws, struct i2400m_work, ws);
struct i2400m_report_hook_args *args = (void *) iw->pl;
- i2400m_report_hook(iw->i2400m, args->l3l4_hdr, args->size);
+ if (iw->i2400m->ready)
+ i2400m_report_hook(iw->i2400m, args->l3l4_hdr, args->size);
kfree_skb(args->skb_rx);
i2400m_put(iw->i2400m);
kfree(iw);
@@ -309,6 +310,9 @@ void i2400m_rx_ctl(struct i2400m *i2400m, struct sk_buff *skb_rx,
skb_get(skb_rx);
i2400m_queue_work(i2400m, i2400m_report_hook_work,
GFP_KERNEL, &args, sizeof(args));
+ if (unlikely(i2400m->trace_msg_from_user))
+ wimax_msg(&i2400m->wimax_dev, "echo",
+ l3l4_hdr, size, GFP_KERNEL);
result = wimax_msg(&i2400m->wimax_dev, NULL, l3l4_hdr, size,
GFP_KERNEL);
if (result < 0)
@@ -1144,7 +1148,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
num_pls = le16_to_cpu(msg_hdr->num_pls);
pl_itr = sizeof(*msg_hdr) + /* Check payload descriptor(s) */
num_pls * sizeof(msg_hdr->pld[0]);
- pl_itr = ALIGN(pl_itr, I2400M_PL_PAD);
+ pl_itr = ALIGN(pl_itr, I2400M_PL_ALIGN);
if (pl_itr > skb->len) { /* got all the payload descriptors? */
dev_err(dev, "RX: HW BUG? message too short (%u bytes) for "
"%u payload descriptors (%zu each, total %zu)\n",
@@ -1162,7 +1166,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
single_last = num_pls == 1 || i == num_pls - 1;
i2400m_rx_payload(i2400m, skb, single_last, &msg_hdr->pld[i],
skb->data + pl_itr);
- pl_itr += ALIGN(pl_size, I2400M_PL_PAD);
+ pl_itr += ALIGN(pl_size, I2400M_PL_ALIGN);
cond_resched(); /* Don't monopolize */
}
kfree_skb(skb);
diff --git a/drivers/net/wimax/i2400m/sdio-fw.c b/drivers/net/wimax/i2400m/sdio-fw.c
index 3487205d8f5..7d6ec0f475f 100644
--- a/drivers/net/wimax/i2400m/sdio-fw.c
+++ b/drivers/net/wimax/i2400m/sdio-fw.c
@@ -46,17 +46,24 @@
* Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
* - SDIO rehash for changes in the bus-driver model
*
+ * Dirk Brandewie <dirk.j.brandewie@intel.com>
+ * - Make it IRQ based, not polling
+ *
* THE PROCEDURE
*
* See fw.c for the generic description of this procedure.
*
* This file implements only the SDIO specifics. It boils down to how
* to send a command and waiting for an acknowledgement from the
- * device. We do polled reads.
+ * device.
+ *
+ * All this code is sequential -- all i2400ms_bus_bm_*() functions are
+ * executed in the same thread, except i2400ms_bm_irq() [on its own by
+ * the SDIO driver]. This makes it possible to avoid locking.
*
* COMMAND EXECUTION
*
- * THe generic firmware upload code will call i2400m_bus_bm_cmd_send()
+ * The generic firmware upload code will call i2400m_bus_bm_cmd_send()
* to send commands.
*
* The SDIO devices expects things in 256 byte blocks, so it will pad
@@ -64,12 +71,15 @@
*
* ACK RECEPTION
*
- * This works in polling mode -- the fw loader says when to wait for
- * data and for that it calls i2400ms_bus_bm_wait_for_ack().
+ * This works in IRQ mode -- the fw loader says when to wait for data
+ * and for that it calls i2400ms_bus_bm_wait_for_ack().
*
- * This will poll the device for data until it is received. We need to
- * receive at least as much bytes as where asked for (although it'll
- * always be a multiple of 256 bytes).
+ * This checks if there is any data available (RX size > 0); if not,
+ * waits for the IRQ handler to notify about it. Once there is data,
+ * it is read and passed to the caller. Doing it this way we don't
+ * need much coordination/locking, and it makes it much more difficult
+ * for an interrupt to be lost and the wait_for_ack() function getting
+ * stuck even when data is pending.
*/
#include <linux/mmc/sdio_func.h>
#include "i2400m-sdio.h"
@@ -78,6 +88,7 @@
#define D_SUBMODULE fw
#include "sdio-debug-levels.h"
+
/*
* Send a boot-mode command to the SDIO function
*
@@ -139,7 +150,7 @@ error_too_big:
/*
- * Read an ack from the device's boot-mode (polling)
+ * Read an ack from the device's boot-mode
*
* @i2400m:
* @_ack: pointer to where to store the read data
@@ -150,75 +161,49 @@ error_too_big:
* The ACK for a BM command is always at least sizeof(*ack) bytes, so
* check for that. We don't need to check for device reboots
*
- * NOTE: We do an artificial timeout of 1 sec over the SDIO timeout;
- * this way we have control over it...there is no way that I know
- * of setting an SDIO transaction timeout.
*/
ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *i2400m,
struct i2400m_bootrom_header *ack,
size_t ack_size)
{
- int result;
- ssize_t rx_size;
- u64 timeout;
+ ssize_t result;
struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m);
struct sdio_func *func = i2400ms->func;
struct device *dev = &func->dev;
+ int size;
BUG_ON(sizeof(*ack) > ack_size);
d_fnstart(5, dev, "(i2400m %p ack %p size %zu)\n",
i2400m, ack, ack_size);
- timeout = get_jiffies_64() + 2 * HZ;
- sdio_claim_host(func);
- while (1) {
- if (time_after64(get_jiffies_64(), timeout)) {
- rx_size = -ETIMEDOUT;
- dev_err(dev, "timeout waiting for ack data\n");
- goto error_timedout;
- }
+ spin_lock(&i2400m->rx_lock);
+ i2400ms->bm_ack_size = -EINPROGRESS;
+ spin_unlock(&i2400m->rx_lock);
- /* Find the RX size, check if it fits or not -- it if
- * doesn't fit, fail, as we have no way to dispose of
- * the extra data. */
- rx_size = __i2400ms_rx_get_size(i2400ms);
- if (rx_size < 0)
- goto error_rx_get_size;
- result = -ENOSPC; /* Check it fits */
- if (rx_size < sizeof(*ack)) {
- rx_size = -EIO;
- dev_err(dev, "HW BUG? received is too small (%zu vs "
- "%zu needed)\n", sizeof(*ack), rx_size);
- goto error_too_small;
- }
- if (rx_size > I2400M_BM_ACK_BUF_SIZE) {
- dev_err(dev, "SW BUG? BM_ACK_BUF is too small (%u vs "
- "%zu needed)\n", I2400M_BM_ACK_BUF_SIZE,
- rx_size);
- goto error_too_small;
- }
+ result = wait_event_timeout(i2400ms->bm_wfa_wq,
+ i2400ms->bm_ack_size != -EINPROGRESS,
+ 2 * HZ);
+ if (result == 0) {
+ result = -ETIMEDOUT;
+ dev_err(dev, "BM: error waiting for an ack\n");
+ goto error_timeout;
+ }
- /* Read it */
- result = sdio_memcpy_fromio(func, i2400m->bm_ack_buf,
- I2400MS_DATA_ADDR, rx_size);
- if (result == -ETIMEDOUT || result == -ETIME)
- continue;
- if (result < 0) {
- dev_err(dev, "BM SDIO receive (%zu B) failed: %d\n",
- rx_size, result);
- goto error_read;
- } else
- break;
+ spin_lock(&i2400m->rx_lock);
+ result = i2400ms->bm_ack_size;
+ BUG_ON(result == -EINPROGRESS);
+ if (result < 0) /* so we exit when rx_release() is called */
+ dev_err(dev, "BM: %s failed: %zd\n", __func__, result);
+ else {
+ size = min(ack_size, i2400ms->bm_ack_size);
+ memcpy(ack, i2400m->bm_ack_buf, size);
}
- rx_size = min((ssize_t)ack_size, rx_size);
- memcpy(ack, i2400m->bm_ack_buf, rx_size);
-error_read:
-error_too_small:
-error_rx_get_size:
-error_timedout:
- sdio_release_host(func);
- d_fnend(5, dev, "(i2400m %p ack %p size %zu) = %ld\n",
- i2400m, ack, ack_size, (long) rx_size);
- return rx_size;
+ i2400ms->bm_ack_size = -EINPROGRESS;
+ spin_unlock(&i2400m->rx_lock);
+
+error_timeout:
+ d_fnend(5, dev, "(i2400m %p ack %p size %zu) = %zd\n",
+ i2400m, ack, ack_size, result);
+ return result;
}
diff --git a/drivers/net/wimax/i2400m/sdio-rx.c b/drivers/net/wimax/i2400m/sdio-rx.c
index a3008b904f7..321beadf6e4 100644
--- a/drivers/net/wimax/i2400m/sdio-rx.c
+++ b/drivers/net/wimax/i2400m/sdio-rx.c
@@ -69,6 +69,13 @@
#define D_SUBMODULE rx
#include "sdio-debug-levels.h"
+static const __le32 i2400m_ACK_BARKER[4] = {
+ __constant_cpu_to_le32(I2400M_ACK_BARKER),
+ __constant_cpu_to_le32(I2400M_ACK_BARKER),
+ __constant_cpu_to_le32(I2400M_ACK_BARKER),
+ __constant_cpu_to_le32(I2400M_ACK_BARKER)
+};
+
/*
* Read and return the amount of bytes available for RX
@@ -131,25 +138,35 @@ void i2400ms_rx(struct i2400ms *i2400ms)
ret = rx_size;
goto error_get_size;
}
+
ret = -ENOMEM;
skb = alloc_skb(rx_size, GFP_ATOMIC);
if (NULL == skb) {
dev_err(dev, "RX: unable to alloc skb\n");
goto error_alloc_skb;
}
-
ret = sdio_memcpy_fromio(func, skb->data,
I2400MS_DATA_ADDR, rx_size);
if (ret < 0) {
dev_err(dev, "RX: SDIO data read failed: %d\n", ret);
goto error_memcpy_fromio;
}
- /* Check if device has reset */
- if (!memcmp(skb->data, i2400m_NBOOT_BARKER,
- sizeof(i2400m_NBOOT_BARKER))
- || !memcmp(skb->data, i2400m_SBOOT_BARKER,
- sizeof(i2400m_SBOOT_BARKER))) {
+
+ rmb(); /* make sure we get boot_mode from dev_reset_handle */
+ if (i2400m->boot_mode == 1) {
+ spin_lock(&i2400m->rx_lock);
+ i2400ms->bm_ack_size = rx_size;
+ spin_unlock(&i2400m->rx_lock);
+ memcpy(i2400m->bm_ack_buf, skb->data, rx_size);
+ wake_up(&i2400ms->bm_wfa_wq);
+ dev_err(dev, "RX: SDIO boot mode message\n");
+ kfree_skb(skb);
+ } else if (unlikely(!memcmp(skb->data, i2400m_NBOOT_BARKER,
+ sizeof(i2400m_NBOOT_BARKER))
+ || !memcmp(skb->data, i2400m_SBOOT_BARKER,
+ sizeof(i2400m_SBOOT_BARKER)))) {
ret = i2400m_dev_reset_handle(i2400m);
+ dev_err(dev, "RX: SDIO reboot barker\n");
kfree_skb(skb);
} else {
skb_put(skb, rx_size);
@@ -179,7 +196,6 @@ void i2400ms_irq(struct sdio_func *func)
{
int ret;
struct i2400ms *i2400ms = sdio_get_drvdata(func);
- struct i2400m *i2400m = &i2400ms->i2400m;
struct device *dev = &func->dev;
int val;
@@ -194,10 +210,7 @@ void i2400ms_irq(struct sdio_func *func)
goto error_no_irq;
}
sdio_writeb(func, 1, I2400MS_INTR_CLEAR_ADDR, &ret);
- if (WARN_ON(i2400m->boot_mode != 0))
- dev_err(dev, "RX: SW BUG? boot mode and IRQ is up?\n");
- else
- i2400ms_rx(i2400ms);
+ i2400ms_rx(i2400ms);
error_no_irq:
d_fnend(6, dev, "(i2400ms %p) = void\n", i2400ms);
return;
@@ -214,8 +227,15 @@ int i2400ms_rx_setup(struct i2400ms *i2400ms)
int result;
struct sdio_func *func = i2400ms->func;
struct device *dev = &func->dev;
+ struct i2400m *i2400m = &i2400ms->i2400m;
d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms);
+
+ init_waitqueue_head(&i2400ms->bm_wfa_wq);
+ spin_lock(&i2400m->rx_lock);
+ i2400ms->bm_wait_result = -EINPROGRESS;
+ spin_unlock(&i2400m->rx_lock);
+
sdio_claim_host(func);
result = sdio_claim_irq(func, i2400ms_irq);
if (result < 0) {
@@ -245,8 +265,13 @@ void i2400ms_rx_release(struct i2400ms *i2400ms)
int result;
struct sdio_func *func = i2400ms->func;
struct device *dev = &func->dev;
+ struct i2400m *i2400m = &i2400ms->i2400m;
d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms);
+ spin_lock(&i2400m->rx_lock);
+ i2400ms->bm_ack_size = -EINTR;
+ spin_unlock(&i2400m->rx_lock);
+ wake_up_all(&i2400ms->bm_wfa_wq);
sdio_claim_host(func);
sdio_writeb(func, 0, I2400MS_INTR_ENABLE_ADDR, &result);
sdio_release_irq(func);
diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c
index 5ac5e76701c..2538825d1c6 100644
--- a/drivers/net/wimax/i2400m/sdio.c
+++ b/drivers/net/wimax/i2400m/sdio.c
@@ -78,6 +78,14 @@ static const char *i2400ms_bus_fw_names[] = {
};
+static const struct i2400m_poke_table i2400ms_pokes[] = {
+ I2400M_FW_POKE(0x6BE260, 0x00000088),
+ I2400M_FW_POKE(0x080550, 0x00000005),
+ I2400M_FW_POKE(0xAE0000, 0x00000000),
+ I2400M_FW_POKE(0x000000, 0x00000000), /* MUST be 0 terminated or bad
+ * things will happen */
+};
+
/*
* Enable the SDIO function
*
@@ -148,19 +156,14 @@ int i2400ms_bus_dev_start(struct i2400m *i2400m)
d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
msleep(200);
- result = i2400ms_rx_setup(i2400ms);
- if (result < 0)
- goto error_rx_setup;
result = i2400ms_tx_setup(i2400ms);
if (result < 0)
goto error_tx_setup;
d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
return result;
- i2400ms_tx_release(i2400ms);
error_tx_setup:
- i2400ms_rx_release(i2400ms);
-error_rx_setup:
+ i2400ms_tx_release(i2400ms);
d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
return result;
}
@@ -174,7 +177,6 @@ void i2400ms_bus_dev_stop(struct i2400m *i2400m)
struct device *dev = &func->dev;
d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
- i2400ms_rx_release(i2400ms);
i2400ms_tx_release(i2400ms);
d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
}
@@ -255,7 +257,7 @@ error_kzalloc:
static
int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
{
- int result;
+ int result = 0;
struct i2400ms *i2400ms =
container_of(i2400m, struct i2400ms, i2400m);
struct device *dev = i2400m_dev(i2400m);
@@ -280,8 +282,25 @@ int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
sizeof(i2400m_COLD_BOOT_BARKER));
else if (rt == I2400M_RT_BUS) {
do_bus_reset:
- dev_err(dev, "FIXME: SDIO bus reset not implemented\n");
- result = rt == I2400M_RT_WARM ? -ENODEV : -ENOSYS;
+ /* call netif_tx_disable() before sending IOE disable,
+ * so that all the tx from network layer are stopped
+ * while IOE is being reset. Make sure it is called
+ * only after register_netdev() was issued.
+ */
+ if (i2400m->wimax_dev.net_dev->reg_state == NETREG_REGISTERED)
+ netif_tx_disable(i2400m->wimax_dev.net_dev);
+
+ i2400ms_rx_release(i2400ms);
+ sdio_claim_host(i2400ms->func);
+ sdio_disable_func(i2400ms->func);
+ sdio_release_host(i2400ms->func);
+
+ /* Wait for the device to settle */
+ msleep(40);
+
+ result = i2400ms_enable_function(i2400ms->func);
+ if (result >= 0)
+ i2400ms_rx_setup(i2400ms);
} else
BUG();
if (result < 0 && rt != I2400M_RT_BUS) {
@@ -404,24 +423,32 @@ int i2400ms_probe(struct sdio_func *func,
i2400m->bus_dev_stop = i2400ms_bus_dev_stop;
i2400m->bus_tx_kick = i2400ms_bus_tx_kick;
i2400m->bus_reset = i2400ms_bus_reset;
+ /* The iwmc3200-wimax sometimes requires the driver to try
+ * hard when we paint it into a corner. */
+ i2400m->bus_bm_retries = I3200_BOOT_RETRIES;
i2400m->bus_bm_cmd_send = i2400ms_bus_bm_cmd_send;
i2400m->bus_bm_wait_for_ack = i2400ms_bus_bm_wait_for_ack;
i2400m->bus_fw_names = i2400ms_bus_fw_names;
i2400m->bus_bm_mac_addr_impaired = 1;
-
- result = i2400ms_enable_function(i2400ms->func);
- if (result < 0) {
- dev_err(dev, "Cannot enable SDIO function: %d\n", result);
- goto error_func_enable;
- }
+ i2400m->bus_bm_pokes_table = &i2400ms_pokes[0];
sdio_claim_host(func);
result = sdio_set_block_size(func, I2400MS_BLK_SIZE);
+ sdio_release_host(func);
if (result < 0) {
dev_err(dev, "Failed to set block size: %d\n", result);
goto error_set_blk_size;
}
- sdio_release_host(func);
+
+ result = i2400ms_enable_function(i2400ms->func);
+ if (result < 0) {
+ dev_err(dev, "Cannot enable SDIO function: %d\n", result);
+ goto error_func_enable;
+ }
+
+ result = i2400ms_rx_setup(i2400ms);
+ if (result < 0)
+ goto error_rx_setup;
result = i2400m_setup(i2400m, I2400M_BRI_NO_REBOOT);
if (result < 0) {
@@ -440,12 +467,14 @@ int i2400ms_probe(struct sdio_func *func,
error_debugfs_add:
i2400m_release(i2400m);
error_setup:
- sdio_set_drvdata(func, NULL);
+ i2400ms_rx_release(i2400ms);
+error_rx_setup:
sdio_claim_host(func);
-error_set_blk_size:
sdio_disable_func(func);
sdio_release_host(func);
error_func_enable:
+error_set_blk_size:
+ sdio_set_drvdata(func, NULL);
free_netdev(net_dev);
error_alloc_netdev:
return result;
@@ -462,6 +491,7 @@ void i2400ms_remove(struct sdio_func *func)
d_fnstart(3, dev, "SDIO func %p\n", func);
debugfs_remove_recursive(i2400ms->debugfs_dentry);
+ i2400ms_rx_release(i2400ms);
i2400m_release(i2400m);
sdio_set_drvdata(func, NULL);
sdio_claim_host(func);
diff --git a/drivers/net/wimax/i2400m/tx.c b/drivers/net/wimax/i2400m/tx.c
index 613a88ffd65..fa16ccf8e26 100644
--- a/drivers/net/wimax/i2400m/tx.c
+++ b/drivers/net/wimax/i2400m/tx.c
@@ -278,6 +278,48 @@ enum {
#define TAIL_FULL ((void *)~(unsigned long)NULL)
/*
+ * Calculate how much tail room is available
+ *
+ * Note the trick here. This path is ONLY caleed for Case A (see
+ * i2400m_tx_fifo_push() below), where we have:
+ *
+ * Case A
+ * N ___________
+ * | tail room |
+ * | |
+ * |<- IN ->|
+ * | |
+ * | data |
+ * | |
+ * |<- OUT ->|
+ * | |
+ * | head room |
+ * 0 -----------
+ *
+ * When calculating the tail_room, tx_in might get to be zero if
+ * i2400m->tx_in is right at the end of the buffer (really full
+ * buffer) if there is no head room. In this case, tail_room would be
+ * I2400M_TX_BUF_SIZE, although it is actually zero. Hence the final
+ * mod (%) operation. However, when doing this kind of optimization,
+ * i2400m->tx_in being zero would fail, so we treat is an a special
+ * case.
+ */
+static inline
+size_t __i2400m_tx_tail_room(struct i2400m *i2400m)
+{
+ size_t tail_room;
+ size_t tx_in;
+
+ if (unlikely(i2400m->tx_in) == 0)
+ return I2400M_TX_BUF_SIZE;
+ tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE;
+ tail_room = I2400M_TX_BUF_SIZE - tx_in;
+ tail_room %= I2400M_TX_BUF_SIZE;
+ return tail_room;
+}
+
+
+/*
* Allocate @size bytes in the TX fifo, return a pointer to it
*
* @i2400m: device descriptor
@@ -338,7 +380,7 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding)
return NULL;
}
/* Is there space at the tail? */
- tail_room = I2400M_TX_BUF_SIZE - i2400m->tx_in % I2400M_TX_BUF_SIZE;
+ tail_room = __i2400m_tx_tail_room(i2400m);
if (tail_room < needed_size) {
if (i2400m->tx_out % I2400M_TX_BUF_SIZE
< i2400m->tx_in % I2400M_TX_BUF_SIZE) {
@@ -367,17 +409,29 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding)
* (I2400M_PL_PAD for the payloads, I2400M_TX_PLD_SIZE for the
* header).
*
+ * Tail room can get to be zero if a message was opened when there was
+ * space only for a header. _tx_close() will mark it as to-skip (as it
+ * will have no payloads) and there will be no more space to flush, so
+ * nothing has to be done here. This is probably cheaper than ensuring
+ * in _tx_new() that there is some space for payloads...as we could
+ * always possibly hit the same problem if the payload wouldn't fit.
+ *
* Note:
*
* Assumes i2400m->tx_lock is taken, and we use that as a barrier
+ *
+ * This path is only taken for Case A FIFO situations [see
+ * i2400m_tx_fifo_push()]
*/
static
void i2400m_tx_skip_tail(struct i2400m *i2400m)
{
struct device *dev = i2400m_dev(i2400m);
size_t tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE;
- size_t tail_room = I2400M_TX_BUF_SIZE - tx_in;
+ size_t tail_room = __i2400m_tx_tail_room(i2400m);
struct i2400m_msg_hdr *msg = i2400m->tx_buf + tx_in;
+ if (unlikely(tail_room == 0))
+ return;
BUG_ON(tail_room < sizeof(*msg));
msg->size = tail_room | I2400M_TX_SKIP;
d_printf(2, dev, "skip tail: skipping %zu bytes @%zu\n",
@@ -474,10 +528,18 @@ void i2400m_tx_close(struct i2400m *i2400m)
struct i2400m_msg_hdr *tx_msg_moved;
size_t aligned_size, padding, hdr_size;
void *pad_buf;
+ unsigned num_pls;
if (tx_msg->size & I2400M_TX_SKIP) /* a skipper? nothing to do */
goto out;
-
+ num_pls = le16_to_cpu(tx_msg->num_pls);
+ /* We can get this situation when a new message was started
+ * and there was no space to add payloads before hitting the
+ tail (and taking padding into consideration). */
+ if (num_pls == 0) {
+ tx_msg->size |= I2400M_TX_SKIP;
+ goto out;
+ }
/* Relocate the message header
*
* Find the current header size, align it to 16 and if we need
@@ -491,7 +553,7 @@ void i2400m_tx_close(struct i2400m *i2400m)
*/
hdr_size = sizeof(*tx_msg)
+ le16_to_cpu(tx_msg->num_pls) * sizeof(tx_msg->pld[0]);
- hdr_size = ALIGN(hdr_size, I2400M_PL_PAD);
+ hdr_size = ALIGN(hdr_size, I2400M_PL_ALIGN);
tx_msg->offset = I2400M_TX_PLD_SIZE - hdr_size;
tx_msg_moved = (void *) tx_msg + tx_msg->offset;
memmove(tx_msg_moved, tx_msg, hdr_size);
@@ -574,7 +636,7 @@ int i2400m_tx(struct i2400m *i2400m, const void *buf, size_t buf_len,
d_fnstart(3, dev, "(i2400m %p skb %p [%zu bytes] pt %u)\n",
i2400m, buf, buf_len, pl_type);
- padded_len = ALIGN(buf_len, I2400M_PL_PAD);
+ padded_len = ALIGN(buf_len, I2400M_PL_ALIGN);
d_printf(5, dev, "padded_len %zd buf_len %zd\n", padded_len, buf_len);
/* If there is no current TX message, create one; if the
* current one is out of payload slots or we have a singleton,
@@ -591,6 +653,8 @@ try_new:
i2400m_tx_close(i2400m);
i2400m_tx_new(i2400m);
}
+ if (i2400m->tx_msg == NULL)
+ goto error_tx_new;
if (i2400m->tx_msg->size + padded_len > I2400M_TX_BUF_SIZE / 2) {
d_printf(2, dev, "TX: message too big, going new\n");
i2400m_tx_close(i2400m);
@@ -773,7 +837,6 @@ void i2400m_tx_msg_sent(struct i2400m *i2400m)
n = i2400m->tx_out / I2400M_TX_BUF_SIZE;
i2400m->tx_out %= I2400M_TX_BUF_SIZE;
i2400m->tx_in -= n * I2400M_TX_BUF_SIZE;
- netif_start_queue(i2400m->wimax_dev.net_dev);
spin_unlock_irqrestore(&i2400m->tx_lock, flags);
d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
}
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index 17851321b7f..cfdaf69da9d 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -254,8 +254,10 @@ do_bus_reset:
dev_err(dev, "USB reset failed (%d), giving up!\n",
result);
}
- } else
+ } else {
+ result = -EINVAL; /* shut gcc up in certain arches */
BUG();
+ }
if (result < 0
&& result != -EINVAL /* device is gone */
&& rt != I2400M_RT_BUS) {
@@ -399,6 +401,7 @@ int i2400mu_probe(struct usb_interface *iface,
i2400m->bus_dev_stop = i2400mu_bus_dev_stop;
i2400m->bus_tx_kick = i2400mu_bus_tx_kick;
i2400m->bus_reset = i2400mu_bus_reset;
+ i2400m->bus_bm_retries = I2400M_BOOT_RETRIES;
i2400m->bus_bm_cmd_send = i2400mu_bus_bm_cmd_send;
i2400m->bus_bm_wait_for_ack = i2400mu_bus_bm_wait_for_ack;
i2400m->bus_fw_names = i2400mu_bus_fw_names;
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 3359497012a..5bc00db21b2 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -146,14 +146,14 @@ config LIBERTAS_CS
A driver for Marvell Libertas 8385 CompactFlash devices.
config LIBERTAS_SDIO
- tristate "Marvell Libertas 8385 and 8686 SDIO 802.11b/g cards"
+ tristate "Marvell Libertas 8385/8686/8688 SDIO 802.11b/g cards"
depends on LIBERTAS && MMC
---help---
- A driver for Marvell Libertas 8385 and 8686 SDIO devices.
+ A driver for Marvell Libertas 8385/8686/8688 SDIO devices.
config LIBERTAS_SPI
tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
- depends on LIBERTAS && SPI && GENERIC_GPIO
+ depends on LIBERTAS && SPI
---help---
A driver for Marvell Libertas 8686 SPI devices.
@@ -333,6 +333,7 @@ config USB_ZD1201
config USB_NET_RNDIS_WLAN
tristate "Wireless RNDIS USB support"
depends on USB && WLAN_80211 && EXPERIMENTAL
+ depends on CFG80211
select USB_USBNET
select USB_NET_CDCETHER
select USB_NET_RNDIS_HOST
@@ -434,6 +435,13 @@ config RTL8187
Thanks to Realtek for their support!
+# If possible, automatically enable LEDs for RTL8187.
+
+config RTL8187_LEDS
+ bool
+ depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187)
+ default y
+
config ADM8211
tristate "ADMtek ADM8211 support"
depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
@@ -484,9 +492,7 @@ config MWL8K
will be called mwl8k. If unsure, say N.
source "drivers/net/wireless/p54/Kconfig"
-source "drivers/net/wireless/ath5k/Kconfig"
-source "drivers/net/wireless/ath9k/Kconfig"
-source "drivers/net/wireless/ar9170/Kconfig"
+source "drivers/net/wireless/ath/Kconfig"
source "drivers/net/wireless/ipw2x00/Kconfig"
source "drivers/net/wireless/iwlwifi/Kconfig"
source "drivers/net/wireless/hostap/Kconfig"
@@ -495,5 +501,7 @@ source "drivers/net/wireless/b43legacy/Kconfig"
source "drivers/net/wireless/zd1211rw/Kconfig"
source "drivers/net/wireless/rt2x00/Kconfig"
source "drivers/net/wireless/orinoco/Kconfig"
+source "drivers/net/wireless/wl12xx/Kconfig"
+source "drivers/net/wireless/iwmc3200wifi/Kconfig"
endmenu
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 50e7fba7f0e..7a4647e78fd 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -55,8 +55,10 @@ obj-$(CONFIG_RT2X00) += rt2x00/
obj-$(CONFIG_P54_COMMON) += p54/
-obj-$(CONFIG_ATH5K) += ath5k/
-obj-$(CONFIG_ATH9K) += ath9k/
-obj-$(CONFIG_AR9170_USB) += ar9170/
+obj-$(CONFIG_ATH_COMMON) += ath/
obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
+
+obj-$(CONFIG_WL12XX) += wl12xx/
+
+obj-$(CONFIG_IWM) += iwmc3200wifi/
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index f7182179501..2b9e379994a 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1311,18 +1311,20 @@ static int adm8211_config(struct ieee80211_hw *dev, u32 changed)
return 0;
}
-static int adm8211_config_interface(struct ieee80211_hw *dev,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
+static void adm8211_bss_info_changed(struct ieee80211_hw *dev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf,
+ u32 changes)
{
struct adm8211_priv *priv = dev->priv;
+ if (!(changes & BSS_CHANGED_BSSID))
+ return;
+
if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {
adm8211_set_bssid(dev, conf->bssid);
memcpy(priv->bssid, conf->bssid, ETH_ALEN);
}
-
- return 0;
}
static void adm8211_configure_filter(struct ieee80211_hw *dev,
@@ -1753,7 +1755,7 @@ static const struct ieee80211_ops adm8211_ops = {
.add_interface = adm8211_add_interface,
.remove_interface = adm8211_remove_interface,
.config = adm8211_config,
- .config_interface = adm8211_config_interface,
+ .bss_info_changed = adm8211_bss_info_changed,
.configure_filter = adm8211_configure_filter,
.get_stats = adm8211_get_stats,
.get_tx_stats = adm8211_get_tx_stats,
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 9eabf4d1f2e..c70604f0329 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -1935,7 +1935,7 @@ static int mpi_start_xmit(struct sk_buff *skb, struct net_device *dev) {
netif_stop_queue (dev);
if (npacks > MAXTXQ) {
dev->stats.tx_fifo_errors++;
- return 1;
+ return NETDEV_TX_BUSY;
}
skb_queue_tail (&ai->txq, skb);
return 0;
@@ -2139,7 +2139,7 @@ static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
if (i == MAX_FIDS / 2) {
dev->stats.tx_fifo_errors++;
- return 1;
+ return NETDEV_TX_BUSY;
}
}
/* check min length*/
@@ -2193,7 +2193,8 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
if (test_bit(FLAG_MPI, &priv->flags)) {
/* Not implemented yet for MPI350 */
netif_stop_queue(dev);
- return -ENETDOWN;
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
}
if ( skb == NULL ) {
@@ -2210,7 +2211,7 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
if (i == MAX_FIDS) {
dev->stats.tx_fifo_errors++;
- return 1;
+ return NETDEV_TX_BUSY;
}
}
/* check min length*/
diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c
index a54a67c425c..d84caf198a2 100644
--- a/drivers/net/wireless/arlan-main.c
+++ b/drivers/net/wireless/arlan-main.c
@@ -1199,7 +1199,7 @@ bad_end:
arlan_process_interrupt(dev);
netif_stop_queue (dev);
ARLAN_DEBUG_EXIT("arlan_tx");
- return 1;
+ return NETDEV_TX_BUSY;
}
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 8d93ca4651b..4efbdbe6d6b 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1965,13 +1965,18 @@ static int at76_config(struct ieee80211_hw *hw, u32 changed)
return 0;
}
-static int at76_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
+static void at76_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf,
+ u32 changed)
{
struct at76_priv *priv = hw->priv;
at76_dbg(DBG_MAC80211, "%s():", __func__);
+
+ if (!(changed & BSS_CHANGED_BSSID))
+ return;
+
at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:");
mutex_lock(&priv->mtx);
@@ -1983,8 +1988,6 @@ static int at76_config_interface(struct ieee80211_hw *hw,
at76_join(priv);
mutex_unlock(&priv->mtx);
-
- return 0;
}
/* must be atomic */
@@ -2076,7 +2079,7 @@ static const struct ieee80211_ops at76_ops = {
.add_interface = at76_add_interface,
.remove_interface = at76_remove_interface,
.config = at76_config,
- .config_interface = at76_config_interface,
+ .bss_info_changed = at76_bss_info_changed,
.configure_filter = at76_configure_filter,
.start = at76_mac80211_start,
.stop = at76_mac80211_stop,
@@ -2250,6 +2253,7 @@ static int at76_init_new_device(struct at76_priv *priv,
/* mac80211 initialisation */
priv->hw->wiphy->max_scan_ssids = 1;
+ priv->hw->wiphy->max_scan_ie_len = 0;
priv->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &at76_supported_band;
priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
@@ -2311,8 +2315,7 @@ static void at76_delete_device(struct at76_priv *priv)
del_timer_sync(&ledtrig_tx_timer);
- if (priv->rx_skb)
- kfree_skb(priv->rx_skb);
+ kfree_skb(priv->rx_skb);
usb_put_dev(priv->udev);
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
new file mode 100644
index 00000000000..d26e7b48531
--- /dev/null
+++ b/drivers/net/wireless/ath/Kconfig
@@ -0,0 +1,8 @@
+config ATH_COMMON
+ tristate "Atheros Wireless Cards"
+ depends on ATH5K || ATH9K || AR9170_USB
+
+source "drivers/net/wireless/ath/ath5k/Kconfig"
+source "drivers/net/wireless/ath/ath9k/Kconfig"
+source "drivers/net/wireless/ath/ar9170/Kconfig"
+
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile
new file mode 100644
index 00000000000..4bb0132ada3
--- /dev/null
+++ b/drivers/net/wireless/ath/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_ATH5K) += ath5k/
+obj-$(CONFIG_ATH9K) += ath9k/
+obj-$(CONFIG_AR9170_USB) += ar9170/
+
+obj-$(CONFIG_ATH_COMMON) += ath.o
+ath-objs := main.o regd.o
diff --git a/drivers/net/wireless/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig
index de4281fda12..b99e3263ee6 100644
--- a/drivers/net/wireless/ar9170/Kconfig
+++ b/drivers/net/wireless/ath/ar9170/Kconfig
@@ -2,6 +2,7 @@ config AR9170_USB
tristate "Atheros AR9170 802.11n USB support"
depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
select FW_LOADER
+ select ATH_COMMON
help
This is a driver for the Atheros "otus" 802.11n USB devices.
diff --git a/drivers/net/wireless/ar9170/Makefile b/drivers/net/wireless/ath/ar9170/Makefile
index 8d91c7ee321..8d91c7ee321 100644
--- a/drivers/net/wireless/ar9170/Makefile
+++ b/drivers/net/wireless/ath/ar9170/Makefile
diff --git a/drivers/net/wireless/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index f4fb2e94aea..bb97981fb24 100644
--- a/drivers/net/wireless/ar9170/ar9170.h
+++ b/drivers/net/wireless/ath/ar9170/ar9170.h
@@ -40,7 +40,7 @@
#include <linux/completion.h>
#include <linux/spinlock.h>
-#include <net/wireless.h>
+#include <net/cfg80211.h>
#include <net/mac80211.h>
#ifdef CONFIG_AR9170_LEDS
#include <linux/leds.h>
@@ -48,6 +48,8 @@
#include "eeprom.h"
#include "hw.h"
+#include "../regd.h"
+
#define PAYLOAD_MAX (AR9170_MAX_CMD_LEN/4 - 1)
enum ar9170_bw {
@@ -58,6 +60,21 @@ enum ar9170_bw {
__AR9170_NUM_BW,
};
+static inline enum ar9170_bw nl80211_to_ar9170(enum nl80211_channel_type type)
+{
+ switch (type) {
+ case NL80211_CHAN_NO_HT:
+ case NL80211_CHAN_HT20:
+ return AR9170_BW_20;
+ case NL80211_CHAN_HT40MINUS:
+ return AR9170_BW_40_BELOW;
+ case NL80211_CHAN_HT40PLUS:
+ return AR9170_BW_40_ABOVE;
+ default:
+ BUG();
+ }
+}
+
enum ar9170_rf_init_mode {
AR9170_RFI_NONE,
AR9170_RFI_WARM,
@@ -74,6 +91,7 @@ struct ar9170_led {
struct led_classdev l;
char name[32];
unsigned int toggled;
+ bool last_state;
bool registered;
};
@@ -84,20 +102,31 @@ enum ar9170_device_state {
AR9170_STOPPED,
AR9170_IDLE,
AR9170_STARTED,
- AR9170_ASSOCIATED,
};
+struct ar9170_rxstream_mpdu_merge {
+ struct ar9170_rx_head plcp;
+ bool has_plcp;
+};
+
+#define AR9170_QUEUE_TIMEOUT 64
+#define AR9170_TX_TIMEOUT 8
+#define AR9170_JANITOR_DELAY 128
+#define AR9170_TX_INVALID_RATE 0xffffffff
+
struct ar9170 {
struct ieee80211_hw *hw;
struct mutex mutex;
enum ar9170_device_state state;
+ unsigned long bad_hw_nagger;
int (*open)(struct ar9170 *);
void (*stop)(struct ar9170 *);
- int (*tx)(struct ar9170 *, struct sk_buff *, bool, unsigned int);
+ int (*tx)(struct ar9170 *, struct sk_buff *);
int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 ,
void *, u32 , void *);
void (*callback_cmd)(struct ar9170 *, u32 , void *);
+ int (*flush)(struct ar9170 *);
/* interface mode settings */
struct ieee80211_vif *vif;
@@ -117,7 +146,8 @@ struct ar9170 {
struct work_struct filter_config_work;
u64 cur_mc_hash, want_mc_hash;
u32 cur_filter, want_filter;
- unsigned int filter_changed;
+ unsigned long filter_changed;
+ unsigned int filter_state;
bool sniffer_enabled;
/* PHY */
@@ -151,21 +181,35 @@ struct ar9170 {
/* EEPROM */
struct ar9170_eeprom eeprom;
+ struct ath_regulatory regulatory;
- /* global tx status for unregistered Stations. */
- struct sk_buff_head global_tx_status;
- struct sk_buff_head global_tx_status_waste;
- struct delayed_work tx_status_janitor;
+ /* tx queues - as seen by hw - */
+ struct sk_buff_head tx_pending[__AR9170_NUM_TXQ];
+ struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
+ struct delayed_work tx_janitor;
+
+ /* rxstream mpdu merge */
+ struct ar9170_rxstream_mpdu_merge rx_mpdu;
+ struct sk_buff *rx_failover;
+ int rx_failover_missing;
};
struct ar9170_sta_info {
- struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
};
-#define IS_STARTED(a) (a->state >= AR9170_STARTED)
-#define IS_ACCEPTING_CMD(a) (a->state >= AR9170_IDLE)
+#define AR9170_TX_FLAG_WAIT_FOR_ACK BIT(0)
+#define AR9170_TX_FLAG_NO_ACK BIT(1)
+#define AR9170_TX_FLAG_BLOCK_ACK BIT(2)
+
+struct ar9170_tx_info {
+ unsigned long timeout;
+ unsigned int flags;
+};
+
+#define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED)
+#define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE)
-#define AR9170_FILTER_CHANGED_PROMISC BIT(0)
+#define AR9170_FILTER_CHANGED_MODE BIT(0)
#define AR9170_FILTER_CHANGED_MULTICAST BIT(1)
#define AR9170_FILTER_CHANGED_FRAMEFILTER BIT(2)
@@ -174,8 +218,9 @@ void *ar9170_alloc(size_t priv_size);
int ar9170_register(struct ar9170 *ar, struct device *pdev);
void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb);
void ar9170_unregister(struct ar9170 *ar);
-void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
- bool update_statistics, u16 tx_status);
+void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb);
+void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
+int ar9170_nag_limiter(struct ar9170 *ar);
/* MAC */
int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -185,6 +230,9 @@ int ar9170_update_multicast(struct ar9170 *ar);
int ar9170_update_frame_filter(struct ar9170 *ar);
int ar9170_set_operating_mode(struct ar9170 *ar);
int ar9170_set_beacon_timers(struct ar9170 *ar);
+int ar9170_set_dyn_sifs_ack(struct ar9170 *ar);
+int ar9170_set_slot_time(struct ar9170 *ar);
+int ar9170_set_basic_rates(struct ar9170 *ar);
int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry);
int ar9170_update_beacon(struct ar9170 *ar);
void ar9170_new_beacon(struct work_struct *work);
diff --git a/drivers/net/wireless/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c
index f57a6200167..f57a6200167 100644
--- a/drivers/net/wireless/ar9170/cmd.c
+++ b/drivers/net/wireless/ath/ar9170/cmd.c
diff --git a/drivers/net/wireless/ar9170/cmd.h b/drivers/net/wireless/ath/ar9170/cmd.h
index a4f0e50e52b..a4f0e50e52b 100644
--- a/drivers/net/wireless/ar9170/cmd.h
+++ b/drivers/net/wireless/ath/ar9170/cmd.h
diff --git a/drivers/net/wireless/ar9170/eeprom.h b/drivers/net/wireless/ath/ar9170/eeprom.h
index d2c8cc83f1d..d2c8cc83f1d 100644
--- a/drivers/net/wireless/ar9170/eeprom.h
+++ b/drivers/net/wireless/ath/ar9170/eeprom.h
diff --git a/drivers/net/wireless/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h
index 53e250a4278..6cbfb2f8339 100644
--- a/drivers/net/wireless/ar9170/hw.h
+++ b/drivers/net/wireless/ath/ar9170/hw.h
@@ -207,6 +207,9 @@ enum ar9170_cmd {
#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xB44)
#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xB48)
+#define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xB9C)
+#define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xBA0)
+
#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xC00)
#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xC50)
@@ -312,7 +315,7 @@ struct ar9170_rx_head {
u8 plcp[12];
} __packed;
-struct ar9170_rx_tail {
+struct ar9170_rx_phystatus {
union {
struct {
u8 rssi_ant0, rssi_ant1, rssi_ant2,
@@ -324,6 +327,9 @@ struct ar9170_rx_tail {
u8 evm_stream0[6], evm_stream1[6];
u8 phy_err;
+} __packed;
+
+struct ar9170_rx_macstatus {
u8 SAidx, DAidx;
u8 error;
u8 status;
@@ -339,7 +345,7 @@ struct ar9170_rx_tail {
#define AR9170_RX_ENC_SOFTWARE 0x8
-static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t)
+static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t)
{
return (t->SAidx & 0xc0) >> 4 |
(t->DAidx & 0xc0) >> 6;
@@ -357,10 +363,9 @@ static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t)
#define AR9170_RX_STATUS_MPDU_MASK 0x30
#define AR9170_RX_STATUS_MPDU_SINGLE 0x00
-#define AR9170_RX_STATUS_MPDU_FIRST 0x10
-#define AR9170_RX_STATUS_MPDU_MIDDLE 0x20
-#define AR9170_RX_STATUS_MPDU_LAST 0x30
-
+#define AR9170_RX_STATUS_MPDU_FIRST 0x20
+#define AR9170_RX_STATUS_MPDU_MIDDLE 0x30
+#define AR9170_RX_STATUS_MPDU_LAST 0x10
#define AR9170_RX_ERROR_RXTO 0x01
#define AR9170_RX_ERROR_OVERRUN 0x02
@@ -369,9 +374,9 @@ static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t)
#define AR9170_RX_ERROR_WRONG_RA 0x10
#define AR9170_RX_ERROR_PLCP 0x20
#define AR9170_RX_ERROR_MMIC 0x40
+#define AR9170_RX_ERROR_FATAL 0x80
struct ar9170_cmd_tx_status {
- __le16 unkn;
u8 dst[ETH_ALEN];
__le32 rate;
__le16 status;
@@ -389,6 +394,7 @@ struct ar9170_cmd_ba_failed_count {
struct ar9170_cmd_response {
u8 flag;
u8 type;
+ __le16 padding;
union {
struct ar9170_cmd_tx_status tx_status;
@@ -414,4 +420,7 @@ enum ar9170_txq {
__AR9170_NUM_TXQ,
};
+#define AR9170_TXQ_DEPTH 32
+#define AR9170_TX_MAX_PENDING 128
+
#endif /* __AR9170_HW_H */
diff --git a/drivers/net/wireless/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c
index 341cead7f60..63fda6cd210 100644
--- a/drivers/net/wireless/ar9170/led.c
+++ b/drivers/net/wireless/ath/ar9170/led.c
@@ -74,7 +74,7 @@ static void ar9170_update_leds(struct work_struct *work)
mutex_lock(&ar->mutex);
for (i = 0; i < AR9170_NUM_LEDS; i++)
- if (ar->leds[i].toggled) {
+ if (ar->leds[i].registered && ar->leds[i].toggled) {
led_val |= 1 << i;
tmp = 70 + 200 / (ar->leds[i].toggled);
@@ -101,9 +101,15 @@ static void ar9170_led_brightness_set(struct led_classdev *led,
struct ar9170_led *arl = container_of(led, struct ar9170_led, l);
struct ar9170 *ar = arl->ar;
- arl->toggled++;
+ if (unlikely(!arl->registered))
+ return ;
+
+ if (arl->last_state != !!brightness) {
+ arl->toggled++;
+ arl->last_state = !!brightness;
+ }
- if (likely(IS_ACCEPTING_CMD(ar) && brightness))
+ if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled))
queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10);
}
@@ -136,13 +142,14 @@ void ar9170_unregister_leds(struct ar9170 *ar)
{
int i;
- cancel_delayed_work_sync(&ar->led_work);
-
for (i = 0; i < AR9170_NUM_LEDS; i++)
if (ar->leds[i].registered) {
led_classdev_unregister(&ar->leds[i].l);
ar->leds[i].registered = false;
+ ar->leds[i].toggled = 0;
}
+
+ cancel_delayed_work_sync(&ar->led_work);
}
int ar9170_register_leds(struct ar9170 *ar)
diff --git a/drivers/net/wireless/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c
index c8fa3073169..d9f1f46de18 100644
--- a/drivers/net/wireless/ar9170/mac.c
+++ b/drivers/net/wireless/ath/ar9170/mac.c
@@ -38,6 +38,55 @@
#include "ar9170.h"
#include "cmd.h"
+int ar9170_set_dyn_sifs_ack(struct ar9170 *ar)
+{
+ u32 val;
+
+ if (conf_is_ht40(&ar->hw->conf))
+ val = 0x010a;
+ else {
+ if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+ val = 0x105;
+ else
+ val = 0x104;
+ }
+
+ return ar9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
+}
+
+int ar9170_set_slot_time(struct ar9170 *ar)
+{
+ u32 slottime = 20;
+
+ if (!ar->vif)
+ return 0;
+
+ if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
+ ar->vif->bss_conf.use_short_slot)
+ slottime = 9;
+
+ return ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, slottime << 10);
+}
+
+int ar9170_set_basic_rates(struct ar9170 *ar)
+{
+ u8 cck, ofdm;
+
+ if (!ar->vif)
+ return 0;
+
+ ofdm = ar->vif->bss_conf.basic_rates >> 4;
+
+ /* FIXME: is still necessary? */
+ if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
+ cck = 0;
+ else
+ cck = ar->vif->bss_conf.basic_rates & 0xf;
+
+ return ar9170_write_reg(ar, AR9170_MAC_REG_BASIC_RATE,
+ ofdm << 8 | cck);
+}
+
int ar9170_set_qos(struct ar9170 *ar)
{
ar9170_regwrite_begin(ar);
@@ -72,6 +121,24 @@ int ar9170_set_qos(struct ar9170 *ar)
return ar9170_regwrite_result();
}
+static int ar9170_set_ampdu_density(struct ar9170 *ar, u8 mpdudensity)
+{
+ u32 val;
+
+ /* don't allow AMPDU density > 8us */
+ if (mpdudensity > 6)
+ return -EINVAL;
+
+ /* Watch out! Otus uses slightly different density values. */
+ val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0);
+
+ ar9170_regwrite_begin(ar);
+ ar9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, val);
+ ar9170_regwrite_finish();
+
+ return ar9170_regwrite_result();
+}
+
int ar9170_init_mac(struct ar9170 *ar)
{
ar9170_regwrite_begin(ar);
@@ -265,9 +332,9 @@ int ar9170_set_operating_mode(struct ar9170 *ar)
case NL80211_IFTYPE_ADHOC:
pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS;
break;
-/* case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_AP:
pm_mode |= AR9170_MAC_REG_POWERMGT_AP;
- break;*/
+ break;
case NL80211_IFTYPE_WDS:
pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS;
break;
@@ -296,6 +363,11 @@ int ar9170_set_operating_mode(struct ar9170 *ar)
if (err)
return err;
+ /* set AMPDU density to 8us. */
+ err = ar9170_set_ampdu_density(ar, 6);
+ if (err)
+ return err;
+
ar9170_regwrite_begin(ar);
ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode);
@@ -316,9 +388,9 @@ int ar9170_set_beacon_timers(struct ar9170 *ar)
u32 v = 0;
u32 pretbtt = 0;
- v |= ar->hw->conf.beacon_int;
-
if (ar->vif) {
+ v |= ar->vif->bss_conf.beacon_int;
+
switch (ar->vif->type) {
case NL80211_IFTYPE_MESH_POINT:
case NL80211_IFTYPE_ADHOC:
@@ -326,7 +398,7 @@ int ar9170_set_beacon_timers(struct ar9170 *ar)
break;
case NL80211_IFTYPE_AP:
v |= BIT(24);
- pretbtt = (ar->hw->conf.beacon_int - 6) << 16;
+ pretbtt = (ar->vif->bss_conf.beacon_int - 6) << 16;
break;
default:
break;
@@ -375,10 +447,10 @@ int ar9170_update_beacon(struct ar9170 *ar)
/* XXX: use skb->cb info */
if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
- ((skb->len + 4) << (3+16)) + 0x0400);
+ ((skb->len + 4) << (3 + 16)) + 0x0400);
else
ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
- ((skb->len + 4) << (3+16)) + 0x0400);
+ ((skb->len + 4) << 16) + 0x001b);
ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
diff --git a/drivers/net/wireless/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 5996ff9f7f4..9d38cf60a0d 100644
--- a/drivers/net/wireless/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -142,73 +142,153 @@ static struct ieee80211_channel ar9170_5ghz_chantable[] = {
};
#undef CHAN
+#define AR9170_HT_CAP \
+{ \
+ .ht_supported = true, \
+ .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
+ IEEE80211_HT_CAP_SGI_40 | \
+ IEEE80211_HT_CAP_DSSSCCK40 | \
+ IEEE80211_HT_CAP_SM_PS, \
+ .ampdu_factor = 3, \
+ .ampdu_density = 6, \
+ .mcs = { \
+ .rx_mask = { 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, }, \
+ }, \
+}
+
static struct ieee80211_supported_band ar9170_band_2GHz = {
.channels = ar9170_2ghz_chantable,
.n_channels = ARRAY_SIZE(ar9170_2ghz_chantable),
.bitrates = ar9170_g_ratetable,
.n_bitrates = ar9170_g_ratetable_size,
+ .ht_cap = AR9170_HT_CAP,
};
-#ifdef AR9170_QUEUE_DEBUG
-/*
- * In case some wants works with AR9170's crazy tx_status queueing techniques.
- * He might need this rather useful probing function.
- *
- * NOTE: caller must hold the queue's spinlock!
- */
+static struct ieee80211_supported_band ar9170_band_5GHz = {
+ .channels = ar9170_5ghz_chantable,
+ .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
+ .bitrates = ar9170_a_ratetable,
+ .n_bitrates = ar9170_a_ratetable_size,
+ .ht_cap = AR9170_HT_CAP,
+};
+static void ar9170_tx(struct ar9170 *ar);
+
+#ifdef AR9170_QUEUE_DEBUG
static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
{
struct ar9170_tx_control *txc = (void *) skb->data;
- struct ieee80211_hdr *hdr = (void *)txc->frame_data;
+ struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
+ struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
+ struct ieee80211_hdr *hdr = (void *) txc->frame_data;
- printk(KERN_DEBUG "%s: => FRAME [skb:%p, queue:%d, DA:[%pM] "
- "mac_control:%04x, phy_control:%08x]\n",
+ printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x "
+ "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
- ieee80211_get_DA(hdr), le16_to_cpu(txc->mac_control),
- le32_to_cpu(txc->phy_control));
+ ieee80211_get_DA(hdr), arinfo->flags,
+ le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
+ jiffies_to_msecs(arinfo->timeout - jiffies));
}
-static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar,
- struct sk_buff_head *queue)
+static void __ar9170_dump_txqueue(struct ar9170 *ar,
+ struct sk_buff_head *queue)
{
struct sk_buff *skb;
int i = 0;
printk(KERN_DEBUG "---[ cut here ]---\n");
- printk(KERN_DEBUG "%s: %d entries in tx_status queue.\n",
+ printk(KERN_DEBUG "%s: %d entries in queue.\n",
wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
skb_queue_walk(queue, skb) {
- struct ar9170_tx_control *txc = (void *) skb->data;
- struct ieee80211_hdr *hdr = (void *)txc->frame_data;
-
- printk(KERN_DEBUG "index:%d => \n", i);
+ printk(KERN_DEBUG "index:%d => \n", i++);
ar9170_print_txheader(ar, skb);
}
+ if (i != skb_queue_len(queue))
+ printk(KERN_DEBUG "WARNING: queue frame counter "
+ "mismatch %d != %d\n", skb_queue_len(queue), i);
printk(KERN_DEBUG "---[ end ]---\n");
}
-#endif /* AR9170_QUEUE_DEBUG */
-static struct ieee80211_supported_band ar9170_band_5GHz = {
- .channels = ar9170_5ghz_chantable,
- .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
- .bitrates = ar9170_a_ratetable,
- .n_bitrates = ar9170_a_ratetable_size,
-};
+static void ar9170_dump_txqueue(struct ar9170 *ar,
+ struct sk_buff_head *queue)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&queue->lock, flags);
+ __ar9170_dump_txqueue(ar, queue);
+ spin_unlock_irqrestore(&queue->lock, flags);
+}
-void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
- bool valid_status, u16 tx_status)
+static void __ar9170_dump_txstats(struct ar9170 *ar)
+{
+ int i;
+
+ printk(KERN_DEBUG "%s: QoS queue stats\n",
+ wiphy_name(ar->hw->wiphy));
+
+ for (i = 0; i < __AR9170_NUM_TXQ; i++)
+ printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d\n",
+ wiphy_name(ar->hw->wiphy), i, ar->tx_stats[i].limit,
+ ar->tx_stats[i].len, skb_queue_len(&ar->tx_status[i]));
+}
+
+static void ar9170_dump_txstats(struct ar9170 *ar)
{
- struct ieee80211_tx_info *txinfo;
- unsigned int retries = 0, queue = skb_get_queue_mapping(skb);
unsigned long flags;
spin_lock_irqsave(&ar->tx_stats_lock, flags);
- ar->tx_stats[queue].len--;
- if (ieee80211_queue_stopped(ar->hw, queue))
- ieee80211_wake_queue(ar->hw, queue);
+ __ar9170_dump_txstats(ar);
spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+}
+#endif /* AR9170_QUEUE_DEBUG */
+
+/* caller must guarantee exclusive access for _bin_ queue. */
+static void ar9170_recycle_expired(struct ar9170 *ar,
+ struct sk_buff_head *queue,
+ struct sk_buff_head *bin)
+{
+ struct sk_buff *skb, *old = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&queue->lock, flags);
+ while ((skb = skb_peek(queue))) {
+ struct ieee80211_tx_info *txinfo;
+ struct ar9170_tx_info *arinfo;
+
+ txinfo = IEEE80211_SKB_CB(skb);
+ arinfo = (void *) txinfo->rate_driver_data;
+
+ if (time_is_before_jiffies(arinfo->timeout)) {
+#ifdef AR9170_QUEUE_DEBUG
+ printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => "
+ "recycle \n", wiphy_name(ar->hw->wiphy),
+ jiffies, arinfo->timeout);
+ ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+ __skb_unlink(skb, queue);
+ __skb_queue_tail(bin, skb);
+ } else {
+ break;
+ }
+
+ if (unlikely(old == skb)) {
+ /* bail out - queue is shot. */
+
+ WARN_ON(1);
+ break;
+ }
+ old = skb;
+ }
+ spin_unlock_irqrestore(&queue->lock, flags);
+}
+
+static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
+ u16 tx_status)
+{
+ struct ieee80211_tx_info *txinfo;
+ unsigned int retries = 0;
txinfo = IEEE80211_SKB_CB(skb);
ieee80211_tx_info_clear_status(txinfo);
@@ -230,45 +310,61 @@ void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
break;
}
- if (valid_status)
- txinfo->status.rates[0].count = retries + 1;
-
+ txinfo->status.rates[0].count = retries + 1;
skb_pull(skb, sizeof(struct ar9170_tx_control));
ieee80211_tx_status_irqsafe(ar->hw, skb);
}
-static struct sk_buff *ar9170_find_skb_in_queue(struct ar9170 *ar,
- const u8 *mac,
- const u32 queue,
- struct sk_buff_head *q)
+void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data;
+ unsigned int queue = skb_get_queue_mapping(skb);
unsigned long flags;
- struct sk_buff *skb;
- spin_lock_irqsave(&q->lock, flags);
- skb_queue_walk(q, skb) {
- struct ar9170_tx_control *txc = (void *) skb->data;
- struct ieee80211_hdr *hdr = (void *) txc->frame_data;
- u32 txc_queue = (le32_to_cpu(txc->phy_control) &
- AR9170_TX_PHY_QOS_MASK) >>
- AR9170_TX_PHY_QOS_SHIFT;
+ spin_lock_irqsave(&ar->tx_stats_lock, flags);
+ ar->tx_stats[queue].len--;
- if ((queue != txc_queue) ||
- (compare_ether_addr(ieee80211_get_DA(hdr), mac)))
- continue;
+ if (skb_queue_empty(&ar->tx_pending[queue])) {
+#ifdef AR9170_QUEUE_STOP_DEBUG
+ printk(KERN_DEBUG "%s: wake queue %d\n",
+ wiphy_name(ar->hw->wiphy), queue);
+ __ar9170_dump_txstats(ar);
+#endif /* AR9170_QUEUE_STOP_DEBUG */
+ ieee80211_wake_queue(ar->hw, queue);
+ }
+ spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
- __skb_unlink(skb, q);
- spin_unlock_irqrestore(&q->lock, flags);
- return skb;
+ if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) {
+ dev_kfree_skb_any(skb);
+ } else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) {
+ arinfo->timeout = jiffies +
+ msecs_to_jiffies(AR9170_TX_TIMEOUT);
+
+ skb_queue_tail(&ar->tx_status[queue], skb);
+ } else if (arinfo->flags & AR9170_TX_FLAG_NO_ACK) {
+ ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED);
+ } else {
+#ifdef AR9170_QUEUE_DEBUG
+ printk(KERN_DEBUG "%s: unsupported frame flags!\n",
+ wiphy_name(ar->hw->wiphy));
+ ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+ dev_kfree_skb_any(skb);
+ }
+
+ if (!ar->tx_stats[queue].len &&
+ !skb_queue_empty(&ar->tx_pending[queue])) {
+ ar9170_tx(ar);
}
- spin_unlock_irqrestore(&q->lock, flags);
- return NULL;
}
-static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac,
- const u32 queue)
+static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
+ const u8 *mac,
+ struct sk_buff_head *queue,
+ const u32 rate)
{
- struct ieee80211_sta *sta;
+ unsigned long flags;
struct sk_buff *skb;
/*
@@ -279,85 +375,94 @@ static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac,
* the firmware provided (-> destination MAC, and phy_control) -
* and hope that we picked the right one...
*/
- rcu_read_lock();
- sta = ieee80211_find_sta(ar->hw, mac);
-
- if (likely(sta)) {
- struct ar9170_sta_info *sta_priv = (void *) sta->drv_priv;
- skb = skb_dequeue(&sta_priv->tx_status[queue]);
- rcu_read_unlock();
- if (likely(skb))
- return skb;
- } else
- rcu_read_unlock();
-
- /* scan the waste queue for candidates */
- skb = ar9170_find_skb_in_queue(ar, mac, queue,
- &ar->global_tx_status_waste);
- if (!skb) {
- /* so it still _must_ be in the global list. */
- skb = ar9170_find_skb_in_queue(ar, mac, queue,
- &ar->global_tx_status);
- }
+ spin_lock_irqsave(&queue->lock, flags);
+ skb_queue_walk(queue, skb) {
+ struct ar9170_tx_control *txc = (void *) skb->data;
+ struct ieee80211_hdr *hdr = (void *) txc->frame_data;
+ u32 r;
+
+ if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) {
+#ifdef AR9170_QUEUE_DEBUG
+ printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n",
+ wiphy_name(ar->hw->wiphy), mac,
+ ieee80211_get_DA(hdr));
+ ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+ continue;
+ }
+
+ r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >>
+ AR9170_TX_PHY_MCS_SHIFT;
+
+ if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) {
#ifdef AR9170_QUEUE_DEBUG
- if (unlikely((!skb) && net_ratelimit())) {
- printk(KERN_ERR "%s: ESS:[%pM] does not have any "
- "outstanding frames in this queue (%d).\n",
- wiphy_name(ar->hw->wiphy), mac, queue);
+ printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n",
+ wiphy_name(ar->hw->wiphy), rate, r);
+ ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+ continue;
+ }
+
+ __skb_unlink(skb, queue);
+ spin_unlock_irqrestore(&queue->lock, flags);
+ return skb;
}
+
+#ifdef AR9170_QUEUE_DEBUG
+ printk(KERN_ERR "%s: ESS:[%pM] does not have any "
+ "outstanding frames in queue.\n",
+ wiphy_name(ar->hw->wiphy), mac);
+ __ar9170_dump_txqueue(ar, queue);
#endif /* AR9170_QUEUE_DEBUG */
- return skb;
+ spin_unlock_irqrestore(&queue->lock, flags);
+
+ return NULL;
}
/*
- * This worker tries to keep the global tx_status queue empty.
- * So we can guarantee that incoming tx_status reports for
- * unregistered stations are always synced with the actual
- * frame - which we think - belongs to.
+ * This worker tries to keeps an maintain tx_status queues.
+ * So we can guarantee that incoming tx_status reports are
+ * actually for a pending frame.
*/
-static void ar9170_tx_status_janitor(struct work_struct *work)
+static void ar9170_tx_janitor(struct work_struct *work)
{
struct ar9170 *ar = container_of(work, struct ar9170,
- tx_status_janitor.work);
- struct sk_buff *skb;
+ tx_janitor.work);
+ struct sk_buff_head waste;
+ unsigned int i;
+ bool resched = false;
if (unlikely(!IS_STARTED(ar)))
return ;
- mutex_lock(&ar->mutex);
- /* recycle the garbage back to mac80211... one by one. */
- while ((skb = skb_dequeue(&ar->global_tx_status_waste))) {
+ skb_queue_head_init(&waste);
+
+ for (i = 0; i < __AR9170_NUM_TXQ; i++) {
#ifdef AR9170_QUEUE_DEBUG
- printk(KERN_DEBUG "%s: dispose queued frame =>\n",
- wiphy_name(ar->hw->wiphy));
- ar9170_print_txheader(ar, skb);
+ printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n",
+ wiphy_name(ar->hw->wiphy), i);
+ ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
+ ar9170_dump_txqueue(ar, &ar->tx_status[i]);
#endif /* AR9170_QUEUE_DEBUG */
- ar9170_handle_tx_status(ar, skb, false,
- AR9170_TX_STATUS_FAILED);
- }
- while ((skb = skb_dequeue(&ar->global_tx_status))) {
-#ifdef AR9170_QUEUE_DEBUG
- printk(KERN_DEBUG "%s: moving frame into waste queue =>\n",
- wiphy_name(ar->hw->wiphy));
+ ar9170_recycle_expired(ar, &ar->tx_status[i], &waste);
+ ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste);
+ skb_queue_purge(&waste);
- ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
- skb_queue_tail(&ar->global_tx_status_waste, skb);
+ if (!skb_queue_empty(&ar->tx_status[i]) ||
+ !skb_queue_empty(&ar->tx_pending[i]))
+ resched = true;
}
- /* recall the janitor in 100ms - if there's garbage in the can. */
- if (skb_queue_len(&ar->global_tx_status_waste) > 0)
- queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
- msecs_to_jiffies(100));
-
- mutex_unlock(&ar->mutex);
+ if (resched)
+ queue_delayed_work(ar->hw->workqueue,
+ &ar->tx_janitor,
+ msecs_to_jiffies(AR9170_JANITOR_DELAY));
}
-static void ar9170_handle_command_response(struct ar9170 *ar,
- void *buf, u32 len)
+void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
{
struct ar9170_cmd_response *cmd = (void *) buf;
@@ -381,15 +486,21 @@ static void ar9170_handle_command_response(struct ar9170 *ar,
*/
struct sk_buff *skb;
- u32 queue = (le32_to_cpu(cmd->tx_status.rate) &
- AR9170_TX_PHY_QOS_MASK) >> AR9170_TX_PHY_QOS_SHIFT;
+ u32 phy = le32_to_cpu(cmd->tx_status.rate);
+ u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >>
+ AR9170_TX_PHY_QOS_SHIFT;
+#ifdef AR9170_QUEUE_DEBUG
+ printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n",
+ wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q);
+#endif /* AR9170_QUEUE_DEBUG */
- skb = ar9170_find_queued_skb(ar, cmd->tx_status.dst, queue);
+ skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst,
+ &ar->tx_status[q],
+ AR9170_TX_INVALID_RATE);
if (unlikely(!skb))
return ;
- ar9170_handle_tx_status(ar, skb, true,
- le16_to_cpu(cmd->tx_status.status));
+ ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status));
break;
}
@@ -429,6 +540,38 @@ static void ar9170_handle_command_response(struct ar9170 *ar,
/* retransmission issue / SIFS/EIFS collision ?! */
break;
+ /* firmware debug */
+ case 0xca:
+ printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, (char *)buf + 4);
+ break;
+ case 0xcb:
+ len -= 4;
+
+ switch (len) {
+ case 1:
+ printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n",
+ *((char *)buf + 4));
+ break;
+ case 2:
+ printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n",
+ le16_to_cpup((__le16 *)((char *)buf + 4)));
+ break;
+ case 4:
+ printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n",
+ le32_to_cpup((__le32 *)((char *)buf + 4)));
+ break;
+ case 8:
+ printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n",
+ (unsigned long)le64_to_cpup(
+ (__le64 *)((char *)buf + 4)));
+ break;
+ }
+ break;
+ case 0xcc:
+ print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE,
+ (char *)buf + 4, len - 4);
+ break;
+
default:
printk(KERN_INFO "received unhandled event %x\n", cmd->type);
print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
@@ -436,214 +579,430 @@ static void ar9170_handle_command_response(struct ar9170 *ar,
}
}
-/*
- * If the frame alignment is right (or the kernel has
- * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
- * is only a single MPDU in the USB frame, then we can
- * submit to mac80211 the SKB directly. However, since
- * there may be multiple packets in one SKB in stream
- * mode, and we need to observe the proper ordering,
- * this is non-trivial.
- */
-static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
+static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar)
{
- struct sk_buff *skb;
- struct ar9170_rx_head *head = (void *)buf;
- struct ar9170_rx_tail *tail;
- struct ieee80211_rx_status status;
- int mpdu_len, i;
- u8 error, antennas = 0, decrypt;
- __le16 fc;
- int reserved;
+ memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head));
+ ar->rx_mpdu.has_plcp = false;
+}
- if (unlikely(!IS_STARTED(ar)))
- return ;
+int ar9170_nag_limiter(struct ar9170 *ar)
+{
+ bool print_message;
+
+ /*
+ * we expect all sorts of errors in promiscuous mode.
+ * don't bother with it, it's OK!
+ */
+ if (ar->sniffer_enabled)
+ return false;
+
+ /*
+ * only go for frequent errors! The hardware tends to
+ * do some stupid thing once in a while under load, in
+ * noisy environments or just for fun!
+ */
+ if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit())
+ print_message = true;
+ else
+ print_message = false;
+
+ /* reset threshold for "once in a while" */
+ ar->bad_hw_nagger = jiffies + HZ / 4;
+ return print_message;
+}
+
+static int ar9170_rx_mac_status(struct ar9170 *ar,
+ struct ar9170_rx_head *head,
+ struct ar9170_rx_macstatus *mac,
+ struct ieee80211_rx_status *status)
+{
+ u8 error, decrypt;
- /* Received MPDU */
- mpdu_len = len;
- mpdu_len -= sizeof(struct ar9170_rx_head);
- mpdu_len -= sizeof(struct ar9170_rx_tail);
BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
- BUILD_BUG_ON(sizeof(struct ar9170_rx_tail) != 24);
+ BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
- if (mpdu_len <= FCS_LEN)
- return;
+ error = mac->error;
+ if (error & AR9170_RX_ERROR_MMIC) {
+ status->flag |= RX_FLAG_MMIC_ERROR;
+ error &= ~AR9170_RX_ERROR_MMIC;
+ }
- tail = (void *)(buf + sizeof(struct ar9170_rx_head) + mpdu_len);
+ if (error & AR9170_RX_ERROR_PLCP) {
+ status->flag |= RX_FLAG_FAILED_PLCP_CRC;
+ error &= ~AR9170_RX_ERROR_PLCP;
- for (i = 0; i < 3; i++)
- if (tail->rssi[i] != 0x80)
- antennas |= BIT(i);
+ if (!(ar->filter_state & FIF_PLCPFAIL))
+ return -EINVAL;
+ }
- /* post-process RSSI */
- for (i = 0; i < 7; i++)
- if (tail->rssi[i] & 0x80)
- tail->rssi[i] = ((tail->rssi[i] & 0x7f) + 1) & 0x7f;
+ if (error & AR9170_RX_ERROR_FCS) {
+ status->flag |= RX_FLAG_FAILED_FCS_CRC;
+ error &= ~AR9170_RX_ERROR_FCS;
- memset(&status, 0, sizeof(status));
+ if (!(ar->filter_state & FIF_FCSFAIL))
+ return -EINVAL;
+ }
+
+ decrypt = ar9170_get_decrypt_type(mac);
+ if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
+ decrypt != AR9170_ENC_ALG_NONE)
+ status->flag |= RX_FLAG_DECRYPTED;
+
+ /* ignore wrong RA errors */
+ error &= ~AR9170_RX_ERROR_WRONG_RA;
+
+ if (error & AR9170_RX_ERROR_DECRYPT) {
+ error &= ~AR9170_RX_ERROR_DECRYPT;
+ /*
+ * Rx decryption is done in place,
+ * the original data is lost anyway.
+ */
+
+ return -EINVAL;
+ }
+
+ /* drop any other error frames */
+ if (unlikely(error)) {
+ /* TODO: update netdevice's RX dropped/errors statistics */
+
+ if (ar9170_nag_limiter(ar))
+ printk(KERN_DEBUG "%s: received frame with "
+ "suspicious error code (%#x).\n",
+ wiphy_name(ar->hw->wiphy), error);
+
+ return -EINVAL;
+ }
- status.band = ar->channel->band;
- status.freq = ar->channel->center_freq;
- status.signal = ar->noise[0] + tail->rssi_combined;
- status.noise = ar->noise[0];
- status.antenna = antennas;
+ status->band = ar->channel->band;
+ status->freq = ar->channel->center_freq;
- switch (tail->status & AR9170_RX_STATUS_MODULATION_MASK) {
+ switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) {
case AR9170_RX_STATUS_MODULATION_CCK:
- if (tail->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
- status.flag |= RX_FLAG_SHORTPRE;
+ if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
+ status->flag |= RX_FLAG_SHORTPRE;
switch (head->plcp[0]) {
case 0x0a:
- status.rate_idx = 0;
+ status->rate_idx = 0;
break;
case 0x14:
- status.rate_idx = 1;
+ status->rate_idx = 1;
break;
case 0x37:
- status.rate_idx = 2;
+ status->rate_idx = 2;
break;
case 0x6e:
- status.rate_idx = 3;
+ status->rate_idx = 3;
break;
default:
- if ((!ar->sniffer_enabled) && (net_ratelimit()))
+ if (ar9170_nag_limiter(ar))
printk(KERN_ERR "%s: invalid plcp cck rate "
"(%x).\n", wiphy_name(ar->hw->wiphy),
head->plcp[0]);
- return;
+ return -EINVAL;
}
break;
+
case AR9170_RX_STATUS_MODULATION_OFDM:
- switch (head->plcp[0] & 0xF) {
- case 0xB:
- status.rate_idx = 0;
+ switch (head->plcp[0] & 0xf) {
+ case 0xb:
+ status->rate_idx = 0;
break;
- case 0xF:
- status.rate_idx = 1;
+ case 0xf:
+ status->rate_idx = 1;
break;
- case 0xA:
- status.rate_idx = 2;
+ case 0xa:
+ status->rate_idx = 2;
break;
- case 0xE:
- status.rate_idx = 3;
+ case 0xe:
+ status->rate_idx = 3;
break;
case 0x9:
- status.rate_idx = 4;
+ status->rate_idx = 4;
break;
- case 0xD:
- status.rate_idx = 5;
+ case 0xd:
+ status->rate_idx = 5;
break;
case 0x8:
- status.rate_idx = 6;
+ status->rate_idx = 6;
break;
- case 0xC:
- status.rate_idx = 7;
+ case 0xc:
+ status->rate_idx = 7;
break;
default:
- if ((!ar->sniffer_enabled) && (net_ratelimit()))
+ if (ar9170_nag_limiter(ar))
printk(KERN_ERR "%s: invalid plcp ofdm rate "
"(%x).\n", wiphy_name(ar->hw->wiphy),
head->plcp[0]);
- return;
+ return -EINVAL;
}
- if (status.band == IEEE80211_BAND_2GHZ)
- status.rate_idx += 4;
+ if (status->band == IEEE80211_BAND_2GHZ)
+ status->rate_idx += 4;
break;
+
case AR9170_RX_STATUS_MODULATION_HT:
+ if (head->plcp[3] & 0x80)
+ status->flag |= RX_FLAG_40MHZ;
+ if (head->plcp[6] & 0x80)
+ status->flag |= RX_FLAG_SHORT_GI;
+
+ status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f);
+ status->flag |= RX_FLAG_HT;
+ break;
+
case AR9170_RX_STATUS_MODULATION_DUPOFDM:
/* XXX */
-
- if (net_ratelimit())
+ if (ar9170_nag_limiter(ar))
printk(KERN_ERR "%s: invalid modulation\n",
wiphy_name(ar->hw->wiphy));
- return;
+ return -EINVAL;
}
- error = tail->error;
+ return 0;
+}
+
+static void ar9170_rx_phy_status(struct ar9170 *ar,
+ struct ar9170_rx_phystatus *phy,
+ struct ieee80211_rx_status *status)
+{
+ int i;
- if (error & AR9170_RX_ERROR_MMIC) {
- status.flag |= RX_FLAG_MMIC_ERROR;
- error &= ~AR9170_RX_ERROR_MMIC;
- }
+ BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20);
- if (error & AR9170_RX_ERROR_PLCP) {
- status.flag |= RX_FLAG_FAILED_PLCP_CRC;
- error &= ~AR9170_RX_ERROR_PLCP;
+ for (i = 0; i < 3; i++)
+ if (phy->rssi[i] != 0x80)
+ status->antenna |= BIT(i);
+
+ /* post-process RSSI */
+ for (i = 0; i < 7; i++)
+ if (phy->rssi[i] & 0x80)
+ phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f;
+
+ /* TODO: we could do something with phy_errors */
+ status->signal = ar->noise[0] + phy->rssi_combined;
+ status->noise = ar->noise[0];
+}
+
+static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len)
+{
+ struct sk_buff *skb;
+ int reserved = 0;
+ struct ieee80211_hdr *hdr = (void *) buf;
+
+ if (ieee80211_is_data_qos(hdr->frame_control)) {
+ u8 *qc = ieee80211_get_qos_ctl(hdr);
+ reserved += NET_IP_ALIGN;
+
+ if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
+ reserved += NET_IP_ALIGN;
}
- if (error & AR9170_RX_ERROR_FCS) {
- status.flag |= RX_FLAG_FAILED_FCS_CRC;
- error &= ~AR9170_RX_ERROR_FCS;
+ 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);
}
- decrypt = ar9170_get_decrypt_type(tail);
- if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
- decrypt != AR9170_ENC_ALG_NONE)
- status.flag |= RX_FLAG_DECRYPTED;
+ return skb;
+}
- /* ignore wrong RA errors */
- error &= ~AR9170_RX_ERROR_WRONG_RA;
+/*
+ * 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.
+ */
- if (error & AR9170_RX_ERROR_DECRYPT) {
- error &= ~AR9170_RX_ERROR_DECRYPT;
+static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
+{
+ struct ar9170_rx_head *head;
+ struct ar9170_rx_macstatus *mac;
+ struct ar9170_rx_phystatus *phy = NULL;
+ struct ieee80211_rx_status status;
+ struct sk_buff *skb;
+ int mpdu_len;
+
+ if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac))))
+ return ;
+
+ /* Received MPDU */
+ mpdu_len = len - sizeof(*mac);
+
+ mac = (void *)(buf + mpdu_len);
+ if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
+ /* this frame is too damaged and can't be used - drop it */
- /*
- * Rx decryption is done in place,
- * the original data is lost anyway.
- */
return ;
}
- /* drop any other error frames */
- if ((error) && (net_ratelimit())) {
- printk(KERN_DEBUG "%s: errors: %#x\n",
- wiphy_name(ar->hw->wiphy), error);
- return;
+ switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) {
+ case AR9170_RX_STATUS_MPDU_FIRST:
+ /* first mpdu packet has the plcp header */
+ if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
+ head = (void *) buf;
+ memcpy(&ar->rx_mpdu.plcp, (void *) buf,
+ sizeof(struct ar9170_rx_head));
+
+ mpdu_len -= sizeof(struct ar9170_rx_head);
+ buf += sizeof(struct ar9170_rx_head);
+ ar->rx_mpdu.has_plcp = true;
+ } else {
+ if (ar9170_nag_limiter(ar))
+ printk(KERN_ERR "%s: plcp info is clipped.\n",
+ wiphy_name(ar->hw->wiphy));
+ return ;
+ }
+ break;
+
+ case AR9170_RX_STATUS_MPDU_LAST:
+ /* last mpdu has a extra tail with phy status information */
+
+ if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
+ mpdu_len -= sizeof(struct ar9170_rx_phystatus);
+ phy = (void *)(buf + mpdu_len);
+ } else {
+ if (ar9170_nag_limiter(ar))
+ printk(KERN_ERR "%s: frame tail is clipped.\n",
+ wiphy_name(ar->hw->wiphy));
+ return ;
+ }
+
+ case AR9170_RX_STATUS_MPDU_MIDDLE:
+ /* middle mpdus are just data */
+ if (unlikely(!ar->rx_mpdu.has_plcp)) {
+ if (!ar9170_nag_limiter(ar))
+ return ;
+
+ printk(KERN_ERR "%s: rx stream did not start "
+ "with a first_mpdu frame tag.\n",
+ wiphy_name(ar->hw->wiphy));
+
+ return ;
+ }
+
+ head = &ar->rx_mpdu.plcp;
+ break;
+
+ case AR9170_RX_STATUS_MPDU_SINGLE:
+ /* single mpdu - has plcp (head) and phy status (tail) */
+ head = (void *) buf;
+
+ mpdu_len -= sizeof(struct ar9170_rx_head);
+ mpdu_len -= sizeof(struct ar9170_rx_phystatus);
+
+ buf += sizeof(struct ar9170_rx_head);
+ phy = (void *)(buf + mpdu_len);
+ break;
+
+ default:
+ BUG_ON(1);
+ break;
}
- buf += sizeof(struct ar9170_rx_head);
- fc = *(__le16 *)buf;
+ if (unlikely(mpdu_len < FCS_LEN))
+ return ;
- if (ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc))
- reserved = 32 + 2;
- else
- reserved = 32;
+ memset(&status, 0, sizeof(status));
+ if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status)))
+ return ;
- skb = dev_alloc_skb(mpdu_len + reserved);
- if (!skb)
- return;
+ if (phy)
+ ar9170_rx_phy_status(ar, phy, &status);
- skb_reserve(skb, reserved);
- memcpy(skb_put(skb, mpdu_len), buf, mpdu_len);
- ieee80211_rx_irqsafe(ar->hw, skb, &status);
+ skb = ar9170_rx_copy_data(buf, mpdu_len);
+ if (likely(skb))
+ ieee80211_rx_irqsafe(ar->hw, skb, &status);
}
void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
{
- unsigned int i, tlen, resplen;
+ unsigned int i, tlen, resplen, wlen = 0, clen = 0;
u8 *tbuf, *respbuf;
tbuf = skb->data;
tlen = skb->len;
while (tlen >= 4) {
- int clen = tbuf[1] << 8 | tbuf[0];
- int wlen = (clen + 3) & ~3;
+ clen = tbuf[1] << 8 | tbuf[0];
+ wlen = ALIGN(clen, 4);
- /*
- * parse stream (if any)
- */
+ /* check if this is stream has a valid tag.*/
if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
- printk(KERN_ERR "%s: missing tag!\n",
- wiphy_name(ar->hw->wiphy));
+ /*
+ * TODO: handle the highly unlikely event that the
+ * corrupted stream has the TAG at the right position.
+ */
+
+ /* check if the frame can be repaired. */
+ if (!ar->rx_failover_missing) {
+ /* this is no "short read". */
+ if (ar9170_nag_limiter(ar)) {
+ printk(KERN_ERR "%s: missing tag!\n",
+ wiphy_name(ar->hw->wiphy));
+ goto err_telluser;
+ } else
+ goto err_silent;
+ }
+
+ if (ar->rx_failover_missing > tlen) {
+ if (ar9170_nag_limiter(ar)) {
+ printk(KERN_ERR "%s: possible multi "
+ "stream corruption!\n",
+ wiphy_name(ar->hw->wiphy));
+ goto err_telluser;
+ } else
+ goto err_silent;
+ }
+
+ memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
+ ar->rx_failover_missing -= tlen;
+
+ if (ar->rx_failover_missing <= 0) {
+ /*
+ * nested ar9170_rx call!
+ * termination is guranteed, even when the
+ * combined frame also have a element with
+ * a bad tag.
+ */
+
+ ar->rx_failover_missing = 0;
+ ar9170_rx(ar, ar->rx_failover);
+
+ skb_reset_tail_pointer(ar->rx_failover);
+ skb_trim(ar->rx_failover, 0);
+ }
+
return ;
}
+
+ /* check if stream is clipped */
if (wlen > tlen - 4) {
- printk(KERN_ERR "%s: invalid RX (%d, %d, %d)\n",
- wiphy_name(ar->hw->wiphy), clen, wlen, tlen);
- print_hex_dump(KERN_DEBUG, "data: ",
- DUMP_PREFIX_OFFSET,
- 16, 1, tbuf, tlen, true);
+ if (ar->rx_failover_missing) {
+ /* TODO: handle double stream corruption. */
+ if (ar9170_nag_limiter(ar)) {
+ printk(KERN_ERR "%s: double rx stream "
+ "corruption!\n",
+ wiphy_name(ar->hw->wiphy));
+ goto err_telluser;
+ } else
+ goto err_silent;
+ }
+
+ /*
+ * save incomplete data set.
+ * the firmware will resend the missing bits when
+ * the rx - descriptor comes round again.
+ */
+
+ memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
+ ar->rx_failover_missing = clen - tlen;
return ;
}
resplen = clen;
@@ -668,12 +1027,44 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
if (i == 12)
ar9170_handle_command_response(ar, respbuf, resplen);
else
- ar9170_handle_mpdu(ar, respbuf, resplen);
+ ar9170_handle_mpdu(ar, respbuf, clen);
}
- if (tlen)
- printk(KERN_ERR "%s: buffer remains!\n",
- wiphy_name(ar->hw->wiphy));
+ if (tlen) {
+ if (net_ratelimit())
+ printk(KERN_ERR "%s: %d bytes of unprocessed "
+ "data left in rx stream!\n",
+ wiphy_name(ar->hw->wiphy), tlen);
+
+ goto err_telluser;
+ }
+
+ return ;
+
+err_telluser:
+ printk(KERN_ERR "%s: damaged RX stream data [want:%d, "
+ "data:%d, rx:%d, pending:%d ]\n",
+ wiphy_name(ar->hw->wiphy), clen, wlen, tlen,
+ ar->rx_failover_missing);
+
+ if (ar->rx_failover_missing)
+ print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
+ ar->rx_failover->data,
+ ar->rx_failover->len);
+
+ print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
+ skb->data, skb->len);
+
+ printk(KERN_ERR "%s: please check your hardware and cables, if "
+ "you see this message frequently.\n",
+ wiphy_name(ar->hw->wiphy));
+
+err_silent:
+ if (ar->rx_failover_missing) {
+ skb_reset_tail_pointer(ar->rx_failover);
+ skb_trim(ar->rx_failover, 0);
+ ar->rx_failover_missing = 0;
+ }
}
#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \
@@ -691,10 +1082,12 @@ static int ar9170_op_start(struct ieee80211_hw *hw)
mutex_lock(&ar->mutex);
+ ar->filter_changed = 0;
+
/* reinitialize queues statistics */
memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
- for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++)
- ar->tx_stats[i].limit = 8;
+ for (i = 0; i < __AR9170_NUM_TXQ; i++)
+ ar->tx_stats[i].limit = AR9170_TXQ_DEPTH;
/* reset QoS defaults */
AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/
@@ -703,6 +1096,8 @@ static int ar9170_op_start(struct ieee80211_hw *hw)
AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */
AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
+ ar->bad_hw_nagger = jiffies;
+
err = ar->open(ar);
if (err)
goto out;
@@ -738,17 +1133,17 @@ out:
static void ar9170_op_stop(struct ieee80211_hw *hw)
{
struct ar9170 *ar = hw->priv;
+ unsigned int i;
if (IS_STARTED(ar))
ar->state = AR9170_IDLE;
- mutex_lock(&ar->mutex);
+ flush_workqueue(ar->hw->workqueue);
- cancel_delayed_work_sync(&ar->tx_status_janitor);
+ cancel_delayed_work_sync(&ar->tx_janitor);
cancel_work_sync(&ar->filter_config_work);
cancel_work_sync(&ar->beacon_work);
- skb_queue_purge(&ar->global_tx_status_waste);
- skb_queue_purge(&ar->global_tx_status);
+ mutex_lock(&ar->mutex);
if (IS_ACCEPTING_CMD(ar)) {
ar9170_set_leds_state(ar, 0);
@@ -758,51 +1153,32 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
ar->stop(ar);
}
+ for (i = 0; i < __AR9170_NUM_TXQ; i++) {
+ skb_queue_purge(&ar->tx_pending[i]);
+ skb_queue_purge(&ar->tx_status[i]);
+ }
mutex_unlock(&ar->mutex);
}
-int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
{
- struct ar9170 *ar = hw->priv;
struct ieee80211_hdr *hdr;
struct ar9170_tx_control *txc;
struct ieee80211_tx_info *info;
- struct ieee80211_rate *rate = NULL;
struct ieee80211_tx_rate *txrate;
+ struct ar9170_tx_info *arinfo;
unsigned int queue = skb_get_queue_mapping(skb);
- unsigned long flags = 0;
- struct ar9170_sta_info *sta_info = NULL;
- u32 power, chains;
u16 keytype = 0;
u16 len, icv = 0;
- int err;
- bool tx_status;
- if (unlikely(!IS_STARTED(ar)))
- goto err_free;
+ BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
hdr = (void *)skb->data;
info = IEEE80211_SKB_CB(skb);
len = skb->len;
- spin_lock_irqsave(&ar->tx_stats_lock, flags);
- if (ar->tx_stats[queue].limit < ar->tx_stats[queue].len) {
- spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
- return NETDEV_TX_OK;
- }
-
- ar->tx_stats[queue].len++;
- ar->tx_stats[queue].count++;
- if (ar->tx_stats[queue].limit == ar->tx_stats[queue].len)
- ieee80211_stop_queue(hw, queue);
-
- spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-
txc = (void *)skb_push(skb, sizeof(*txc));
- tx_status = (((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) != 0) ||
- ((info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) != 0));
-
if (info->control.hw_key) {
icv = info->control.hw_key->icv_len;
@@ -818,7 +1194,7 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
break;
default:
WARN_ON(1);
- goto err_dequeue;
+ goto err_out;
}
}
@@ -835,16 +1211,65 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
- if (info->flags & IEEE80211_TX_CTL_AMPDU)
- txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
-
txrate = &info->control.rates[0];
-
if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
+ arinfo = (void *)info->rate_driver_data;
+ arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT);
+
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+ (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
+ if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+ if (unlikely(!info->control.sta))
+ goto err_out;
+
+ txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
+ arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK;
+ goto out;
+ }
+
+ txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
+ /*
+ * WARNING:
+ * Putting the QoS queue bits into an unexplored territory is
+ * certainly not elegant.
+ *
+ * In my defense: This idea provides a reasonable way to
+ * smuggle valuable information to the tx_status callback.
+ * Also, the idea behind this bit-abuse came straight from
+ * the original driver code.
+ */
+
+ txc->phy_control |=
+ cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
+ arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK;
+ } else {
+ arinfo->flags = AR9170_TX_FLAG_NO_ACK;
+ }
+
+out:
+ return 0;
+
+err_out:
+ skb_pull(skb, sizeof(*txc));
+ return -EINVAL;
+}
+
+static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct ar9170_tx_control *txc;
+ struct ieee80211_tx_info *info;
+ struct ieee80211_rate *rate = NULL;
+ struct ieee80211_tx_rate *txrate;
+ u32 power, chains;
+
+ txc = (void *) skb->data;
+ info = IEEE80211_SKB_CB(skb);
+ txrate = &info->control.rates[0];
+
if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
@@ -864,9 +1289,12 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
u32 r = txrate->idx;
u8 *txpower;
+ /* heavy clip control */
+ txc->phy_control |= cpu_to_le32((r & 0x7) << 7);
+
r <<= AR9170_TX_PHY_MCS_SHIFT;
- if (WARN_ON(r & ~AR9170_TX_PHY_MCS_MASK))
- goto err_dequeue;
+ BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK);
+
txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
@@ -928,53 +1356,154 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
chains = AR9170_TX_PHY_TXCHAIN_1;
}
txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
+}
- if (tx_status) {
- txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
- /*
- * WARNING:
- * Putting the QoS queue bits into an unexplored territory is
- * certainly not elegant.
- *
- * In my defense: This idea provides a reasonable way to
- * smuggle valuable information to the tx_status callback.
- * Also, the idea behind this bit-abuse came straight from
- * the original driver code.
- */
+static void ar9170_tx(struct ar9170 *ar)
+{
+ struct sk_buff *skb;
+ unsigned long flags;
+ struct ieee80211_tx_info *info;
+ struct ar9170_tx_info *arinfo;
+ unsigned int i, frames, frames_failed, remaining_space;
+ int err;
+ bool schedule_garbagecollector = false;
- txc->phy_control |=
- cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
+ BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
- if (info->control.sta) {
- sta_info = (void *) info->control.sta->drv_priv;
- skb_queue_tail(&sta_info->tx_status[queue], skb);
- } else {
- skb_queue_tail(&ar->global_tx_status, skb);
+ if (unlikely(!IS_STARTED(ar)))
+ return ;
+
+ remaining_space = AR9170_TX_MAX_PENDING;
+
+ for (i = 0; i < __AR9170_NUM_TXQ; i++) {
+ spin_lock_irqsave(&ar->tx_stats_lock, flags);
+ if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
+#ifdef AR9170_QUEUE_DEBUG
+ printk(KERN_DEBUG "%s: queue %d full\n",
+ wiphy_name(ar->hw->wiphy), i);
+
+ __ar9170_dump_txstats(ar);
+ printk(KERN_DEBUG "stuck frames: ===> \n");
+ ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
+ ar9170_dump_txqueue(ar, &ar->tx_status[i]);
+#endif /* AR9170_QUEUE_DEBUG */
+ ieee80211_stop_queue(ar->hw, i);
+ spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+ continue;
+ }
+
+ frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
+ skb_queue_len(&ar->tx_pending[i]));
+
+ if (remaining_space < frames) {
+#ifdef AR9170_QUEUE_DEBUG
+ printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
+ "remaining slots:%d, needed:%d\n",
+ wiphy_name(ar->hw->wiphy), i, remaining_space,
+ frames);
+
+ ar9170_dump_txstats(ar);
+#endif /* AR9170_QUEUE_DEBUG */
+ frames = remaining_space;
+ }
+
+ ar->tx_stats[i].len += frames;
+ ar->tx_stats[i].count += frames;
+ spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+
+ if (!frames)
+ continue;
+
+ frames_failed = 0;
+ while (frames) {
+ skb = skb_dequeue(&ar->tx_pending[i]);
+ if (unlikely(!skb)) {
+ frames_failed += frames;
+ frames = 0;
+ break;
+ }
+
+ info = IEEE80211_SKB_CB(skb);
+ arinfo = (void *) info->rate_driver_data;
+
+ /* TODO: cancel stuck frames */
+ arinfo->timeout = jiffies +
+ msecs_to_jiffies(AR9170_TX_TIMEOUT);
+
+#ifdef AR9170_QUEUE_DEBUG
+ printk(KERN_DEBUG "%s: send frame q:%d =>\n",
+ wiphy_name(ar->hw->wiphy), i);
+ ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+
+ err = ar->tx(ar, skb);
+ if (unlikely(err)) {
+ frames_failed++;
+ dev_kfree_skb_any(skb);
+ } else {
+ remaining_space--;
+ schedule_garbagecollector = true;
+ }
+
+ frames--;
+ }
+
+#ifdef AR9170_QUEUE_DEBUG
+ printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n",
+ wiphy_name(ar->hw->wiphy), i);
- queue_delayed_work(ar->hw->workqueue,
- &ar->tx_status_janitor,
- msecs_to_jiffies(100));
+ printk(KERN_DEBUG "%s: unprocessed pending frames left:\n",
+ wiphy_name(ar->hw->wiphy));
+ ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
+#endif /* AR9170_QUEUE_DEBUG */
+
+ if (unlikely(frames_failed)) {
+#ifdef AR9170_QUEUE_DEBUG
+ printk(KERN_DEBUG "%s: frames failed =>\n",
+ wiphy_name(ar->hw->wiphy), frames_failed);
+#endif /* AR9170_QUEUE_DEBUG */
+
+ spin_lock_irqsave(&ar->tx_stats_lock, flags);
+ ar->tx_stats[i].len -= frames_failed;
+ ar->tx_stats[i].count -= frames_failed;
+ ieee80211_wake_queue(ar->hw, i);
+ spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
}
}
- err = ar->tx(ar, skb, tx_status, 0);
- if (unlikely(tx_status && err)) {
- if (info->control.sta)
- skb_unlink(skb, &sta_info->tx_status[queue]);
- else
- skb_unlink(skb, &ar->global_tx_status);
+ if (schedule_garbagecollector)
+ queue_delayed_work(ar->hw->workqueue,
+ &ar->tx_janitor,
+ msecs_to_jiffies(AR9170_JANITOR_DELAY));
+}
+
+int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct ar9170 *ar = hw->priv;
+ struct ieee80211_tx_info *info;
+
+ if (unlikely(!IS_STARTED(ar)))
+ goto err_free;
+
+ if (unlikely(ar9170_tx_prepare(ar, skb)))
+ goto err_free;
+
+ info = IEEE80211_SKB_CB(skb);
+ if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+ /* drop frame, we do not allow TX A-MPDU aggregation yet. */
+ goto err_free;
+ } else {
+ unsigned int queue = skb_get_queue_mapping(skb);
+
+ ar9170_tx_prepare_phy(ar, skb);
+ skb_queue_tail(&ar->tx_pending[queue], skb);
}
+ ar9170_tx(ar);
return NETDEV_TX_OK;
-err_dequeue:
- spin_lock_irqsave(&ar->tx_stats_lock, flags);
- ar->tx_stats[queue].len--;
- ar->tx_stats[queue].count--;
- spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-
err_free:
- dev_kfree_skb(skb);
+ dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
@@ -1037,11 +1566,6 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&ar->mutex);
- if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
- /* TODO */
- err = 0;
- }
-
if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
/* TODO */
err = 0;
@@ -1068,48 +1592,28 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
goto out;
}
- if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) {
+ if (changed & BSS_CHANGED_BEACON_INT) {
err = ar9170_set_beacon_timers(ar);
if (err)
goto out;
}
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
- err = ar9170_set_channel(ar, hw->conf.channel,
- AR9170_RFI_NONE, AR9170_BW_20);
+
+ /* adjust slot time for 5 GHz */
+ err = ar9170_set_slot_time(ar);
if (err)
goto out;
- /* adjust slot time for 5 GHz */
- if (hw->conf.channel->band == IEEE80211_BAND_5GHZ)
- err = ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
- 9 << 10);
- }
-
-out:
- mutex_unlock(&ar->mutex);
- return err;
-}
-
-static int ar9170_op_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct ar9170 *ar = hw->priv;
- int err = 0;
-
- mutex_lock(&ar->mutex);
- if (conf->changed & IEEE80211_IFCC_BSSID) {
- memcpy(ar->bssid, conf->bssid, ETH_ALEN);
- err = ar9170_set_operating_mode(ar);
- }
-
- if (conf->changed & IEEE80211_IFCC_BEACON) {
- err = ar9170_update_beacon(ar);
+ err = ar9170_set_dyn_sifs_ack(ar);
+ if (err)
+ goto out;
+ err = ar9170_set_channel(ar, hw->conf.channel,
+ AR9170_RFI_NONE,
+ nl80211_to_ar9170(hw->conf.channel_type));
if (err)
goto out;
- err = ar9170_set_beacon_timers(ar);
}
out:
@@ -1123,24 +1627,30 @@ static void ar9170_set_filters(struct work_struct *work)
filter_config_work);
int err;
- mutex_lock(&ar->mutex);
if (unlikely(!IS_STARTED(ar)))
- goto unlock;
+ return ;
- if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) {
+ mutex_lock(&ar->mutex);
+ if (test_and_clear_bit(AR9170_FILTER_CHANGED_MODE,
+ &ar->filter_changed)) {
err = ar9170_set_operating_mode(ar);
if (err)
goto unlock;
}
- if (ar->filter_changed & AR9170_FILTER_CHANGED_MULTICAST) {
+ if (test_and_clear_bit(AR9170_FILTER_CHANGED_MULTICAST,
+ &ar->filter_changed)) {
err = ar9170_update_multicast(ar);
if (err)
goto unlock;
}
- if (ar->filter_changed & AR9170_FILTER_CHANGED_FRAMEFILTER)
+ if (test_and_clear_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
+ &ar->filter_changed)) {
err = ar9170_update_frame_filter(ar);
+ if (err)
+ goto unlock;
+ }
unlock:
mutex_unlock(&ar->mutex);
@@ -1155,8 +1665,8 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
/* mask supported flags */
*new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
- FIF_PROMISC_IN_BSS;
-
+ FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
+ ar->filter_state = *new_flags;
/*
* We can support more by setting the sniffer bit and
* then checking the error flags, later.
@@ -1170,7 +1680,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
int i;
/* always get broadcast frames */
- mchash = 1ULL << (0xff>>2);
+ mchash = 1ULL << (0xff >> 2);
for (i = 0; i < mc_count; i++) {
if (WARN_ON(!mclist))
@@ -1180,7 +1690,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
}
ar->want_mc_hash = mchash;
}
- ar->filter_changed |= AR9170_FILTER_CHANGED_MULTICAST;
+ set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed);
}
if (changed_flags & FIF_CONTROL) {
@@ -1196,12 +1706,14 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
else
ar->want_filter = ar->cur_filter & ~filter;
- ar->filter_changed |= AR9170_FILTER_CHANGED_FRAMEFILTER;
+ set_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
+ &ar->filter_changed);
}
if (changed_flags & FIF_PROMISC_IN_BSS) {
ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
- ar->filter_changed |= AR9170_FILTER_CHANGED_PROMISC;
+ set_bit(AR9170_FILTER_CHANGED_MODE,
+ &ar->filter_changed);
}
if (likely(IS_STARTED(ar)))
@@ -1218,48 +1730,54 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
mutex_lock(&ar->mutex);
- ar9170_regwrite_begin(ar);
+ if (changed & BSS_CHANGED_BSSID) {
+ memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN);
+ err = ar9170_set_operating_mode(ar);
+ if (err)
+ goto out;
+ }
- if (changed & BSS_CHANGED_ASSOC) {
- ar->state = bss_conf->assoc ? AR9170_ASSOCIATED : ar->state;
+ if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) {
+ err = ar9170_update_beacon(ar);
+ if (err)
+ goto out;
+ err = ar9170_set_beacon_timers(ar);
+ if (err)
+ goto out;
+ }
+
+ if (changed & BSS_CHANGED_ASSOC) {
#ifndef CONFIG_AR9170_LEDS
/* enable assoc LED. */
err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
#endif /* CONFIG_AR9170_LEDS */
}
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ err = ar9170_set_beacon_timers(ar);
+ if (err)
+ goto out;
+ }
+
if (changed & BSS_CHANGED_HT) {
/* TODO */
err = 0;
}
if (changed & BSS_CHANGED_ERP_SLOT) {
- u32 slottime = 20;
-
- if (bss_conf->use_short_slot)
- slottime = 9;
-
- ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, slottime << 10);
+ err = ar9170_set_slot_time(ar);
+ if (err)
+ goto out;
}
if (changed & BSS_CHANGED_BASIC_RATES) {
- u32 cck, ofdm;
-
- if (hw->conf.channel->band == IEEE80211_BAND_5GHZ) {
- ofdm = bss_conf->basic_rates;
- cck = 0;
- } else {
- /* four cck rates */
- cck = bss_conf->basic_rates & 0xf;
- ofdm = bss_conf->basic_rates >> 4;
- }
- ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE,
- ofdm << 8 | cck);
+ err = ar9170_set_basic_rates(ar);
+ if (err)
+ goto out;
}
- ar9170_regwrite_finish();
- err = ar9170_regwrite_result();
+out:
mutex_unlock(&ar->mutex);
}
@@ -1298,7 +1816,7 @@ static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
switch (key->alg) {
case ALG_WEP:
- if (key->keylen == LEN_WEP40)
+ if (key->keylen == WLAN_KEY_LEN_WEP40)
ktype = AR9170_ENC_ALG_WEP64;
else
ktype = AR9170_ENC_ALG_WEP128;
@@ -1411,43 +1929,6 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw,
enum sta_notify_cmd cmd,
struct ieee80211_sta *sta)
{
- struct ar9170 *ar = hw->priv;
- struct ar9170_sta_info *info = (void *) sta->drv_priv;
- struct sk_buff *skb;
- unsigned int i;
-
- switch (cmd) {
- case STA_NOTIFY_ADD:
- for (i = 0; i < ar->hw->queues; i++)
- skb_queue_head_init(&info->tx_status[i]);
- break;
-
- case STA_NOTIFY_REMOVE:
-
- /*
- * transfer all outstanding frames that need a tx_status
- * reports to the global tx_status queue
- */
-
- for (i = 0; i < ar->hw->queues; i++) {
- while ((skb = skb_dequeue(&info->tx_status[i]))) {
-#ifdef AR9170_QUEUE_DEBUG
- printk(KERN_DEBUG "%s: queueing frame in "
- "global tx_status queue =>\n",
- wiphy_name(ar->hw->wiphy));
-
- ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
- skb_queue_tail(&ar->global_tx_status, skb);
- }
- }
- queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
- msecs_to_jiffies(100));
- break;
-
- default:
- break;
- }
}
static int ar9170_get_stats(struct ieee80211_hw *hw,
@@ -1486,7 +1967,7 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
int ret;
mutex_lock(&ar->mutex);
- if ((param) && !(queue > ar->hw->queues)) {
+ if ((param) && !(queue > __AR9170_NUM_TXQ)) {
memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
param, sizeof(*param));
@@ -1498,6 +1979,24 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
return ret;
}
+static int ar9170_ampdu_action(struct ieee80211_hw *hw,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn)
+{
+ switch (action) {
+ case IEEE80211_AMPDU_RX_START:
+ case IEEE80211_AMPDU_RX_STOP:
+ /*
+ * Something goes wrong -- RX locks up
+ * after a while of receiving aggregated
+ * frames -- not enabling for now.
+ */
+ return -EOPNOTSUPP;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static const struct ieee80211_ops ar9170_ops = {
.start = ar9170_op_start,
.stop = ar9170_op_stop,
@@ -1505,7 +2004,6 @@ static const struct ieee80211_ops ar9170_ops = {
.add_interface = ar9170_op_add_interface,
.remove_interface = ar9170_op_remove_interface,
.config = ar9170_op_config,
- .config_interface = ar9170_op_config_interface,
.configure_filter = ar9170_op_configure_filter,
.conf_tx = ar9170_conf_tx,
.bss_info_changed = ar9170_op_bss_info_changed,
@@ -1514,29 +2012,45 @@ static const struct ieee80211_ops ar9170_ops = {
.sta_notify = ar9170_sta_notify,
.get_stats = ar9170_get_stats,
.get_tx_stats = ar9170_get_tx_stats,
+ .ampdu_action = ar9170_ampdu_action,
};
void *ar9170_alloc(size_t priv_size)
{
struct ieee80211_hw *hw;
struct ar9170 *ar;
+ struct sk_buff *skb;
int i;
+ /*
+ * this buffer is used for rx stream reconstruction.
+ * Under heavy load this device (or the transport layer?)
+ * tends to split the streams into seperate rx descriptors.
+ */
+
+ skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL);
+ if (!skb)
+ goto err_nomem;
+
hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
if (!hw)
- return ERR_PTR(-ENOMEM);
+ goto err_nomem;
ar = hw->priv;
ar->hw = hw;
+ ar->rx_failover = skb;
mutex_init(&ar->mutex);
spin_lock_init(&ar->cmdlock);
spin_lock_init(&ar->tx_stats_lock);
- skb_queue_head_init(&ar->global_tx_status);
- skb_queue_head_init(&ar->global_tx_status_waste);
+ for (i = 0; i < __AR9170_NUM_TXQ; i++) {
+ skb_queue_head_init(&ar->tx_status[i]);
+ skb_queue_head_init(&ar->tx_pending[i]);
+ }
+ ar9170_rx_reset_rx_mpdu(ar);
INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
- INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor);
+ INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
/* all hw supports 2.4 GHz, so set channel to 1 by default */
ar->channel = &ar9170_2ghz_chantable[0];
@@ -1561,6 +2075,10 @@ void *ar9170_alloc(size_t priv_size)
ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
return ar;
+
+err_nomem:
+ kfree_skb(skb);
+ return ERR_PTR(-ENOMEM);
}
static int ar9170_read_eeprom(struct ar9170 *ar)
@@ -1619,12 +2137,24 @@ static int ar9170_read_eeprom(struct ar9170 *ar)
else
ar->hw->channel_change_time = 80 * 1000;
+ ar->regulatory.current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
+ ar->regulatory.current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
+
/* second part of wiphy init */
SET_IEEE80211_PERM_ADDR(ar->hw, addr);
return bands ? 0 : -EINVAL;
}
+static int ar9170_reg_notifier(struct wiphy *wiphy,
+ struct regulatory_request *request)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct ar9170 *ar = hw->priv;
+
+ return ath_reg_notifier_apply(wiphy, request, &ar->regulatory);
+}
+
int ar9170_register(struct ar9170 *ar, struct device *pdev)
{
int err;
@@ -1634,10 +2164,18 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev)
if (err)
goto err_out;
+ err = ath_regd_init(&ar->regulatory, ar->hw->wiphy,
+ ar9170_reg_notifier);
+ if (err)
+ goto err_out;
+
err = ieee80211_register_hw(ar->hw);
if (err)
goto err_out;
+ if (!ath_is_world_regd(&ar->regulatory))
+ regulatory_hint(ar->hw->wiphy, ar->regulatory.alpha2);
+
err = ar9170_init_leds(ar);
if (err)
goto err_unreg;
@@ -1666,6 +2204,7 @@ void ar9170_unregister(struct ar9170 *ar)
ar9170_unregister_leds(ar);
#endif /* CONFIG_AR9170_LEDS */
+ kfree_skb(ar->rx_failover);
ieee80211_unregister_hw(ar->hw);
mutex_destroy(&ar->mutex);
}
diff --git a/drivers/net/wireless/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c
index 6ce20754b8e..df86f70cd81 100644
--- a/drivers/net/wireless/ar9170/phy.c
+++ b/drivers/net/wireless/ath/ar9170/phy.c
@@ -401,7 +401,7 @@ int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
int i, err;
u32 val;
bool is_2ghz = band == IEEE80211_BAND_2GHZ;
- bool is_40mhz = false; /* XXX: for now */
+ bool is_40mhz = conf_is_ht40(&ar->hw->conf);
ar9170_regwrite_begin(ar);
@@ -1200,7 +1200,7 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
return -ENOSYS;
}
- if (0 /* 2 streams capable */)
+ if (ar->eeprom.tx_mask != 1)
tmp |= 0x100;
err = ar9170_write_reg(ar, 0x1c5804, tmp);
@@ -1214,7 +1214,7 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
freqpar = ar9170_get_hw_dyn_params(channel, bw);
vals[0] = cpu_to_le32(channel->center_freq * 1000);
- vals[1] = cpu_to_le32(bw == AR9170_BW_20 ? 0 : 1);
+ vals[1] = cpu_to_le32(conf_is_ht40(&ar->hw->conf));
vals[2] = cpu_to_le32(offs << 2 | 1);
vals[3] = cpu_to_le32(freqpar->coeff_exp);
vals[4] = cpu_to_le32(freqpar->coeff_man);
diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index fddda477095..754b1f8d8da 100644
--- a/drivers/net/wireless/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -51,9 +51,14 @@ MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
+MODULE_FIRMWARE("ar9170.fw");
MODULE_FIRMWARE("ar9170-1.fw");
MODULE_FIRMWARE("ar9170-2.fw");
+enum ar9170_requirements {
+ AR9170_REQ_FW1_ONLY = 1,
+};
+
static struct usb_device_id ar9170_usb_ids[] = {
/* Atheros 9170 */
{ USB_DEVICE(0x0cf3, 0x9170) },
@@ -81,25 +86,74 @@ static struct usb_device_id ar9170_usb_ids[] = {
{ USB_DEVICE(0x2019, 0x5304) },
/* IO-Data WNGDNUS2 */
{ USB_DEVICE(0x04bb, 0x093f) },
+ /* AVM FRITZ!WLAN USB Stick N */
+ { USB_DEVICE(0x057C, 0x8401) },
+ /* AVM FRITZ!WLAN USB Stick N 2.4 */
+ { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
/* terminate */
{}
};
MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
-static void ar9170_usb_tx_urb_complete_free(struct urb *urb)
+static void ar9170_usb_submit_urb(struct ar9170_usb *aru)
+{
+ struct urb *urb;
+ unsigned long flags;
+ int err;
+
+ if (unlikely(!IS_STARTED(&aru->common)))
+ return ;
+
+ spin_lock_irqsave(&aru->tx_urb_lock, flags);
+ if (aru->tx_submitted_urbs >= AR9170_NUM_TX_URBS) {
+ spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
+ return ;
+ }
+ aru->tx_submitted_urbs++;
+
+ urb = usb_get_from_anchor(&aru->tx_pending);
+ if (!urb) {
+ aru->tx_submitted_urbs--;
+ spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
+
+ return ;
+ }
+ spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
+
+ aru->tx_pending_urbs--;
+ usb_anchor_urb(urb, &aru->tx_submitted);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (unlikely(err)) {
+ if (ar9170_nag_limiter(&aru->common))
+ dev_err(&aru->udev->dev, "submit_urb failed (%d).\n",
+ err);
+
+ usb_unanchor_urb(urb);
+ aru->tx_submitted_urbs--;
+ ar9170_tx_callback(&aru->common, urb->context);
+ }
+
+ usb_free_urb(urb);
+}
+
+static void ar9170_usb_tx_urb_complete_frame(struct urb *urb)
{
struct sk_buff *skb = urb->context;
struct ar9170_usb *aru = (struct ar9170_usb *)
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
- if (!aru) {
+ if (unlikely(!aru)) {
dev_kfree_skb_irq(skb);
return ;
}
- ar9170_handle_tx_status(&aru->common, skb, false,
- AR9170_TX_STATUS_COMPLETE);
+ aru->tx_submitted_urbs--;
+
+ ar9170_tx_callback(&aru->common, skb);
+
+ ar9170_usb_submit_urb(aru);
}
static void ar9170_usb_tx_urb_complete(struct urb *urb)
@@ -126,8 +180,8 @@ static void ar9170_usb_irq_completed(struct urb *urb)
goto resubmit;
}
- print_hex_dump_bytes("ar9170 irq: ", DUMP_PREFIX_OFFSET,
- urb->transfer_buffer, urb->actual_length);
+ ar9170_handle_command_response(&aru->common, urb->transfer_buffer,
+ urb->actual_length);
resubmit:
usb_anchor_urb(urb, &aru->rx_submitted);
@@ -177,16 +231,15 @@ resubmit:
usb_anchor_urb(urb, &aru->rx_submitted);
err = usb_submit_urb(urb, GFP_ATOMIC);
- if (err) {
+ if (unlikely(err)) {
usb_unanchor_urb(urb);
- dev_kfree_skb_irq(skb);
+ goto free;
}
return ;
free:
dev_kfree_skb_irq(skb);
- return;
}
static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
@@ -282,21 +335,47 @@ err_out:
return err;
}
-static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
+static int ar9170_usb_flush(struct ar9170 *ar)
{
- int ret;
+ struct ar9170_usb *aru = (void *) ar;
+ struct urb *urb;
+ int ret, err = 0;
- aru->common.state = AR9170_UNKNOWN_STATE;
+ if (IS_STARTED(ar))
+ aru->common.state = AR9170_IDLE;
- usb_unlink_anchored_urbs(&aru->tx_submitted);
+ usb_wait_anchor_empty_timeout(&aru->tx_pending,
+ msecs_to_jiffies(800));
+ while ((urb = usb_get_from_anchor(&aru->tx_pending))) {
+ ar9170_tx_callback(&aru->common, (void *) urb->context);
+ usb_free_urb(urb);
+ }
- /* give the LED OFF command and the deauth frame a chance to air. */
+ /* lets wait a while until the tx - queues are dried out */
ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
msecs_to_jiffies(100));
if (ret == 0)
- dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
- usb_poison_anchored_urbs(&aru->tx_submitted);
+ err = -ETIMEDOUT;
+
+ usb_kill_anchored_urbs(&aru->tx_submitted);
+ if (IS_ACCEPTING_CMD(ar))
+ aru->common.state = AR9170_STARTED;
+
+ return err;
+}
+
+static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
+{
+ int err;
+
+ aru->common.state = AR9170_UNKNOWN_STATE;
+
+ err = ar9170_usb_flush(&aru->common);
+ if (err)
+ dev_err(&aru->udev->dev, "stuck tx urbs!\n");
+
+ usb_poison_anchored_urbs(&aru->tx_submitted);
usb_poison_anchored_urbs(&aru->rx_submitted);
}
@@ -337,7 +416,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
usb_anchor_urb(urb, &aru->tx_submitted);
err = usb_submit_urb(urb, GFP_ATOMIC);
- if (err) {
+ if (unlikely(err)) {
usb_unanchor_urb(urb);
usb_free_urb(urb);
goto err_unbuf;
@@ -350,7 +429,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
goto err_unbuf;
}
- if (outlen >= 0 && aru->readlen != outlen) {
+ if (aru->readlen != outlen) {
err = -EMSGSIZE;
goto err_unbuf;
}
@@ -380,12 +459,10 @@ err_free:
return err;
}
-static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb,
- bool txstatus_needed, unsigned int extra_len)
+static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb)
{
struct ar9170_usb *aru = (struct ar9170_usb *) ar;
struct urb *urb;
- int err;
if (unlikely(!IS_STARTED(ar))) {
/* Seriously, what were you drink... err... thinking!? */
@@ -398,18 +475,17 @@ static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb,
usb_fill_bulk_urb(urb, aru->udev,
usb_sndbulkpipe(aru->udev, AR9170_EP_TX),
- skb->data, skb->len + extra_len, (txstatus_needed ?
- ar9170_usb_tx_urb_complete :
- ar9170_usb_tx_urb_complete_free), skb);
+ skb->data, skb->len,
+ ar9170_usb_tx_urb_complete_frame, skb);
urb->transfer_flags |= URB_ZERO_PACKET;
- usb_anchor_urb(urb, &aru->tx_submitted);
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (unlikely(err))
- usb_unanchor_urb(urb);
+ usb_anchor_urb(urb, &aru->tx_pending);
+ aru->tx_pending_urbs++;
usb_free_urb(urb);
- return err;
+
+ ar9170_usb_submit_urb(aru);
+ return 0;
}
static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
@@ -418,7 +494,7 @@ static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
unsigned long flags;
u32 in, out;
- if (!buffer)
+ if (unlikely(!buffer))
return ;
in = le32_to_cpup((__le32 *)buffer);
@@ -504,17 +580,29 @@ static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
{
int err = 0;
- err = request_firmware(&aru->init_values, "ar9170-1.fw",
+ err = request_firmware(&aru->firmware, "ar9170.fw",
&aru->udev->dev);
- if (err) {
- dev_err(&aru->udev->dev, "file with init values not found.\n");
- return err;
+ if (!err) {
+ aru->init_values = NULL;
+ return 0;
}
+ if (aru->req_one_stage_fw) {
+ dev_err(&aru->udev->dev, "ar9170.fw firmware file "
+ "not found and is required for this device\n");
+ return -EINVAL;
+ }
+
+ dev_err(&aru->udev->dev, "ar9170.fw firmware file "
+ "not found, trying old firmware...\n");
+
+ err = request_firmware(&aru->init_values, "ar9170-1.fw",
+ &aru->udev->dev);
+
err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
if (err) {
release_firmware(aru->init_values);
- dev_err(&aru->udev->dev, "firmware file not found.\n");
+ dev_err(&aru->udev->dev, "file with init values not found.\n");
return err;
}
@@ -548,6 +636,9 @@ static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
{
int err;
+ if (!aru->init_values)
+ goto upload_fw_start;
+
/* First, upload initial values to device RAM */
err = ar9170_usb_upload(aru, aru->init_values->data,
aru->init_values->size, 0x102800, false);
@@ -557,6 +648,8 @@ static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
return err;
}
+upload_fw_start:
+
/* Then, upload the firmware itself and start it */
return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
0x200000, true);
@@ -592,10 +685,8 @@ static void ar9170_usb_stop(struct ar9170 *ar)
if (IS_ACCEPTING_CMD(ar))
aru->common.state = AR9170_STOPPED;
- /* lets wait a while until the tx - queues are dried out */
- ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
- msecs_to_jiffies(1000));
- if (ret == 0)
+ ret = ar9170_usb_flush(ar);
+ if (ret)
dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
usb_poison_anchored_urbs(&aru->tx_submitted);
@@ -656,6 +747,15 @@ err_out:
return err;
}
+static bool ar9170_requires_one_stage(const struct usb_device_id *id)
+{
+ if (!id->driver_info)
+ return false;
+ if (id->driver_info == AR9170_REQ_FW1_ONLY)
+ return true;
+ return false;
+}
+
static int ar9170_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
@@ -676,19 +776,30 @@ static int ar9170_usb_probe(struct usb_interface *intf,
aru->intf = intf;
ar = &aru->common;
+ aru->req_one_stage_fw = ar9170_requires_one_stage(id);
+
usb_set_intfdata(intf, aru);
SET_IEEE80211_DEV(ar->hw, &udev->dev);
init_usb_anchor(&aru->rx_submitted);
+ init_usb_anchor(&aru->tx_pending);
init_usb_anchor(&aru->tx_submitted);
init_completion(&aru->cmd_wait);
+ spin_lock_init(&aru->tx_urb_lock);
+
+ aru->tx_pending_urbs = 0;
+ aru->tx_submitted_urbs = 0;
aru->common.stop = ar9170_usb_stop;
+ aru->common.flush = ar9170_usb_flush;
aru->common.open = ar9170_usb_open;
aru->common.tx = ar9170_usb_tx;
aru->common.exec_cmd = ar9170_usb_exec_cmd;
aru->common.callback_cmd = ar9170_usb_callback_cmd;
+#ifdef CONFIG_PM
+ udev->reset_resume = 1;
+#endif /* CONFIG_PM */
err = ar9170_usb_reset(aru);
if (err)
goto err_freehw;
@@ -773,11 +884,6 @@ static int ar9170_resume(struct usb_interface *intf)
usb_unpoison_anchored_urbs(&aru->rx_submitted);
usb_unpoison_anchored_urbs(&aru->tx_submitted);
- /*
- * FIXME: firmware upload will fail on resume.
- * but this is better than a hang!
- */
-
err = ar9170_usb_init_device(aru);
if (err)
goto err_unrx;
@@ -805,6 +911,7 @@ static struct usb_driver ar9170_driver = {
#ifdef CONFIG_PM
.suspend = ar9170_suspend,
.resume = ar9170_resume,
+ .reset_resume = ar9170_resume,
#endif /* CONFIG_PM */
};
diff --git a/drivers/net/wireless/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h
index f5852924cd6..d098f4d5d2f 100644
--- a/drivers/net/wireless/ar9170/usb.h
+++ b/drivers/net/wireless/ath/ar9170/usb.h
@@ -43,7 +43,7 @@
#include <linux/completion.h>
#include <linux/spinlock.h>
#include <linux/leds.h>
-#include <net/wireless.h>
+#include <net/cfg80211.h>
#include <net/mac80211.h>
#include <linux/firmware.h>
#include "eeprom.h"
@@ -51,6 +51,7 @@
#include "ar9170.h"
#define AR9170_NUM_RX_URBS 16
+#define AR9170_NUM_TX_URBS 8
struct firmware;
@@ -60,9 +61,15 @@ struct ar9170_usb {
struct usb_interface *intf;
struct usb_anchor rx_submitted;
+ struct usb_anchor tx_pending;
struct usb_anchor tx_submitted;
- spinlock_t cmdlock;
+ bool req_one_stage_fw;
+
+ spinlock_t tx_urb_lock;
+ unsigned int tx_submitted_urbs;
+ unsigned int tx_pending_urbs;
+
struct completion cmd_wait;
int readlen;
u8 *readbuf;
diff --git a/drivers/net/wireless/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index 75383a5df99..509b6f94f73 100644
--- a/drivers/net/wireless/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -1,6 +1,7 @@
config ATH5K
tristate "Atheros 5xxx wireless cards support"
depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
+ select ATH_COMMON
select MAC80211_LEDS
select LEDS_CLASS
select NEW_LEDS
diff --git a/drivers/net/wireless/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
index 84a74c5248e..090dc6d268a 100644
--- a/drivers/net/wireless/ath5k/Makefile
+++ b/drivers/net/wireless/ath/ath5k/Makefile
@@ -11,5 +11,6 @@ ath5k-y += reset.o
ath5k-y += attach.o
ath5k-y += base.o
ath5k-y += led.o
+ath5k-y += rfkill.o
ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
obj-$(CONFIG_ATH5K) += ath5k.o
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 0b616e72fe0..6358233bac9 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -27,6 +27,8 @@
#include <linux/types.h>
#include <net/mac80211.h>
+#include "../regd.h"
+
/* RX/TX descriptor hw structs
* TODO: Driver part should only see sw structs */
#include "desc.h"
@@ -207,7 +209,6 @@
#define AR5K_TUNE_MAX_TXPOWER 63
#define AR5K_TUNE_DEFAULT_TXPOWER 25
#define AR5K_TUNE_TPC_TXPOWER false
-#define AR5K_TUNE_ANT_DIVERSITY true
#define AR5K_TUNE_HWTXTRIES 4
#define AR5K_INIT_CARR_SENSE_EN 1
@@ -418,6 +419,17 @@ enum ath5k_driver_mode {
AR5K_MODE_MAX = 5
};
+enum ath5k_ant_mode {
+ AR5K_ANTMODE_DEFAULT = 0, /* default antenna setup */
+ AR5K_ANTMODE_FIXED_A = 1, /* only antenna A is present */
+ AR5K_ANTMODE_FIXED_B = 2, /* only antenna B is present */
+ AR5K_ANTMODE_SINGLE_AP = 3, /* sta locked on a single ap */
+ AR5K_ANTMODE_SECTOR_AP = 4, /* AP with tx antenna set on tx desc */
+ AR5K_ANTMODE_SECTOR_STA = 5, /* STA with tx antenna set on tx desc */
+ AR5K_ANTMODE_DEBUG = 6, /* Debug mode -A -> Rx, B-> Tx- */
+ AR5K_ANTMODE_MAX,
+};
+
/****************\
TX DEFINITIONS
@@ -1039,8 +1051,6 @@ struct ath5k_hw {
bool ah_5ghz;
bool ah_2ghz;
-#define ah_regdomain ah_capabilities.cap_regdomain.reg_current
-#define ah_regdomain_hw ah_capabilities.cap_regdomain.reg_hw
#define ah_modes ah_capabilities.cap_mode
#define ah_ee_version ah_capabilities.cap_eeprom.ee_version
@@ -1051,8 +1061,11 @@ struct ath5k_hw {
bool ah_software_retry;
u32 ah_limit_tx_retries;
- u32 ah_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
- bool ah_ant_diversity;
+ /* Antenna Control */
+ u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
+ u8 ah_ant_mode;
+ u8 ah_tx_ant;
+ u8 ah_def_ant;
u8 ah_sta_id[ETH_ALEN];
@@ -1065,6 +1078,7 @@ struct ath5k_hw {
u32 ah_gpio[AR5K_MAX_GPIO];
int ah_gpio_npins;
+ struct ath_regulatory ah_regulatory;
struct ath5k_capabilities ah_capabilities;
struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES];
@@ -1099,11 +1113,12 @@ struct ath5k_hw {
/* Values in 0.25dB units */
s16 txp_min_pwr;
s16 txp_max_pwr;
+ /* Values in 0.5dB units */
s16 txp_offset;
s16 txp_ofdm;
- /* Values in dB units */
- s16 txp_cck_ofdm_pwr_delta;
s16 txp_cck_ofdm_gainf_delta;
+ /* Value in dB units */
+ s16 txp_cck_ofdm_pwr_delta;
} ah_txpower;
struct {
@@ -1241,6 +1256,10 @@ extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio);
extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level);
+/* rfkill Functions */
+extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah);
+extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
+
/* Misc functions */
int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result);
@@ -1263,14 +1282,21 @@ extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *chann
/* PHY calibration */
extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel);
extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
+/* Spur mitigation */
+bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel);
+void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel);
/* Misc PHY functions */
extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
-extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant);
-extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
+/* Antenna control */
+extern void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
+extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant);
+extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
/* TX power setup */
extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower);
-extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 ee_mode, u8 txpower);
+extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
/*
* Functions used internaly
diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index 70d376c63aa..c41ef58393e 100644
--- a/drivers/net/wireless/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -133,7 +133,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
ah->ah_cw_min = AR5K_TUNE_CWMIN;
ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
ah->ah_software_retry = false;
- ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
/*
* Set the mac version based on the pci id
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 32df27a9c7a..55f7de09d13 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -61,9 +61,13 @@
static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
static int modparam_nohwcrypt;
-module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+static int modparam_all_channels;
+module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO);
+MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
+
/******************\
* Internal defines *
@@ -223,9 +227,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
static void ath5k_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf);
static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
-static int ath5k_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf);
static void ath5k_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *new_flags,
@@ -241,8 +242,8 @@ static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
static void ath5k_reset_tsf(struct ieee80211_hw *hw);
-static int ath5k_beacon_update(struct ath5k_softc *sc,
- struct sk_buff *skb);
+static 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,
@@ -255,7 +256,6 @@ static const struct ieee80211_ops ath5k_hw_ops = {
.add_interface = ath5k_add_interface,
.remove_interface = ath5k_remove_interface,
.config = ath5k_config,
- .config_interface = ath5k_config_interface,
.configure_filter = ath5k_configure_filter,
.set_key = ath5k_set_key,
.get_stats = ath5k_get_stats,
@@ -516,6 +516,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
IEEE80211_HW_NOISE_DBM;
hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT);
@@ -705,6 +706,15 @@ err_no_irq:
* Driver Initialization *
\***********************/
+static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct ath5k_softc *sc = hw->priv;
+ struct ath_regulatory *reg = &sc->ah->ah_regulatory;
+
+ return ath_reg_notifier_apply(wiphy, request, reg);
+}
+
static int
ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
{
@@ -793,12 +803,23 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
memset(sc->bssidmask, 0xff, ETH_ALEN);
ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
+ ah->ah_regulatory.current_rd =
+ ah->ah_capabilities.cap_eeprom.ee_regdomain;
+ ret = ath_regd_init(&ah->ah_regulatory, hw->wiphy, ath5k_reg_notifier);
+ if (ret) {
+ ATH5K_ERR(sc, "can't initialize regulatory system\n");
+ goto err_queues;
+ }
+
ret = ieee80211_register_hw(hw);
if (ret) {
ATH5K_ERR(sc, "can't register ieee80211 hw\n");
goto err_queues;
}
+ if (!ath_is_world_regd(&sc->ah->ah_regulatory))
+ regulatory_hint(hw->wiphy, sc->ah->ah_regulatory.alpha2);
+
ath5k_init_leds(sc);
return 0;
@@ -862,6 +883,20 @@ ath5k_ieee2mhz(short chan)
return 2212 + chan * 20;
}
+/*
+ * Returns true for the channel numbers used without all_channels modparam.
+ */
+static bool ath5k_is_standard_channel(short chan)
+{
+ return ((chan <= 14) ||
+ /* UNII 1,2 */
+ ((chan & 3) == 0 && chan >= 36 && chan <= 64) ||
+ /* midband */
+ ((chan & 3) == 0 && chan >= 100 && chan <= 140) ||
+ /* UNII-3 */
+ ((chan & 3) == 1 && chan >= 149 && chan <= 165));
+}
+
static unsigned int
ath5k_copy_channels(struct ath5k_hw *ah,
struct ieee80211_channel *channels,
@@ -899,6 +934,9 @@ ath5k_copy_channels(struct ath5k_hw *ah,
if (!ath5k_channel_ok(ah, freq, chfreq))
continue;
+ if (!modparam_all_channels && !ath5k_is_standard_channel(ch))
+ continue;
+
/* Write channel info and increment counter */
channels[count].center_freq = freq;
channels[count].band = (chfreq == CHANNEL_2GHZ) ?
@@ -1238,7 +1276,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
(sc->power_level * 2),
hw_rate,
- info->control.rates[0].count, keyidx, 0, flags,
+ info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
cts_rate, duration);
if (ret)
goto err_unmap;
@@ -1574,9 +1612,8 @@ ath5k_rx_start(struct ath5k_softc *sc)
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n",
sc->cachelsz, sc->rxbufsize);
- sc->rxlink = NULL;
-
spin_lock_bh(&sc->rxbuflock);
+ sc->rxlink = NULL;
list_for_each_entry(bf, &sc->rxbuf, list) {
ret = ath5k_rxbuf_setup(sc, bf);
if (ret != 0) {
@@ -1585,9 +1622,9 @@ ath5k_rx_start(struct ath5k_softc *sc)
}
}
bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
+ ath5k_hw_set_rxdp(ah, bf->daddr);
spin_unlock_bh(&sc->rxbuflock);
- ath5k_hw_set_rxdp(ah, bf->daddr);
ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */
ath5k_mode_setup(sc); /* set filters, etc. */
ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */
@@ -1699,35 +1736,6 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
}
}
-static void ath5k_tasklet_beacon(unsigned long data)
-{
- struct ath5k_softc *sc = (struct ath5k_softc *) data;
-
- /*
- * Software beacon alert--time to send a beacon.
- *
- * In IBSS mode we use this interrupt just to
- * keep track of the next TBTT (target beacon
- * transmission time) in order to detect wether
- * automatic TSF updates happened.
- */
- if (sc->opmode == NL80211_IFTYPE_ADHOC) {
- /* XXX: only if VEOL suppported */
- u64 tsf = ath5k_hw_get_tsf64(sc->ah);
- sc->nexttbtt += sc->bintval;
- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
- "SWBA nexttbtt: %x hw_tu: %x "
- "TSF: %llx\n",
- sc->nexttbtt,
- TSF_TO_TU(tsf),
- (unsigned long long) tsf);
- } else {
- spin_lock(&sc->block);
- ath5k_beacon_send(sc);
- spin_unlock(&sc->block);
- }
-}
-
static void
ath5k_tasklet_rx(unsigned long data)
{
@@ -1736,7 +1744,7 @@ ath5k_tasklet_rx(unsigned long data)
struct sk_buff *skb, *next_skb;
dma_addr_t next_skb_addr;
struct ath5k_softc *sc = (void *)data;
- struct ath5k_buf *bf, *bf_last;
+ struct ath5k_buf *bf;
struct ath5k_desc *ds;
int ret;
int hdrlen;
@@ -1747,7 +1755,6 @@ ath5k_tasklet_rx(unsigned long data)
ATH5K_WARN(sc, "empty rx buf pool\n");
goto unlock;
}
- bf_last = list_entry(sc->rxbuf.prev, struct ath5k_buf, list);
do {
rxs.flag = 0;
@@ -1756,24 +1763,9 @@ ath5k_tasklet_rx(unsigned long data)
skb = bf->skb;
ds = bf->desc;
- /*
- * last buffer must not be freed to ensure proper hardware
- * function. When the hardware finishes also a packet next to
- * it, we are sure, it doesn't use it anymore and we can go on.
- */
- if (bf_last == bf)
- bf->flags |= 1;
- if (bf->flags) {
- struct ath5k_buf *bf_next = list_entry(bf->list.next,
- struct ath5k_buf, list);
- ret = sc->ah->ah_proc_rx_desc(sc->ah, bf_next->desc,
- &rs);
- if (ret)
- break;
- bf->flags &= ~1;
- /* skip the overwritten one (even status is martian) */
- goto next;
- }
+ /* bail if HW is still using self-linked descriptor */
+ if (ath5k_hw_get_rxdp(sc->ah) == bf->daddr)
+ break;
ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs);
if (unlikely(ret == -EINPROGRESS))
@@ -2014,7 +2006,8 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ath5k_hw *ah = sc->ah;
struct ath5k_desc *ds;
- int ret, antenna = 0;
+ int ret = 0;
+ u8 antenna;
u32 flags;
bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
@@ -2028,23 +2021,35 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
}
ds = bf->desc;
+ antenna = ah->ah_tx_ant;
flags = AR5K_TXDESC_NOACK;
if (sc->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) {
ds->ds_link = bf->daddr; /* self-linked */
flags |= AR5K_TXDESC_VEOL;
- /*
- * Let hardware handle antenna switching if txantenna is not set
- */
- } else {
+ } else
ds->ds_link = 0;
- /*
- * Switch antenna every 4 beacons if txantenna is not set
- * XXX assumes two antennas
- */
- if (antenna == 0)
- antenna = sc->bsent & 4 ? 2 : 1;
- }
+
+ /*
+ * If we use multiple antennas on AP and use
+ * the Sectored AP scenario, switch antenna every
+ * 4 beacons to make sure everybody hears our AP.
+ * When a client tries to associate, hw will keep
+ * track of the tx antenna to be used for this client
+ * automaticaly, based on ACKed packets.
+ *
+ * Note: AP still listens and transmits RTS on the
+ * default antenna which is supposed to be an omni.
+ *
+ * Note2: On sectored scenarios it's possible to have
+ * multiple antennas (1omni -the default- and 14 sectors)
+ * so if we choose to actually support this mode we need
+ * to allow user to set how many antennas we have and tweak
+ * the code below to send beacons on all of them.
+ */
+ if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP)
+ antenna = sc->bsent & 4 ? 2 : 1;
+
/* FIXME: If we are in g mode and rate is a CCK rate
* subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
@@ -2065,6 +2070,13 @@ err_unmap:
return ret;
}
+static void ath5k_beacon_disable(struct ath5k_softc *sc)
+{
+ sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
+ ath5k_hw_set_imr(sc->ah, sc->imask);
+ ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq);
+}
+
/*
* Transmit a beacon frame at SWBA. Dynamic updates to the
* frame contents are done as needed and the slot time is
@@ -2097,7 +2109,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
sc->bmisscount++;
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
"missed %u consecutive beacons\n", sc->bmisscount);
- if (sc->bmisscount > 3) { /* NB: 3 is a guess */
+ if (sc->bmisscount > 10) { /* NB: 10 is a guess */
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
"stuck beacon time (%u missed)\n",
sc->bmisscount);
@@ -2118,10 +2130,14 @@ ath5k_beacon_send(struct ath5k_softc *sc)
* are still pending on the queue.
*/
if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) {
- ATH5K_WARN(sc, "beacon queue %u didn't stop?\n", sc->bhalq);
+ ATH5K_WARN(sc, "beacon queue %u didn't start/stop ?\n", sc->bhalq);
/* NB: hw still stops DMA, so proceed */
}
+ /* refresh the beacon for AP mode */
+ if (sc->opmode == NL80211_IFTYPE_AP)
+ ath5k_beacon_update(sc->hw, sc->vif);
+
ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
ath5k_hw_start_tx_dma(ah, sc->bhalq);
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
@@ -2278,6 +2294,35 @@ ath5k_beacon_config(struct ath5k_softc *sc)
ath5k_hw_set_imr(ah, sc->imask);
}
+static void ath5k_tasklet_beacon(unsigned long data)
+{
+ struct ath5k_softc *sc = (struct ath5k_softc *) data;
+
+ /*
+ * Software beacon alert--time to send a beacon.
+ *
+ * In IBSS mode we use this interrupt just to
+ * keep track of the next TBTT (target beacon
+ * transmission time) in order to detect wether
+ * automatic TSF updates happened.
+ */
+ if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+ /* XXX: only if VEOL suppported */
+ u64 tsf = ath5k_hw_get_tsf64(sc->ah);
+ sc->nexttbtt += sc->bintval;
+ ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+ "SWBA nexttbtt: %x hw_tu: %x "
+ "TSF: %llx\n",
+ sc->nexttbtt,
+ TSF_TO_TU(tsf),
+ (unsigned long long) tsf);
+ } else {
+ spin_lock(&sc->block);
+ ath5k_beacon_send(sc);
+ spin_unlock(&sc->block);
+ }
+}
+
/********************\
* Interrupt handling *
@@ -2315,6 +2360,8 @@ ath5k_init(struct ath5k_softc *sc)
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.
@@ -2423,6 +2470,8 @@ ath5k_stop_hw(struct ath5k_softc *sc)
tasklet_kill(&sc->restq);
tasklet_kill(&sc->beacontq);
+ ath5k_rfkill_hw_stop(sc->ah);
+
return ret;
}
@@ -2452,7 +2501,7 @@ ath5k_intr(int irq, void *dev_id)
tasklet_schedule(&sc->restq);
} else {
if (status & AR5K_INT_SWBA) {
- tasklet_schedule(&sc->beacontq);
+ tasklet_hi_schedule(&sc->beacontq);
}
if (status & AR5K_INT_RXEOL) {
/*
@@ -2481,8 +2530,11 @@ ath5k_intr(int irq, void *dev_id)
*/
ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
}
+ if (status & AR5K_INT_GPIO)
+ tasklet_schedule(&sc->rf_kill.toggleq);
+
}
- } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0);
+ } while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
if (unlikely(!counter))
ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
@@ -2719,6 +2771,7 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
goto end;
ath5k_hw_set_lladdr(sc->ah, mac);
+ ath5k_beacon_disable(sc);
sc->vif = NULL;
end:
mutex_unlock(&sc->lock);
@@ -2731,53 +2784,43 @@ static int
ath5k_config(struct ieee80211_hw *hw, u32 changed)
{
struct ath5k_softc *sc = hw->priv;
+ struct ath5k_hw *ah = sc->ah;
struct ieee80211_conf *conf = &hw->conf;
- int ret;
+ int ret = 0;
mutex_lock(&sc->lock);
- sc->bintval = conf->beacon_int;
- sc->power_level = conf->power_level;
-
ret = ath5k_chan_set(sc, conf->channel);
+ if (ret < 0)
+ goto unlock;
- mutex_unlock(&sc->lock);
- return ret;
-}
-
-static int
-ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct ath5k_softc *sc = hw->priv;
- struct ath5k_hw *ah = sc->ah;
- int ret = 0;
+ if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
+ (sc->power_level != conf->power_level)) {
+ sc->power_level = conf->power_level;
- mutex_lock(&sc->lock);
- if (sc->vif != vif) {
- ret = -EIO;
- goto unlock;
- }
- if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
- /* Cache for later use during resets */
- memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN);
- /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
- * a clean way of letting us retrieve this yet. */
- ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
- mmiowb();
- }
- if (conf->changed & IEEE80211_IFCC_BEACON &&
- (vif->type == NL80211_IFTYPE_ADHOC ||
- vif->type == NL80211_IFTYPE_MESH_POINT ||
- vif->type == NL80211_IFTYPE_AP)) {
- struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
- if (!beacon) {
- ret = -ENOMEM;
- goto unlock;
- }
- ath5k_beacon_update(sc, beacon);
+ /* Half dB steps */
+ ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2));
}
+ /* TODO:
+ * 1) Move this on config_interface and handle each case
+ * separately eg. when we have only one STA vif, use
+ * AR5K_ANTMODE_SINGLE_AP
+ *
+ * 2) Allow the user to change antenna mode eg. when only
+ * one antenna is present
+ *
+ * 3) Allow the user to set default/tx antenna when possible
+ *
+ * 4) Default mode should handle 90% of the cases, together
+ * with fixed a/b and single AP modes we should be able to
+ * handle 99%. Sectored modes are extreme cases and i still
+ * haven't found a usage for them. If we decide to support them,
+ * then we must allow the user to set how many tx antennas we
+ * have available
+ */
+ ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
+
unlock:
mutex_unlock(&sc->lock);
return ret;
@@ -3020,28 +3063,62 @@ 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 ath5k_softc *sc, struct sk_buff *skb)
+ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
- unsigned long flags;
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);
- spin_lock_irqsave(&sc->block, flags);
ath5k_txbuf_free(sc, sc->bbuf);
sc->bbuf->skb = skb;
ret = ath5k_beacon_setup(sc, sc->bbuf);
if (ret)
sc->bbuf->skb = NULL;
+out:
+ return ret;
+}
+
+/*
+ * Update the beacon and reconfigure the beacon queues.
+ */
+static void
+ath5k_beacon_reconfig(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ int ret;
+ unsigned long flags;
+ struct ath5k_softc *sc = hw->priv;
+
+ spin_lock_irqsave(&sc->block, flags);
+ ret = ath5k_beacon_update(hw, vif);
spin_unlock_irqrestore(&sc->block, flags);
- if (!ret) {
+ if (ret == 0) {
ath5k_beacon_config(sc);
mmiowb();
}
-
- return ret;
}
+
static void
set_beacon_filter(struct ieee80211_hw *hw, bool enable)
{
@@ -3063,11 +3140,37 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
u32 changes)
{
struct ath5k_softc *sc = hw->priv;
+ struct ath5k_hw *ah = sc->ah;
+
+ mutex_lock(&sc->lock);
+ if (WARN_ON(sc->vif != vif))
+ goto unlock;
+
+ if (changes & BSS_CHANGED_BSSID) {
+ /* Cache for later use during resets */
+ memcpy(ah->ah_bssid, bss_conf->bssid, ETH_ALEN);
+ /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
+ * a clean way of letting us retrieve this yet. */
+ ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+ mmiowb();
+ }
+
+ if (changes & BSS_CHANGED_BEACON_INT)
+ sc->bintval = bss_conf->beacon_int;
+
if (changes & BSS_CHANGED_ASSOC) {
- mutex_lock(&sc->lock);
sc->assoc = bss_conf->assoc;
if (sc->opmode == NL80211_IFTYPE_STATION)
set_beacon_filter(hw, sc->assoc);
- mutex_unlock(&sc->lock);
}
+
+ if (changes & BSS_CHANGED_BEACON &&
+ (vif->type == NL80211_IFTYPE_ADHOC ||
+ vif->type == NL80211_IFTYPE_MESH_POINT ||
+ vif->type == NL80211_IFTYPE_AP)) {
+ ath5k_beacon_reconfig(hw, vif);
+ }
+
+ unlock:
+ mutex_unlock(&sc->lock);
}
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 822956114cd..f9b7f2f819b 100644
--- a/drivers/net/wireless/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -46,6 +46,7 @@
#include <linux/wireless.h>
#include <linux/if_ether.h>
#include <linux/leds.h>
+#include <linux/rfkill.h>
#include "ath5k.h"
#include "debug.h"
@@ -56,7 +57,6 @@
struct ath5k_buf {
struct list_head list;
- unsigned int flags; /* rx descriptor flags */
struct ath5k_desc *desc; /* virtual addr of desc */
dma_addr_t daddr; /* physical addr of desc */
struct sk_buff *skb; /* skbuff for buf */
@@ -92,6 +92,15 @@ struct ath5k_led
struct led_classdev led_dev; /* led classdev */
};
+/* Rfkill */
+struct ath5k_rfkill {
+ /* GPIO PIN for rfkill */
+ u16 gpio;
+ /* polarity of rfkill GPIO PIN */
+ bool polarity;
+ /* RFKILL toggle tasklet */
+ struct tasklet_struct toggleq;
+};
#if CHAN_DEBUG
#define ATH_CHAN_MAX (26+26+26+200+200)
@@ -168,6 +177,8 @@ struct ath5k_softc {
struct tasklet_struct txtq; /* tx intr tasklet */
struct ath5k_led tx_led; /* tx led */
+ struct ath5k_rfkill rf_kill;
+
spinlock_t block; /* protects beacon */
struct tasklet_struct beacontq; /* beacon intr tasklet */
struct ath5k_buf *bbuf; /* beacon buffer */
diff --git a/drivers/net/wireless/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c
index 367a6c7d3cc..367a6c7d3cc 100644
--- a/drivers/net/wireless/ath5k/caps.c
+++ b/drivers/net/wireless/ath/ath5k/caps.c
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 4904a07e4b5..4904a07e4b5 100644
--- a/drivers/net/wireless/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index 66f69f04e55..66f69f04e55 100644
--- a/drivers/net/wireless/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
diff --git a/drivers/net/wireless/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c
index dc30a2b70a6..dc30a2b70a6 100644
--- a/drivers/net/wireless/ath5k/desc.c
+++ b/drivers/net/wireless/ath/ath5k/desc.c
diff --git a/drivers/net/wireless/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h
index 56158c804e3..56158c804e3 100644
--- a/drivers/net/wireless/ath5k/desc.h
+++ b/drivers/net/wireless/ath/ath5k/desc.h
diff --git a/drivers/net/wireless/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c
index b65b4feb2d2..941b51130a6 100644
--- a/drivers/net/wireless/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -80,8 +80,6 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
* ath5k_hw_get_rxdp - Get RX Descriptor's address
*
* @ah: The &struct ath5k_hw
- *
- * XXX: Is RXDP read and clear ?
*/
u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
{
diff --git a/drivers/net/wireless/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index c0fb3b09ba4..c56b494d417 100644
--- a/drivers/net/wireless/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -156,6 +156,17 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
}
+ AR5K_EEPROM_READ(AR5K_EEPROM_IS_HB63, val);
+
+ if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && val)
+ ee->ee_is_hb63 = true;
+ else
+ ee->ee_is_hb63 = false;
+
+ AR5K_EEPROM_READ(AR5K_EEPROM_RFKILL, val);
+ ee->ee_rfkill_pin = (u8) AR5K_REG_MS(val, AR5K_EEPROM_RFKILL_GPIO_SEL);
+ ee->ee_rfkill_pol = val & AR5K_EEPROM_RFKILL_POLARITY ? true : false;
+
return 0;
}
@@ -197,16 +208,16 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
ee->ee_ant_control[mode][i++] = val & 0x3f;
- /* Get antenna modes */
- ah->ah_antenna[mode][0] =
+ /* Get antenna switch tables */
+ ah->ah_ant_ctl[mode][AR5K_ANT_CTL] =
(ee->ee_ant_control[mode][0] << 4);
- ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
+ ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] =
ee->ee_ant_control[mode][1] |
(ee->ee_ant_control[mode][2] << 6) |
(ee->ee_ant_control[mode][3] << 12) |
(ee->ee_ant_control[mode][4] << 18) |
(ee->ee_ant_control[mode][5] << 24);
- ah->ah_antenna[mode][AR5K_ANT_FIXED_B] =
+ ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] =
ee->ee_ant_control[mode][6] |
(ee->ee_ant_control[mode][7] << 6) |
(ee->ee_ant_control[mode][8] << 12) |
@@ -640,9 +651,9 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
static inline void
ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
{
- const static u16 intercepts3[] =
+ static const u16 intercepts3[] =
{ 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
- const static u16 intercepts3_2[] =
+ static const u16 intercepts3_2[] =
{ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
const u16 *ip;
int i;
@@ -1694,9 +1705,40 @@ ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
return 0;
}
+static int
+ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ u32 offset;
+ u16 val;
+ int ret = 0, i;
+
+ offset = AR5K_EEPROM_CTL(ee->ee_version) +
+ AR5K_EEPROM_N_CTLS(ee->ee_version);
+
+ if (ee->ee_version < AR5K_EEPROM_VERSION_5_3) {
+ /* No spur info for 5GHz */
+ ee->ee_spur_chans[0][0] = AR5K_EEPROM_NO_SPUR;
+ /* 2 channels for 2GHz (2464/2420) */
+ ee->ee_spur_chans[0][1] = AR5K_EEPROM_5413_SPUR_CHAN_1;
+ ee->ee_spur_chans[1][1] = AR5K_EEPROM_5413_SPUR_CHAN_2;
+ ee->ee_spur_chans[2][1] = AR5K_EEPROM_NO_SPUR;
+ } else if (ee->ee_version >= AR5K_EEPROM_VERSION_5_3) {
+ for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
+ AR5K_EEPROM_READ(offset, val);
+ ee->ee_spur_chans[i][0] = val;
+ AR5K_EEPROM_READ(offset + AR5K_EEPROM_N_SPUR_CHANS,
+ val);
+ ee->ee_spur_chans[i][1] = val;
+ offset++;
+ }
+ }
+
+ return ret;
+}
/*
- * Initialize eeprom power tables
+ * Initialize eeprom data structure
*/
int
ath5k_eeprom_init(struct ath5k_hw *ah)
@@ -1719,6 +1761,10 @@ ath5k_eeprom_init(struct ath5k_hw *ah)
if (err < 0)
return err;
+ err = ath5k_eeprom_read_spur_chans(ah);
+ if (err < 0)
+ return err;
+
return 0;
}
@@ -1754,16 +1800,3 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
return 0;
}
-
-bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah)
-{
- u16 data;
-
- ath5k_hw_eeprom_read(ah, AR5K_EEPROM_IS_HB63, &data);
-
- if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && data)
- return true;
- else
- return false;
-}
-
diff --git a/drivers/net/wireless/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index b0c0606dea0..64be73a5eda 100644
--- a/drivers/net/wireless/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -26,6 +26,13 @@
#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
#define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */
+
+#define AR5K_EEPROM_RFKILL 0x0f
+#define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c
+#define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2
+#define AR5K_EEPROM_RFKILL_POLARITY 0x00000002
+#define AR5K_EEPROM_RFKILL_POLARITY_S 1
+
#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
#define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */
#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
@@ -66,11 +73,6 @@
#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */
#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */
-#define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c
-#define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2
-#define AR5K_EEPROM_RFKILL_POLARITY 0x00000002
-#define AR5K_EEPROM_RFKILL_POLARITY_S 1
-
/* Newer EEPROMs are using a different offset */
#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
(((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0)
@@ -211,6 +213,23 @@
#define AR5K_EEPROM_I_GAIN 10
#define AR5K_EEPROM_CCK_OFDM_DELTA 15
#define AR5K_EEPROM_N_IQ_CAL 2
+/* 5GHz/2GHz */
+enum ath5k_eeprom_freq_bands{
+ AR5K_EEPROM_BAND_5GHZ = 0,
+ AR5K_EEPROM_BAND_2GHZ = 1,
+ AR5K_EEPROM_N_FREQ_BANDS,
+};
+/* Spur chans per freq band */
+#define AR5K_EEPROM_N_SPUR_CHANS 5
+/* fbin value for chan 2464 x2 */
+#define AR5K_EEPROM_5413_SPUR_CHAN_1 1640
+/* fbin value for chan 2420 x2 */
+#define AR5K_EEPROM_5413_SPUR_CHAN_2 1200
+#define AR5K_EEPROM_SPUR_CHAN_MASK 0x3FFF
+#define AR5K_EEPROM_NO_SPUR 0x8000
+#define AR5K_SPUR_CHAN_WIDTH 87
+#define AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz 3125
+#define AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz 6250
#define AR5K_EEPROM_READ(_o, _v) do { \
ret = ath5k_hw_eeprom_read(ah, (_o), &(_v)); \
@@ -221,11 +240,11 @@
#define AR5K_EEPROM_READ_HDR(_o, _v) \
AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \
-enum ath5k_ant_setting {
- AR5K_ANT_VARIABLE = 0, /* variable by programming */
- AR5K_ANT_FIXED_A = 1, /* fixed to 11a frequencies */
- AR5K_ANT_FIXED_B = 2, /* fixed to 11b frequencies */
- AR5K_ANT_MAX = 3,
+enum ath5k_ant_table {
+ AR5K_ANT_CTL = 0, /* Idle switch table settings */
+ AR5K_ANT_SWTABLE_A = 1, /* Switch table for antenna A */
+ AR5K_ANT_SWTABLE_B = 2, /* Switch table for antenna B */
+ AR5K_ANT_MAX,
};
enum ath5k_ctl_mode {
@@ -369,6 +388,9 @@ struct ath5k_eeprom_info {
u16 ee_version;
u16 ee_header;
u16 ee_ant_gain;
+ u8 ee_rfkill_pin;
+ bool ee_rfkill_pol;
+ bool ee_is_hb63;
u16 ee_misc0;
u16 ee_misc1;
u16 ee_misc2;
@@ -436,6 +458,10 @@ struct ath5k_eeprom_info {
s8 ee_pga_desired_size_turbo[AR5K_EEPROM_N_MODES];
s8 ee_pd_gain_overlap;
+ /* Spur mitigation data (fbin values for spur channels) */
+ u16 ee_spur_chans[AR5K_EEPROM_N_SPUR_CHANS][AR5K_EEPROM_N_FREQ_BANDS];
+
+ /* Antenna raw switch tables */
u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
};
diff --git a/drivers/net/wireless/ath5k/gpio.c b/drivers/net/wireless/ath/ath5k/gpio.c
index 64a27e73d02..64a27e73d02 100644
--- a/drivers/net/wireless/ath5k/gpio.c
+++ b/drivers/net/wireless/ath/ath5k/gpio.c
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c
index 61fb621ed20..18eb5190ce4 100644
--- a/drivers/net/wireless/ath5k/initvals.c
+++ b/drivers/net/wireless/ath/ath5k/initvals.c
@@ -537,8 +537,6 @@ static const struct ath5k_ini ar5212_ini_common_start[] = {
{ AR5K_DCU_TX_FILTER_1(15), 0x00000000 },
{ AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
{ AR5K_DCU_TX_FILTER_SET, 0x00000000 },
- { AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
- { AR5K_DCU_TX_FILTER_SET, 0x00000000 },
{ AR5K_STA_ID1, 0x00000000 },
{ AR5K_BSS_ID0, 0x00000000 },
{ AR5K_BSS_ID1, 0x00000000 },
@@ -669,7 +667,7 @@ static const struct ath5k_ini ar5212_ini_common_start[] = {
/*{ AR5K_PHY(650), 0x000001b5 },*/
{ AR5K_PHY(651), 0x00000000 },
{ AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
- { AR5K_PHY_TXPOWER_RATE2, 0x20202020 },
+ { AR5K_PHY_TXPOWER_RATE4, 0x20202020 },
/*{ AR5K_PHY(655), 0x13c889af },*/
{ AR5K_PHY(656), 0x38490a20 },
{ AR5K_PHY(657), 0x00007bb6 },
@@ -718,7 +716,7 @@ static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
{ AR5K_PHY_SETTLING,
{ 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
{ AR5K_PHY_AGCCTL,
- { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } },
+ { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d10 } },
{ AR5K_PHY_NF,
{ 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
{ AR5K_PHY_WEAK_OFDM_HIGH_THR,
@@ -799,7 +797,7 @@ static const struct ath5k_ini_mode rf5112_ini_mode_end[] = {
{ AR5K_PHY_DESIRED_SIZE,
{ 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } },
+ { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7e800d2e } },
{ AR5K_PHY_AGCCOARSE,
{ 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
diff --git a/drivers/net/wireless/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index 19555fb79c9..876725f08b6 100644
--- a/drivers/net/wireless/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -53,8 +53,6 @@
/* Devices we match on for LED config info (typically laptops) */
static const struct pci_device_id ath5k_led_devices[] = {
- /* IBM-specific AR5212 */
- { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
/* AR5211 */
{ PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) },
/* HP Compaq nc6xx, nc4000, nx6000 */
@@ -67,6 +65,12 @@ static const struct pci_device_id ath5k_led_devices[] = {
{ ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
/* Acer Extensa 5620z (nekoreeve@gmail.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) },
+ /* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) },
+ /* IBM ThinkPad AR5BXB6 (legovini@spiro.fisica.unipd.it) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_IBM, 0x058a), ATH_LED(1, 0) },
+ /* IBM-specific AR5212 (all others) */
+ { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
{ }
};
@@ -78,7 +82,7 @@ void ath5k_led_enable(struct ath5k_softc *sc)
}
}
-void ath5k_led_on(struct ath5k_softc *sc)
+static void ath5k_led_on(struct ath5k_softc *sc)
{
if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
return;
diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 55122f1e198..ec35503f6a4 100644
--- a/drivers/net/wireless/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -736,8 +736,8 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
/* When in AP mode zero timer0 to start TSF */
if (ah->ah_op_mode == NL80211_IFTYPE_AP)
ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
- else
- ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
+
+ ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
@@ -1003,7 +1003,7 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
* Note2: Windows driver (ndiswrapper) sets this to
* 0x00000714 instead of 0x00000007
*/
- if (ah->ah_version > AR5K_AR5211) {
+ if (ah->ah_version >= AR5K_AR5211) {
ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
AR5K_KEYTABLE_TYPE(entry));
@@ -1038,9 +1038,9 @@ int ath5k_keycache_type(const struct ieee80211_key_conf *key)
case ALG_CCMP:
return AR5K_KEYTABLE_TYPE_CCM;
case ALG_WEP:
- if (key->keylen == LEN_WEP40)
+ if (key->keylen == WLAN_KEY_LEN_WEP40)
return AR5K_KEYTABLE_TYPE_40;
- else if (key->keylen == LEN_WEP104)
+ else if (key->keylen == WLAN_KEY_LEN_WEP104)
return AR5K_KEYTABLE_TYPE_104;
return -EINVAL;
default:
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index b48b29dca3d..a876ca8d69e 100644
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -168,9 +168,6 @@ int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
* tx power and a Peak to Average Power Detector (PAPD) will try
* to measure the gain.
*
- * TODO: Use propper tx power setting for the probe packet so
- * that we don't observe a serious power drop on the receiver
- *
* XXX: How about forcing a tx packet (bypassing PCU arbitrator etc)
* just after we enable the probe so that we don't mess with
* standard traffic ? Maybe it's time to use sw interrupts and
@@ -186,7 +183,7 @@ static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
/* Send the packet with 2dB below max power as
* patent doc suggest */
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max_pwr - 4,
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_ofdm - 4,
AR5K_PHY_PAPD_PROBE_TXPOWER) |
AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
@@ -1356,6 +1353,257 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
return ret;
}
+/***************************\
+* Spur mitigation functions *
+\***************************/
+
+bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ u8 refclk_freq;
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+ refclk_freq = 40;
+ else
+ refclk_freq = 32;
+
+ if ((channel->center_freq % refclk_freq != 0) &&
+ ((channel->center_freq % refclk_freq < 10) ||
+ (channel->center_freq % refclk_freq > 22)))
+ return true;
+ else
+ return false;
+}
+
+void
+ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ u32 mag_mask[4] = {0, 0, 0, 0};
+ u32 pilot_mask[2] = {0, 0};
+ /* Note: fbin values are scaled up by 2 */
+ u16 spur_chan_fbin, chan_fbin, symbol_width, spur_detection_window;
+ s32 spur_delta_phase, spur_freq_sigma_delta;
+ s32 spur_offset, num_symbols_x16;
+ u8 num_symbol_offsets, i, freq_band;
+
+ /* Convert current frequency to fbin value (the same way channels
+ * are stored on EEPROM, check out ath5k_eeprom_bin2freq) and scale
+ * up by 2 so we can compare it later */
+ if (channel->hw_value & CHANNEL_2GHZ) {
+ chan_fbin = (channel->center_freq - 2300) * 10;
+ freq_band = AR5K_EEPROM_BAND_2GHZ;
+ } else {
+ chan_fbin = (channel->center_freq - 4900) * 10;
+ freq_band = AR5K_EEPROM_BAND_5GHZ;
+ }
+
+ /* Check if any spur_chan_fbin from EEPROM is
+ * within our current channel's spur detection range */
+ spur_chan_fbin = AR5K_EEPROM_NO_SPUR;
+ spur_detection_window = AR5K_SPUR_CHAN_WIDTH;
+ /* XXX: Half/Quarter channels ?*/
+ if (channel->hw_value & CHANNEL_TURBO)
+ spur_detection_window *= 2;
+
+ for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
+ spur_chan_fbin = ee->ee_spur_chans[i][freq_band];
+
+ /* Note: mask cleans AR5K_EEPROM_NO_SPUR flag
+ * so it's zero if we got nothing from EEPROM */
+ if (spur_chan_fbin == AR5K_EEPROM_NO_SPUR) {
+ spur_chan_fbin &= AR5K_EEPROM_SPUR_CHAN_MASK;
+ break;
+ }
+
+ if ((chan_fbin - spur_detection_window <=
+ (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK)) &&
+ (chan_fbin + spur_detection_window >=
+ (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK))) {
+ spur_chan_fbin &= AR5K_EEPROM_SPUR_CHAN_MASK;
+ break;
+ }
+ }
+
+ /* We need to enable spur filter for this channel */
+ if (spur_chan_fbin) {
+ spur_offset = spur_chan_fbin - chan_fbin;
+ /*
+ * Calculate deltas:
+ * spur_freq_sigma_delta -> spur_offset / sample_freq << 21
+ * spur_delta_phase -> spur_offset / chip_freq << 11
+ * Note: Both values have 100KHz resolution
+ */
+ /* XXX: Half/Quarter rate channels ? */
+ switch (channel->hw_value) {
+ case CHANNEL_A:
+ /* Both sample_freq and chip_freq are 40MHz */
+ spur_delta_phase = (spur_offset << 17) / 25;
+ spur_freq_sigma_delta = (spur_delta_phase >> 10);
+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
+ break;
+ case CHANNEL_G:
+ /* sample_freq -> 40MHz chip_freq -> 44MHz
+ * (for b compatibility) */
+ spur_freq_sigma_delta = (spur_offset << 8) / 55;
+ spur_delta_phase = (spur_offset << 17) / 25;
+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
+ break;
+ case CHANNEL_T:
+ case CHANNEL_TG:
+ /* Both sample_freq and chip_freq are 80MHz */
+ spur_delta_phase = (spur_offset << 16) / 25;
+ spur_freq_sigma_delta = (spur_delta_phase >> 10);
+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz;
+ break;
+ default:
+ return;
+ }
+
+ /* Calculate pilot and magnitude masks */
+
+ /* Scale up spur_offset by 1000 to switch to 100HZ resolution
+ * and divide by symbol_width to find how many symbols we have
+ * Note: number of symbols is scaled up by 16 */
+ num_symbols_x16 = ((spur_offset * 1000) << 4) / symbol_width;
+
+ /* Spur is on a symbol if num_symbols_x16 % 16 is zero */
+ if (!(num_symbols_x16 & 0xF))
+ /* _X_ */
+ num_symbol_offsets = 3;
+ else
+ /* _xx_ */
+ num_symbol_offsets = 4;
+
+ for (i = 0; i < num_symbol_offsets; i++) {
+
+ /* Calculate pilot mask */
+ s32 curr_sym_off =
+ (num_symbols_x16 / 16) + i + 25;
+
+ /* Pilot magnitude mask seems to be a way to
+ * declare the boundaries for our detection
+ * window or something, it's 2 for the middle
+ * value(s) where the symbol is expected to be
+ * and 1 on the boundary values */
+ u8 plt_mag_map =
+ (i == 0 || i == (num_symbol_offsets - 1))
+ ? 1 : 2;
+
+ if (curr_sym_off >= 0 && curr_sym_off <= 32) {
+ if (curr_sym_off <= 25)
+ pilot_mask[0] |= 1 << curr_sym_off;
+ else if (curr_sym_off >= 27)
+ pilot_mask[0] |= 1 << (curr_sym_off - 1);
+ } else if (curr_sym_off >= 33 && curr_sym_off <= 52)
+ pilot_mask[1] |= 1 << (curr_sym_off - 33);
+
+ /* Calculate magnitude mask (for viterbi decoder) */
+ if (curr_sym_off >= -1 && curr_sym_off <= 14)
+ mag_mask[0] |=
+ plt_mag_map << (curr_sym_off + 1) * 2;
+ else if (curr_sym_off >= 15 && curr_sym_off <= 30)
+ mag_mask[1] |=
+ plt_mag_map << (curr_sym_off - 15) * 2;
+ else if (curr_sym_off >= 31 && curr_sym_off <= 46)
+ mag_mask[2] |=
+ plt_mag_map << (curr_sym_off - 31) * 2;
+ else if (curr_sym_off >= 46 && curr_sym_off <= 53)
+ mag_mask[3] |=
+ plt_mag_map << (curr_sym_off - 47) * 2;
+
+ }
+
+ /* Write settings on hw to enable spur filter */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
+ AR5K_PHY_BIN_MASK_CTL_RATE, 0xff);
+ /* XXX: Self correlator also ? */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
+ AR5K_PHY_IQ_PILOT_MASK_EN |
+ AR5K_PHY_IQ_CHAN_MASK_EN |
+ AR5K_PHY_IQ_SPUR_FILT_EN);
+
+ /* Set delta phase and freq sigma delta */
+ ath5k_hw_reg_write(ah,
+ AR5K_REG_SM(spur_delta_phase,
+ AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE) |
+ AR5K_REG_SM(spur_freq_sigma_delta,
+ AR5K_PHY_TIMING_11_SPUR_FREQ_SD) |
+ AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC,
+ AR5K_PHY_TIMING_11);
+
+ /* Write pilot masks */
+ ath5k_hw_reg_write(ah, pilot_mask[0], AR5K_PHY_TIMING_7);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_8,
+ AR5K_PHY_TIMING_8_PILOT_MASK_2,
+ pilot_mask[1]);
+
+ ath5k_hw_reg_write(ah, pilot_mask[0], AR5K_PHY_TIMING_9);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_10,
+ AR5K_PHY_TIMING_10_PILOT_MASK_2,
+ pilot_mask[1]);
+
+ /* Write magnitude masks */
+ ath5k_hw_reg_write(ah, mag_mask[0], AR5K_PHY_BIN_MASK_1);
+ ath5k_hw_reg_write(ah, mag_mask[1], AR5K_PHY_BIN_MASK_2);
+ ath5k_hw_reg_write(ah, mag_mask[2], AR5K_PHY_BIN_MASK_3);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
+ AR5K_PHY_BIN_MASK_CTL_MASK_4,
+ mag_mask[3]);
+
+ ath5k_hw_reg_write(ah, mag_mask[0], AR5K_PHY_BIN_MASK2_1);
+ ath5k_hw_reg_write(ah, mag_mask[1], AR5K_PHY_BIN_MASK2_2);
+ ath5k_hw_reg_write(ah, mag_mask[2], AR5K_PHY_BIN_MASK2_3);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK2_4,
+ AR5K_PHY_BIN_MASK2_4_MASK_4,
+ mag_mask[3]);
+
+ } else if (ath5k_hw_reg_read(ah, AR5K_PHY_IQ) &
+ AR5K_PHY_IQ_SPUR_FILT_EN) {
+ /* Clean up spur mitigation settings and disable fliter */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
+ AR5K_PHY_BIN_MASK_CTL_RATE, 0);
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_IQ,
+ AR5K_PHY_IQ_PILOT_MASK_EN |
+ AR5K_PHY_IQ_CHAN_MASK_EN |
+ AR5K_PHY_IQ_SPUR_FILT_EN);
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_11);
+
+ /* Clear pilot masks */
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_7);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_8,
+ AR5K_PHY_TIMING_8_PILOT_MASK_2,
+ 0);
+
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_9);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_10,
+ AR5K_PHY_TIMING_10_PILOT_MASK_2,
+ 0);
+
+ /* Clear magnitude masks */
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_1);
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_2);
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_3);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
+ AR5K_PHY_BIN_MASK_CTL_MASK_4,
+ 0);
+
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_1);
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_2);
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_3);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK2_4,
+ AR5K_PHY_BIN_MASK2_4_MASK_4,
+ 0);
+ }
+}
+
+/********************\
+ Misc PHY functions
+\********************/
+
int ath5k_hw_phy_disable(struct ath5k_hw *ah)
{
ATH5K_TRACE(ah->ah_sc);
@@ -1365,10 +1613,6 @@ int ath5k_hw_phy_disable(struct ath5k_hw *ah)
return 0;
}
-/********************\
- Misc PHY functions
-\********************/
-
/*
* Get the PHY Chip revision
*/
@@ -1417,25 +1661,189 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
return ret;
}
+/*****************\
+* Antenna control *
+\*****************/
+
void /*TODO:Boundary check*/
-ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant)
+ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
{
ATH5K_TRACE(ah->ah_sc);
- /*Just a try M.F.*/
+
if (ah->ah_version != AR5K_AR5210)
- ath5k_hw_reg_write(ah, ant, AR5K_DEFAULT_ANTENNA);
+ ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
}
unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
{
ATH5K_TRACE(ah->ah_sc);
- /*Just a try M.F.*/
+
if (ah->ah_version != AR5K_AR5210)
- return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
+ return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA) & 0x7;
return false; /*XXX: What do we return for 5210 ?*/
}
+/*
+ * Enable/disable fast rx antenna diversity
+ */
+static void
+ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable)
+{
+ switch (ee_mode) {
+ case AR5K_EEPROM_MODE_11G:
+ /* XXX: This is set to
+ * disabled on initvals !!! */
+ case AR5K_EEPROM_MODE_11A:
+ if (enable)
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGCCTL,
+ AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
+ else
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+ AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
+ break;
+ case AR5K_EEPROM_MODE_11B:
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+ AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
+ break;
+ default:
+ return;
+ }
+
+ if (enable) {
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
+ AR5K_PHY_RESTART_DIV_GC, 0xc);
+
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
+ AR5K_PHY_FAST_ANT_DIV_EN);
+ } else {
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
+ AR5K_PHY_RESTART_DIV_GC, 0x8);
+
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
+ AR5K_PHY_FAST_ANT_DIV_EN);
+ }
+}
+
+/*
+ * Set antenna operating mode
+ */
+void
+ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
+{
+ struct ieee80211_channel *channel = &ah->ah_current_channel;
+ bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
+ bool use_def_for_sg;
+ u8 def_ant, tx_ant, ee_mode;
+ u32 sta_id1 = 0;
+
+ def_ant = ah->ah_def_ant;
+
+ ATH5K_TRACE(ah->ah_sc);
+
+ switch (channel->hw_value & CHANNEL_MODES) {
+ case CHANNEL_A:
+ case CHANNEL_T:
+ case CHANNEL_XR:
+ ee_mode = AR5K_EEPROM_MODE_11A;
+ break;
+ case CHANNEL_G:
+ case CHANNEL_TG:
+ ee_mode = AR5K_EEPROM_MODE_11G;
+ break;
+ case CHANNEL_B:
+ ee_mode = AR5K_EEPROM_MODE_11B;
+ break;
+ default:
+ ATH5K_ERR(ah->ah_sc,
+ "invalid channel: %d\n", channel->center_freq);
+ return;
+ }
+
+ switch (ant_mode) {
+ case AR5K_ANTMODE_DEFAULT:
+ tx_ant = 0;
+ use_def_for_tx = false;
+ update_def_on_tx = false;
+ use_def_for_rts = false;
+ use_def_for_sg = false;
+ fast_div = true;
+ break;
+ case AR5K_ANTMODE_FIXED_A:
+ def_ant = 1;
+ tx_ant = 0;
+ use_def_for_tx = true;
+ update_def_on_tx = false;
+ use_def_for_rts = true;
+ use_def_for_sg = true;
+ fast_div = false;
+ break;
+ case AR5K_ANTMODE_FIXED_B:
+ def_ant = 2;
+ tx_ant = 0;
+ use_def_for_tx = true;
+ update_def_on_tx = false;
+ use_def_for_rts = true;
+ use_def_for_sg = true;
+ fast_div = false;
+ break;
+ case AR5K_ANTMODE_SINGLE_AP:
+ def_ant = 1; /* updated on tx */
+ tx_ant = 0;
+ use_def_for_tx = true;
+ update_def_on_tx = true;
+ use_def_for_rts = true;
+ use_def_for_sg = true;
+ fast_div = true;
+ break;
+ case AR5K_ANTMODE_SECTOR_AP:
+ tx_ant = 1; /* variable */
+ use_def_for_tx = false;
+ update_def_on_tx = false;
+ use_def_for_rts = true;
+ use_def_for_sg = false;
+ fast_div = false;
+ break;
+ case AR5K_ANTMODE_SECTOR_STA:
+ tx_ant = 1; /* variable */
+ use_def_for_tx = true;
+ update_def_on_tx = false;
+ use_def_for_rts = true;
+ use_def_for_sg = false;
+ fast_div = true;
+ break;
+ case AR5K_ANTMODE_DEBUG:
+ def_ant = 1;
+ tx_ant = 2;
+ use_def_for_tx = false;
+ update_def_on_tx = false;
+ use_def_for_rts = false;
+ use_def_for_sg = false;
+ fast_div = false;
+ break;
+ default:
+ return;
+ }
+
+ ah->ah_tx_ant = tx_ant;
+ ah->ah_ant_mode = ant_mode;
+
+ sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0;
+ sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0;
+ sta_id1 |= use_def_for_rts ? AR5K_STA_ID1_RTS_DEF_ANTENNA : 0;
+ sta_id1 |= use_def_for_sg ? AR5K_STA_ID1_SELFGEN_DEF_ANT : 0;
+
+ AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_ANTENNA_SETTINGS);
+
+ if (sta_id1)
+ AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, sta_id1);
+
+ /* Note: set diversity before default antenna
+ * because it won't work correctly */
+ ath5k_hw_set_fast_div(ah, ee_mode, fast_div);
+ ath5k_hw_set_def_antenna(ah, def_ant);
+}
+
/****************\
* TX power setup *
@@ -1489,6 +1897,9 @@ ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
s16 min_pwrL, min_pwrR;
s16 pwr_i;
+ if (WARN_ON(stepL[0] == stepL[1] || stepR[0] == stepR[1]))
+ return 0;
+
if (pwrL[0] == pwrL[1])
min_pwrL = pwrL[0];
else {
@@ -1750,8 +2161,6 @@ done:
* Get the max edge power for this channel if
* we have such data from EEPROM's Conformance Test
* Limits (CTL), and limit max power if needed.
- *
- * FIXME: Only works for world regulatory domains
*/
static void
ath5k_get_max_ctl_power(struct ath5k_hw *ah,
@@ -1767,26 +2176,23 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,
u8 ctl_idx = 0xFF;
u32 target = channel->center_freq;
- /* Find out a CTL for our mode that's not mapped
- * on a specific reg domain.
- *
- * TODO: Map our current reg domain to one of the 3 available
- * reg domain ids so that we can support more CTLs. */
+ ctl_mode = ath_regd_get_band_ctl(&ah->ah_regulatory, channel->band);
+
switch (channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A:
- ctl_mode = AR5K_CTL_11A | AR5K_CTL_NO_REGDOMAIN;
+ ctl_mode |= AR5K_CTL_11A;
break;
case CHANNEL_G:
- ctl_mode = AR5K_CTL_11G | AR5K_CTL_NO_REGDOMAIN;
+ ctl_mode |= AR5K_CTL_11G;
break;
case CHANNEL_B:
- ctl_mode = AR5K_CTL_11B | AR5K_CTL_NO_REGDOMAIN;
+ ctl_mode |= AR5K_CTL_11B;
break;
case CHANNEL_T:
- ctl_mode = AR5K_CTL_TURBO | AR5K_CTL_NO_REGDOMAIN;
+ ctl_mode |= AR5K_CTL_TURBO;
break;
case CHANNEL_TG:
- ctl_mode = AR5K_CTL_TURBOG | AR5K_CTL_NO_REGDOMAIN;
+ ctl_mode |= AR5K_CTL_TURBOG;
break;
case CHANNEL_XR:
/* Fall through */
@@ -2482,8 +2888,19 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
for (i = 8; i <= 15; i++)
rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta;
- ah->ah_txpower.txp_min_pwr = rates[7];
- ah->ah_txpower.txp_max_pwr = rates[0];
+ /* Now that we have all rates setup use table offset to
+ * match the power range set by user with the power indices
+ * on PCDAC/PDADC table */
+ for (i = 0; i < 16; i++) {
+ rates[i] += ah->ah_txpower.txp_offset;
+ /* Don't get out of bounds */
+ if (rates[i] > 63)
+ rates[i] = 63;
+ }
+
+ /* Min/max in 0.25dB units */
+ ah->ah_txpower.txp_min_pwr = 2 * rates[7];
+ ah->ah_txpower.txp_max_pwr = 2 * rates[0];
ah->ah_txpower.txp_ofdm = rates[7];
}
@@ -2591,16 +3008,37 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
return 0;
}
-int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 mode, u8 txpower)
+int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
{
/*Just a try M.F.*/
struct ieee80211_channel *channel = &ah->ah_current_channel;
+ u8 ee_mode;
ATH5K_TRACE(ah->ah_sc);
+
+ switch (channel->hw_value & CHANNEL_MODES) {
+ case CHANNEL_A:
+ case CHANNEL_T:
+ case CHANNEL_XR:
+ ee_mode = AR5K_EEPROM_MODE_11A;
+ break;
+ case CHANNEL_G:
+ case CHANNEL_TG:
+ ee_mode = AR5K_EEPROM_MODE_11G;
+ break;
+ case CHANNEL_B:
+ ee_mode = AR5K_EEPROM_MODE_11B;
+ break;
+ default:
+ ATH5K_ERR(ah->ah_sc,
+ "invalid channel: %d\n", channel->center_freq);
+ return -EINVAL;
+ }
+
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
"changing txpower to %d\n", txpower);
- return ath5k_hw_txpower(ah, channel, mode, txpower);
+ return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
}
#undef _ATH5K_PHY
diff --git a/drivers/net/wireless/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 5094c394a4b..73407b3f53e 100644
--- a/drivers/net/wireless/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -160,7 +160,8 @@ u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
if (ah->ah_version == AR5K_AR5210)
return false;
- pending = (AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT);
+ pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
+ pending &= AR5K_QCU_STS_FRMPENDCNT;
/* It's possible to have no frames pending even if TXE
* is set. To indicate that q has not stopped return
@@ -401,14 +402,16 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
(AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
AR5K_DCU_MISC_ARBLOCK_CTL_S) |
+ AR5K_DCU_MISC_ARBLOCK_IGNORE |
AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
AR5K_DCU_MISC_BCN_ENABLE);
break;
case AR5K_TX_QUEUE_CAB:
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
- AR5K_QCU_MISC_FRSHED_DBA_GT |
+ AR5K_QCU_MISC_FRSHED_BCN_SENT_GT |
AR5K_QCU_MISC_CBREXP_DIS |
+ AR5K_QCU_MISC_RDY_VEOL_POLICY |
AR5K_QCU_MISC_CBREXP_BCN_DIS);
ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index 7070d1543cd..6809b54a2ad 100644
--- a/drivers/net/wireless/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -1148,6 +1148,11 @@
#define AR5K_STA_ID1_CBCIV_ENDIAN 0x40000000 /* ??? */
#define AR5K_STA_ID1_KEYSRCH_MCAST 0x80000000 /* Do key cache search for mcast frames */
+#define AR5K_STA_ID1_ANTENNA_SETTINGS (AR5K_STA_ID1_DEFAULT_ANTENNA | \
+ AR5K_STA_ID1_DESC_ANTENNA | \
+ AR5K_STA_ID1_RTS_DEF_ANTENNA | \
+ AR5K_STA_ID1_SELFGEN_DEF_ANT)
+
/*
* First BSSID register (MAC address, lower 32bits)
*/
@@ -2028,7 +2033,9 @@
#define AR5K_PHY_AGCCTL 0x9860 /* Register address */
#define AR5K_PHY_AGCCTL_CAL 0x00000001 /* Enable PHY calibration */
#define AR5K_PHY_AGCCTL_NF 0x00000002 /* Enable Noise Floor calibration */
+#define AR5K_PHY_AGCCTL_OFDM_DIV_DIS 0x00000008 /* Disable antenna diversity on OFDM modes */
#define AR5K_PHY_AGCCTL_NF_EN 0x00008000 /* Enable nf calibration to happen (?) */
+#define AR5K_PHY_AGCTL_FLTR_CAL 0x00010000 /* Allow filter calibration (?) */
#define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automaticaly */
/*
@@ -2528,7 +2535,7 @@
* PHY CCK Cross-correlator Barker RSSI threshold register [5212+]
*/
#define AR5K_PHY_CCK_CROSSCORR 0xa208
-#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000000f
+#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000003f
#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S 0
/* Same address is used for antenna diversity activation */
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 5f72c111c2e..bd0a97a38d3 100644
--- a/drivers/net/wireless/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -54,9 +54,8 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
u32 coef_scaled, coef_exp, coef_man,
ds_coef_exp, ds_coef_man, clock;
- if (!(ah->ah_version == AR5K_AR5212) ||
- !(channel->hw_value & CHANNEL_OFDM))
- BUG();
+ BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
+ !(channel->hw_value & CHANNEL_OFDM));
/* Get coefficient
* ALGO: coef = (5 * clock * carrier_freq) / 2)
@@ -508,7 +507,7 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
scal = AR5K_PHY_SCAL_32MHZ_2417;
- else if (ath5k_eeprom_is_hb63(ah))
+ else if (ee->ee_is_hb63)
scal = AR5K_PHY_SCAL_32MHZ_HB63;
else
scal = AR5K_PHY_SCAL_32MHZ;
@@ -537,26 +536,6 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
return;
}
-static bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
- struct ieee80211_channel *channel)
-{
- u8 refclk_freq;
-
- if ((ah->ah_radio == AR5K_RF5112) ||
- (ah->ah_radio == AR5K_RF5413) ||
- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
- refclk_freq = 40;
- else
- refclk_freq = 32;
-
- if ((channel->center_freq % refclk_freq != 0) &&
- ((channel->center_freq % refclk_freq < 10) ||
- (channel->center_freq % refclk_freq > 22)))
- return true;
- else
- return false;
-}
-
/* TODO: Half/Quarter rate */
static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
struct ieee80211_channel *channel)
@@ -599,9 +578,10 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
/* Set DAC/ADC delays */
if (ah->ah_version == AR5K_AR5212) {
u32 scal;
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
scal = AR5K_PHY_SCAL_32MHZ_2417;
- else if (ath5k_eeprom_is_hb63(ah))
+ else if (ee->ee_is_hb63)
scal = AR5K_PHY_SCAL_32MHZ_HB63;
else
scal = AR5K_PHY_SCAL_32MHZ;
@@ -698,13 +678,13 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
/* Set antenna idle switch table */
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
- (ah->ah_antenna[ee_mode][0] |
+ (ah->ah_ant_ctl[ee_mode][0] |
AR5K_PHY_ANT_CTL_TXRX_EN));
- /* Set antenna switch table */
- ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
+ /* Set antenna switch tables */
+ ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[0]],
AR5K_PHY_ANT_SWITCH_TABLE_0);
- ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
+ ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[1]],
AR5K_PHY_ANT_SWITCH_TABLE_1);
/* Noise floor threshold */
@@ -998,10 +978,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ath5k_hw_tweak_initval_settings(ah, channel);
/*
- * Set TX power (FIXME)
+ * Set TX power
*/
ret = ath5k_hw_txpower(ah, channel, ee_mode,
- AR5K_TUNE_DEFAULT_TXPOWER);
+ ah->ah_txpower.txp_max_pwr / 2);
if (ret)
return ret;
@@ -1024,9 +1004,22 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/* Write OFDM timings on 5212*/
if (ah->ah_version == AR5K_AR5212 &&
channel->hw_value & CHANNEL_OFDM) {
+ struct ath5k_eeprom_info *ee =
+ &ah->ah_capabilities.cap_eeprom;
+
ret = ath5k_hw_write_ofdm_timings(ah, channel);
if (ret)
return ret;
+
+ /* Note: According to docs we can have a newer
+ * EEPROM on old hardware, so we need to verify
+ * that our hardware is new enough to have spur
+ * mitigation registers (delta phase etc) */
+ if (ah->ah_mac_srev >= AR5K_SREV_AR5424 ||
+ (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
+ ee->ee_version >= AR5K_EEPROM_VERSION_5_3))
+ ath5k_hw_set_spur_mitigation_filter(ah,
+ channel);
}
/*Enable/disable 802.11b mode on 5111
@@ -1042,17 +1035,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/*
* In case a fixed antenna was set as default
- * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
- * registers.
+ * use the same switch table twice.
*/
- if (s_ant != 0) {
- if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */
- ant[0] = ant[1] = AR5K_ANT_FIXED_A;
- else /* 2 - Aux */
- ant[0] = ant[1] = AR5K_ANT_FIXED_B;
- } else {
- ant[0] = AR5K_ANT_FIXED_A;
- ant[1] = AR5K_ANT_FIXED_B;
+ if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A)
+ ant[0] = ant[1] = AR5K_ANT_SWTABLE_A;
+ else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B)
+ ant[0] = ant[1] = AR5K_ANT_SWTABLE_B;
+ else {
+ ant[0] = AR5K_ANT_SWTABLE_A;
+ ant[1] = AR5K_ANT_SWTABLE_B;
}
/* Commit values from EEPROM */
@@ -1260,6 +1251,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
*/
ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
+ /* Restore antenna mode */
+ ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
/*
* Configure QCUs/DCUs
@@ -1311,23 +1304,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
if (ah->ah_version != AR5K_AR5210)
ath5k_hw_set_imr(ah, ah->ah_imr);
- /*
- * Setup RFKill interrupt if rfkill flag is set on eeprom.
- * TODO: Use gpio pin and polarity infos from eeprom
- * TODO: Handle this in ath5k_intr because it'll result
- * a nasty interrupt storm.
- */
-#if 0
- if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
- ath5k_hw_set_gpio_input(ah, 0);
- ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
- if (ah->ah_gpio[0] == 0)
- ath5k_hw_set_gpio_intr(ah, 0, 1);
- else
- ath5k_hw_set_gpio_intr(ah, 0, 0);
- }
-#endif
-
/* Enable 32KHz clock function for AR5212+ chips
* Set clocks to 32KHz operation and use an
* external 32KHz crystal when sleeping if one
diff --git a/drivers/net/wireless/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h
index e50baff6617..e50baff6617 100644
--- a/drivers/net/wireless/ath5k/rfbuffer.h
+++ b/drivers/net/wireless/ath/ath5k/rfbuffer.h
diff --git a/drivers/net/wireless/ath5k/rfgain.h b/drivers/net/wireless/ath/ath5k/rfgain.h
index 1354d8c392c..1354d8c392c 100644
--- a/drivers/net/wireless/ath5k/rfgain.h
+++ b/drivers/net/wireless/ath/ath5k/rfgain.h
diff --git a/drivers/net/wireless/ath/ath5k/rfkill.c b/drivers/net/wireless/ath/ath5k/rfkill.c
new file mode 100644
index 00000000000..41a877b73fc
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/rfkill.c
@@ -0,0 +1,121 @@
+/*
+ * RFKILL support for ath5k
+ *
+ * Copyright (c) 2009 Tobias Doerffel <tobias.doerffel@gmail.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "base.h"
+
+
+static inline void ath5k_rfkill_disable(struct ath5k_softc *sc)
+{
+ ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill disable (gpio:%d polarity:%d)\n",
+ sc->rf_kill.gpio, sc->rf_kill.polarity);
+ ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
+ ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, !sc->rf_kill.polarity);
+}
+
+
+static inline void ath5k_rfkill_enable(struct ath5k_softc *sc)
+{
+ ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill enable (gpio:%d polarity:%d)\n",
+ sc->rf_kill.gpio, sc->rf_kill.polarity);
+ ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
+ ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, sc->rf_kill.polarity);
+}
+
+static inline void ath5k_rfkill_set_intr(struct ath5k_softc *sc, bool enable)
+{
+ struct ath5k_hw *ah = sc->ah;
+ u32 curval;
+
+ ath5k_hw_set_gpio_input(ah, sc->rf_kill.gpio);
+ curval = ath5k_hw_get_gpio(ah, sc->rf_kill.gpio);
+ ath5k_hw_set_gpio_intr(ah, sc->rf_kill.gpio, enable ?
+ !!curval : !curval);
+}
+
+static bool
+ath5k_is_rfkill_set(struct ath5k_softc *sc)
+{
+ /* configuring GPIO for input for some reason disables rfkill */
+ /*ath5k_hw_set_gpio_input(sc->ah, sc->rf_kill.gpio);*/
+ return ath5k_hw_get_gpio(sc->ah, sc->rf_kill.gpio) ==
+ sc->rf_kill.polarity;
+}
+
+static void
+ath5k_tasklet_rfkill_toggle(unsigned long data)
+{
+ struct ath5k_softc *sc = (void *)data;
+ bool blocked;
+
+ blocked = ath5k_is_rfkill_set(sc);
+ wiphy_rfkill_set_hw_state(sc->hw->wiphy, blocked);
+}
+
+
+void
+ath5k_rfkill_hw_start(struct ath5k_hw *ah)
+{
+ struct ath5k_softc *sc = ah->ah_sc;
+
+ /* read rfkill GPIO configuration from EEPROM header */
+ sc->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin;
+ sc->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol;
+
+ tasklet_init(&sc->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle,
+ (unsigned long)sc);
+
+ ath5k_rfkill_disable(sc);
+
+ /* enable interrupt for rfkill switch */
+ if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header))
+ ath5k_rfkill_set_intr(sc, true);
+}
+
+
+void
+ath5k_rfkill_hw_stop(struct ath5k_hw *ah)
+{
+ struct ath5k_softc *sc = ah->ah_sc;
+
+ /* disable interrupt for rfkill switch */
+ if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header))
+ ath5k_rfkill_set_intr(sc, false);
+
+ tasklet_kill(&sc->rf_kill.toggleq);
+
+ /* enable RFKILL when stopping HW so Wifi LED is turned off */
+ ath5k_rfkill_enable(sc);
+}
+
diff --git a/drivers/net/wireless/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 90a8dd87378..0ed1ac312aa 100644
--- a/drivers/net/wireless/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -2,6 +2,7 @@ config ATH9K
tristate "Atheros 802.11n wireless cards support"
depends on PCI && MAC80211 && WLAN_80211
depends on RFKILL || RFKILL=n
+ select ATH_COMMON
select MAC80211_LEDS
select LEDS_CLASS
select NEW_LEDS
diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 1a4d4eab6fe..783bc39eb2f 100644
--- a/drivers/net/wireless/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -4,7 +4,6 @@ ath9k-y += hw.o \
calib.o \
ani.o \
phy.o \
- regd.o \
beacon.o \
main.o \
recv.o \
diff --git a/drivers/net/wireless/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 0e65c51ba17..0e65c51ba17 100644
--- a/drivers/net/wireless/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 6c5e887d50d..1aeafb511dd 100644
--- a/drivers/net/wireless/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -569,8 +569,7 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"phyCnt1 0x%x, resetting "
"counter value to 0x%x\n",
- phyCnt1,
- aniState->ofdmPhyErrBase);
+ phyCnt1, aniState->ofdmPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_1,
aniState->ofdmPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_MASK_1,
@@ -580,8 +579,7 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"phyCnt2 0x%x, resetting "
"counter value to 0x%x\n",
- phyCnt2,
- aniState->cckPhyErrBase);
+ phyCnt2, aniState->cckPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_2,
aniState->cckPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_MASK_2,
@@ -667,7 +665,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
u32 cc = REG_READ(ah, AR_CCCNT);
if (cycles == 0 || cycles > cc) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
+ DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"cycle counter wrap. ExtBusy = 0\n");
good = 0;
} else {
diff --git a/drivers/net/wireless/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 08b4e7ed5ff..08b4e7ed5ff 100644
--- a/drivers/net/wireless/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 2689a08a284..515880aa211 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -53,11 +53,7 @@ struct ath_node;
#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
-#define ASSERT(exp) do { \
- if (unlikely(!(exp))) { \
- BUG(); \
- } \
- } while (0)
+#define ASSERT(exp) BUG_ON(!(exp))
#define TSF_TO_TU(_h,_l) \
((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
@@ -70,7 +66,6 @@ struct ath_config {
u32 ath_aggr_prot;
u16 txpowlimit;
u8 cabqReadytime;
- u8 swBeaconProcess;
};
/*************************/
@@ -78,13 +73,17 @@ struct ath_config {
/*************************/
#define ATH_TXBUF_RESET(_bf) do { \
- (_bf)->bf_status = 0; \
+ (_bf)->bf_stale = false; \
(_bf)->bf_lastbf = NULL; \
(_bf)->bf_next = NULL; \
memset(&((_bf)->bf_state), 0, \
sizeof(struct ath_buf_state)); \
} while (0)
+#define ATH_RXBUF_RESET(_bf) do { \
+ (_bf)->bf_stale = false; \
+ } while (0)
+
/**
* enum buffer_type - Buffer type flags
*
@@ -110,7 +109,7 @@ struct ath_buf_state {
int bfs_seqno;
int bfs_tidno;
int bfs_retries;
- u32 bf_type;
+ u8 bf_type;
u32 bfs_keyix;
enum ath9k_key_type bfs_keytype;
};
@@ -134,26 +133,21 @@ struct ath_buf {
struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or
an aggregate) */
struct ath_buf *bf_next; /* next subframe in the aggregate */
- void *bf_mpdu; /* enclosing frame structure */
+ struct sk_buff *bf_mpdu; /* enclosing frame structure */
struct ath_desc *bf_desc; /* virtual addr of desc */
dma_addr_t bf_daddr; /* physical addr of desc */
dma_addr_t bf_buf_addr; /* physical addr of data buffer */
- u32 bf_status;
+ bool bf_stale;
u16 bf_flags;
struct ath_buf_state bf_state;
dma_addr_t bf_dmacontext;
};
-#define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0)
-#define ATH_BUFSTATUS_STALE 0x00000002
-
struct ath_descdma {
- const char *dd_name;
struct ath_desc *dd_desc;
dma_addr_t dd_desc_paddr;
u32 dd_desc_len;
struct ath_buf *dd_bufptr;
- dma_addr_t dd_dmacontext;
};
int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
@@ -299,26 +293,6 @@ struct ath_tx_control {
#define ATH_TX_XRETRY 0x02
#define ATH_TX_BAR 0x04
-/* All RSSI values are noise floor adjusted */
-struct ath_tx_stat {
- int rssi;
- int rssictl[ATH_MAX_ANTENNA];
- int rssiextn[ATH_MAX_ANTENNA];
- int rateieee;
- int rateKbps;
- int ratecode;
- int flags;
- u32 airtime; /* time on air per final tx rate */
-};
-
-struct aggr_rifs_param {
- int param_max_frames;
- int param_max_len;
- int param_rl;
- int param_al;
- struct ath_rc_series *param_rcs;
-};
-
struct ath_node {
struct ath_softc *an_sc;
struct ath_atx_tid tid[WME_NUM_TID];
@@ -366,7 +340,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
int ath_tx_init(struct ath_softc *sc, int nbufs);
-int ath_tx_cleanup(struct ath_softc *sc);
+void ath_tx_cleanup(struct ath_softc *sc);
struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
int ath_txq_update(struct ath_softc *sc, int qnum,
struct ath9k_tx_queue_info *q);
@@ -486,12 +460,9 @@ struct ath_led {
bool registered;
};
-/* Rfkill */
-#define ATH_RFKILL_POLL_INTERVAL 2000 /* msecs */
-
struct ath_rfkill {
struct rfkill *rfkill;
- struct delayed_work rfkill_poll;
+ struct rfkill_ops ops;
char rfkill_name[32];
};
@@ -529,19 +500,20 @@ struct ath_rfkill {
#define SC_OP_BEACONS BIT(1)
#define SC_OP_RXAGGR BIT(2)
#define SC_OP_TXAGGR BIT(3)
-#define SC_OP_CHAINMASK_UPDATE BIT(4)
-#define SC_OP_FULL_RESET BIT(5)
-#define SC_OP_PREAMBLE_SHORT BIT(6)
-#define SC_OP_PROTECT_ENABLE BIT(7)
-#define SC_OP_RXFLUSH BIT(8)
-#define SC_OP_LED_ASSOCIATED BIT(9)
-#define SC_OP_RFKILL_REGISTERED BIT(10)
-#define SC_OP_RFKILL_SW_BLOCKED BIT(11)
-#define SC_OP_RFKILL_HW_BLOCKED BIT(12)
-#define SC_OP_WAIT_FOR_BEACON BIT(13)
-#define SC_OP_LED_ON BIT(14)
-#define SC_OP_SCANNING BIT(15)
-#define SC_OP_TSF_RESET BIT(16)
+#define SC_OP_FULL_RESET BIT(4)
+#define SC_OP_PREAMBLE_SHORT BIT(5)
+#define SC_OP_PROTECT_ENABLE BIT(6)
+#define SC_OP_RXFLUSH BIT(7)
+#define SC_OP_LED_ASSOCIATED BIT(8)
+#define SC_OP_RFKILL_REGISTERED BIT(9)
+#define SC_OP_WAIT_FOR_BEACON BIT(12)
+#define SC_OP_LED_ON BIT(13)
+#define SC_OP_SCANNING BIT(14)
+#define SC_OP_TSF_RESET BIT(15)
+#define SC_OP_WAIT_FOR_CAB BIT(16)
+#define SC_OP_WAIT_FOR_PSPOLL_DATA BIT(17)
+#define SC_OP_WAIT_FOR_TX_ACK BIT(18)
+#define SC_OP_BEACON_SYNC BIT(19)
struct ath_bus_ops {
void (*read_cachesize)(struct ath_softc *sc, int *csz);
@@ -603,8 +575,8 @@ struct ath_softc {
struct ath_tx tx;
struct ath_beacon beacon;
struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
- struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
- struct ath_rate_table *cur_rate_table;
+ const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
+ const struct ath_rate_table *cur_rate_table;
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
struct ath_led radio_led;
@@ -617,6 +589,8 @@ struct ath_softc {
int led_on_cnt;
int led_off_cnt;
+ int beacon_interval;
+
struct ath_rfkill rf_kill;
struct ath_ani ani;
struct ath9k_node_stats nodestats;
@@ -624,6 +598,7 @@ struct ath_softc {
struct ath9k_debug debug;
#endif
struct ath_bus_ops *bus_ops;
+ struct ath_beacon_config cur_beacon_conf;
};
struct ath_wiphy {
@@ -701,7 +676,9 @@ static inline void ath9k_ps_restore(struct ath_softc *sc)
{
if (atomic_dec_and_test(&sc->ps_usecount))
if ((sc->hw->conf.flags & IEEE80211_CONF_PS) &&
- !(sc->sc_flags & SC_OP_WAIT_FOR_BEACON))
+ !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
+ SC_OP_WAIT_FOR_PSPOLL_DATA |
+ SC_OP_WAIT_FOR_TX_ACK)))
ath9k_hw_setpower(sc->sc_ah,
sc->sc_ah->restore_mode);
}
@@ -722,36 +699,7 @@ void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
bool ath9k_wiphy_scanning(struct ath_softc *sc);
void ath9k_wiphy_work(struct work_struct *work);
-/*
- * Read and write, they both share the same lock. We do this to serialize
- * reads and writes on Atheros 802.11n PCI devices only. This is required
- * as the FIFO on these devices can only accept sanely 2 requests. After
- * that the device goes bananas. Serializing the reads/writes prevents this
- * from happening.
- */
-
-static inline void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
-{
- if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
- unsigned long flags;
- spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
- iowrite32(val, ah->ah_sc->mem + reg_offset);
- spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
- } else
- iowrite32(val, ah->ah_sc->mem + reg_offset);
-}
-
-static inline unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
-{
- u32 val;
- if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
- unsigned long flags;
- spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
- val = ioread32(ah->ah_sc->mem + reg_offset);
- spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
- } else
- val = ioread32(ah->ah_sc->mem + reg_offset);
- return val;
-}
+void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val);
+unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset);
#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index ec995730632..3639a2e6987 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -43,7 +43,7 @@ static int ath_beaconq_config(struct ath_softc *sc)
if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
DPRINTF(sc, ATH_DBG_FATAL,
- "unable to update h/w beacon queue parameters\n");
+ "Unable to update h/w beacon queue parameters\n");
return 0;
} else {
ath9k_hw_resettxqueue(ah, sc->beacon.beaconq);
@@ -59,11 +59,11 @@ static int ath_beaconq_config(struct ath_softc *sc)
static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
struct ath_buf *bf)
{
- struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
+ struct sk_buff *skb = bf->bf_mpdu;
struct ath_hw *ah = sc->sc_ah;
struct ath_desc *ds;
struct ath9k_11n_rate_series series[4];
- struct ath_rate_table *rt;
+ const struct ath_rate_table *rt;
int flags, antenna, ctsrate = 0, ctsduration = 0;
u8 rate;
@@ -132,16 +132,13 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
avp = (void *)vif->drv_priv;
cabq = sc->beacon.cabq;
- if (avp->av_bcbuf == NULL) {
- DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n",
- avp, avp->av_bcbuf);
+ if (avp->av_bcbuf == NULL)
return NULL;
- }
/* Release the old beacon first */
bf = avp->av_bcbuf;
- skb = (struct sk_buff *)bf->bf_mpdu;
+ skb = bf->bf_mpdu;
if (skb) {
dma_unmap_single(sc->dev, bf->bf_dmacontext,
skb->len, DMA_TO_DEVICE);
@@ -229,7 +226,7 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc,
return;
bf = avp->av_bcbuf;
- skb = (struct sk_buff *) bf->bf_mpdu;
+ skb = bf->bf_mpdu;
ath_beacon_setup(sc, avp, bf);
@@ -302,7 +299,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
/* release the previous beacon frame, if it already exists. */
bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) {
- skb = (struct sk_buff *)bf->bf_mpdu;
+ skb = bf->bf_mpdu;
dma_unmap_single(sc->dev, bf->bf_dmacontext,
skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
@@ -323,8 +320,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
u64 tsfadjust;
int intval;
- intval = sc->hw->conf.beacon_int ?
- sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
+ intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL;
/*
* Calculate the TSF offset for this beacon slot, i.e., the
@@ -374,7 +370,7 @@ 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 = (struct sk_buff *)bf->bf_mpdu;
+ struct sk_buff *skb = bf->bf_mpdu;
dma_unmap_single(sc->dev, bf->bf_dmacontext,
skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
@@ -415,6 +411,7 @@ void ath_beacon_tasklet(unsigned long data)
} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
DPRINTF(sc, ATH_DBG_BEACON,
"beacon is officially stuck\n");
+ sc->sc_flags |= SC_OP_TSF_RESET;
ath_reset(sc, false);
}
@@ -434,8 +431,7 @@ void ath_beacon_tasklet(unsigned long data)
* on the tsf to safeguard against missing an swba.
*/
- intval = sc->hw->conf.beacon_int ?
- sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
+ intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL;
tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU(tsf>>32, tsf);
@@ -512,8 +508,7 @@ void ath_beacon_tasklet(unsigned long data)
* slot. Slots that are not occupied will generate nothing.
*/
static void ath_beacon_config_ap(struct ath_softc *sc,
- struct ath_beacon_config *conf,
- struct ath_vif *avp)
+ struct ath_beacon_config *conf)
{
u32 nexttbtt, intval;
@@ -558,14 +553,14 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
* we've associated with.
*/
static void ath_beacon_config_sta(struct ath_softc *sc,
- struct ath_beacon_config *conf,
- struct ath_vif *avp)
+ struct ath_beacon_config *conf)
{
struct ath9k_beacon_state bs;
int dtimperiod, dtimcount, sleepduration;
int cfpperiod, cfpcount;
u32 nexttbtt = 0, intval, tsftu;
u64 tsf;
+ int num_beacons, offset, dtim_dec_count, cfp_dec_count;
memset(&bs, 0, sizeof(bs));
intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
@@ -593,14 +588,27 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
*/
tsf = ath9k_hw_gettsf64(sc->sc_ah);
tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
- do {
+
+ num_beacons = tsftu / intval + 1;
+ offset = tsftu % intval;
+ nexttbtt = tsftu - offset;
+ if (offset)
nexttbtt += intval;
- if (--dtimcount < 0) {
- dtimcount = dtimperiod - 1;
- if (--cfpcount < 0)
- cfpcount = cfpperiod - 1;
- }
- } while (nexttbtt < tsftu);
+
+ /* DTIM Beacon every dtimperiod Beacon */
+ dtim_dec_count = num_beacons % dtimperiod;
+ /* CFP every cfpperiod DTIM Beacon */
+ cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod;
+ if (dtim_dec_count)
+ cfp_dec_count++;
+
+ dtimcount -= dtim_dec_count;
+ if (dtimcount < 0)
+ dtimcount += dtimperiod;
+
+ cfpcount -= cfp_dec_count;
+ if (cfpcount < 0)
+ cfpcount += cfpperiod;
bs.bs_intval = intval;
bs.bs_nexttbtt = nexttbtt;
@@ -659,7 +667,6 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
static void ath_beacon_config_adhoc(struct ath_softc *sc,
struct ath_beacon_config *conf,
- struct ath_vif *avp,
struct ieee80211_vif *vif)
{
u64 tsf;
@@ -667,6 +674,14 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+ /*
+ * It looks like mac80211 may end up using beacon interval of zero in
+ * some cases (at least for mesh point). Avoid getting into an
+ * infinite loop by using a bit safer value instead..
+ */
+ if (intval == 0)
+ intval = 100;
+
/* Pull nexttbtt forward to reflect the current TSF */
nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
@@ -703,44 +718,50 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
sc->beacon.bmisscnt = 0;
ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
+ /* FIXME: Handle properly when vif is NULL */
+ if (vif && sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
ath_beacon_start_adhoc(sc, vif);
}
void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
{
- struct ath_beacon_config conf;
+ struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
+ enum nl80211_iftype iftype;
/* Setup the beacon configuration parameters */
- memset(&conf, 0, sizeof(struct ath_beacon_config));
- conf.beacon_interval = sc->hw->conf.beacon_int ?
- sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
- conf.listen_interval = 1;
- conf.dtim_period = conf.beacon_interval;
- conf.dtim_count = 1;
- conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
-
if (vif) {
- struct ath_vif *avp = (struct ath_vif *)vif->drv_priv;
-
- switch(avp->av_opmode) {
- case NL80211_IFTYPE_AP:
- ath_beacon_config_ap(sc, &conf, avp);
- break;
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_MESH_POINT:
- ath_beacon_config_adhoc(sc, &conf, avp, vif);
- break;
- case NL80211_IFTYPE_STATION:
- ath_beacon_config_sta(sc, &conf, avp);
- break;
- default:
- DPRINTF(sc, ATH_DBG_CONFIG,
- "Unsupported beaconing mode\n");
- return;
- }
+ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+
+ iftype = vif->type;
+
+ cur_conf->beacon_interval = bss_conf->beacon_int;
+ cur_conf->dtim_period = bss_conf->dtim_period;
+ cur_conf->listen_interval = 1;
+ cur_conf->dtim_count = 1;
+ cur_conf->bmiss_timeout =
+ ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
+ } else {
+ iftype = sc->sc_ah->opmode;
+ }
+
- sc->sc_flags |= SC_OP_BEACONS;
+ switch (iftype) {
+ case NL80211_IFTYPE_AP:
+ ath_beacon_config_ap(sc, cur_conf);
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
+ ath_beacon_config_adhoc(sc, cur_conf, vif);
+ break;
+ case NL80211_IFTYPE_STATION:
+ ath_beacon_config_sta(sc, cur_conf);
+ break;
+ default:
+ DPRINTF(sc, ATH_DBG_CONFIG,
+ "Unsupported beaconing mode\n");
+ return;
}
+
+ sc->sc_flags |= SC_OP_BEACONS;
}
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index e2d62e97131..a32d7e7fecb 100644
--- a/drivers/net/wireless/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -186,7 +186,7 @@ static bool getNoiseFloorThresh(struct ath_hw *ah,
}
static void ath9k_hw_setup_calibration(struct ath_hw *ah,
- struct hal_cal_list *currCal)
+ struct ath9k_cal_list *currCal)
{
REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
@@ -220,7 +220,7 @@ static void ath9k_hw_setup_calibration(struct ath_hw *ah,
}
static void ath9k_hw_reset_calibration(struct ath_hw *ah,
- struct hal_cal_list *currCal)
+ struct ath9k_cal_list *currCal)
{
int i;
@@ -238,13 +238,12 @@ static void ath9k_hw_reset_calibration(struct ath_hw *ah,
ah->cal_samples = 0;
}
-static void ath9k_hw_per_calibration(struct ath_hw *ah,
+static bool ath9k_hw_per_calibration(struct ath_hw *ah,
struct ath9k_channel *ichan,
u8 rxchainmask,
- struct hal_cal_list *currCal,
- bool *isCalDone)
+ struct ath9k_cal_list *currCal)
{
- *isCalDone = false;
+ bool iscaldone = false;
if (currCal->calState == CAL_RUNNING) {
if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
@@ -263,7 +262,7 @@ static void ath9k_hw_per_calibration(struct ath_hw *ah,
currCal->calData->calPostProc(ah, numChains);
ichan->CalValid |= currCal->calData->calType;
currCal->calState = CAL_DONE;
- *isCalDone = true;
+ iscaldone = true;
} else {
ath9k_hw_setup_calibration(ah, currCal);
}
@@ -271,11 +270,13 @@ static void ath9k_hw_per_calibration(struct ath_hw *ah,
} else if (!(ichan->CalValid & currCal->calData->calType)) {
ath9k_hw_reset_calibration(ah, currCal);
}
+
+ return iscaldone;
}
/* Assumes you are talking about the currently configured channel */
static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
- enum hal_cal_types calType)
+ enum ath9k_cal_types calType)
{
struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
@@ -284,8 +285,8 @@ static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
return true;
case ADC_GAIN_CAL:
case ADC_DC_CAL:
- if (conf->channel->band == IEEE80211_BAND_5GHZ &&
- conf_is_ht20(conf))
+ if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
+ conf_is_ht20(conf)))
return true;
break;
}
@@ -498,7 +499,7 @@ static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
{
u32 iOddMeasOffset, iEvenMeasOffset, val, i;
int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
- const struct hal_percal_data *calData =
+ const struct ath9k_percal_data *calData =
ah->cal_list_curr->calData;
u32 numSamples =
(1 << (calData->calCountMax + 5)) * calData->calNumSamples;
@@ -555,7 +556,7 @@ static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
{
struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
- struct hal_cal_list *currCal = ah->cal_list_curr;
+ struct ath9k_cal_list *currCal = ah->cal_list_curr;
if (!ah->curchan)
return true;
@@ -841,30 +842,28 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
}
bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
- u8 rxchainmask, bool longcal,
- bool *isCalDone)
+ u8 rxchainmask, bool longcal)
{
- struct hal_cal_list *currCal = ah->cal_list_curr;
-
- *isCalDone = true;
+ bool iscaldone = true;
+ struct ath9k_cal_list *currCal = ah->cal_list_curr;
if (currCal &&
(currCal->calState == CAL_RUNNING ||
currCal->calState == CAL_WAITING)) {
- ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal,
- isCalDone);
- if (*isCalDone) {
+ iscaldone = ath9k_hw_per_calibration(ah, chan,
+ rxchainmask, currCal);
+ if (iscaldone) {
ah->cal_list_curr = currCal = currCal->calNext;
if (currCal->calState == CAL_WAITING) {
- *isCalDone = false;
+ iscaldone = false;
ath9k_hw_reset_calibration(ah, currCal);
}
}
}
if (longcal) {
- if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
+ if (AR_SREV_9285_11_OR_LATER(ah))
ath9k_hw_9285_pa_cal(ah);
if (OLC_FOR_AR9280_20_LATER)
@@ -872,18 +871,15 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
ath9k_hw_getnf(ah, chan);
ath9k_hw_loadnf(ah, ah->curchan);
ath9k_hw_start_nfcal(ah);
-
- if (chan->channelFlags & CHANNEL_CW_INT)
- chan->channelFlags &= ~CHANNEL_CW_INT;
}
- return true;
+ return iscaldone;
}
static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
{
REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
- if (chan->channelFlags & CHANNEL_HT20) {
+ if (IS_CHAN_HT20(chan)) {
REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
@@ -919,83 +915,66 @@ static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
return true;
}
-bool ath9k_hw_init_cal(struct ath_hw *ah,
- struct ath9k_channel *chan)
+bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
{
- if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
+ if (AR_SREV_9285_12_OR_LATER(ah)) {
if (!ar9285_clc(ah, chan))
return false;
- } else if (AR_SREV_9280_10_OR_LATER(ah)) {
- REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
- REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
- REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+ } else {
+ if (AR_SREV_9280_10_OR_LATER(ah)) {
+ REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ }
- /* Kick off the cal */
+ /* Calibrate the AGC */
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
- REG_READ(ah, AR_PHY_AGC_CONTROL) |
- AR_PHY_AGC_CONTROL_CAL);
+ REG_READ(ah, AR_PHY_AGC_CONTROL) |
+ AR_PHY_AGC_CONTROL_CAL);
- if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
- AR_PHY_AGC_CONTROL_CAL, 0,
- AH_WAIT_TIMEOUT)) {
+ /* Poll for offset calibration complete */
+ if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
+ 0, AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"offset calibration failed to complete in 1ms; "
"noisy environment?\n");
return false;
}
- REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
- REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
- REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
- }
-
- /* Calibrate the AGC */
- REG_WRITE(ah, AR_PHY_AGC_CONTROL,
- REG_READ(ah, AR_PHY_AGC_CONTROL) |
- AR_PHY_AGC_CONTROL_CAL);
-
- if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
- 0, AH_WAIT_TIMEOUT)) {
- DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "offset calibration failed to complete in 1ms; "
- "noisy environment?\n");
- return false;
- }
-
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
- REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ if (AR_SREV_9280_10_OR_LATER(ah)) {
+ REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ }
}
/* Do PA Calibration */
- if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
+ if (AR_SREV_9285_11_OR_LATER(ah))
ath9k_hw_9285_pa_cal(ah);
- /* Do NF Calibration */
+ /* Do NF Calibration after DC offset and other calibrations */
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
- REG_READ(ah, AR_PHY_AGC_CONTROL) |
- AR_PHY_AGC_CONTROL_NF);
+ REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
+ /* Enable IQ, ADC Gain and ADC DC offset CALs */
if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
INIT_CAL(&ah->adcgain_caldata);
INSERT_CAL(ah, &ah->adcgain_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "enabling ADC Gain Calibration.\n");
+ "enabling ADC Gain Calibration.\n");
}
if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
INIT_CAL(&ah->adcdc_caldata);
INSERT_CAL(ah, &ah->adcdc_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "enabling ADC DC Calibration.\n");
+ "enabling ADC DC Calibration.\n");
}
if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
INIT_CAL(&ah->iq_caldata);
INSERT_CAL(ah, &ah->iq_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "enabling IQ Calibration.\n");
+ "enabling IQ Calibration.\n");
}
ah->cal_list_curr = ah->cal_list;
@@ -1009,49 +988,49 @@ bool ath9k_hw_init_cal(struct ath_hw *ah,
return true;
}
-const struct hal_percal_data iq_cal_multi_sample = {
+const struct ath9k_percal_data iq_cal_multi_sample = {
IQ_MISMATCH_CAL,
MAX_CAL_SAMPLES,
PER_MIN_LOG_COUNT,
ath9k_hw_iqcal_collect,
ath9k_hw_iqcalibrate
};
-const struct hal_percal_data iq_cal_single_sample = {
+const struct ath9k_percal_data iq_cal_single_sample = {
IQ_MISMATCH_CAL,
MIN_CAL_SAMPLES,
PER_MAX_LOG_COUNT,
ath9k_hw_iqcal_collect,
ath9k_hw_iqcalibrate
};
-const struct hal_percal_data adc_gain_cal_multi_sample = {
+const struct ath9k_percal_data adc_gain_cal_multi_sample = {
ADC_GAIN_CAL,
MAX_CAL_SAMPLES,
PER_MIN_LOG_COUNT,
ath9k_hw_adc_gaincal_collect,
ath9k_hw_adc_gaincal_calibrate
};
-const struct hal_percal_data adc_gain_cal_single_sample = {
+const struct ath9k_percal_data adc_gain_cal_single_sample = {
ADC_GAIN_CAL,
MIN_CAL_SAMPLES,
PER_MAX_LOG_COUNT,
ath9k_hw_adc_gaincal_collect,
ath9k_hw_adc_gaincal_calibrate
};
-const struct hal_percal_data adc_dc_cal_multi_sample = {
+const struct ath9k_percal_data adc_dc_cal_multi_sample = {
ADC_DC_CAL,
MAX_CAL_SAMPLES,
PER_MIN_LOG_COUNT,
ath9k_hw_adc_dccal_collect,
ath9k_hw_adc_dccal_calibrate
};
-const struct hal_percal_data adc_dc_cal_single_sample = {
+const struct ath9k_percal_data adc_dc_cal_single_sample = {
ADC_DC_CAL,
MIN_CAL_SAMPLES,
PER_MAX_LOG_COUNT,
ath9k_hw_adc_dccal_collect,
ath9k_hw_adc_dccal_calibrate
};
-const struct hal_percal_data adc_init_dc_cal = {
+const struct ath9k_percal_data adc_init_dc_cal = {
ADC_DC_INIT_CAL,
MIN_CAL_SAMPLES,
INIT_LOG_COUNT,
diff --git a/drivers/net/wireless/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 1c74bd50700..fe5367f1414 100644
--- a/drivers/net/wireless/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -17,13 +17,13 @@
#ifndef CALIB_H
#define CALIB_H
-extern const struct hal_percal_data iq_cal_multi_sample;
-extern const struct hal_percal_data iq_cal_single_sample;
-extern const struct hal_percal_data adc_gain_cal_multi_sample;
-extern const struct hal_percal_data adc_gain_cal_single_sample;
-extern const struct hal_percal_data adc_dc_cal_multi_sample;
-extern const struct hal_percal_data adc_dc_cal_single_sample;
-extern const struct hal_percal_data adc_init_dc_cal;
+extern const struct ath9k_percal_data iq_cal_multi_sample;
+extern const struct ath9k_percal_data iq_cal_single_sample;
+extern const struct ath9k_percal_data adc_gain_cal_multi_sample;
+extern const struct ath9k_percal_data adc_gain_cal_single_sample;
+extern const struct ath9k_percal_data adc_dc_cal_multi_sample;
+extern const struct ath9k_percal_data adc_dc_cal_single_sample;
+extern const struct ath9k_percal_data adc_init_dc_cal;
#define AR_PHY_CCA_MAX_GOOD_VALUE -85
#define AR_PHY_CCA_MAX_HIGH_VALUE -62
@@ -67,14 +67,14 @@ struct ar5416IniArray {
} \
} while (0)
-enum hal_cal_types {
+enum ath9k_cal_types {
ADC_DC_INIT_CAL = 0x1,
ADC_GAIN_CAL = 0x2,
ADC_DC_CAL = 0x4,
IQ_MISMATCH_CAL = 0x8
};
-enum hal_cal_state {
+enum ath9k_cal_state {
CAL_INACTIVE,
CAL_WAITING,
CAL_RUNNING,
@@ -87,18 +87,18 @@ enum hal_cal_state {
#define PER_MIN_LOG_COUNT 2
#define PER_MAX_LOG_COUNT 10
-struct hal_percal_data {
- enum hal_cal_types calType;
+struct ath9k_percal_data {
+ enum ath9k_cal_types calType;
u32 calNumSamples;
u32 calCountMax;
void (*calCollect) (struct ath_hw *);
void (*calPostProc) (struct ath_hw *, u8);
};
-struct hal_cal_list {
- const struct hal_percal_data *calData;
- enum hal_cal_state calState;
- struct hal_cal_list *calNext;
+struct ath9k_cal_list {
+ const struct ath9k_percal_data *calData;
+ enum ath9k_cal_state calState;
+ struct ath9k_cal_list *calNext;
};
struct ath9k_nfcal_hist {
@@ -116,8 +116,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
- u8 rxchainmask, bool longcal,
- bool *isCalDone);
+ u8 rxchainmask, bool longcal);
bool ath9k_hw_init_cal(struct ath_hw *ah,
struct ath9k_channel *chan);
diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index fdf9528fa49..6d20725d645 100644
--- a/drivers/net/wireless/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -44,6 +44,44 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file)
return 0;
}
+static ssize_t read_file_debug(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ char buf[32];
+ unsigned int len;
+
+ len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.debug_mask);
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ unsigned long mask;
+ char buf[32];
+ ssize_t len;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EINVAL;
+
+ buf[len] = '\0';
+ if (strict_strtoul(buf, 0, &mask))
+ return -EINVAL;
+
+ sc->debug.debug_mask = mask;
+ return count;
+}
+
+static const struct file_operations fops_debug = {
+ .read = read_file_debug,
+ .write = write_file_debug,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE
+};
+
static ssize_t read_file_dma(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -224,111 +262,66 @@ static const struct file_operations fops_interrupt = {
.owner = THIS_MODULE
};
-static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb)
-{
- struct ath_tx_info_priv *tx_info_priv = NULL;
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ieee80211_tx_rate *rates = tx_info->status.rates;
- int final_ts_idx, idx;
-
- tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
- final_ts_idx = tx_info_priv->tx.ts_rateindex;
- idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate;
-
- sc->debug.stats.n_rcstats[idx].success++;
-}
-
-static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb)
+void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
{
struct ath_tx_info_priv *tx_info_priv = NULL;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rates = tx_info->status.rates;
int final_ts_idx, idx;
+ struct ath_rc_stats *stats;
tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
final_ts_idx = tx_info_priv->tx.ts_rateindex;
idx = rates[final_ts_idx].idx;
-
- sc->debug.stats.legacy_rcstats[idx].success++;
+ stats = &sc->debug.stats.rcstats[idx];
+ stats->success++;
}
-void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
-{
- if (conf_is_ht(&sc->hw->conf))
- ath_debug_stat_11n_rc(sc, skb);
- else
- ath_debug_stat_legacy_rc(sc, skb);
-}
-
-/* FIXME: legacy rates, later on .. */
void ath_debug_stat_retries(struct ath_softc *sc, int rix,
int xretries, int retries, u8 per)
{
- if (conf_is_ht(&sc->hw->conf)) {
- int idx = sc->cur_rate_table->info[rix].dot11rate;
+ struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix];
- sc->debug.stats.n_rcstats[idx].xretries += xretries;
- sc->debug.stats.n_rcstats[idx].retries += retries;
- sc->debug.stats.n_rcstats[idx].per = per;
- }
+ stats->xretries += xretries;
+ stats->retries += retries;
+ stats->per = per;
}
-static ssize_t ath_read_file_stat_11n_rc(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
+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[1024];
- unsigned int len = 0;
+ char *buf;
+ unsigned int len = 0, max;
int i = 0;
+ ssize_t retval;
- len += sprintf(buf, "%7s %13s %8s %8s %6s\n\n", "Rate", "Success",
- "Retries", "XRetries", "PER");
-
- for (i = 0; i <= 15; i++) {
- len += snprintf(buf + len, sizeof(buf) - len,
- "%5s%3d: %8u %8u %8u %8u\n", "MCS", i,
- sc->debug.stats.n_rcstats[i].success,
- sc->debug.stats.n_rcstats[i].retries,
- sc->debug.stats.n_rcstats[i].xretries,
- sc->debug.stats.n_rcstats[i].per);
- }
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
+ if (sc->cur_rate_table == NULL)
+ return 0;
-static ssize_t ath_read_file_stat_legacy_rc(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath_softc *sc = file->private_data;
- char buf[512];
- unsigned int len = 0;
- int i = 0;
+ max = 80 + sc->cur_rate_table->rate_cnt * 64;
+ buf = kmalloc(max + 1, GFP_KERNEL);
+ if (buf == NULL)
+ return 0;
+ buf[max] = 0;
- len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success");
+ len += sprintf(buf, "%5s %15s %8s %9s %3s\n\n", "Rate", "Success",
+ "Retries", "XRetries", "PER");
for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
- len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n",
- sc->cur_rate_table->info[i].ratekbps / 1000,
- sc->debug.stats.legacy_rcstats[i].success);
+ u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
+ struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
+
+ len += snprintf(buf + len, max - len,
+ "%3u.%d: %8u %8u %8u %8u\n", ratekbps / 1000,
+ (ratekbps % 1000) / 100, stats->success,
+ stats->retries, stats->xretries,
+ stats->per);
}
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath_softc *sc = file->private_data;
-
- if (sc->cur_rate_table == NULL)
- return 0;
-
- if (conf_is_ht(&sc->hw->conf))
- return ath_read_file_stat_11n_rc(file, user_buf, count, ppos);
- else
- return ath_read_file_stat_legacy_rc(file, user_buf, count ,ppos);
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+ return retval;
}
static const struct file_operations fops_rcstat = {
@@ -498,11 +491,19 @@ int ath9k_init_debug(struct ath_softc *sc)
{
sc->debug.debug_mask = ath9k_debug;
+ if (!ath9k_debugfs_root)
+ return -ENOENT;
+
sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
ath9k_debugfs_root);
if (!sc->debug.debugfs_phy)
goto err;
+ sc->debug.debugfs_debug = debugfs_create_file("debug",
+ S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug);
+ if (!sc->debug.debugfs_debug)
+ goto err;
+
sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
sc->debug.debugfs_phy, sc, &fops_dma);
if (!sc->debug.debugfs_dma)
@@ -540,6 +541,7 @@ void ath9k_exit_debug(struct ath_softc *sc)
debugfs_remove(sc->debug.debugfs_rcstat);
debugfs_remove(sc->debug.debugfs_interrupt);
debugfs_remove(sc->debug.debugfs_dma);
+ debugfs_remove(sc->debug.debugfs_debug);
debugfs_remove(sc->debug.debugfs_phy);
}
diff --git a/drivers/net/wireless/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 7b0e5419d2b..edda15bf2c1 100644
--- a/drivers/net/wireless/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -19,20 +19,17 @@
enum ATH_DEBUG {
ATH_DBG_RESET = 0x00000001,
- ATH_DBG_REG_IO = 0x00000002,
- ATH_DBG_QUEUE = 0x00000004,
- ATH_DBG_EEPROM = 0x00000008,
- ATH_DBG_CALIBRATE = 0x00000010,
- ATH_DBG_CHANNEL = 0x00000020,
- ATH_DBG_INTERRUPT = 0x00000040,
- ATH_DBG_REGULATORY = 0x00000080,
- ATH_DBG_ANI = 0x00000100,
- ATH_DBG_POWER_MGMT = 0x00000200,
- ATH_DBG_XMIT = 0x00000400,
- ATH_DBG_BEACON = 0x00001000,
- ATH_DBG_CONFIG = 0x00002000,
- ATH_DBG_KEYCACHE = 0x00004000,
- ATH_DBG_FATAL = 0x00008000,
+ ATH_DBG_QUEUE = 0x00000002,
+ ATH_DBG_EEPROM = 0x00000004,
+ ATH_DBG_CALIBRATE = 0x00000008,
+ ATH_DBG_INTERRUPT = 0x00000010,
+ ATH_DBG_REGULATORY = 0x00000020,
+ ATH_DBG_ANI = 0x00000040,
+ ATH_DBG_XMIT = 0x00000080,
+ ATH_DBG_BEACON = 0x00000100,
+ ATH_DBG_CONFIG = 0x00000200,
+ ATH_DBG_FATAL = 0x00000400,
+ ATH_DBG_PS = 0x00000800,
ATH_DBG_ANY = 0xffffffff
};
@@ -83,11 +80,7 @@ struct ath_interrupt_stats {
u32 dtim;
};
-struct ath_legacy_rc_stats {
- u32 success;
-};
-
-struct ath_11n_rc_stats {
+struct ath_rc_stats {
u32 success;
u32 retries;
u32 xretries;
@@ -96,13 +89,13 @@ struct ath_11n_rc_stats {
struct ath_stats {
struct ath_interrupt_stats istats;
- struct ath_legacy_rc_stats legacy_rcstats[12]; /* max(11a,11b,11g) */
- struct ath_11n_rc_stats n_rcstats[16]; /* 0..15 MCS rates */
+ struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
};
struct ath9k_debug {
int debug_mask;
struct dentry *debugfs_phy;
+ struct dentry *debugfs_debug;
struct dentry *debugfs_dma;
struct dentry *debugfs_interrupt;
struct dentry *debugfs_rcstat;
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index ffc36b0361c..a2fda702b62 100644
--- a/drivers/net/wireless/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -694,7 +694,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
#undef TMP_VAL_VPD_TABLE
}
-static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
+static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
struct ath9k_channel *chan,
int16_t *pTxPowerIndexOffset)
{
@@ -783,11 +783,11 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
((pdadcValues[4 * j + 3] & 0xFF) << 24);
REG_WRITE(ah, regOffset, reg32);
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"PDADC (%d,%4x): %4.4x %8.8x\n",
i, regChainOffset, regOffset,
reg32);
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"PDADC: Chain %d | "
"PDADC %3d Value %3d | "
"PDADC %3d Value %3d | "
@@ -805,11 +805,9 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
}
*pTxPowerIndexOffset = 0;
-
- return true;
}
-static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
+static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
struct ath9k_channel *chan,
int16_t *ratesArray,
u16 cfgCtl,
@@ -910,7 +908,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
ah->eep_ops->get_eeprom_rev(ah) <= 2)
twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
"EXT_ADDITIVE %d\n",
ctlMode, numCtlModes, isHt40CtlMode,
@@ -918,7 +916,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
for (i = 0; (i < AR5416_NUM_CTLS) &&
pEepData->ctlIndex[i]; i++) {
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
" LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
"pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
"chan %d\n",
@@ -941,7 +939,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
IS_CHAN_2GHZ(chan),
AR5416_EEP4K_NUM_BAND_EDGES);
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
" MATCH-EE_IDX %d: ch %d is2 %d "
"2xMinEdge %d chainmask %d chains %d\n",
i, freq, IS_CHAN_2GHZ(chan),
@@ -961,7 +959,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
" SEL-Min ctlMode %d pCtlMode %d "
"2xMaxEdge %d sP %d minCtlPwr %d\n",
ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
@@ -1041,10 +1039,9 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
}
- return true;
}
-static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
+static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
struct ath9k_channel *chan,
u16 cfgCtl,
u8 twiceAntennaReduction,
@@ -1065,22 +1062,13 @@ static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
}
- if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan,
+ ath9k_hw_set_4k_power_per_rate_table(ah, chan,
&ratesArray[0], cfgCtl,
twiceAntennaReduction,
twiceMaxRegulatoryPower,
- powerLimit)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "ath9k_hw_set_txpower: unable to set "
- "tx power per rate table\n");
- return -EIO;
- }
+ powerLimit);
- if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "ath9k_hw_set_txpower: unable to set power table\n");
- return -EIO;
- }
+ ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
@@ -1168,7 +1156,6 @@ static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
else
ah->regulatory.max_power_level = ratesArray[i];
- return 0;
}
static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
@@ -2103,7 +2090,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
return;
}
-static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
+static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
struct ath9k_channel *chan,
int16_t *pTxPowerIndexOffset)
{
@@ -2234,11 +2221,11 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
((pdadcValues[4 * j + 3] & 0xFF) << 24);
REG_WRITE(ah, regOffset, reg32);
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"PDADC (%d,%4x): %4.4x %8.8x\n",
i, regChainOffset, regOffset,
reg32);
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"PDADC: Chain %d | PDADC %3d "
"Value %3d | PDADC %3d Value %3d | "
"PDADC %3d Value %3d | PDADC %3d "
@@ -2255,13 +2242,11 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
}
*pTxPowerIndexOffset = 0;
-
- return true;
#undef SM_PD_GAIN
#undef SM_PDGAIN_B
}
-static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
+static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
struct ath9k_channel *chan,
int16_t *ratesArray,
u16 cfgCtl,
@@ -2415,14 +2400,14 @@ static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
ah->eep_ops->get_eeprom_rev(ah) <= 2)
twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
"EXT_ADDITIVE %d\n",
ctlMode, numCtlModes, isHt40CtlMode,
(pCtlMode[ctlMode] & EXT_ADDITIVE));
for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
" LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
"pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
"chan %d\n",
@@ -2441,7 +2426,7 @@ static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
" MATCH-EE_IDX %d: ch %d is2 %d "
"2xMinEdge %d chainmask %d chains %d\n",
i, freq, IS_CHAN_2GHZ(chan),
@@ -2460,7 +2445,7 @@ static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
minCtlPower = min(twiceMaxEdgePower, scaledPower);
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
" SEL-Min ctlMode %d pCtlMode %d "
"2xMaxEdge %d sP %d minCtlPwr %d\n",
ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
@@ -2549,10 +2534,9 @@ static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
targetPowerCckExt.tPow2x[0];
}
}
- return true;
}
-static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
+static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
struct ath9k_channel *chan,
u16 cfgCtl,
u8 twiceAntennaReduction,
@@ -2575,22 +2559,13 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
}
- if (!ath9k_hw_set_def_power_per_rate_table(ah, chan,
+ ath9k_hw_set_def_power_per_rate_table(ah, chan,
&ratesArray[0], cfgCtl,
twiceAntennaReduction,
twiceMaxRegulatoryPower,
- powerLimit)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "ath9k_hw_set_txpower: unable to set "
- "tx power per rate table\n");
- return -EIO;
- }
+ powerLimit);
- if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "ath9k_hw_set_txpower: unable to set power table\n");
- return -EIO;
- }
+ ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
@@ -2717,8 +2692,6 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
"Invalid chainmask configuration\n");
break;
}
-
- return 0;
}
static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 25b68c881ff..67b8bd12941 100644
--- a/drivers/net/wireless/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -17,6 +17,8 @@
#ifndef EEPROM_H
#define EEPROM_H
+#include <net/cfg80211.h>
+
#define AH_USE_EEPROM 0x1
#ifdef __BIG_ENDIAN
@@ -492,7 +494,7 @@ struct eeprom_ops {
struct ath9k_channel *chan);
void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
- int (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
+ void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
u16 cfgCtl, u8 twiceAntennaReduction,
u8 twiceMaxRegulatoryPower, u8 powerLimit);
u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index b15eaf8417f..1579c9407ed 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -84,6 +84,38 @@ static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
return ath9k_hw_mac_clks(ah, usecs);
}
+/*
+ * Read and write, they both share the same lock. We do this to serialize
+ * reads and writes on Atheros 802.11n PCI devices only. This is required
+ * as the FIFO on these devices can only accept sanely 2 requests. After
+ * that the device goes bananas. Serializing the reads/writes prevents this
+ * from happening.
+ */
+
+void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
+{
+ if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+ unsigned long flags;
+ spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+ iowrite32(val, ah->ah_sc->mem + reg_offset);
+ spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+ } else
+ iowrite32(val, ah->ah_sc->mem + reg_offset);
+}
+
+unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
+{
+ u32 val;
+ if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+ unsigned long flags;
+ spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+ val = ioread32(ah->ah_sc->mem + reg_offset);
+ spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+ } else
+ val = ioread32(ah->ah_sc->mem + reg_offset);
+ return val;
+}
+
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
{
int i;
@@ -97,7 +129,7 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
udelay(AH_TIME_QUANTUM);
}
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_ANY,
"timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
timeout, reg, REG_READ(ah, reg), mask, val);
@@ -136,7 +168,7 @@ bool ath9k_get_channel_edges(struct ath_hw *ah,
}
u16 ath9k_hw_computetxtime(struct ath_hw *ah,
- struct ath_rate_table *rates,
+ const struct ath_rate_table *rates,
u32 frameLen, u16 rateix,
bool shortPreamble)
{
@@ -181,7 +213,7 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah,
}
break;
default:
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Unknown phy %u (rate ix %u)\n",
rates->info[rateix].phy, rateix);
txTime = 0;
@@ -306,7 +338,7 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
REG_WRITE(ah, addr, wrData);
rdData = REG_READ(ah, addr);
if (rdData != wrData) {
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"address test failed "
"addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
addr, wrData, rdData);
@@ -318,7 +350,7 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
REG_WRITE(ah, addr, wrData);
rdData = REG_READ(ah, addr);
if (wrData != rdData) {
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"address test failed "
"addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
addr, wrData, rdData);
@@ -363,10 +395,7 @@ static void ath9k_hw_set_defaults(struct ath_hw *ah)
ah->config.ack_6mb = 0x0;
ah->config.cwm_ignore_extcca = 0;
ah->config.pcie_powersave_enable = 0;
- ah->config.pcie_l1skp_enable = 0;
ah->config.pcie_clock_req = 0;
- ah->config.pcie_power_reset = 0x100;
- ah->config.pcie_restore = 0;
ah->config.pcie_waen = 0;
ah->config.analog_shiftreg = 1;
ah->config.ht_enable = 1;
@@ -375,13 +404,6 @@ static void ath9k_hw_set_defaults(struct ath_hw *ah)
ah->config.cck_trig_high = 200;
ah->config.cck_trig_low = 100;
ah->config.enable_ani = 1;
- ah->config.noise_immunity_level = 4;
- ah->config.ofdm_weaksignal_det = 1;
- ah->config.cck_weaksignal_thr = 0;
- ah->config.spur_immunity_level = 2;
- ah->config.firstep_level = 0;
- ah->config.rssi_thr_high = 40;
- ah->config.rssi_thr_low = 7;
ah->config.diversity_control = 0;
ah->config.antenna_switch_swap = 0;
@@ -390,7 +412,7 @@ static void ath9k_hw_set_defaults(struct ath_hw *ah)
ah->config.spurchans[i][1] = AR_NO_SPUR;
}
- ah->config.intr_mitigation = 1;
+ ah->config.intr_mitigation = true;
/*
* We need this for PCI devices only (Cardbus, PCI, miniPCI)
@@ -463,8 +485,8 @@ static int ath9k_hw_rfattach(struct ath_hw *ah)
rfStatus = ath9k_hw_init_rf(ah, &ecode);
if (!rfStatus) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET,
- "RF setup failed, status %u\n", ecode);
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "RF setup failed, status: %u\n", ecode);
return ecode;
}
@@ -488,10 +510,9 @@ static int ath9k_hw_rf_claim(struct ath_hw *ah)
case AR_RAD2122_SREV_MAJOR:
break;
default:
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "5G Radio Chip Rev 0x%02X is not "
- "supported by this driver\n",
- ah->hw_version.analog5GhzRev);
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "Radio Chip Rev 0x%02X not supported\n",
+ val & AR_RADIO_SREV_MAJOR);
return -EOPNOTSUPP;
}
@@ -513,12 +534,8 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah)
ah->macaddr[2 * i] = eeval >> 8;
ah->macaddr[2 * i + 1] = eeval & 0xff;
}
- if (sum == 0 || sum == 0xffff * 3) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "mac address read failed: %pM\n",
- ah->macaddr);
+ if (sum == 0 || sum == 0xffff * 3)
return -EADDRNOTAVAIL;
- }
return 0;
}
@@ -575,11 +592,8 @@ static int ath9k_hw_post_attach(struct ath_hw *ah)
{
int ecode;
- if (!ath9k_hw_chip_test(ah)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
- "hardware self-test failed\n");
+ if (!ath9k_hw_chip_test(ah))
return -ENODEV;
- }
ecode = ath9k_hw_rf_claim(ah);
if (ecode != 0)
@@ -617,17 +631,14 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
ath9k_hw_set_defaults(ah);
- if (ah->config.intr_mitigation != 0)
- ah->intr_mitigation = true;
-
if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
- DPRINTF(sc, ATH_DBG_RESET, "Couldn't reset chip\n");
+ DPRINTF(sc, ATH_DBG_FATAL, "Couldn't reset chip\n");
ecode = -EIO;
goto bad;
}
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
- DPRINTF(sc, ATH_DBG_RESET, "Couldn't wakeup chip\n");
+ DPRINTF(sc, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
ecode = -EIO;
goto bad;
}
@@ -650,7 +661,7 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
(ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) &&
(ah->hw_version.macVersion != AR_SREV_VERSION_9160) &&
(!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) {
- DPRINTF(sc, ATH_DBG_RESET,
+ DPRINTF(sc, ATH_DBG_FATAL,
"Mac Chip Rev 0x%02x.%x is not supported by "
"this driver\n", ah->hw_version.macVersion,
ah->hw_version.macRev);
@@ -690,10 +701,6 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
if (AR_SREV_9280_10_OR_LATER(ah))
ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
- DPRINTF(sc, ATH_DBG_RESET,
- "This Mac Chip Rev 0x%02x.%x is \n",
- ah->hw_version.macVersion, ah->hw_version.macRev);
-
if (AR_SREV_9285_12_OR_LATER(ah)) {
INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
@@ -859,11 +866,7 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
if (AR_SREV_9280_20(ah))
ath9k_hw_init_txgain_ini(ah);
- if (!ath9k_hw_fill_cap_info(ah)) {
- DPRINTF(sc, ATH_DBG_RESET, "failed ath9k_hw_fill_cap_info\n");
- ecode = -EINVAL;
- goto bad;
- }
+ ath9k_hw_fill_cap_info(ah);
if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
@@ -885,8 +888,8 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
ecode = ath9k_hw_init_macaddr(ah);
if (ecode != 0) {
- DPRINTF(sc, ATH_DBG_RESET,
- "failed initializing mac address\n");
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Failed to initialize MAC address\n");
goto bad;
}
@@ -1054,7 +1057,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
AR_IMR_RXORN |
AR_IMR_BCNMISC;
- if (ah->intr_mitigation)
+ if (ah->config.intr_mitigation)
ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
else
ah->mask_reg |= AR_IMR_RXOK;
@@ -1203,23 +1206,23 @@ static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah,
switch (ah->hw_version.devid) {
case AR9280_DEVID_PCI:
if (reg == 0x7894) {
- DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"ini VAL: %x EEPROM: %x\n", value,
(pBase->version & 0xff));
if ((pBase->version & 0xff) > 0x0a) {
- DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"PWDCLKIND: %d\n",
pBase->pwdclkind);
value &= ~AR_AN_TOP2_PWDCLKIND;
value |= AR_AN_TOP2_PWDCLKIND &
(pBase->pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
} else {
- DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"PWDCLKIND Earlier Rev\n");
}
- DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"final ini VAL: %x\n", value);
}
break;
@@ -1249,6 +1252,21 @@ static void ath9k_olc_init(struct ath_hw *ah)
ah->PDADCdelta = 0;
}
+static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg,
+ struct ath9k_channel *chan)
+{
+ u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band);
+
+ if (IS_CHAN_B(chan))
+ ctl |= CTL_11B;
+ else if (IS_CHAN_G(chan))
+ ctl |= CTL_11G;
+ else
+ ctl |= CTL_11A;
+
+ return ctl;
+}
+
static int ath9k_hw_process_ini(struct ath_hw *ah,
struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode)
@@ -1256,7 +1274,6 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
int i, regWrites = 0;
struct ieee80211_channel *channel = chan->chan;
u32 modesIndex, freqIndex;
- int status;
switch (chan->chanmode) {
case CHANNEL_A:
@@ -1327,8 +1344,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
if (AR_SREV_9280(ah))
REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
- if (AR_SREV_9280(ah) || (AR_SREV_9285(ah) &&
- AR_SREV_9285_12_OR_LATER(ah)))
+ if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah))
REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
for (i = 0; i < ah->iniCommon.ia_rows; i++) {
@@ -1359,20 +1375,15 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
if (OLC_FOR_AR9280_20_LATER)
ath9k_olc_init(ah);
- status = ah->eep_ops->set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
- channel->max_antenna_gain * 2,
- channel->max_power * 2,
- min((u32) MAX_RATE_POWER,
- (u32) ah->regulatory.power_limit));
- if (status != 0) {
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
- "error init'ing transmit power\n");
- return -EIO;
- }
+ ah->eep_ops->set_txpower(ah, chan,
+ ath9k_regd_get_ctl(&ah->regulatory, chan),
+ channel->max_antenna_gain * 2,
+ channel->max_power * 2,
+ min((u32) MAX_RATE_POWER,
+ (u32) ah->regulatory.power_limit));
if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"ar5416SetRfRegs failed\n");
return -EIO;
}
@@ -1600,11 +1611,9 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
switch (type) {
case ATH9K_RESET_POWER_ON:
return ath9k_hw_set_reset_power_on(ah);
- break;
case ATH9K_RESET_WARM:
case ATH9K_RESET_COLD:
return ath9k_hw_set_reset(ah, type);
- break;
default:
return false;
}
@@ -1678,7 +1687,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Could not kill baseband RX\n");
return false;
}
@@ -1686,29 +1695,21 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
ath9k_hw_set_regs(ah, chan, macmode);
if (AR_SREV_9280_10_OR_LATER(ah)) {
- if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "failed to set channel\n");
- return false;
- }
+ ath9k_hw_ar9280_set_channel(ah, chan);
} else {
if (!(ath9k_hw_set_channel(ah, chan))) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "failed to set channel\n");
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "Failed to set channel\n");
return false;
}
}
- if (ah->eep_ops->set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
+ ah->eep_ops->set_txpower(ah, chan,
+ ath9k_regd_get_ctl(&ah->regulatory, chan),
channel->max_antenna_gain * 2,
channel->max_power * 2,
min((u32) MAX_RATE_POWER,
- (u32) ah->regulatory.power_limit)) != 0) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "error init'ing transmit power\n");
- return false;
- }
+ (u32) ah->regulatory.power_limit));
synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
if (IS_CHAN_B(chan))
@@ -2199,14 +2200,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ah->txchainmask = sc->tx_chainmask;
ah->rxchainmask = sc->rx_chainmask;
- if (AR_SREV_9285(ah)) {
- ah->txchainmask &= 0x1;
- ah->rxchainmask &= 0x1;
- } else if (AR_SREV_9280(ah)) {
- ah->txchainmask &= 0x3;
- ah->rxchainmask &= 0x3;
- }
-
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
return -EIO;
@@ -2242,7 +2235,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ath9k_hw_mark_phy_inactive(ah);
if (!ath9k_hw_chip_reset(ah, chan)) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n");
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Chip reset failed\n");
return -EINVAL;
}
@@ -2304,13 +2297,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
- return -EIO;
- } else {
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ ath9k_hw_ar9280_set_channel(ah, chan);
+ else
if (!(ath9k_hw_set_channel(ah, chan)))
return -EIO;
- }
for (i = 0; i < AR_NUM_DCU; i++)
REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
@@ -2335,8 +2326,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_OBS, 8);
- if (ah->intr_mitigation) {
-
+ if (ah->config.intr_mitigation) {
REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
}
@@ -2385,8 +2375,8 @@ bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry)
u32 keyType;
if (entry >= ah->caps.keycache_size) {
- DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
- "entry %u out of range\n", entry);
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "keychache entry %u out of range\n", entry);
return false;
}
@@ -2422,8 +2412,8 @@ bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
u32 macHi, macLo;
if (entry >= ah->caps.keycache_size) {
- DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
- "entry %u out of range\n", entry);
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "keychache entry %u out of range\n", entry);
return false;
}
@@ -2454,8 +2444,8 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
u32 keyType;
if (entry >= pCap->keycache_size) {
- DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
- "entry %u out of range\n", entry);
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "keycache entry %u out of range\n", entry);
return false;
}
@@ -2465,7 +2455,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
break;
case ATH9K_CIPHER_AES_CCM:
if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
- DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+ DPRINTF(ah->ah_sc, ATH_DBG_ANY,
"AES-CCM not supported by mac rev 0x%x\n",
ah->hw_version.macRev);
return false;
@@ -2476,20 +2466,20 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
keyType = AR_KEYTABLE_TYPE_TKIP;
if (ATH9K_IS_MIC_ENABLED(ah)
&& entry + 64 >= pCap->keycache_size) {
- DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+ DPRINTF(ah->ah_sc, ATH_DBG_ANY,
"entry %u inappropriate for TKIP\n", entry);
return false;
}
break;
case ATH9K_CIPHER_WEP:
- if (k->kv_len < LEN_WEP40) {
- DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+ if (k->kv_len < WLAN_KEY_LEN_WEP40) {
+ DPRINTF(ah->ah_sc, ATH_DBG_ANY,
"WEP key length %u too small\n", k->kv_len);
return false;
}
- if (k->kv_len <= LEN_WEP40)
+ if (k->kv_len <= WLAN_KEY_LEN_WEP40)
keyType = AR_KEYTABLE_TYPE_40;
- else if (k->kv_len <= LEN_WEP104)
+ else if (k->kv_len <= WLAN_KEY_LEN_WEP104)
keyType = AR_KEYTABLE_TYPE_104;
else
keyType = AR_KEYTABLE_TYPE_128;
@@ -2498,7 +2488,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
keyType = AR_KEYTABLE_TYPE_CLR;
break;
default:
- DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"cipher %u not supported\n", k->kv_type);
return false;
}
@@ -2508,7 +2498,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
key2 = get_unaligned_le32(k->kv_val + 6);
key3 = get_unaligned_le16(k->kv_val + 10);
key4 = get_unaligned_le32(k->kv_val + 12);
- if (k->kv_len <= LEN_WEP104)
+ if (k->kv_len <= WLAN_KEY_LEN_WEP104)
key4 &= 0xff;
/*
@@ -2716,7 +2706,7 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
AR_RTC_FORCE_WAKE_EN);
}
if (i == 0) {
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Failed to wakeup in %uus\n", POWER_UP_TIME / 20);
return false;
}
@@ -2737,9 +2727,8 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
"UNDEFINED"
};
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s -> %s (%s)\n",
- modes[ah->power_mode], modes[mode],
- setChip ? "set chip " : "");
+ DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s -> %s\n",
+ modes[ah->power_mode], modes[mode]);
switch (mode) {
case ATH9K_PM_AWAKE:
@@ -2753,7 +2742,7 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
ath9k_set_power_network_sleep(ah, setChip);
break;
default:
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Unknown power mode %u\n", mode);
return false;
}
@@ -2943,7 +2932,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
*masked = isr & ATH9K_INT_COMMON;
- if (ah->intr_mitigation) {
+ if (ah->config.intr_mitigation) {
if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
*masked |= ATH9K_INT_RX;
}
@@ -3000,6 +2989,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
DPRINTF(ah->ah_sc, ATH_DBG_ANY,
"received PCI PERR interrupt\n");
}
+ *masked |= ATH9K_INT_FATAL;
}
if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
@@ -3061,7 +3051,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
}
if (ints & ATH9K_INT_RX) {
mask |= AR_IMR_RXERR;
- if (ah->intr_mitigation)
+ if (ah->config.intr_mitigation)
mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
else
mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
@@ -3259,7 +3249,7 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
/* HW Capabilities */
/*******************/
-bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
+void ath9k_hw_fill_cap_info(struct ath_hw *ah)
{
struct ath9k_hw_capabilities *pCap = &ah->caps;
u16 capField = 0, eeval;
@@ -3343,8 +3333,6 @@ bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
- pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
-
if (ah->config.ht_enable)
pCap->hw_caps |= ATH9K_HW_CAP_HT;
else
@@ -3368,7 +3356,6 @@ bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->keycache_size = AR_KEYTABLE_SIZE;
pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
- pCap->num_mr_retries = 4;
pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
if (AR_SREV_9285_10_OR_LATER(ah))
@@ -3378,14 +3365,6 @@ bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
else
pCap->num_gpio_pins = AR_NUM_GPIO;
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- pCap->hw_caps |= ATH9K_HW_CAP_WOW;
- pCap->hw_caps |= ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
- } else {
- pCap->hw_caps &= ~ATH9K_HW_CAP_WOW;
- pCap->hw_caps &= ~ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
- }
-
if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
pCap->hw_caps |= ATH9K_HW_CAP_CST;
pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
@@ -3411,7 +3390,8 @@ bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
(ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) ||
(ah->hw_version.macVersion == AR_SREV_VERSION_9160) ||
(ah->hw_version.macVersion == AR_SREV_VERSION_9100) ||
- (ah->hw_version.macVersion == AR_SREV_VERSION_9280))
+ (ah->hw_version.macVersion == AR_SREV_VERSION_9280) ||
+ (ah->hw_version.macVersion == AR_SREV_VERSION_9285))
pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
else
pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
@@ -3445,8 +3425,6 @@ bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
ah->btactive_gpio = 6;
ah->wlanactive_gpio = 5;
}
-
- return true;
}
bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
@@ -3754,22 +3732,19 @@ bool ath9k_hw_disable(struct ath_hw *ah)
return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
}
-bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
+void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
{
struct ath9k_channel *chan = ah->curchan;
struct ieee80211_channel *channel = chan->chan;
ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER);
- if (ah->eep_ops->set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
- channel->max_antenna_gain * 2,
- channel->max_power * 2,
- min((u32) MAX_RATE_POWER,
- (u32) ah->regulatory.power_limit)) != 0)
- return false;
-
- return true;
+ ah->eep_ops->set_txpower(ah, chan,
+ ath9k_regd_get_ctl(&ah->regulatory, chan),
+ channel->max_antenna_gain * 2,
+ channel->max_power * 2,
+ min((u32) MAX_RATE_POWER,
+ (u32) ah->regulatory.power_limit));
}
void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 0b594e0ee26..dd8508ef6e0 100644
--- a/drivers/net/wireless/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -25,10 +25,11 @@
#include "ani.h"
#include "eeprom.h"
#include "calib.h"
-#include "regd.h"
#include "reg.h"
#include "phy.h"
+#include "../regd.h"
+
#define ATHEROS_VENDOR_ID 0x168c
#define AR5416_DEVID_PCI 0x0023
#define AR5416_DEVID_PCIE 0x0024
@@ -124,29 +125,24 @@ enum wireless_mode {
};
enum ath9k_hw_caps {
- ATH9K_HW_CAP_CHAN_SPREAD = BIT(0),
- ATH9K_HW_CAP_MIC_AESCCM = BIT(1),
- ATH9K_HW_CAP_MIC_CKIP = BIT(2),
- ATH9K_HW_CAP_MIC_TKIP = BIT(3),
- ATH9K_HW_CAP_CIPHER_AESCCM = BIT(4),
- ATH9K_HW_CAP_CIPHER_CKIP = BIT(5),
- ATH9K_HW_CAP_CIPHER_TKIP = BIT(6),
- ATH9K_HW_CAP_VEOL = BIT(7),
- ATH9K_HW_CAP_BSSIDMASK = BIT(8),
- ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(9),
- ATH9K_HW_CAP_CHAN_HALFRATE = BIT(10),
- ATH9K_HW_CAP_CHAN_QUARTERRATE = BIT(11),
- ATH9K_HW_CAP_HT = BIT(12),
- ATH9K_HW_CAP_GTT = BIT(13),
- ATH9K_HW_CAP_FASTCC = BIT(14),
- ATH9K_HW_CAP_RFSILENT = BIT(15),
- ATH9K_HW_CAP_WOW = BIT(16),
- ATH9K_HW_CAP_CST = BIT(17),
- ATH9K_HW_CAP_ENHANCEDPM = BIT(18),
- ATH9K_HW_CAP_AUTOSLEEP = BIT(19),
- ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(20),
- ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT = BIT(21),
- ATH9K_HW_CAP_BT_COEX = BIT(22)
+ ATH9K_HW_CAP_MIC_AESCCM = BIT(0),
+ ATH9K_HW_CAP_MIC_CKIP = BIT(1),
+ ATH9K_HW_CAP_MIC_TKIP = BIT(2),
+ ATH9K_HW_CAP_CIPHER_AESCCM = BIT(3),
+ ATH9K_HW_CAP_CIPHER_CKIP = BIT(4),
+ ATH9K_HW_CAP_CIPHER_TKIP = BIT(5),
+ ATH9K_HW_CAP_VEOL = BIT(6),
+ ATH9K_HW_CAP_BSSIDMASK = BIT(7),
+ ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(8),
+ ATH9K_HW_CAP_HT = BIT(9),
+ ATH9K_HW_CAP_GTT = BIT(10),
+ ATH9K_HW_CAP_FASTCC = BIT(11),
+ ATH9K_HW_CAP_RFSILENT = BIT(12),
+ ATH9K_HW_CAP_CST = BIT(13),
+ ATH9K_HW_CAP_ENHANCEDPM = BIT(14),
+ ATH9K_HW_CAP_AUTOSLEEP = BIT(15),
+ ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(16),
+ ATH9K_HW_CAP_BT_COEX = BIT(17)
};
enum ath9k_capability_type {
@@ -166,7 +162,6 @@ struct ath9k_hw_capabilities {
u16 keycache_size;
u16 low_5ghz_chan, high_5ghz_chan;
u16 low_2ghz_chan, high_2ghz_chan;
- u16 num_mr_retries;
u16 rts_aggr_limit;
u8 tx_chainmask;
u8 rx_chainmask;
@@ -184,11 +179,8 @@ struct ath9k_ops_config {
int ack_6mb;
int cwm_ignore_extcca;
u8 pcie_powersave_enable;
- u8 pcie_l1skp_enable;
u8 pcie_clock_req;
u32 pcie_waen;
- int pcie_power_reset;
- u8 pcie_restore;
u8 analog_shiftreg;
u8 ht_enable;
u32 ofdm_trig_low;
@@ -196,17 +188,10 @@ struct ath9k_ops_config {
u32 cck_trig_high;
u32 cck_trig_low;
u32 enable_ani;
- u8 noise_immunity_level;
- u32 ofdm_weaksignal_det;
- u32 cck_weaksignal_thr;
- u8 spur_immunity_level;
- u8 firstep_level;
- int8_t rssi_thr_high;
- int8_t rssi_thr_low;
u16 diversity_control;
u16 antenna_switch_swap;
int serialize_regmode;
- int intr_mitigation;
+ bool intr_mitigation;
#define SPUR_DISABLE 0
#define SPUR_ENABLE_IOCTL 1
#define SPUR_ENABLE_EEPROM 2
@@ -281,13 +266,6 @@ enum ath9k_int {
#define CHANNEL_HT40PLUS 0x20000
#define CHANNEL_HT40MINUS 0x40000
-#define CHANNEL_INTERFERENCE 0x01
-#define CHANNEL_DFS 0x02
-#define CHANNEL_4MS_LIMIT 0x04
-#define CHANNEL_DFS_CLEAR 0x08
-#define CHANNEL_DISALLOW_ADHOC 0x10
-#define CHANNEL_PER_11D_ADHOC 0x20
-
#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
@@ -318,10 +296,6 @@ struct ath9k_channel {
int16_t rawNoiseFloor;
};
-#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \
- (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \
- (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \
- (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS))
#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
(((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
(((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
@@ -329,7 +303,6 @@ struct ath9k_channel {
#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
-#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
#define IS_CHAN_A_5MHZ_SPACED(_c) \
@@ -420,7 +393,7 @@ struct ath_hw {
struct ath9k_hw_version hw_version;
struct ath9k_ops_config config;
struct ath9k_hw_capabilities caps;
- struct ath9k_regulatory regulatory;
+ struct ath_regulatory regulatory;
struct ath9k_channel channels[38];
struct ath9k_channel *curchan;
@@ -463,14 +436,14 @@ struct ath_hw {
enum ath9k_ant_setting diversity_control;
/* Calibration */
- enum hal_cal_types supp_cals;
- struct hal_cal_list iq_caldata;
- struct hal_cal_list adcgain_caldata;
- struct hal_cal_list adcdc_calinitdata;
- struct hal_cal_list adcdc_caldata;
- struct hal_cal_list *cal_list;
- struct hal_cal_list *cal_list_last;
- struct hal_cal_list *cal_list_curr;
+ enum ath9k_cal_types supp_cals;
+ struct ath9k_cal_list iq_caldata;
+ struct ath9k_cal_list adcgain_caldata;
+ struct ath9k_cal_list adcdc_calinitdata;
+ struct ath9k_cal_list adcdc_caldata;
+ struct ath9k_cal_list *cal_list;
+ struct ath9k_cal_list *cal_list_last;
+ struct ath9k_cal_list *cal_list_curr;
#define totalPowerMeasI meas0.unsign
#define totalPowerMeasQ meas1.unsign
#define totalIqCorrMeas meas2.sign
@@ -540,7 +513,6 @@ struct ath_hw {
enum ath9k_ani_cmd ani_function;
u32 intr_txqs;
- bool intr_mitigation;
enum ath9k_ht_extprotspacing extprotspacing;
u8 txchainmask;
u8 rxchainmask;
@@ -573,7 +545,7 @@ struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error);
void ath9k_hw_rfdetach(struct ath_hw *ah);
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
bool bChannelChange);
-bool ath9k_hw_fill_cap_info(struct ath_hw *ah);
+void ath9k_hw_fill_cap_info(struct ath_hw *ah);
bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
u32 capability, u32 *result);
bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
@@ -608,7 +580,8 @@ bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
u32 ath9k_hw_reverse_bits(u32 val, u32 n);
bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
-u16 ath9k_hw_computetxtime(struct ath_hw *ah, struct ath_rate_table *rates,
+u16 ath9k_hw_computetxtime(struct ath_hw *ah,
+ const struct ath_rate_table *rates,
u32 frameLen, u16 rateix, bool shortPreamble);
void ath9k_hw_get_channel_centers(struct ath_hw *ah,
struct ath9k_channel *chan,
@@ -617,7 +590,7 @@ u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
bool ath9k_hw_phy_disable(struct ath_hw *ah);
bool ath9k_hw_disable(struct ath_hw *ah);
-bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
+void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac);
void ath9k_hw_setopmode(struct ath_hw *ah);
void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
diff --git a/drivers/net/wireless/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/initvals.h
index e2f0a34b79a..e2f0a34b79a 100644
--- a/drivers/net/wireless/ath9k/initvals.h
+++ b/drivers/net/wireless/ath/ath9k/initvals.h
diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index e0a6dee4583..8ae4ec21667 100644
--- a/drivers/net/wireless/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -49,7 +49,7 @@ bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
bool ath9k_hw_txstart(struct ath_hw *ah, u32 q)
{
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q);
REG_WRITE(ah, AR_Q_TXE, 1 << q);
@@ -110,13 +110,15 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
if (q >= pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, "
+ "invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, "
+ "inactive queue: %u\n", q);
return false;
}
@@ -146,7 +148,7 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
break;
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
- "TSF have moved while trying to set "
+ "TSF has moved while trying to set "
"quiet time TSF: 0x%08x\n", tsfLow);
}
@@ -158,8 +160,8 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
wait = wait_time;
while (ath9k_hw_numtxpending(ah, q)) {
if ((--wait) == 0) {
- DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
- "Failed to stop Tx DMA in 100 "
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+ "Failed to stop TX DMA in 100 "
"msec after killing last frame\n");
break;
}
@@ -454,17 +456,19 @@ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, "
+ "invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, "
+ "inactive queue: %u\n", q);
return false;
}
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %p\n", qi);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q);
qi->tqi_ver = qinfo->tqi_ver;
qi->tqi_subtype = qinfo->tqi_subtype;
@@ -521,13 +525,15 @@ bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, "
+ "invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, "
+ "inactive queue: %u\n", q);
return false;
}
@@ -575,22 +581,23 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
ATH9K_TX_QUEUE_INACTIVE)
break;
if (q == pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
- "no available tx queue\n");
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "No available TX queue\n");
return -1;
}
break;
default:
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "bad tx queue type %u\n", type);
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Invalid TX queue type: %u\n",
+ type);
return -1;
}
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q);
qi = &ah->txq[q];
if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
- "tx queue %u already active\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "TX queue: %u already active\n", q);
return -1;
}
memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
@@ -620,16 +627,18 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, "
+ "invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, "
+ "inactive queue: %u\n", q);
return false;
}
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "release queue %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TX queue: %u\n", q);
qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
ah->txok_interrupt_mask &= ~(1 << q);
@@ -650,17 +659,19 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
u32 cwMin, chanCwMin, value;
if (q >= pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, "
+ "invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, "
+ "inactive queue: %u\n", q);
return true;
}
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "reset queue %u\n", q);
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q);
if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
if (chan && IS_CHAN_B(chan))
@@ -894,7 +905,7 @@ bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
reg = REG_READ(ah, AR_OBS_BUS_1);
DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
- "rx failed to go idle in 10 ms RXSM=0x%x\n", reg);
+ "RX failed to go idle in 10 ms RXSM=0x%x\n", reg);
return false;
}
@@ -949,8 +960,8 @@ bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
}
if (i == 0) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
- "dma failed to stop in %d ms "
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "DMA failed to stop in %d ms "
"AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
AH_RX_STOP_DMA_TIMEOUT / 1000,
REG_READ(ah, AR_CR),
diff --git a/drivers/net/wireless/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 1176bce8b76..1176bce8b76 100644
--- a/drivers/net/wireless/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 13d4e6756c9..f7baa406918 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -35,14 +35,14 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
#define CHAN2G(_freq, _idx) { \
.center_freq = (_freq), \
.hw_value = (_idx), \
- .max_power = 30, \
+ .max_power = 20, \
}
#define CHAN5G(_freq, _idx) { \
.band = IEEE80211_BAND_5GHZ, \
.center_freq = (_freq), \
.hw_value = (_idx), \
- .max_power = 30, \
+ .max_power = 20, \
}
/* Some 2 GHz radios are actually tunable on 2312-2732
@@ -189,7 +189,7 @@ static u8 parse_mpdudensity(u8 mpdudensity)
static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
{
- struct ath_rate_table *rate_table = NULL;
+ const struct ath_rate_table *rate_table = NULL;
struct ieee80211_supported_band *sband;
struct ieee80211_rate *rate;
int i, maxrates;
@@ -280,14 +280,13 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset channel (%u Mhz) "
- "reset status %u\n",
+ "reset status %d\n",
channel->center_freq, r);
spin_unlock_bh(&sc->sc_resetlock);
return r;
}
spin_unlock_bh(&sc->sc_resetlock);
- sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE;
sc->sc_flags &= ~SC_OP_FULL_RESET;
if (ath_startrecv(sc) != 0) {
@@ -330,6 +329,12 @@ static void ath_ani_calibrate(unsigned long data)
if (sc->sc_flags & SC_OP_SCANNING)
goto set_timer;
+ /* Only calibrate if awake */
+ if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE)
+ goto set_timer;
+
+ ath9k_ps_wakeup(sc);
+
/* Long calibration runs independently of short calibration. */
if ((timestamp - sc->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
longcal = true;
@@ -368,31 +373,21 @@ static void ath_ani_calibrate(unsigned long data)
/* Perform calibration if necessary */
if (longcal || shortcal) {
- bool iscaldone = false;
-
- if (ath9k_hw_calibrate(ah, ah->curchan,
- sc->rx_chainmask, longcal,
- &iscaldone)) {
- if (longcal)
- sc->ani.noise_floor =
- ath9k_hw_getchan_noise(ah,
- ah->curchan);
-
- DPRINTF(sc, ATH_DBG_ANI,
- "calibrate chan %u/%x nf: %d\n",
- ah->curchan->channel,
- ah->curchan->channelFlags,
- sc->ani.noise_floor);
- } else {
- DPRINTF(sc, ATH_DBG_ANY,
- "calibrate chan %u/%x failed\n",
- ah->curchan->channel,
- ah->curchan->channelFlags);
- }
- sc->ani.caldone = iscaldone;
+ sc->ani.caldone = ath9k_hw_calibrate(ah, ah->curchan,
+ sc->rx_chainmask, longcal);
+
+ if (longcal)
+ sc->ani.noise_floor = ath9k_hw_getchan_noise(ah,
+ ah->curchan);
+
+ DPRINTF(sc, ATH_DBG_ANI," calibrate chan %u/%x nf: %d\n",
+ ah->curchan->channel, ah->curchan->channelFlags,
+ sc->ani.noise_floor);
}
}
+ ath9k_ps_restore(sc);
+
set_timer:
/*
* Set timer interval based on previous results.
@@ -408,6 +403,18 @@ set_timer:
mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
}
+static void ath_start_ani(struct ath_softc *sc)
+{
+ unsigned long timestamp = jiffies_to_msecs(jiffies);
+
+ sc->ani.longcal_timer = timestamp;
+ sc->ani.shortcal_timer = timestamp;
+ sc->ani.checkani_timer = timestamp;
+
+ mod_timer(&sc->ani.timer,
+ jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
+}
+
/*
* Update tx/rx chainmask. For legacy association,
* hard code chainmask to 1x1, for 11n association, use
@@ -416,7 +423,6 @@ set_timer:
*/
void ath_update_chainmask(struct ath_softc *sc, int is_ht)
{
- sc->sc_flags |= SC_OP_CHAINMASK_UPDATE;
if (is_ht ||
(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) {
sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
@@ -436,12 +442,12 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
an = (struct ath_node *)sta->drv_priv;
- if (sc->sc_flags & SC_OP_TXAGGR)
+ if (sc->sc_flags & SC_OP_TXAGGR) {
ath_tx_node_init(sc, an);
-
- an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
- sta->ht_cap.ampdu_factor);
- an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
+ an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
+ sta->ht_cap.ampdu_factor);
+ an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
+ }
}
static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
@@ -457,133 +463,130 @@ static void ath9k_tasklet(unsigned long data)
struct ath_softc *sc = (struct ath_softc *)data;
u32 status = sc->intrstatus;
+ ath9k_ps_wakeup(sc);
+
if (status & ATH9K_INT_FATAL) {
- /* need a chip reset */
ath_reset(sc, false);
+ ath9k_ps_restore(sc);
return;
- } else {
+ }
- if (status &
- (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
- spin_lock_bh(&sc->rx.rxflushlock);
- ath_rx_tasklet(sc, 0);
- spin_unlock_bh(&sc->rx.rxflushlock);
- }
- /* XXX: optimize this */
- if (status & ATH9K_INT_TX)
- ath_tx_tasklet(sc);
+ if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
+ spin_lock_bh(&sc->rx.rxflushlock);
+ ath_rx_tasklet(sc, 0);
+ spin_unlock_bh(&sc->rx.rxflushlock);
+ }
+
+ if (status & ATH9K_INT_TX)
+ ath_tx_tasklet(sc);
+
+ if ((status & ATH9K_INT_TSFOOR) &&
+ (sc->hw->conf.flags & IEEE80211_CONF_PS)) {
+ /*
+ * TSF sync does not look correct; remain awake to sync with
+ * the next Beacon.
+ */
+ DPRINTF(sc, ATH_DBG_PS, "TSFOOR - Sync with next Beacon\n");
+ sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC;
}
/* re-enable hardware interrupt */
ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+ ath9k_ps_restore(sc);
}
irqreturn_t ath_isr(int irq, void *dev)
{
+#define SCHED_INTR ( \
+ ATH9K_INT_FATAL | \
+ ATH9K_INT_RXORN | \
+ ATH9K_INT_RXEOL | \
+ ATH9K_INT_RX | \
+ ATH9K_INT_TX | \
+ ATH9K_INT_BMISS | \
+ ATH9K_INT_CST | \
+ ATH9K_INT_TSFOOR)
+
struct ath_softc *sc = dev;
struct ath_hw *ah = sc->sc_ah;
enum ath9k_int status;
bool sched = false;
- do {
- if (sc->sc_flags & SC_OP_INVALID) {
- /*
- * The hardware is not ready/present, don't
- * touch anything. Note this can happen early
- * on if the IRQ is shared.
- */
- return IRQ_NONE;
- }
- if (!ath9k_hw_intrpend(ah)) { /* shared irq, not for us */
- return IRQ_NONE;
- }
+ /*
+ * The hardware is not ready/present, don't
+ * touch anything. Note this can happen early
+ * on if the IRQ is shared.
+ */
+ if (sc->sc_flags & SC_OP_INVALID)
+ return IRQ_NONE;
- /*
- * Figure out the reason(s) for the interrupt. Note
- * that the hal returns a pseudo-ISR that may include
- * bits we haven't explicitly enabled so we mask the
- * value to insure we only process bits we requested.
- */
- ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
- status &= sc->imask; /* discard unasked-for bits */
+ /* shared irq, not for us */
- /*
- * If there are no status bits set, then this interrupt was not
- * for me (should have been caught above).
- */
- if (!status)
- return IRQ_NONE;
+ if (!ath9k_hw_intrpend(ah))
+ return IRQ_NONE;
- sc->intrstatus = status;
- ath9k_ps_wakeup(sc);
+ /*
+ * Figure out the reason(s) for the interrupt. Note
+ * that the hal returns a pseudo-ISR that may include
+ * bits we haven't explicitly enabled so we mask the
+ * value to insure we only process bits we requested.
+ */
+ ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
+ status &= sc->imask; /* discard unasked-for bits */
- if (status & ATH9K_INT_FATAL) {
- /* need a chip reset */
- sched = true;
- } else if (status & ATH9K_INT_RXORN) {
- /* need a chip reset */
- sched = true;
- } else {
- if (status & ATH9K_INT_SWBA) {
- /* schedule a tasklet for beacon handling */
- tasklet_schedule(&sc->bcon_tasklet);
- }
- if (status & ATH9K_INT_RXEOL) {
- /*
- * NB: the hardware should re-read the link when
- * RXE bit is written, but it doesn't work
- * at least on older hardware revs.
- */
- sched = true;
- }
+ /*
+ * If there are no status bits set, then this interrupt was not
+ * for me (should have been caught above).
+ */
+ if (!status)
+ return IRQ_NONE;
- if (status & ATH9K_INT_TXURN)
- /* bump tx trigger level */
- ath9k_hw_updatetxtriglevel(ah, true);
- /* XXX: optimize this */
- if (status & ATH9K_INT_RX)
- sched = true;
- if (status & ATH9K_INT_TX)
- sched = true;
- if (status & ATH9K_INT_BMISS)
- sched = true;
- /* carrier sense timeout */
- if (status & ATH9K_INT_CST)
- sched = true;
- if (status & ATH9K_INT_MIB) {
- /*
- * Disable interrupts until we service the MIB
- * interrupt; otherwise it will continue to
- * fire.
- */
- ath9k_hw_set_interrupts(ah, 0);
- /*
- * Let the hal handle the event. We assume
- * it will clear whatever condition caused
- * the interrupt.
- */
- ath9k_hw_procmibevent(ah, &sc->nodestats);
- ath9k_hw_set_interrupts(ah, sc->imask);
- }
- if (status & ATH9K_INT_TIM_TIMER) {
- if (!(ah->caps.hw_caps &
- ATH9K_HW_CAP_AUTOSLEEP)) {
- /* Clear RxAbort bit so that we can
- * receive frames */
- ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
- ath9k_hw_setrxabort(ah, 0);
- sched = true;
- sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
- }
- }
- if (status & ATH9K_INT_TSFOOR) {
- /* FIXME: Handle this interrupt for power save */
- sched = true;
- }
+ /* Cache the status */
+ sc->intrstatus = status;
+
+ if (status & SCHED_INTR)
+ sched = true;
+
+ /*
+ * If a FATAL or RXORN interrupt is received, we have to reset the
+ * chip immediately.
+ */
+ if (status & (ATH9K_INT_FATAL | ATH9K_INT_RXORN))
+ goto chip_reset;
+
+ if (status & ATH9K_INT_SWBA)
+ tasklet_schedule(&sc->bcon_tasklet);
+
+ if (status & ATH9K_INT_TXURN)
+ ath9k_hw_updatetxtriglevel(ah, true);
+
+ if (status & ATH9K_INT_MIB) {
+ /*
+ * Disable interrupts until we service the MIB
+ * interrupt; otherwise it will continue to
+ * fire.
+ */
+ ath9k_hw_set_interrupts(ah, 0);
+ /*
+ * Let the hal handle the event. We assume
+ * it will clear whatever condition caused
+ * the interrupt.
+ */
+ ath9k_hw_procmibevent(ah, &sc->nodestats);
+ ath9k_hw_set_interrupts(ah, sc->imask);
+ }
+
+ if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+ if (status & ATH9K_INT_TIM_TIMER) {
+ /* Clear RxAbort bit so that we can
+ * receive frames */
+ ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
+ ath9k_hw_setrxabort(sc->sc_ah, 0);
+ sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
}
- ath9k_ps_restore(sc);
- } while (0);
+
+chip_reset:
ath_debug_stat_interrupt(sc, status);
@@ -594,6 +597,8 @@ irqreturn_t ath_isr(int irq, void *dev)
}
return IRQ_HANDLED;
+
+#undef SCHED_INTR
}
static u32 ath_get_extchanmode(struct ath_softc *sc,
@@ -676,7 +681,7 @@ static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) {
/* TX MIC entry failed. No need to proceed further */
- DPRINTF(sc, ATH_DBG_KEYCACHE,
+ DPRINTF(sc, ATH_DBG_FATAL,
"Setting TX MIC Key Failed\n");
return 0;
}
@@ -909,6 +914,13 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
if (avp->av_opmode == NL80211_IFTYPE_STATION) {
sc->curaid = bss_conf->aid;
ath9k_hw_write_associd(sc);
+
+ /*
+ * Request a re-configuration of Beacon related timers
+ * on the receipt of the first Beacon frame (i.e.,
+ * after time sync with the AP).
+ */
+ sc->sc_flags |= SC_OP_BEACON_SYNC;
}
/* Configure the beacon */
@@ -920,11 +932,9 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
- /* Start ANI */
- mod_timer(&sc->ani.timer,
- jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
+ ath_start_ani(sc);
} else {
- DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISSOC\n");
+ DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
sc->curaid = 0;
}
}
@@ -1098,14 +1108,14 @@ void ath_radio_enable(struct ath_softc *sc)
int r;
ath9k_ps_wakeup(sc);
- spin_lock_bh(&sc->sc_resetlock);
+ ath9k_hw_configpcipowersave(ah, 0);
+ spin_lock_bh(&sc->sc_resetlock);
r = ath9k_hw_reset(ah, ah->curchan, false);
-
if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset channel %u (%uMhz) ",
- "reset status %u\n",
+ "reset status %d\n",
channel->center_freq, r);
}
spin_unlock_bh(&sc->sc_resetlock);
@@ -1157,12 +1167,13 @@ void ath_radio_disable(struct ath_softc *sc)
if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset channel %u (%uMhz) "
- "reset status %u\n",
+ "reset status %d\n",
channel->center_freq, r);
}
spin_unlock_bh(&sc->sc_resetlock);
ath9k_hw_phy_disable(ah);
+ ath9k_hw_configpcipowersave(ah, 1);
ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
ath9k_ps_restore(sc);
}
@@ -1181,121 +1192,69 @@ static bool ath_is_rfkill_set(struct ath_softc *sc)
ah->rfkill_polarity;
}
-/* h/w rfkill poll function */
-static void ath_rfkill_poll(struct work_struct *work)
+/* s/w rfkill handlers */
+static int ath_rfkill_set_block(void *data, bool blocked)
{
- struct ath_softc *sc = container_of(work, struct ath_softc,
- rf_kill.rfkill_poll.work);
- bool radio_on;
-
- if (sc->sc_flags & SC_OP_INVALID)
- return;
-
- radio_on = !ath_is_rfkill_set(sc);
-
- /*
- * enable/disable radio only when there is a
- * state change in RF switch
- */
- if (radio_on == !!(sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED)) {
- enum rfkill_state state;
-
- if (sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED) {
- state = radio_on ? RFKILL_STATE_SOFT_BLOCKED
- : RFKILL_STATE_HARD_BLOCKED;
- } else if (radio_on) {
- ath_radio_enable(sc);
- state = RFKILL_STATE_UNBLOCKED;
- } else {
- ath_radio_disable(sc);
- state = RFKILL_STATE_HARD_BLOCKED;
- }
-
- if (state == RFKILL_STATE_HARD_BLOCKED)
- sc->sc_flags |= SC_OP_RFKILL_HW_BLOCKED;
- else
- sc->sc_flags &= ~SC_OP_RFKILL_HW_BLOCKED;
+ struct ath_softc *sc = data;
- rfkill_force_state(sc->rf_kill.rfkill, state);
- }
+ if (blocked)
+ ath_radio_disable(sc);
+ else
+ ath_radio_enable(sc);
- queue_delayed_work(sc->hw->workqueue, &sc->rf_kill.rfkill_poll,
- msecs_to_jiffies(ATH_RFKILL_POLL_INTERVAL));
+ return 0;
}
-/* s/w rfkill handler */
-static int ath_sw_toggle_radio(void *data, enum rfkill_state state)
+static void ath_rfkill_poll_state(struct rfkill *rfkill, void *data)
{
struct ath_softc *sc = data;
+ bool blocked = !!ath_is_rfkill_set(sc);
- switch (state) {
- case RFKILL_STATE_SOFT_BLOCKED:
- if (!(sc->sc_flags & (SC_OP_RFKILL_HW_BLOCKED |
- SC_OP_RFKILL_SW_BLOCKED)))
- ath_radio_disable(sc);
- sc->sc_flags |= SC_OP_RFKILL_SW_BLOCKED;
- return 0;
- case RFKILL_STATE_UNBLOCKED:
- if ((sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED)) {
- sc->sc_flags &= ~SC_OP_RFKILL_SW_BLOCKED;
- if (sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED) {
- DPRINTF(sc, ATH_DBG_FATAL, "Can't turn on the"
- "radio as it is disabled by h/w\n");
- return -EPERM;
- }
- ath_radio_enable(sc);
- }
- return 0;
- default:
- return -EINVAL;
- }
+ if (rfkill_set_hw_state(rfkill, blocked))
+ ath_radio_disable(sc);
+ else
+ ath_radio_enable(sc);
}
/* Init s/w rfkill */
static int ath_init_sw_rfkill(struct ath_softc *sc)
{
- sc->rf_kill.rfkill = rfkill_allocate(wiphy_dev(sc->hw->wiphy),
- RFKILL_TYPE_WLAN);
+ sc->rf_kill.ops.set_block = ath_rfkill_set_block;
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ sc->rf_kill.ops.poll = ath_rfkill_poll_state;
+
+ snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name),
+ "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy));
+
+ sc->rf_kill.rfkill = rfkill_alloc(sc->rf_kill.rfkill_name,
+ wiphy_dev(sc->hw->wiphy),
+ RFKILL_TYPE_WLAN,
+ &sc->rf_kill.ops, sc);
if (!sc->rf_kill.rfkill) {
DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n");
return -ENOMEM;
}
- snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name),
- "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy));
- sc->rf_kill.rfkill->name = sc->rf_kill.rfkill_name;
- sc->rf_kill.rfkill->data = sc;
- sc->rf_kill.rfkill->toggle_radio = ath_sw_toggle_radio;
- sc->rf_kill.rfkill->state = RFKILL_STATE_UNBLOCKED;
- sc->rf_kill.rfkill->user_claim_unsupported = 1;
-
return 0;
}
/* Deinitialize rfkill */
static void ath_deinit_rfkill(struct ath_softc *sc)
{
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
- cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
-
if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) {
rfkill_unregister(sc->rf_kill.rfkill);
+ rfkill_destroy(sc->rf_kill.rfkill);
sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED;
- sc->rf_kill.rfkill = NULL;
}
}
static int ath_start_rfkill_poll(struct ath_softc *sc)
{
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
- queue_delayed_work(sc->hw->workqueue,
- &sc->rf_kill.rfkill_poll, 0);
-
if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) {
if (rfkill_register(sc->rf_kill.rfkill)) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to register rfkill\n");
- rfkill_free(sc->rf_kill.rfkill);
+ rfkill_destroy(sc->rf_kill.rfkill);
/* Deinitialize the device */
ath_cleanup(sc);
@@ -1362,6 +1321,17 @@ void ath_detach(struct ath_softc *sc)
ath9k_ps_restore(sc);
}
+static int ath9k_reg_notifier(struct wiphy *wiphy,
+ struct regulatory_request *request)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_regulatory *reg = &sc->sc_ah->regulatory;
+
+ return ath_reg_notifier_apply(wiphy, request, reg);
+}
+
static int ath_init(u16 devid, struct ath_softc *sc)
{
struct ath_hw *ah = NULL;
@@ -1403,7 +1373,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
/* Get the hardware key cache size. */
sc->keymax = ah->caps.keycache_size;
if (sc->keymax > ATH_KEYMAX) {
- DPRINTF(sc, ATH_DBG_KEYCACHE,
+ DPRINTF(sc, ATH_DBG_ANY,
"Warning, using only %u entries in %u key cache\n",
ATH_KEYMAX, sc->keymax);
sc->keymax = ATH_KEYMAX;
@@ -1416,7 +1386,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
for (i = 0; i < sc->keymax; i++)
ath9k_hw_keyreset(ah, (u16) i);
- if (ath9k_regd_init(sc->sc_ah))
+ if (error)
goto bad;
/* default to MONITOR mode */
@@ -1545,9 +1515,6 @@ static int ath_init(u16 devid, struct ath_softc *sc)
sc->beacon.bslot_aphy[i] = NULL;
}
- /* save MISC configurations */
- sc->config.swBeaconProcess = 1;
-
/* setup channels and rates */
sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
@@ -1602,9 +1569,6 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT);
- hw->wiphy->reg_notifier = ath9k_reg_notifier;
- hw->wiphy->strict_regulatory = true;
-
hw->queues = 4;
hw->max_rates = 4;
hw->channel_change_time = 5000;
@@ -1625,8 +1589,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
int ath_attach(u16 devid, struct ath_softc *sc)
{
struct ieee80211_hw *hw = sc->hw;
- const struct ieee80211_regdomain *regd;
int error = 0, i;
+ struct ath_regulatory *reg;
DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
@@ -1640,6 +1604,13 @@ int ath_attach(u16 devid, struct ath_softc *sc)
ath_set_hw_capab(sc, hw);
+ error = ath_regd_init(&sc->sc_ah->regulatory, sc->hw->wiphy,
+ ath9k_reg_notifier);
+ if (error)
+ return error;
+
+ reg = &sc->sc_ah->regulatory;
+
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
@@ -1656,41 +1627,20 @@ int ath_attach(u16 devid, struct ath_softc *sc)
goto error_attach;
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- /* Initialze h/w Rfkill */
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
- INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll);
-
/* Initialize s/w rfkill */
error = ath_init_sw_rfkill(sc);
if (error)
goto error_attach;
#endif
- if (ath9k_is_world_regd(sc->sc_ah)) {
- /* Anything applied here (prior to wiphy registration) gets
- * saved on the wiphy orig_* parameters */
- regd = ath9k_world_regdomain(sc->sc_ah);
- hw->wiphy->custom_regulatory = true;
- hw->wiphy->strict_regulatory = false;
- } else {
- /* This gets applied in the case of the absense of CRDA,
- * it's our own custom world regulatory domain, similar to
- * cfg80211's but we enable passive scanning */
- regd = ath9k_default_world_regdomain();
- }
- wiphy_apply_custom_regulatory(hw->wiphy, regd);
- ath9k_reg_apply_radar_flags(hw->wiphy);
- ath9k_reg_apply_world_flags(hw->wiphy, NL80211_REGDOM_SET_BY_DRIVER);
-
INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
sc->wiphy_scheduler_int = msecs_to_jiffies(500);
error = ieee80211_register_hw(hw);
- if (!ath9k_is_world_regd(sc->sc_ah)) {
- error = regulatory_hint(hw->wiphy,
- sc->sc_ah->regulatory.alpha2);
+ if (!ath_is_world_regd(reg)) {
+ error = regulatory_hint(hw->wiphy, reg->alpha2);
if (error)
goto error_attach;
}
@@ -1728,7 +1678,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
if (r)
DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %u\n", r);
+ "Unable to reset hardware; reset status %d\n", r);
spin_unlock_bh(&sc->sc_resetlock);
if (ath_startrecv(sc) != 0)
@@ -1792,7 +1742,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
goto fail;
}
- dd->dd_name = name;
dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
/*
@@ -1822,7 +1771,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
}
ds = dd->dd_desc;
DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
- dd->dd_name, ds, (u32) dd->dd_desc_len,
+ name, ds, (u32) dd->dd_desc_len,
ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
/* allocate buffers */
@@ -2021,7 +1970,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
r = ath9k_hw_reset(sc->sc_ah, init_channel, false);
if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %u "
+ "Unable to reset hardware; reset status %d "
"(freq %u MHz)\n", r,
curchan->center_freq);
spin_unlock_bh(&sc->sc_resetlock);
@@ -2043,8 +1992,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
* here except setup the interrupt mask.
*/
if (ath_startrecv(sc) != 0) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to start recv logic\n");
+ DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n");
r = -EIO;
goto mutex_unlock;
}
@@ -2095,6 +2043,46 @@ static int ath9k_tx(struct ieee80211_hw *hw,
goto exit;
}
+ if (sc->hw->conf.flags & IEEE80211_CONF_PS) {
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ /*
+ * mac80211 does not set PM field for normal data frames, so we
+ * need to update that based on the current PS mode.
+ */
+ if (ieee80211_is_data(hdr->frame_control) &&
+ !ieee80211_is_nullfunc(hdr->frame_control) &&
+ !ieee80211_has_pm(hdr->frame_control)) {
+ DPRINTF(sc, ATH_DBG_PS, "Add PM=1 for a TX frame "
+ "while in PS mode\n");
+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
+ }
+ }
+
+ if (unlikely(sc->sc_ah->power_mode != ATH9K_PM_AWAKE)) {
+ /*
+ * We are using PS-Poll and mac80211 can request TX while in
+ * power save mode. Need to wake up hardware for the TX to be
+ * completed and if needed, also for RX of buffered frames.
+ */
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ ath9k_ps_wakeup(sc);
+ ath9k_hw_setrxabort(sc->sc_ah, 0);
+ if (ieee80211_is_pspoll(hdr->frame_control)) {
+ DPRINTF(sc, ATH_DBG_PS, "Sending PS-Poll to pick a "
+ "buffered frame\n");
+ sc->sc_flags |= SC_OP_WAIT_FOR_PSPOLL_DATA;
+ } else {
+ DPRINTF(sc, ATH_DBG_PS, "Wake up to complete TX\n");
+ sc->sc_flags |= SC_OP_WAIT_FOR_TX_ACK;
+ }
+ /*
+ * The actual restore operation will happen only after
+ * the sc_flags bit is cleared. We are just dropping
+ * the ps_usecount here.
+ */
+ ath9k_ps_restore(sc);
+ }
+
memset(&txctl, 0, sizeof(struct ath_tx_control));
/*
@@ -2171,10 +2159,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
} else
sc->rx.rxlink = NULL;
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
- cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
-#endif
+ rfkill_pause_polling(sc->rf_kill.rfkill);
+
/* disable HAL and put h/w to sleep */
ath9k_hw_disable(sc->sc_ah);
ath9k_hw_configpcipowersave(sc->sc_ah, 1);
@@ -2257,25 +2243,10 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
sc->imask |= ATH9K_INT_TSFOOR;
}
- /*
- * Some hardware processes the TIM IE and fires an
- * interrupt when the TIM bit is set. For hardware
- * that does, if not overridden by configuration,
- * enable the TIM interrupt when operating as station.
- */
- if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) &&
- (conf->type == NL80211_IFTYPE_STATION) &&
- !sc->config.swBeaconProcess)
- sc->imask |= ATH9K_INT_TIM;
-
ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
- if (conf->type == NL80211_IFTYPE_AP) {
- /* TODO: is this a suitable place to start ANI for AP mode? */
- /* Start ANI */
- mod_timer(&sc->ani.timer,
- jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
- }
+ if (conf->type == NL80211_IFTYPE_AP)
+ ath_start_ani(sc);
out:
mutex_unlock(&sc->mutex);
@@ -2326,26 +2297,36 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
struct ieee80211_conf *conf = &hw->conf;
+ struct ath_hw *ah = sc->sc_ah;
mutex_lock(&sc->mutex);
if (changed & IEEE80211_CONF_CHANGE_PS) {
if (conf->flags & IEEE80211_CONF_PS) {
- if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
- sc->imask |= ATH9K_INT_TIM_TIMER;
- ath9k_hw_set_interrupts(sc->sc_ah,
- sc->imask);
+ if (!(ah->caps.hw_caps &
+ ATH9K_HW_CAP_AUTOSLEEP)) {
+ if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
+ sc->imask |= ATH9K_INT_TIM_TIMER;
+ ath9k_hw_set_interrupts(sc->sc_ah,
+ sc->imask);
+ }
+ ath9k_hw_setrxabort(sc->sc_ah, 1);
}
- ath9k_hw_setrxabort(sc->sc_ah, 1);
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
} else {
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
- ath9k_hw_setrxabort(sc->sc_ah, 0);
- sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
- if (sc->imask & ATH9K_INT_TIM_TIMER) {
- sc->imask &= ~ATH9K_INT_TIM_TIMER;
- ath9k_hw_set_interrupts(sc->sc_ah,
- sc->imask);
+ if (!(ah->caps.hw_caps &
+ ATH9K_HW_CAP_AUTOSLEEP)) {
+ ath9k_hw_setrxabort(sc->sc_ah, 0);
+ sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON |
+ SC_OP_WAIT_FOR_CAB |
+ SC_OP_WAIT_FOR_PSPOLL_DATA |
+ SC_OP_WAIT_FOR_TX_ACK);
+ if (sc->imask & ATH9K_INT_TIM_TIMER) {
+ sc->imask &= ~ATH9K_INT_TIM_TIMER;
+ ath9k_hw_set_interrupts(sc->sc_ah,
+ sc->imask);
+ }
}
}
}
@@ -2387,114 +2368,6 @@ skip_chan_change:
if (changed & IEEE80211_CONF_CHANGE_POWER)
sc->config.txpowlimit = 2 * conf->power_level;
- /*
- * The HW TSF has to be reset when the beacon interval changes.
- * We set the flag here, and ath_beacon_config_ap() would take this
- * into account when it gets called through the subsequent
- * config_interface() call - with IFCC_BEACON in the changed field.
- */
-
- if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
- sc->sc_flags |= SC_OP_TSF_RESET;
-
- mutex_unlock(&sc->mutex);
-
- return 0;
-}
-
-static int ath9k_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct ath_wiphy *aphy = hw->priv;
- struct ath_softc *sc = aphy->sc;
- struct ath_hw *ah = sc->sc_ah;
- struct ath_vif *avp = (void *)vif->drv_priv;
- u32 rfilt = 0;
- int error, i;
-
- mutex_lock(&sc->mutex);
-
- /* TODO: Need to decide which hw opmode to use for multi-interface
- * cases */
- if (vif->type == NL80211_IFTYPE_AP &&
- ah->opmode != NL80211_IFTYPE_AP) {
- ah->opmode = NL80211_IFTYPE_STATION;
- ath9k_hw_setopmode(ah);
- memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
- sc->curaid = 0;
- ath9k_hw_write_associd(sc);
- /* Request full reset to get hw opmode changed properly */
- sc->sc_flags |= SC_OP_FULL_RESET;
- }
-
- if ((conf->changed & IEEE80211_IFCC_BSSID) &&
- !is_zero_ether_addr(conf->bssid)) {
- switch (vif->type) {
- case NL80211_IFTYPE_STATION:
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_MESH_POINT:
- /* Set BSSID */
- memcpy(sc->curbssid, conf->bssid, ETH_ALEN);
- memcpy(avp->bssid, conf->bssid, ETH_ALEN);
- sc->curaid = 0;
- ath9k_hw_write_associd(sc);
-
- /* Set aggregation protection mode parameters */
- sc->config.ath_aggr_prot = 0;
-
- DPRINTF(sc, ATH_DBG_CONFIG,
- "RX filter 0x%x bssid %pM aid 0x%x\n",
- rfilt, sc->curbssid, sc->curaid);
-
- /* need to reconfigure the beacon */
- sc->sc_flags &= ~SC_OP_BEACONS ;
-
- break;
- default:
- break;
- }
- }
-
- if ((vif->type == NL80211_IFTYPE_ADHOC) ||
- (vif->type == NL80211_IFTYPE_AP) ||
- (vif->type == NL80211_IFTYPE_MESH_POINT)) {
- if ((conf->changed & IEEE80211_IFCC_BEACON) ||
- (conf->changed & IEEE80211_IFCC_BEACON_ENABLED &&
- conf->enable_beacon)) {
- /*
- * Allocate and setup the beacon frame.
- *
- * Stop any previous beacon DMA. This may be
- * necessary, for example, when an ibss merge
- * causes reconfiguration; we may be called
- * with beacon transmission active.
- */
- ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-
- error = ath_beacon_alloc(aphy, vif);
- if (error != 0) {
- mutex_unlock(&sc->mutex);
- return error;
- }
-
- ath_beacon_config(sc, vif);
- }
- }
-
- /* Check for WLAN_CAPABILITY_PRIVACY ? */
- if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
- for (i = 0; i < IEEE80211_WEP_NKID; i++)
- if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
- ath9k_hw_keysetmac(sc->sc_ah,
- (u16)i,
- sc->curbssid);
- }
-
- /* Only legacy IBSS for now */
- if (vif->type == NL80211_IFTYPE_ADHOC)
- ath_update_chainmask(sc, 0);
-
mutex_unlock(&sc->mutex);
return 0;
@@ -2523,8 +2396,10 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
*total_flags &= SUPPORTED_FILTERS;
sc->rx.rxfilter = *total_flags;
+ ath9k_ps_wakeup(sc);
rfilt = ath_calcrxfilter(sc);
ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
+ ath9k_ps_restore(sc);
DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter);
}
@@ -2562,6 +2437,8 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
mutex_lock(&sc->mutex);
+ memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
+
qi.tqi_aifs = params->aifs;
qi.tqi_cwmin = params->cw_min;
qi.tqi_cwmax = params->cw_max;
@@ -2598,7 +2475,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
mutex_lock(&sc->mutex);
ath9k_ps_wakeup(sc);
- DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n");
+ DPRINTF(sc, ATH_DBG_CONFIG, "Set HW Key\n");
switch (cmd) {
case SET_KEY:
@@ -2634,9 +2511,92 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_vif *avp = (void *)vif->drv_priv;
+ u32 rfilt = 0;
+ int error, i;
mutex_lock(&sc->mutex);
+ /*
+ * TODO: Need to decide which hw opmode to use for
+ * multi-interface cases
+ * XXX: This belongs into add_interface!
+ */
+ if (vif->type == NL80211_IFTYPE_AP &&
+ ah->opmode != NL80211_IFTYPE_AP) {
+ ah->opmode = NL80211_IFTYPE_STATION;
+ ath9k_hw_setopmode(ah);
+ memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
+ sc->curaid = 0;
+ ath9k_hw_write_associd(sc);
+ /* Request full reset to get hw opmode changed properly */
+ sc->sc_flags |= SC_OP_FULL_RESET;
+ }
+
+ if ((changed & BSS_CHANGED_BSSID) &&
+ !is_zero_ether_addr(bss_conf->bssid)) {
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
+ /* Set BSSID */
+ memcpy(sc->curbssid, bss_conf->bssid, ETH_ALEN);
+ memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
+ sc->curaid = 0;
+ ath9k_hw_write_associd(sc);
+
+ /* Set aggregation protection mode parameters */
+ sc->config.ath_aggr_prot = 0;
+
+ DPRINTF(sc, ATH_DBG_CONFIG,
+ "RX filter 0x%x bssid %pM aid 0x%x\n",
+ rfilt, sc->curbssid, sc->curaid);
+
+ /* need to reconfigure the beacon */
+ sc->sc_flags &= ~SC_OP_BEACONS ;
+
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ((vif->type == NL80211_IFTYPE_ADHOC) ||
+ (vif->type == NL80211_IFTYPE_AP) ||
+ (vif->type == NL80211_IFTYPE_MESH_POINT)) {
+ if ((changed & BSS_CHANGED_BEACON) ||
+ (changed & BSS_CHANGED_BEACON_ENABLED &&
+ bss_conf->enable_beacon)) {
+ /*
+ * Allocate and setup the beacon frame.
+ *
+ * Stop any previous beacon DMA. This may be
+ * necessary, for example, when an ibss merge
+ * causes reconfiguration; we may be called
+ * with beacon transmission active.
+ */
+ ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+
+ error = ath_beacon_alloc(aphy, vif);
+ if (!error)
+ ath_beacon_config(sc, vif);
+ }
+ }
+
+ /* Check for WLAN_CAPABILITY_PRIVACY ? */
+ if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
+ for (i = 0; i < IEEE80211_WEP_NKID; i++)
+ if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
+ ath9k_hw_keysetmac(sc->sc_ah,
+ (u16)i,
+ sc->curbssid);
+ }
+
+ /* Only legacy IBSS for now */
+ if (vif->type == NL80211_IFTYPE_ADHOC)
+ ath_update_chainmask(sc, 0);
+
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
bss_conf->use_short_preamble);
@@ -2662,6 +2622,18 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
ath9k_bss_assoc_info(sc, vif, bss_conf);
}
+ /*
+ * The HW TSF has to be reset when the beacon interval changes.
+ * We set the flag here, and ath_beacon_config_ap() would take this
+ * into account when it gets called through the subsequent
+ * config_interface() call - with IFCC_BEACON in the changed field.
+ */
+
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ sc->sc_flags |= SC_OP_TSF_RESET;
+ sc->beacon_interval = bss_conf->beacon_int;
+ }
+
mutex_unlock(&sc->mutex);
}
@@ -2771,6 +2743,7 @@ 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;
+ sc->sc_flags |= SC_OP_FULL_RESET;
mutex_unlock(&sc->mutex);
}
@@ -2781,7 +2754,6 @@ struct ieee80211_ops ath9k_ops = {
.add_interface = ath9k_add_interface,
.remove_interface = ath9k_remove_interface,
.config = ath9k_config,
- .config_interface = ath9k_config_interface,
.configure_filter = ath9k_configure_filter,
.sta_notify = ath9k_sta_notify,
.conf_tx = ath9k_conf_tx,
diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 168411d322a..ccdf20a2e9b 100644
--- a/drivers/net/wireless/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -227,11 +227,6 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
- cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
-#endif
-
pci_save_state(pdev);
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
@@ -256,16 +251,6 @@ static int ath_pci_resume(struct pci_dev *pdev)
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- /*
- * check the h/w rfkill state on resume
- * and start the rfkill poll timer
- */
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
- queue_delayed_work(sc->hw->workqueue,
- &sc->rf_kill.rfkill_poll, 0);
-#endif
-
return 0;
}
diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index 8bcba906929..aaa941561c3 100644
--- a/drivers/net/wireless/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -46,7 +46,7 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
channelSel = ((freq - 704) * 2 - 3040) / 10;
bModeSynth = 1;
} else {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Invalid channel %u MHz\n", freq);
return false;
}
@@ -79,7 +79,7 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
aModeRefSel = ath9k_hw_reverse_bits(1, 2);
} else {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Invalid channel %u MHz\n", freq);
return false;
}
@@ -96,9 +96,8 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
return true;
}
-bool
-ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
- struct ath9k_channel *chan)
+void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
+ struct ath9k_channel *chan)
{
u16 bMode, fracMode, aModeRefSel = 0;
u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
@@ -169,8 +168,6 @@ ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
ah->curchan = chan;
ah->curchan_rad_index = -1;
-
- return true;
}
static void
diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 0f7f8e0c9c9..c70f530642f 100644
--- a/drivers/net/wireless/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -17,7 +17,7 @@
#ifndef PHY_H
#define PHY_H
-bool ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
+void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
struct ath9k_channel
*chan);
bool ath9k_hw_set_channel(struct ath_hw *ah,
@@ -556,9 +556,6 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
int r; \
for (r = 0; r < ((iniarray)->ia_rows); r++) { \
REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, \
- "RF 0x%x V 0x%x\n", \
- INI_RA((iniarray), r, 0), (regData)[r]); \
DO_DELAY(regWr); \
} \
} while (0)
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 824ccbb8b7b..ba06e78b2f5 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -17,7 +17,7 @@
#include "ath9k.h"
-static struct ath_rate_table ar5416_11na_ratetable = {
+static const struct ath_rate_table ar5416_11na_ratetable = {
42,
{
{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
@@ -155,7 +155,7 @@ static struct ath_rate_table ar5416_11na_ratetable = {
/* 4ms frame limit not used for NG mode. The values filled
* for HT are the 64K max aggregate limit */
-static struct ath_rate_table ar5416_11ng_ratetable = {
+static const struct ath_rate_table ar5416_11ng_ratetable = {
46,
{
{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
@@ -302,7 +302,7 @@ static struct ath_rate_table ar5416_11ng_ratetable = {
WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
};
-static struct ath_rate_table ar5416_11a_ratetable = {
+static const struct ath_rate_table ar5416_11a_ratetable = {
8,
{
{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
@@ -335,7 +335,7 @@ static struct ath_rate_table ar5416_11a_ratetable = {
0, /* Phy rates allowed initially */
};
-static struct ath_rate_table ar5416_11g_ratetable = {
+static const struct ath_rate_table ar5416_11g_ratetable = {
12,
{
{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
@@ -380,7 +380,7 @@ static struct ath_rate_table ar5416_11g_ratetable = {
0, /* Phy rates allowed initially */
};
-static struct ath_rate_table ar5416_11b_ratetable = {
+static const struct ath_rate_table ar5416_11b_ratetable = {
4,
{
{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
@@ -420,7 +420,7 @@ static inline int8_t median(int8_t a, int8_t b, int8_t c)
}
}
-static void ath_rc_sort_validrates(struct ath_rate_table *rate_table,
+static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
struct ath_rate_priv *ath_rc_priv)
{
u8 i, j, idx, idx_next;
@@ -461,10 +461,11 @@ static inline int ath_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv,
return ath_rc_priv->valid_rate_index[index];
}
-static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
- struct ath_rate_priv *ath_rc_priv,
- u8 cur_valid_txrate,
- u8 *next_idx)
+static inline
+int ath_rc_get_nextvalid_txrate(const struct ath_rate_table *rate_table,
+ struct ath_rate_priv *ath_rc_priv,
+ u8 cur_valid_txrate,
+ u8 *next_idx)
{
u8 i;
@@ -500,7 +501,7 @@ static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
}
static inline int
-ath_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table,
+ath_rc_get_nextlowervalid_txrate(const struct ath_rate_table *rate_table,
struct ath_rate_priv *ath_rc_priv,
u8 cur_valid_txrate, u8 *next_idx)
{
@@ -517,14 +518,14 @@ ath_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table,
}
static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
- struct ath_rate_table *rate_table,
+ const struct ath_rate_table *rate_table,
u32 capflag)
{
u8 i, hi = 0;
u32 valid;
for (i = 0; i < rate_table->rate_cnt; i++) {
- valid = (ath_rc_priv->single_stream ?
+ valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
rate_table->info[i].valid_single_stream :
rate_table->info[i].valid);
if (valid == 1) {
@@ -547,7 +548,7 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
}
static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
- struct ath_rate_table *rate_table,
+ const struct ath_rate_table *rate_table,
struct ath_rateset *rateset,
u32 capflag)
{
@@ -557,9 +558,9 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
for (i = 0; i < rateset->rs_nrates; i++) {
for (j = 0; j < rate_table->rate_cnt; j++) {
u32 phy = rate_table->info[j].phy;
- u32 valid = (ath_rc_priv->single_stream ?
- rate_table->info[j].valid_single_stream :
- rate_table->info[j].valid);
+ u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
+ rate_table->info[j].valid_single_stream :
+ rate_table->info[j].valid);
u8 rate = rateset->rs_rates[i];
u8 dot11rate = rate_table->info[j].dot11rate;
@@ -592,7 +593,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
}
static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
- struct ath_rate_table *rate_table,
+ const struct ath_rate_table *rate_table,
u8 *mcs_set, u32 capflag)
{
struct ath_rateset *rateset = (struct ath_rateset *)mcs_set;
@@ -603,7 +604,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
for (i = 0; i < rateset->rs_nrates; i++) {
for (j = 0; j < rate_table->rate_cnt; j++) {
u32 phy = rate_table->info[j].phy;
- u32 valid = (ath_rc_priv->single_stream ?
+ u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
rate_table->info[j].valid_single_stream :
rate_table->info[j].valid);
u8 rate = rateset->rs_rates[i];
@@ -630,7 +631,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
- struct ath_rate_table *rate_table,
+ const struct ath_rate_table *rate_table,
int *is_probing)
{
u32 dt, best_thruput, this_thruput, now_msec;
@@ -740,14 +741,15 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
if (rate > (ath_rc_priv->rate_table_size - 1))
rate = ath_rc_priv->rate_table_size - 1;
- ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) ||
+ ASSERT((rate_table->info[rate].valid &&
+ (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) ||
(rate_table->info[rate].valid_single_stream &&
- ath_rc_priv->single_stream));
+ !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)));
return rate;
}
-static void ath_rc_rate_set_series(struct ath_rate_table *rate_table,
+static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table,
struct ieee80211_tx_rate *rate,
struct ieee80211_tx_rate_control *txrc,
u8 tries, u8 rix, int rtsctsenable)
@@ -768,7 +770,7 @@ static void ath_rc_rate_set_series(struct ath_rate_table *rate_table,
}
static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
- struct ath_rate_table *rate_table,
+ const struct ath_rate_table *rate_table,
struct ieee80211_tx_info *tx_info)
{
struct ieee80211_tx_rate *rates = tx_info->control.rates;
@@ -806,12 +808,12 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
static u8 ath_rc_rate_getidx(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
- struct ath_rate_table *rate_table,
+ const struct ath_rate_table *rate_table,
u8 rix, u16 stepdown,
u16 min_rate)
{
u32 j;
- u8 nextindex;
+ u8 nextindex = 0;
if (min_rate) {
for (j = RATE_TABLE_SIZE; j > 0; j--) {
@@ -837,7 +839,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
struct ieee80211_tx_rate_control *txrc)
{
- struct ath_rate_table *rate_table;
+ const struct ath_rate_table *rate_table;
struct sk_buff *skb = txrc->skb;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rates = tx_info->control.rates;
@@ -936,7 +938,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
}
static bool ath_rc_update_per(struct ath_softc *sc,
- struct ath_rate_table *rate_table,
+ const struct ath_rate_table *rate_table,
struct ath_rate_priv *ath_rc_priv,
struct ath_tx_info_priv *tx_info_priv,
int tx_rate, int xretries, int retries,
@@ -1141,7 +1143,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
int rate;
u8 last_per;
bool state_change = false;
- struct ath_rate_table *rate_table = sc->cur_rate_table;
+ const struct ath_rate_table *rate_table = sc->cur_rate_table;
int size = ath_rc_priv->rate_table_size;
if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
@@ -1275,7 +1277,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
#undef CHK_RSSI
}
-static int ath_rc_get_rateindex(struct ath_rate_table *rate_table,
+static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
struct ieee80211_tx_rate *rate)
{
int rix;
@@ -1299,7 +1301,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
int final_ts_idx, int xretries, int long_retry)
{
struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
- struct ath_rate_table *rate_table;
+ const struct ath_rate_table *rate_table;
struct ieee80211_tx_rate *rates = tx_info->status.rates;
u8 flags;
u32 i = 0, rix;
@@ -1320,7 +1322,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
* 40 to 20 => don't update */
if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
- (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG))
+ !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
return;
rix = ath_rc_get_rateindex(rate_table, &rates[i]);
@@ -1345,18 +1347,19 @@ static void ath_rc_tx_status(struct ath_softc *sc,
/* If HT40 and we have switched mode from 40 to 20 => don't update */
if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
- (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) {
+ !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
return;
- }
rix = ath_rc_get_rateindex(rate_table, &rates[i]);
ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix,
xretries, long_retry);
}
-static struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
- enum ieee80211_band band,
- bool is_ht, bool is_cw_40)
+static const
+struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
+ enum ieee80211_band band,
+ bool is_ht,
+ bool is_cw_40)
{
int mode = 0;
@@ -1390,7 +1393,7 @@ static void ath_rc_init(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta,
- struct ath_rate_table *rate_table)
+ const struct ath_rate_table *rate_table)
{
struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
@@ -1420,10 +1423,6 @@ static void ath_rc_init(struct ath_softc *sc,
ath_rc_priv->valid_phy_rateidx[i][j] = 0;
ath_rc_priv->valid_phy_ratecnt[i] = 0;
}
- ath_rc_priv->rc_phy_mode = ath_rc_priv->ht_cap & WLAN_RC_40_FLAG;
-
- /* Set stream capability */
- ath_rc_priv->single_stream = (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? 0 : 1;
if (!rateset->rs_nrates) {
/* No working rate, just initialize valid rates */
@@ -1572,12 +1571,13 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
struct ath_rate_priv *ath_rc_priv = priv_sta;
__le16 fc = hdr->frame_control;
- /* lowest rate for management and multicast/broadcast frames */
- if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
- !sta) {
+ /* lowest rate for management and NO_ACK frames */
+ if (!ieee80211_is_data(fc) ||
+ tx_info->flags & IEEE80211_TX_CTL_NO_ACK || !sta) {
tx_info->control.rates[0].idx = rate_lowest_index(sband, sta);
tx_info->control.rates[0].count =
- is_multicast_ether_addr(hdr->addr1) ? 1 : ATH_MGT_TXMAXTRY;
+ (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) ?
+ 1 : ATH_MGT_TXMAXTRY;
return;
}
@@ -1590,7 +1590,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
{
struct ath_softc *sc = priv;
struct ath_rate_priv *ath_rc_priv = priv_sta;
- struct ath_rate_table *rate_table = NULL;
+ const struct ath_rate_table *rate_table = NULL;
bool is_cw40, is_sgi40;
int i, j = 0;
@@ -1639,7 +1639,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
{
struct ath_softc *sc = priv;
struct ath_rate_priv *ath_rc_priv = priv_sta;
- struct ath_rate_table *rate_table = NULL;
+ const struct ath_rate_table *rate_table = NULL;
bool oper_cw40 = false, oper_sgi40;
bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ?
true : false;
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 199a3ce57d6..e3abd76103f 100644
--- a/drivers/net/wireless/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -24,7 +24,6 @@ struct ath_softc;
#define ATH_RATE_MAX 30
#define RATE_TABLE_SIZE 64
#define MAX_TX_RATE_PHY 48
-#define WLAN_CTRL_FRAME_SIZE (2+2+6+4)
/* VALID_ALL - valid for 20/40/Legacy,
* VALID - Legacy only,
@@ -158,7 +157,6 @@ struct ath_rateset {
* @probe_interval: interval for ratectrl to probe for other rates
* @prev_data_rix: rate idx of last data frame
* @ht_cap: HT capabilities
- * @single_stream: When TRUE, only single TX stream possible
* @neg_rates: Negotatied rates
* @neg_ht_rates: Negotiated HT rates
*/
@@ -176,10 +174,8 @@ struct ath_rate_priv {
u8 max_valid_rate;
u8 valid_rate_index[RATE_TABLE_SIZE];
u8 ht_cap;
- u8 single_stream;
u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX];
u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE];
- u8 rc_phy_mode;
u8 rate_max_phy;
u32 rssi_time;
u32 rssi_down_time;
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index dd1f3015674..5014a19b0f7 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -283,54 +283,51 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
struct ath_buf *bf;
int error = 0;
- do {
- spin_lock_init(&sc->rx.rxflushlock);
- sc->sc_flags &= ~SC_OP_RXFLUSH;
- spin_lock_init(&sc->rx.rxbuflock);
-
- sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
- min(sc->cachelsz,
- (u16)64));
+ spin_lock_init(&sc->rx.rxflushlock);
+ sc->sc_flags &= ~SC_OP_RXFLUSH;
+ spin_lock_init(&sc->rx.rxbuflock);
- DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
- sc->cachelsz, sc->rx.bufsize);
+ sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
+ min(sc->cachelsz, (u16)64));
- /* Initialize rx descriptors */
+ DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
+ sc->cachelsz, sc->rx.bufsize);
- error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
- "rx", nbufs, 1);
- if (error != 0) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "failed to allocate rx descriptors: %d\n", error);
- break;
- }
+ /* Initialize rx descriptors */
- list_for_each_entry(bf, &sc->rx.rxbuf, list) {
- skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL);
- if (skb == NULL) {
- error = -ENOMEM;
- break;
- }
+ error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
+ "rx", nbufs, 1);
+ if (error != 0) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "failed to allocate rx descriptors: %d\n", error);
+ goto err;
+ }
- bf->bf_mpdu = skb;
- bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
- sc->rx.bufsize,
- DMA_FROM_DEVICE);
- if (unlikely(dma_mapping_error(sc->dev,
- bf->bf_buf_addr))) {
- dev_kfree_skb_any(skb);
- bf->bf_mpdu = NULL;
- DPRINTF(sc, ATH_DBG_CONFIG,
- "dma_mapping_error() on RX init\n");
- error = -ENOMEM;
- break;
- }
- bf->bf_dmacontext = bf->bf_buf_addr;
+ list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+ skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL);
+ if (skb == NULL) {
+ error = -ENOMEM;
+ goto err;
}
- sc->rx.rxlink = NULL;
- } while (0);
+ bf->bf_mpdu = skb;
+ bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+ sc->rx.bufsize,
+ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(sc->dev,
+ bf->bf_buf_addr))) {
+ dev_kfree_skb_any(skb);
+ bf->bf_mpdu = NULL;
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "dma_mapping_error() on RX init\n");
+ error = -ENOMEM;
+ goto err;
+ }
+ bf->bf_dmacontext = bf->bf_buf_addr;
+ }
+ sc->rx.rxlink = NULL;
+err:
if (error)
ath_rx_cleanup(sc);
@@ -345,10 +342,8 @@ void ath_rx_cleanup(struct ath_softc *sc)
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
skb = bf->bf_mpdu;
if (skb) {
- dma_unmap_single(sc->dev,
- bf->bf_buf_addr,
- sc->rx.bufsize,
- DMA_FROM_DEVICE);
+ dma_unmap_single(sc->dev, bf->bf_buf_addr,
+ sc->rx.bufsize, DMA_FROM_DEVICE);
dev_kfree_skb(skb);
}
}
@@ -478,6 +473,159 @@ void ath_flushrecv(struct ath_softc *sc)
spin_unlock_bh(&sc->rx.rxflushlock);
}
+static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
+{
+ /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */
+ struct ieee80211_mgmt *mgmt;
+ u8 *pos, *end, id, elen;
+ struct ieee80211_tim_ie *tim;
+
+ mgmt = (struct ieee80211_mgmt *)skb->data;
+ pos = mgmt->u.beacon.variable;
+ end = skb->data + skb->len;
+
+ while (pos + 2 < end) {
+ id = *pos++;
+ elen = *pos++;
+ if (pos + elen > end)
+ break;
+
+ if (id == WLAN_EID_TIM) {
+ if (elen < sizeof(*tim))
+ break;
+ tim = (struct ieee80211_tim_ie *) pos;
+ if (tim->dtim_count != 0)
+ break;
+ return tim->bitmap_ctrl & 0x01;
+ }
+
+ pos += elen;
+ }
+
+ return false;
+}
+
+static void ath_rx_ps_back_to_sleep(struct ath_softc *sc)
+{
+ sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | SC_OP_WAIT_FOR_CAB);
+}
+
+static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
+{
+ struct ieee80211_mgmt *mgmt;
+
+ if (skb->len < 24 + 8 + 2 + 2)
+ return;
+
+ mgmt = (struct ieee80211_mgmt *)skb->data;
+ if (memcmp(sc->curbssid, mgmt->bssid, ETH_ALEN) != 0)
+ return; /* not from our current AP */
+
+ if (sc->sc_flags & SC_OP_BEACON_SYNC) {
+ sc->sc_flags &= ~SC_OP_BEACON_SYNC;
+ DPRINTF(sc, ATH_DBG_PS, "Reconfigure Beacon timers based on "
+ "timestamp from the AP\n");
+ ath_beacon_config(sc, NULL);
+ }
+
+ if (!(sc->hw->conf.flags & IEEE80211_CONF_PS)) {
+ /* We are not in PS mode anymore; remain awake */
+ DPRINTF(sc, ATH_DBG_PS, "Not in PS mode anymore, remain "
+ "awake\n");
+ sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | SC_OP_WAIT_FOR_CAB);
+ return;
+ }
+
+ if (ath_beacon_dtim_pending_cab(skb)) {
+ /*
+ * Remain awake waiting for buffered broadcast/multicast
+ * frames.
+ */
+ DPRINTF(sc, ATH_DBG_PS, "Received DTIM beacon indicating "
+ "buffered broadcast/multicast frame(s)\n");
+ sc->sc_flags |= SC_OP_WAIT_FOR_CAB;
+ return;
+ }
+
+ if (sc->sc_flags & SC_OP_WAIT_FOR_CAB) {
+ /*
+ * This can happen if a broadcast frame is dropped or the AP
+ * fails to send a frame indicating that all CAB frames have
+ * been delivered.
+ */
+ DPRINTF(sc, ATH_DBG_PS, "PS wait for CAB frames timed out\n");
+ }
+
+ /* No more broadcast/multicast frames to be received at this point. */
+ ath_rx_ps_back_to_sleep(sc);
+}
+
+static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr;
+
+ hdr = (struct ieee80211_hdr *)skb->data;
+
+ /* Process Beacon and CAB receive in PS state */
+ if ((sc->sc_flags & SC_OP_WAIT_FOR_BEACON) &&
+ ieee80211_is_beacon(hdr->frame_control))
+ ath_rx_ps_beacon(sc, skb);
+ else if ((sc->sc_flags & SC_OP_WAIT_FOR_CAB) &&
+ (ieee80211_is_data(hdr->frame_control) ||
+ ieee80211_is_action(hdr->frame_control)) &&
+ is_multicast_ether_addr(hdr->addr1) &&
+ !ieee80211_has_moredata(hdr->frame_control)) {
+ DPRINTF(sc, ATH_DBG_PS, "All PS CAB frames received, back to "
+ "sleep\n");
+ /*
+ * No more broadcast/multicast frames to be received at this
+ * point.
+ */
+ ath_rx_ps_back_to_sleep(sc);
+ } else if ((sc->sc_flags & SC_OP_WAIT_FOR_PSPOLL_DATA) &&
+ !is_multicast_ether_addr(hdr->addr1) &&
+ !ieee80211_has_morefrags(hdr->frame_control)) {
+ sc->sc_flags &= ~SC_OP_WAIT_FOR_PSPOLL_DATA;
+ DPRINTF(sc, ATH_DBG_PS, "Going back to sleep after having "
+ "received PS-Poll data (0x%x)\n",
+ sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
+ SC_OP_WAIT_FOR_CAB |
+ SC_OP_WAIT_FOR_PSPOLL_DATA |
+ SC_OP_WAIT_FOR_TX_ACK));
+ }
+}
+
+static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb,
+ struct ieee80211_rx_status *rx_status)
+{
+ struct ieee80211_hdr *hdr;
+
+ hdr = (struct ieee80211_hdr *)skb->data;
+
+ /* Send the frame to mac80211 */
+ if (is_multicast_ether_addr(hdr->addr1)) {
+ int i;
+ /*
+ * Deliver broadcast/multicast frames to all suitable
+ * virtual wiphys.
+ */
+ /* TODO: filter based on channel configuration */
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ struct ath_wiphy *aphy = sc->sec_wiphy[i];
+ struct sk_buff *nskb;
+ if (aphy == NULL)
+ continue;
+ nskb = skb_copy(skb, GFP_ATOMIC);
+ if (nskb)
+ __ieee80211_rx(aphy->hw, nskb, rx_status);
+ }
+ __ieee80211_rx(sc->hw, skb, rx_status);
+ } else {
+ /* Deliver unicast frames based on receiver address */
+ __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb, rx_status);
+ }
+}
+
int ath_rx_tasklet(struct ath_softc *sc, int flush)
{
#define PA2DESC(_sc, _pa) \
@@ -627,7 +775,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) {
rx_status.flag |= RX_FLAG_DECRYPTED;
- } else if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED)
+ } else if (ieee80211_has_protected(fc)
&& !decrypt_error && skb->len >= hdrlen + 4) {
keyix = skb->data[hdrlen + 3] >> 6;
@@ -636,36 +784,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
}
if (ah->sw_mgmt_crypto &&
(rx_status.flag & RX_FLAG_DECRYPTED) &&
- ieee80211_is_mgmt(hdr->frame_control)) {
+ ieee80211_is_mgmt(fc)) {
/* Use software decrypt for management frames. */
rx_status.flag &= ~RX_FLAG_DECRYPTED;
}
- /* Send the frame to mac80211 */
- if (hdr->addr1[5] & 0x01) {
- int i;
- /*
- * Deliver broadcast/multicast frames to all suitable
- * virtual wiphys.
- */
- /* TODO: filter based on channel configuration */
- for (i = 0; i < sc->num_sec_wiphy; i++) {
- struct ath_wiphy *aphy = sc->sec_wiphy[i];
- struct sk_buff *nskb;
- if (aphy == NULL)
- continue;
- nskb = skb_copy(skb, GFP_ATOMIC);
- if (nskb)
- __ieee80211_rx(aphy->hw, nskb,
- &rx_status);
- }
- __ieee80211_rx(sc->hw, skb, &rx_status);
- } else {
- /* Deliver unicast frames based on receiver address */
- __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb,
- &rx_status);
- }
-
/* We will now give hardware our shiny new allocated skb */
bf->bf_mpdu = requeue_skb;
bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
@@ -675,8 +798,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
bf->bf_buf_addr))) {
dev_kfree_skb_any(requeue_skb);
bf->bf_mpdu = NULL;
- DPRINTF(sc, ATH_DBG_CONFIG,
+ DPRINTF(sc, ATH_DBG_FATAL,
"dma_mapping_error() on RX\n");
+ ath_rx_send_to_mac80211(sc, skb, &rx_status);
break;
}
bf->bf_dmacontext = bf->bf_buf_addr;
@@ -692,11 +816,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
sc->rx.rxotherant = 0;
}
- if (ieee80211_is_beacon(fc) &&
- (sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) {
- sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
- ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
- }
+ if (unlikely(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
+ SC_OP_WAIT_FOR_PSPOLL_DATA)))
+ ath_rx_ps(sc, skb);
+
+ ath_rx_send_to_mac80211(sc, skb, &rx_status);
+
requeue:
list_move_tail(&bf->list, &sc->rx.rxbuf);
ath_rx_buf_link(sc, bf);
diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 52605246679..52605246679 100644
--- a/drivers/net/wireless/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
diff --git a/drivers/net/wireless/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index 1ff429b027d..1ff429b027d 100644
--- a/drivers/net/wireless/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 689bdbf7880..b61a071788a 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -283,7 +283,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;
- skb = (struct sk_buff *)bf->bf_mpdu;
+ skb = bf->bf_mpdu;
hdr = (struct ieee80211_hdr *)skb->data;
rcu_read_lock();
@@ -380,8 +380,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
} else {
/* retry the un-acked ones */
- if (bf->bf_next == NULL &&
- bf_last->bf_status & ATH_BUFSTATUS_STALE) {
+ if (bf->bf_next == NULL && bf_last->bf_stale) {
struct ath_buf *tbf;
tbf = ath_clone_txbuf(sc, bf_last);
@@ -435,7 +434,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
struct ath_atx_tid *tid)
{
- struct ath_rate_table *rate_table = sc->cur_rate_table;
+ const struct ath_rate_table *rate_table = sc->cur_rate_table;
struct sk_buff *skb;
struct ieee80211_tx_info *tx_info;
struct ieee80211_tx_rate *rates;
@@ -444,7 +443,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
u16 aggr_limit, legacy = 0, maxampdu;
int i;
- skb = (struct sk_buff *)bf->bf_mpdu;
+ skb = bf->bf_mpdu;
tx_info = IEEE80211_SKB_CB(skb);
rates = tx_info->control.rates;
tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0];
@@ -498,7 +497,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
struct ath_buf *bf, u16 frmlen)
{
- struct ath_rate_table *rt = sc->cur_rate_table;
+ const struct ath_rate_table *rt = sc->cur_rate_table;
struct sk_buff *skb = bf->bf_mpdu;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
u32 nsymbits, nsymbols, mpdudensity;
@@ -712,6 +711,7 @@ int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
return 0;
if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
+ txtid->state &= ~AGGR_ADDBA_PROGRESS;
txtid->addba_exchangeattempts = 0;
return 0;
}
@@ -972,7 +972,7 @@ int ath_cabq_update(struct ath_softc *sc)
else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
- qi.tqi_readyTime = (sc->hw->conf.beacon_int *
+ qi.tqi_readyTime = (sc->beacon_interval *
sc->config.cabqReadytime) / 100;
ath_txq_update(sc, qnum, &qi);
@@ -1004,7 +1004,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
- if (bf->bf_status & ATH_BUFSTATUS_STALE) {
+ if (bf->bf_stale) {
list_del(&bf->list);
spin_unlock_bh(&txq->axq_lock);
@@ -1071,7 +1071,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true);
if (r)
DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %u\n",
+ "Unable to reset hardware; reset status %d\n",
r);
spin_unlock_bh(&sc->sc_resetlock);
}
@@ -1408,7 +1408,7 @@ static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
int width, int half_gi, bool shortPreamble)
{
- struct ath_rate_table *rate_table = sc->cur_rate_table;
+ const struct ath_rate_table *rate_table = sc->cur_rate_table;
u32 nbits, nsymbits, duration, nsymbols;
u8 rc;
int streams, pktlen;
@@ -1440,7 +1440,7 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
{
- struct ath_rate_table *rt = sc->cur_rate_table;
+ const struct ath_rate_table *rt = sc->cur_rate_table;
struct ath9k_11n_rate_series series[4];
struct sk_buff *skb;
struct ieee80211_tx_info *tx_info;
@@ -1452,7 +1452,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
- skb = (struct sk_buff *)bf->bf_mpdu;
+ skb = bf->bf_mpdu;
tx_info = IEEE80211_SKB_CB(skb);
rates = tx_info->control.rates;
hdr = (struct ieee80211_hdr *)skb->data;
@@ -1573,8 +1573,9 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
skb->len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
bf->bf_mpdu = NULL;
- DPRINTF(sc, ATH_DBG_CONFIG,
- "dma_mapping_error() on TX\n");
+ kfree(tx_info_priv);
+ tx_info->rate_driver_data[0] = NULL;
+ DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error() on TX\n");
return -ENOMEM;
}
@@ -1586,7 +1587,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
struct ath_tx_control *txctl)
{
- struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
+ struct sk_buff *skb = bf->bf_mpdu;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ath_node *an = NULL;
@@ -1790,6 +1791,16 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
skb_pull(skb, padsize);
}
+ if (sc->sc_flags & SC_OP_WAIT_FOR_TX_ACK) {
+ sc->sc_flags &= ~SC_OP_WAIT_FOR_TX_ACK;
+ DPRINTF(sc, ATH_DBG_PS, "Going back to sleep after having "
+ "received TX status (0x%x)\n",
+ sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
+ SC_OP_WAIT_FOR_CAB |
+ SC_OP_WAIT_FOR_PSPOLL_DATA |
+ SC_OP_WAIT_FOR_TX_ACK));
+ }
+
if (frame_type == ATH9K_NOT_INTERNAL)
ieee80211_tx_status(hw, skb);
else
@@ -1860,7 +1871,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
int nbad, int txok, bool update_rc)
{
- struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
+ struct sk_buff *skb = bf->bf_mpdu;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
@@ -1941,7 +1952,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
* it with the STALE flag.
*/
bf_held = NULL;
- if (bf->bf_status & ATH_BUFSTATUS_STALE) {
+ if (bf->bf_stale) {
bf_held = bf;
if (list_is_last(&bf_held->list, &txq->axq_q)) {
txq->axq_link = NULL;
@@ -1982,7 +1993,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
* however leave the last descriptor back as the holding
* descriptor for hw.
*/
- lastbf->bf_status |= ATH_BUFSTATUS_STALE;
+ lastbf->bf_stale = true;
INIT_LIST_HEAD(&bf_head);
if (!list_is_singular(&lastbf->list))
list_cut_position(&bf_head,
@@ -2048,44 +2059,38 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
{
int error = 0;
- do {
- spin_lock_init(&sc->tx.txbuflock);
-
- error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
- "tx", nbufs, 1);
- if (error != 0) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "Failed to allocate tx descriptors: %d\n",
- error);
- break;
- }
+ spin_lock_init(&sc->tx.txbuflock);
- error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
- "beacon", ATH_BCBUF, 1);
- if (error != 0) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "Failed to allocate beacon descriptors: %d\n",
- error);
- break;
- }
+ error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
+ "tx", nbufs, 1);
+ if (error != 0) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Failed to allocate tx descriptors: %d\n", error);
+ goto err;
+ }
- } while (0);
+ error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
+ "beacon", ATH_BCBUF, 1);
+ if (error != 0) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Failed to allocate beacon descriptors: %d\n", error);
+ goto err;
+ }
+err:
if (error != 0)
ath_tx_cleanup(sc);
return error;
}
-int ath_tx_cleanup(struct ath_softc *sc)
+void ath_tx_cleanup(struct ath_softc *sc)
{
if (sc->beacon.bdma.dd_desc_len != 0)
ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
if (sc->tx.txdma.dd_desc_len != 0)
ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
-
- return 0;
}
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c
new file mode 100644
index 00000000000..9949b11cb15
--- /dev/null
+++ b/drivers/net/wireless/ath/main.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("Atheros Communications");
+MODULE_DESCRIPTION("Shared library for Atheros wireless LAN cards.");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath/regd.c
index 4ca62510229..eef370bd121 100644
--- a/drivers/net/wireless/ath9k/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -16,7 +16,9 @@
#include <linux/kernel.h>
#include <linux/slab.h>
-#include "ath9k.h"
+#include <net/cfg80211.h>
+#include <net/mac80211.h>
+#include "regd.h"
#include "regd_common.h"
/*
@@ -55,7 +57,7 @@
/* Can be used for:
* 0x60, 0x61, 0x62 */
-static const struct ieee80211_regdomain ath9k_world_regdom_60_61_62 = {
+static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = {
.n_reg_rules = 5,
.alpha2 = "99",
.reg_rules = {
@@ -65,7 +67,7 @@ static const struct ieee80211_regdomain ath9k_world_regdom_60_61_62 = {
};
/* Can be used by 0x63 and 0x65 */
-static const struct ieee80211_regdomain ath9k_world_regdom_63_65 = {
+static const struct ieee80211_regdomain ath_world_regdom_63_65 = {
.n_reg_rules = 4,
.alpha2 = "99",
.reg_rules = {
@@ -76,7 +78,7 @@ static const struct ieee80211_regdomain ath9k_world_regdom_63_65 = {
};
/* Can be used by 0x64 only */
-static const struct ieee80211_regdomain ath9k_world_regdom_64 = {
+static const struct ieee80211_regdomain ath_world_regdom_64 = {
.n_reg_rules = 3,
.alpha2 = "99",
.reg_rules = {
@@ -86,7 +88,7 @@ static const struct ieee80211_regdomain ath9k_world_regdom_64 = {
};
/* Can be used by 0x66 and 0x69 */
-static const struct ieee80211_regdomain ath9k_world_regdom_66_69 = {
+static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
.n_reg_rules = 3,
.alpha2 = "99",
.reg_rules = {
@@ -96,7 +98,7 @@ static const struct ieee80211_regdomain ath9k_world_regdom_66_69 = {
};
/* Can be used by 0x67, 0x6A and 0x68 */
-static const struct ieee80211_regdomain ath9k_world_regdom_67_68_6A = {
+static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = {
.n_reg_rules = 4,
.alpha2 = "99",
.reg_rules = {
@@ -112,49 +114,51 @@ static inline bool is_wwr_sku(u16 regd)
(regd == WORLD);
}
-static u16 ath9k_regd_get_eepromRD(struct ath_hw *ah)
+static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
{
- return ah->regulatory.current_rd & ~WORLDWIDE_ROAMING_FLAG;
+ return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
}
-bool ath9k_is_world_regd(struct ath_hw *ah)
+bool ath_is_world_regd(struct ath_regulatory *reg)
{
- return is_wwr_sku(ath9k_regd_get_eepromRD(ah));
+ return is_wwr_sku(ath_regd_get_eepromRD(reg));
}
+EXPORT_SYMBOL(ath_is_world_regd);
-const struct ieee80211_regdomain *ath9k_default_world_regdomain(void)
+static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
{
/* this is the most restrictive */
- return &ath9k_world_regdom_64;
+ return &ath_world_regdom_64;
}
-const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah)
+static const struct
+ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
{
- switch (ah->regulatory.regpair->regDmnEnum) {
+ switch (reg->regpair->regDmnEnum) {
case 0x60:
case 0x61:
case 0x62:
- return &ath9k_world_regdom_60_61_62;
+ return &ath_world_regdom_60_61_62;
case 0x63:
case 0x65:
- return &ath9k_world_regdom_63_65;
+ return &ath_world_regdom_63_65;
case 0x64:
- return &ath9k_world_regdom_64;
+ return &ath_world_regdom_64;
case 0x66:
case 0x69:
- return &ath9k_world_regdom_66_69;
+ return &ath_world_regdom_66_69;
case 0x67:
case 0x68:
case 0x6A:
- return &ath9k_world_regdom_67_68_6A;
+ return &ath_world_regdom_67_68_6A;
default:
WARN_ON(1);
- return ath9k_default_world_regdomain();
+ return ath_default_world_regdomain();
}
}
/* Frequency is one where radar detection is required */
-static bool ath9k_is_radar_freq(u16 center_freq)
+static bool ath_is_radar_freq(u16 center_freq)
{
return (center_freq >= 5260 && center_freq <= 5700);
}
@@ -168,9 +172,9 @@ static bool ath9k_is_radar_freq(u16 center_freq)
* received a beacon on a channel we can enable active scan and
* adhoc (or beaconing).
*/
-static void ath9k_reg_apply_beaconing_flags(
- struct wiphy *wiphy,
- enum nl80211_reg_initiator initiator)
+static void
+ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator)
{
enum ieee80211_band band;
struct ieee80211_supported_band *sband;
@@ -191,13 +195,15 @@ static void ath9k_reg_apply_beaconing_flags(
ch = &sband->channels[i];
- if (ath9k_is_radar_freq(ch->center_freq) ||
+ if (ath_is_radar_freq(ch->center_freq) ||
(ch->flags & IEEE80211_CHAN_RADAR))
continue;
if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
- r = freq_reg_info(wiphy, ch->center_freq,
- &bandwidth, &reg_rule);
+ r = freq_reg_info(wiphy,
+ ch->center_freq,
+ bandwidth,
+ &reg_rule);
if (r)
continue;
/*
@@ -227,9 +233,9 @@ static void ath9k_reg_apply_beaconing_flags(
}
/* Allows active scan scan on Ch 12 and 13 */
-static void ath9k_reg_apply_active_scan_flags(
- struct wiphy *wiphy,
- enum nl80211_reg_initiator initiator)
+static void
+ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator)
{
struct ieee80211_supported_band *sband;
struct ieee80211_channel *ch;
@@ -261,7 +267,7 @@ static void ath9k_reg_apply_active_scan_flags(
*/
ch = &sband->channels[11]; /* CH 12 */
- r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule);
+ r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
if (!r) {
if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
@@ -269,7 +275,7 @@ static void ath9k_reg_apply_active_scan_flags(
}
ch = &sband->channels[12]; /* CH 13 */
- r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule);
+ r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
if (!r) {
if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
@@ -278,7 +284,7 @@ static void ath9k_reg_apply_active_scan_flags(
}
/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
-void ath9k_reg_apply_radar_flags(struct wiphy *wiphy)
+static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
{
struct ieee80211_supported_band *sband;
struct ieee80211_channel *ch;
@@ -291,7 +297,7 @@ void ath9k_reg_apply_radar_flags(struct wiphy *wiphy)
for (i = 0; i < sband->n_channels; i++) {
ch = &sband->channels[i];
- if (!ath9k_is_radar_freq(ch->center_freq))
+ if (!ath_is_radar_freq(ch->center_freq))
continue;
/* We always enable radar detection/DFS on this
* frequency range. Additionally we also apply on
@@ -310,37 +316,31 @@ void ath9k_reg_apply_radar_flags(struct wiphy *wiphy)
}
}
-void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
- enum nl80211_reg_initiator initiator)
+static void ath_reg_apply_world_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator,
+ struct ath_regulatory *reg)
{
- struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
- struct ath_wiphy *aphy = hw->priv;
- struct ath_softc *sc = aphy->sc;
- struct ath_hw *ah = sc->sc_ah;
-
- switch (ah->regulatory.regpair->regDmnEnum) {
+ switch (reg->regpair->regDmnEnum) {
case 0x60:
case 0x63:
case 0x66:
case 0x67:
- ath9k_reg_apply_beaconing_flags(wiphy, initiator);
+ ath_reg_apply_beaconing_flags(wiphy, initiator);
break;
case 0x68:
- ath9k_reg_apply_beaconing_flags(wiphy, initiator);
- ath9k_reg_apply_active_scan_flags(wiphy, initiator);
+ ath_reg_apply_beaconing_flags(wiphy, initiator);
+ ath_reg_apply_active_scan_flags(wiphy, initiator);
break;
}
return;
}
-int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+int ath_reg_notifier_apply(struct wiphy *wiphy,
+ struct regulatory_request *request,
+ struct ath_regulatory *reg)
{
- struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
- struct ath_wiphy *aphy = hw->priv;
- struct ath_softc *sc = aphy->sc;
-
/* We always apply this */
- ath9k_reg_apply_radar_flags(wiphy);
+ ath_reg_apply_radar_flags(wiphy);
switch (request->initiator) {
case NL80211_REGDOM_SET_BY_DRIVER:
@@ -348,39 +348,47 @@ int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
case NL80211_REGDOM_SET_BY_USER:
break;
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
- if (ath9k_is_world_regd(sc->sc_ah))
- ath9k_reg_apply_world_flags(wiphy, request->initiator);
+ if (ath_is_world_regd(reg))
+ ath_reg_apply_world_flags(wiphy, request->initiator,
+ reg);
break;
}
return 0;
}
+EXPORT_SYMBOL(ath_reg_notifier_apply);
-bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah)
+static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
{
- u16 rd = ath9k_regd_get_eepromRD(ah);
+ u16 rd = ath_regd_get_eepromRD(reg);
int i;
if (rd & COUNTRY_ERD_FLAG) {
/* EEPROM value is a country code */
u16 cc = rd & ~COUNTRY_ERD_FLAG;
+ printk(KERN_DEBUG
+ "ath: EEPROM indicates we should expect "
+ "a country code\n");
for (i = 0; i < ARRAY_SIZE(allCountries); i++)
if (allCountries[i].countryCode == cc)
return true;
} else {
/* EEPROM value is a regpair value */
+ if (rd != CTRY_DEFAULT)
+ printk(KERN_DEBUG "ath: EEPROM indicates we "
+ "should expect a direct regpair map\n");
for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
if (regDomainPairs[i].regDmnEnum == rd)
return true;
}
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "invalid regulatory domain/country code 0x%x\n", rd);
+ printk(KERN_DEBUG
+ "ath: invalid regulatory domain/country code 0x%x\n", rd);
return false;
}
/* EEPROM country code to regpair mapping */
static struct country_code_to_enum_rd*
-ath9k_regd_find_country(u16 countryCode)
+ath_regd_find_country(u16 countryCode)
{
int i;
@@ -393,7 +401,7 @@ ath9k_regd_find_country(u16 countryCode)
/* EEPROM rd code to regpair mapping */
static struct country_code_to_enum_rd*
-ath9k_regd_find_country_by_rd(int regdmn)
+ath_regd_find_country_by_rd(int regdmn)
{
int i;
@@ -405,13 +413,13 @@ ath9k_regd_find_country_by_rd(int regdmn)
}
/* Returns the map of the EEPROM set RD to a country code */
-static u16 ath9k_regd_get_default_country(u16 rd)
+static u16 ath_regd_get_default_country(u16 rd)
{
if (rd & COUNTRY_ERD_FLAG) {
struct country_code_to_enum_rd *country = NULL;
u16 cc = rd & ~COUNTRY_ERD_FLAG;
- country = ath9k_regd_find_country(cc);
+ country = ath_regd_find_country(cc);
if (country != NULL)
return cc;
}
@@ -420,7 +428,7 @@ static u16 ath9k_regd_get_default_country(u16 rd)
}
static struct reg_dmn_pair_mapping*
-ath9k_get_regpair(int regdmn)
+ath_get_regpair(int regdmn)
{
int i;
@@ -433,87 +441,135 @@ ath9k_get_regpair(int regdmn)
return NULL;
}
-int ath9k_regd_init(struct ath_hw *ah)
+static int
+ath_regd_init_wiphy(struct ath_regulatory *reg,
+ struct wiphy *wiphy,
+ int (*reg_notifier)(struct wiphy *wiphy,
+ struct regulatory_request *request))
+{
+ const struct ieee80211_regdomain *regd;
+
+ wiphy->reg_notifier = reg_notifier;
+ wiphy->strict_regulatory = true;
+
+ if (ath_is_world_regd(reg)) {
+ /*
+ * Anything applied here (prior to wiphy registration) gets
+ * saved on the wiphy orig_* parameters
+ */
+ regd = ath_world_regdomain(reg);
+ wiphy->custom_regulatory = true;
+ wiphy->strict_regulatory = false;
+ } else {
+ /*
+ * This gets applied in the case of the absense of CRDA,
+ * it's our own custom world regulatory domain, similar to
+ * cfg80211's but we enable passive scanning.
+ */
+ regd = ath_default_world_regdomain();
+ }
+ wiphy_apply_custom_regulatory(wiphy, regd);
+ ath_reg_apply_radar_flags(wiphy);
+ ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
+ return 0;
+}
+
+int
+ath_regd_init(struct ath_regulatory *reg,
+ struct wiphy *wiphy,
+ int (*reg_notifier)(struct wiphy *wiphy,
+ struct regulatory_request *request))
{
struct country_code_to_enum_rd *country = NULL;
u16 regdmn;
- if (!ath9k_regd_is_eeprom_valid(ah)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Invalid EEPROM contents\n");
+ if (!reg)
+ return -EINVAL;
+
+ printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd);
+
+ if (!ath_regd_is_eeprom_valid(reg)) {
+ printk(KERN_ERR "ath: Invalid EEPROM contents\n");
return -EINVAL;
}
- regdmn = ath9k_regd_get_eepromRD(ah);
- ah->regulatory.country_code = ath9k_regd_get_default_country(regdmn);
+ regdmn = ath_regd_get_eepromRD(reg);
+ reg->country_code = ath_regd_get_default_country(regdmn);
- if (ah->regulatory.country_code == CTRY_DEFAULT &&
- regdmn == CTRY_DEFAULT)
- ah->regulatory.country_code = CTRY_UNITED_STATES;
+ if (reg->country_code == CTRY_DEFAULT &&
+ regdmn == CTRY_DEFAULT) {
+ printk(KERN_DEBUG "ath: EEPROM indicates default "
+ "country code should be used\n");
+ reg->country_code = CTRY_UNITED_STATES;
+ }
- if (ah->regulatory.country_code == CTRY_DEFAULT) {
+ if (reg->country_code == CTRY_DEFAULT) {
country = NULL;
} else {
- country = ath9k_regd_find_country(ah->regulatory.country_code);
+ printk(KERN_DEBUG "ath: doing EEPROM country->regdmn "
+ "map search\n");
+ country = ath_regd_find_country(reg->country_code);
if (country == NULL) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Country is NULL!!!!, cc= %d\n",
- ah->regulatory.country_code);
+ printk(KERN_DEBUG
+ "ath: no valid country maps found for "
+ "country code: 0x%0x\n",
+ reg->country_code);
return -EINVAL;
- } else
+ } else {
regdmn = country->regDmnEnum;
+ printk(KERN_DEBUG "ath: country maps to "
+ "regdmn code: 0x%0x\n",
+ regdmn);
+ }
}
- ah->regulatory.regpair = ath9k_get_regpair(regdmn);
+ reg->regpair = ath_get_regpair(regdmn);
- if (!ah->regulatory.regpair) {
- DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ if (!reg->regpair) {
+ printk(KERN_DEBUG "ath: "
"No regulatory domain pair found, cannot continue\n");
return -EINVAL;
}
if (!country)
- country = ath9k_regd_find_country_by_rd(regdmn);
+ country = ath_regd_find_country_by_rd(regdmn);
if (country) {
- ah->regulatory.alpha2[0] = country->isoName[0];
- ah->regulatory.alpha2[1] = country->isoName[1];
+ reg->alpha2[0] = country->isoName[0];
+ reg->alpha2[1] = country->isoName[1];
} else {
- ah->regulatory.alpha2[0] = '0';
- ah->regulatory.alpha2[1] = '0';
+ reg->alpha2[0] = '0';
+ reg->alpha2[1] = '0';
}
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Country alpha2 being used: %c%c\n"
- "Regulatory.Regpair detected: 0x%0x\n",
- ah->regulatory.alpha2[0], ah->regulatory.alpha2[1],
- ah->regulatory.regpair->regDmnEnum);
+ printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n",
+ reg->alpha2[0], reg->alpha2[1]);
+ printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n",
+ reg->regpair->regDmnEnum);
+ ath_regd_init_wiphy(reg, wiphy, reg_notifier);
return 0;
}
+EXPORT_SYMBOL(ath_regd_init);
-u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan)
+u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
+ enum ieee80211_band band)
{
- u32 ctl = NO_CTL;
-
- if (!ah->regulatory.regpair ||
- (ah->regulatory.country_code == CTRY_DEFAULT &&
- is_wwr_sku(ath9k_regd_get_eepromRD(ah)))) {
- if (IS_CHAN_B(chan))
- ctl = SD_NO_CTL | CTL_11B;
- else if (IS_CHAN_G(chan))
- ctl = SD_NO_CTL | CTL_11G;
- else
- ctl = SD_NO_CTL | CTL_11A;
- return ctl;
+ if (!reg->regpair ||
+ (reg->country_code == CTRY_DEFAULT &&
+ is_wwr_sku(ath_regd_get_eepromRD(reg)))) {
+ return SD_NO_CTL;
}
- if (IS_CHAN_B(chan))
- ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11B;
- else if (IS_CHAN_G(chan))
- ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11G;
- else
- ctl = ah->regulatory.regpair->reg_5ghz_ctl | CTL_11A;
+ switch (band) {
+ case IEEE80211_BAND_2GHZ:
+ return reg->regpair->reg_2ghz_ctl;
+ case IEEE80211_BAND_5GHZ:
+ return reg->regpair->reg_5ghz_ctl;
+ default:
+ return NO_CTL;
+ }
- return ctl;
+ return NO_CTL;
}
+EXPORT_SYMBOL(ath_regd_get_band_ctl);
diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath/regd.h
index 9f5fbd4eea7..07291ccb23f 100644
--- a/drivers/net/wireless/ath9k/regd.h
+++ b/drivers/net/wireless/ath/regd.h
@@ -17,6 +17,25 @@
#ifndef REGD_H
#define REGD_H
+#include <linux/nl80211.h>
+
+#include <net/cfg80211.h>
+
+#define NO_CTL 0xff
+#define SD_NO_CTL 0xE0
+#define NO_CTL 0xff
+#define CTL_MODE_M 7
+#define CTL_11A 0
+#define CTL_11B 1
+#define CTL_11G 2
+#define CTL_2GHT20 5
+#define CTL_5GHT20 6
+#define CTL_2GHT40 7
+#define CTL_5GHT40 8
+
+#define CTRY_DEBUG 0x1ff
+#define CTRY_DEFAULT 0
+
#define COUNTRY_ERD_FLAG 0x8000
#define WORLDWIDE_ROAMING_FLAG 0x4000
@@ -40,7 +59,7 @@ struct country_code_to_enum_rd {
const char *isoName;
};
-struct ath9k_regulatory {
+struct ath_regulatory {
char alpha2[2];
u16 country_code;
u16 max_power_level;
@@ -233,15 +252,14 @@ enum CountryCode {
CTRY_BELGIUM2 = 5002
};
-bool ath9k_is_world_regd(struct ath_hw *ah);
-const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah);
-const struct ieee80211_regdomain *ath9k_default_world_regdomain(void);
-void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
- enum nl80211_reg_initiator initiator);
-void ath9k_reg_apply_radar_flags(struct wiphy *wiphy);
-int ath9k_regd_init(struct ath_hw *ah);
-bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah);
-u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan);
-int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+bool ath_is_world_regd(struct ath_regulatory *reg);
+int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy,
+ int (*reg_notifier)(struct wiphy *wiphy,
+ struct regulatory_request *request));
+u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
+ enum ieee80211_band band);
+int ath_reg_notifier_apply(struct wiphy *wiphy,
+ struct regulatory_request *request,
+ struct ath_regulatory *reg);
#endif
diff --git a/drivers/net/wireless/ath9k/regd_common.h b/drivers/net/wireless/ath/regd_common.h
index 4d0e298cd1c..4d0e298cd1c 100644
--- a/drivers/net/wireless/ath9k/regd_common.h
+++ b/drivers/net/wireless/ath/regd_common.h
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 27eef8fb710..291a94bd46f 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -818,7 +818,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&priv->irqlock, flags);
spin_unlock_bh(&priv->timerlock);
netif_stop_queue(dev);
- return 1;
+ return NETDEV_TX_BUSY;
}
frame_ctl = IEEE80211_FTYPE_DATA;
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 77406245dc7..ddaa859c349 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -279,7 +279,7 @@ static int atmel_config(struct pcmcia_device *link)
struct pcmcia_device_id *did;
dev = link->priv;
- did = handle_to_dev(link).driver_data;
+ did = dev_get_drvdata(&handle_to_dev(link));
DEBUG(0, "atmel_config(0x%p)\n", link);
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index aab71a70ba7..67f564e3722 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -3,7 +3,6 @@ config B43
depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA
select SSB
select FW_LOADER
- select HW_RANDOM
---help---
b43 is a driver for the Broadcom 43xx series wireless devices.
@@ -99,11 +98,11 @@ config B43_LEDS
depends on B43 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43)
default y
-# This config option automatically enables b43 RFKILL support,
-# if it's possible.
-config B43_RFKILL
+# This config option automatically enables b43 HW-RNG support,
+# if the HW-RNG core is enabled.
+config B43_HWRNG
bool
- depends on B43 && (RFKILL = y || RFKILL = B43) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43)
+ depends on B43 && (HW_RANDOM = y || HW_RANDOM = B43)
default y
config B43_DEBUG
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 281ef831035..da379f4b0c3 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -13,7 +13,7 @@ b43-y += lo.o
b43-y += wa.o
b43-y += dma.o
b43-$(CONFIG_B43_PIO) += pio.o
-b43-$(CONFIG_B43_RFKILL) += rfkill.o
+b43-y += rfkill.o
b43-$(CONFIG_B43_LEDS) += leds.o
b43-$(CONFIG_B43_PCMCIA) += pcmcia.o
b43-$(CONFIG_B43_DEBUG) += debugfs.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index beaf18d6e8a..f580c2812d9 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -163,6 +163,7 @@ enum {
#define B43_SHM_SH_WLCOREREV 0x0016 /* 802.11 core revision */
#define B43_SHM_SH_PCTLWDPOS 0x0008
#define B43_SHM_SH_RXPADOFF 0x0034 /* RX Padding data offset (PIO only) */
+#define B43_SHM_SH_FWCAPA 0x0042 /* Firmware capabilities (Opensource firmware only) */
#define B43_SHM_SH_PHYVER 0x0050 /* PHY version */
#define B43_SHM_SH_PHYTYPE 0x0052 /* PHY type */
#define B43_SHM_SH_ANTSWAP 0x005C /* Antenna swap threshold */
@@ -297,6 +298,10 @@ enum {
#define B43_HF_MLADVW 0x001000000000ULL /* N PHY ML ADV workaround (rev >= 13 only) */
#define B43_HF_PR45960W 0x080000000000ULL /* PR 45960 workaround (rev >= 13 only) */
+/* Firmware capabilities field in SHM (Opensource firmware only) */
+#define B43_FWCAPA_HWCRYPTO 0x0001
+#define B43_FWCAPA_QOS 0x0002
+
/* MacFilter offsets. */
#define B43_MACFILTER_SELF 0x0000
#define B43_MACFILTER_BSSID 0x0003
@@ -596,6 +601,13 @@ struct b43_wl {
/* Pointer to the ieee80211 hardware data structure */
struct ieee80211_hw *hw;
+ /* The number of queues that were registered with the mac80211 subsystem
+ * initially. This is a backup copy of hw->queues in case hw->queues has
+ * to be dynamically lowered at runtime (Firmware does not support QoS).
+ * hw->queues has to be restored to the original value before unregistering
+ * from the mac80211 subsystem. */
+ u16 mac80211_initially_registered_queues;
+
struct mutex mutex;
spinlock_t irq_lock;
/* R/W lock for data transmission.
@@ -625,12 +637,11 @@ struct b43_wl {
/* Stats about the wireless interface */
struct ieee80211_low_level_stats ieee_stats;
+#ifdef CONFIG_B43_HWRNG
struct hwrng rng;
- u8 rng_initialized;
+ bool rng_initialized;
char rng_name[30 + 1];
-
- /* The RF-kill button */
- struct b43_rfkill rfkill;
+#endif /* CONFIG_B43_HWRNG */
/* List of all wireless devices on this chip */
struct list_head devlist;
@@ -750,6 +761,8 @@ struct b43_wldev {
bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */
bool radio_hw_enable; /* saved state of radio hardware enabled state */
bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */
+ bool qos_enabled; /* TRUE, if QoS is used. */
+ bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */
/* PHY/Radio device. */
struct b43_phy phy;
@@ -776,8 +789,8 @@ struct b43_wldev {
/* Reason code of the last interrupt. */
u32 irq_reason;
u32 dma_reason[6];
- /* saved irq enable/disable state bitfield. */
- u32 irq_savedstate;
+ /* The currently active generic-interrupt mask. */
+ u32 irq_mask;
/* Link Quality calculation context. */
struct b43_noise_calculation noisecalc;
/* if > 0 MAC is suspended. if == 0 MAC is enabled. */
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index eae680b5305..7964cc32b25 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1285,7 +1285,7 @@ static struct b43_dmaring *select_ring_by_priority(struct b43_wldev *dev,
{
struct b43_dmaring *ring;
- if (b43_modparam_qos) {
+ if (dev->qos_enabled) {
/* 0 = highest priority */
switch (queue_prio) {
default:
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c
index 76f4c7bad8b..c8b317094c3 100644
--- a/drivers/net/wireless/b43/leds.c
+++ b/drivers/net/wireless/b43/leds.c
@@ -28,6 +28,7 @@
#include "b43.h"
#include "leds.h"
+#include "rfkill.h"
static void b43_led_turn_on(struct b43_wldev *dev, u8 led_index,
@@ -87,7 +88,7 @@ static void b43_led_brightness_set(struct led_classdev *led_dev,
}
static int b43_register_led(struct b43_wldev *dev, struct b43_led *led,
- const char *name, char *default_trigger,
+ const char *name, const char *default_trigger,
u8 led_index, bool activelow)
{
int err;
@@ -164,10 +165,10 @@ static void b43_map_led(struct b43_wldev *dev,
snprintf(name, sizeof(name),
"b43-%s::radio", wiphy_name(hw->wiphy));
b43_register_led(dev, &dev->led_radio, name,
- b43_rfkill_led_name(dev),
+ ieee80211_get_radio_led_name(hw),
led_index, activelow);
- /* Sync the RF-kill LED state with the switch state. */
- if (dev->radio_hw_enable)
+ /* Sync the RF-kill LED state with radio and switch states. */
+ if (dev->phy.radio_on && b43_is_hw_radio_enabled(dev))
b43_led_turn_on(dev, led_index, activelow);
break;
case B43_LED_WEIRD:
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 79b685e300c..6456afebdba 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -80,8 +80,8 @@ static int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
-int b43_modparam_qos = 1;
-module_param_named(qos, b43_modparam_qos, int, 0444);
+static int modparam_qos = 1;
+module_param_named(qos, modparam_qos, int, 0444);
MODULE_PARM_DESC(qos, "Enable QOS support (default on)");
static int modparam_btcoex = 1;
@@ -538,6 +538,13 @@ void b43_hf_write(struct b43_wldev *dev, u64 value)
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi);
}
+/* Read the firmware capabilities bitmask (Opensource firmware only) */
+static u16 b43_fwcapa_read(struct b43_wldev *dev)
+{
+ B43_WARN_ON(!dev->fw.opensource);
+ return b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_FWCAPA);
+}
+
void b43_tsf_read(struct b43_wldev *dev, u64 *tsf)
{
u32 low, high;
@@ -673,32 +680,6 @@ static void b43_short_slot_timing_disable(struct b43_wldev *dev)
b43_set_slot_time(dev, 20);
}
-/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
- * Returns the _previously_ enabled IRQ mask.
- */
-static inline u32 b43_interrupt_enable(struct b43_wldev *dev, u32 mask)
-{
- u32 old_mask;
-
- old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
- b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask | mask);
-
- return old_mask;
-}
-
-/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable.
- * Returns the _previously_ enabled IRQ mask.
- */
-static inline u32 b43_interrupt_disable(struct b43_wldev *dev, u32 mask)
-{
- u32 old_mask;
-
- old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
- b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask & ~mask);
-
- return old_mask;
-}
-
/* Synchronize IRQ top- and bottom-half.
* IRQs must be masked before calling this.
* This must not be called with the irq_lock held.
@@ -1593,7 +1574,7 @@ static void handle_irq_beacon(struct b43_wldev *dev)
/* This is the bottom half of the asynchronous beacon update. */
/* Ignore interrupt in the future. */
- dev->irq_savedstate &= ~B43_IRQ_BEACON;
+ dev->irq_mask &= ~B43_IRQ_BEACON;
cmd = b43_read32(dev, B43_MMIO_MACCMD);
beacon0_valid = (cmd & B43_MACCMD_BEACON0_VALID);
@@ -1602,7 +1583,7 @@ static void handle_irq_beacon(struct b43_wldev *dev)
/* Schedule interrupt manually, if busy. */
if (beacon0_valid && beacon1_valid) {
b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_BEACON);
- dev->irq_savedstate |= B43_IRQ_BEACON;
+ dev->irq_mask |= B43_IRQ_BEACON;
return;
}
@@ -1641,11 +1622,9 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
spin_lock_irq(&wl->irq_lock);
/* update beacon right away or defer to irq */
- dev->irq_savedstate = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
handle_irq_beacon(dev);
/* The handler might have updated the IRQ mask. */
- b43_write32(dev, B43_MMIO_GEN_IRQ_MASK,
- dev->irq_savedstate);
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
mmiowb();
spin_unlock_irq(&wl->irq_lock);
}
@@ -1879,7 +1858,7 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
if (reason & B43_IRQ_TX_OK)
handle_irq_transmit_status(dev);
- b43_interrupt_enable(dev, dev->irq_savedstate);
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
mmiowb();
spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
}
@@ -1893,7 +1872,9 @@ static void b43_interrupt_ack(struct b43_wldev *dev, u32 reason)
b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]);
b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]);
b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]);
+/* Unused ring
b43_write32(dev, B43_MMIO_DMA5_REASON, dev->dma_reason[5]);
+*/
}
/* Interrupt handler top-half */
@@ -1903,18 +1884,19 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
struct b43_wldev *dev = dev_id;
u32 reason;
- if (!dev)
- return IRQ_NONE;
+ B43_WARN_ON(!dev);
spin_lock(&dev->wl->irq_lock);
- if (b43_status(dev) < B43_STAT_STARTED)
+ if (unlikely(b43_status(dev) < B43_STAT_STARTED)) {
+ /* This can only happen on shared IRQ lines. */
goto out;
+ }
reason = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
if (reason == 0xffffffff) /* shared IRQ */
goto out;
ret = IRQ_HANDLED;
- reason &= b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
+ reason &= dev->irq_mask;
if (!reason)
goto out;
@@ -1928,16 +1910,18 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
& 0x0001DC00;
dev->dma_reason[4] = b43_read32(dev, B43_MMIO_DMA4_REASON)
& 0x0000DC00;
+/* Unused ring
dev->dma_reason[5] = b43_read32(dev, B43_MMIO_DMA5_REASON)
& 0x0000DC00;
+*/
b43_interrupt_ack(dev, reason);
/* disable all IRQs. They are enabled again in the bottom half. */
- dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
/* save the reason code and call our bottom half. */
dev->irq_reason = reason;
tasklet_schedule(&dev->isr_tasklet);
- out:
+out:
mmiowb();
spin_unlock(&dev->wl->irq_lock);
@@ -2330,12 +2314,34 @@ static int b43_upload_microcode(struct b43_wldev *dev)
dev->fw.patch = fwpatch;
dev->fw.opensource = (fwdate == 0xFFFF);
+ /* Default to use-all-queues. */
+ dev->wl->hw->queues = dev->wl->mac80211_initially_registered_queues;
+ dev->qos_enabled = !!modparam_qos;
+ /* Default to firmware/hardware crypto acceleration. */
+ dev->hwcrypto_enabled = 1;
+
if (dev->fw.opensource) {
+ u16 fwcapa;
+
/* Patchlevel info is encoded in the "time" field. */
dev->fw.patch = fwtime;
- b43info(dev->wl, "Loading OpenSource firmware version %u.%u%s\n",
- dev->fw.rev, dev->fw.patch,
- dev->fw.pcm_request_failed ? " (Hardware crypto not supported)" : "");
+ b43info(dev->wl, "Loading OpenSource firmware version %u.%u\n",
+ dev->fw.rev, dev->fw.patch);
+
+ fwcapa = b43_fwcapa_read(dev);
+ if (!(fwcapa & B43_FWCAPA_HWCRYPTO) || dev->fw.pcm_request_failed) {
+ b43info(dev->wl, "Hardware crypto acceleration not supported by firmware\n");
+ /* Disable hardware crypto and fall back to software crypto. */
+ dev->hwcrypto_enabled = 0;
+ }
+ if (!(fwcapa & B43_FWCAPA_QOS)) {
+ b43info(dev->wl, "QoS not supported by firmware\n");
+ /* Disable QoS. Tweak hw->queues to 1. It will be restored before
+ * ieee80211_unregister to make sure the networking core can
+ * properly free possible resources. */
+ dev->wl->hw->queues = 1;
+ dev->qos_enabled = 0;
+ }
} else {
b43info(dev->wl, "Loading firmware version %u.%u "
"(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
@@ -2980,6 +2986,7 @@ static void b43_security_init(struct b43_wldev *dev)
b43_clear_keys(dev);
}
+#ifdef CONFIG_B43_HWRNG
static int b43_rng_read(struct hwrng *rng, u32 *data)
{
struct b43_wl *wl = (struct b43_wl *)rng->priv;
@@ -2995,17 +3002,21 @@ static int b43_rng_read(struct hwrng *rng, u32 *data)
return (sizeof(u16));
}
+#endif /* CONFIG_B43_HWRNG */
static void b43_rng_exit(struct b43_wl *wl)
{
+#ifdef CONFIG_B43_HWRNG
if (wl->rng_initialized)
hwrng_unregister(&wl->rng);
+#endif /* CONFIG_B43_HWRNG */
}
static int b43_rng_init(struct b43_wl *wl)
{
- int err;
+ int err = 0;
+#ifdef CONFIG_B43_HWRNG
snprintf(wl->rng_name, ARRAY_SIZE(wl->rng_name),
"%s_%s", KBUILD_MODNAME, wiphy_name(wl->hw->wiphy));
wl->rng.name = wl->rng_name;
@@ -3018,6 +3029,7 @@ static int b43_rng_init(struct b43_wl *wl)
b43err(wl, "Failed to register the random "
"number generator (%d)\n", err);
}
+#endif /* CONFIG_B43_HWRNG */
return err;
}
@@ -3485,14 +3497,9 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
if (phy->ops->set_rx_antenna)
phy->ops->set_rx_antenna(dev, antenna);
- /* Update templates for AP/mesh mode. */
- if (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
- b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT))
- b43_set_beacon_int(dev, conf->beacon_int);
-
if (!!conf->radio_enabled != phy->radio_on) {
if (conf->radio_enabled) {
- b43_software_rfkill(dev, RFKILL_STATE_UNBLOCKED);
+ b43_software_rfkill(dev, false);
b43info(dev->wl, "Radio turned on by software\n");
if (!dev->radio_hw_enable) {
b43info(dev->wl, "The hardware RF-kill button "
@@ -3500,7 +3507,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
"Press the button to turn it on.\n");
}
} else {
- b43_software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED);
+ b43_software_rfkill(dev, true);
b43info(dev->wl, "Radio turned off by software\n");
}
}
@@ -3565,14 +3572,45 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
+ unsigned long flags;
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (!dev || b43_status(dev) < B43_STAT_STARTED)
goto out_unlock_mutex;
+
+ B43_WARN_ON(wl->vif != vif);
+
+ spin_lock_irqsave(&wl->irq_lock, flags);
+ if (changed & BSS_CHANGED_BSSID) {
+ if (conf->bssid)
+ memcpy(wl->bssid, conf->bssid, ETH_ALEN);
+ else
+ memset(wl->bssid, 0, ETH_ALEN);
+ }
+
+ if (b43_status(dev) >= B43_STAT_INITIALIZED) {
+ if (changed & BSS_CHANGED_BEACON &&
+ (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
+ b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) ||
+ b43_is_mode(wl, NL80211_IFTYPE_ADHOC)))
+ b43_update_templates(wl);
+
+ if (changed & BSS_CHANGED_BSSID)
+ b43_write_mac_bssid_templates(dev);
+ }
+ spin_unlock_irqrestore(&wl->irq_lock, flags);
+
b43_mac_suspend(dev);
+ /* Update templates for AP/mesh mode. */
+ if (changed & BSS_CHANGED_BEACON_INT &&
+ (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
+ b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) ||
+ b43_is_mode(wl, NL80211_IFTYPE_ADHOC)))
+ b43_set_beacon_int(dev, conf->beacon_int);
+
if (changed & BSS_CHANGED_BASIC_RATES)
b43_update_basic_rates(dev, conf->basic_rates);
@@ -3586,8 +3624,6 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
b43_mac_enable(dev);
out_unlock_mutex:
mutex_unlock(&wl->mutex);
-
- return;
}
static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -3620,7 +3656,7 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (!dev || b43_status(dev) < B43_STAT_INITIALIZED)
goto out_unlock;
- if (dev->fw.pcm_request_failed) {
+ if (dev->fw.pcm_request_failed || !dev->hwcrypto_enabled) {
/* We don't have firmware for the crypto engine.
* Must use software-crypto. */
err = -EOPNOTSUPP;
@@ -3630,7 +3666,7 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
err = -EINVAL;
switch (key->alg) {
case ALG_WEP:
- if (key->keylen == LEN_WEP40)
+ if (key->keylen == WLAN_KEY_LEN_WEP40)
algorithm = B43_SEC_ALGO_WEP40;
else
algorithm = B43_SEC_ALGO_WEP104;
@@ -3745,41 +3781,6 @@ static void b43_op_configure_filter(struct ieee80211_hw *hw,
spin_unlock_irqrestore(&wl->irq_lock, flags);
}
-static int b43_op_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct b43_wl *wl = hw_to_b43_wl(hw);
- struct b43_wldev *dev = wl->current_dev;
- unsigned long flags;
-
- if (!dev)
- return -ENODEV;
- mutex_lock(&wl->mutex);
- spin_lock_irqsave(&wl->irq_lock, flags);
- B43_WARN_ON(wl->vif != vif);
- if (conf->bssid)
- memcpy(wl->bssid, conf->bssid, ETH_ALEN);
- else
- memset(wl->bssid, 0, ETH_ALEN);
- if (b43_status(dev) >= B43_STAT_INITIALIZED) {
- if (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
- b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT)) {
- B43_WARN_ON(vif->type != wl->if_type);
- if (conf->changed & IEEE80211_IFCC_BEACON)
- b43_update_templates(wl);
- } else if (b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) {
- if (conf->changed & IEEE80211_IFCC_BEACON)
- b43_update_templates(wl);
- }
- b43_write_mac_bssid_templates(dev);
- }
- spin_unlock_irqrestore(&wl->irq_lock, flags);
- mutex_unlock(&wl->mutex);
-
- return 0;
-}
-
/* Locking: wl->mutex */
static void b43_wireless_core_stop(struct b43_wldev *dev)
{
@@ -3793,7 +3794,7 @@ static void b43_wireless_core_stop(struct b43_wldev *dev)
* setting the status to INITIALIZED, as the interrupt handler
* won't care about IRQs then. */
spin_lock_irqsave(&wl->irq_lock, flags);
- dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */
spin_unlock_irqrestore(&wl->irq_lock, flags);
b43_synchronize_irq(dev);
@@ -3834,7 +3835,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
/* Start data flow (TX/RX). */
b43_mac_enable(dev);
- b43_interrupt_enable(dev, dev->irq_savedstate);
+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
/* Start maintainance work */
b43_periodic_tasks_setup(dev);
@@ -3997,9 +3998,9 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev)
/* IRQ related flags */
dev->irq_reason = 0;
memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
- dev->irq_savedstate = B43_IRQ_MASKTEMPLATE;
+ dev->irq_mask = B43_IRQ_MASKTEMPLATE;
if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
- dev->irq_savedstate &= ~B43_IRQ_PHY_TXERR;
+ dev->irq_mask &= ~B43_IRQ_PHY_TXERR;
dev->mac_suspended = 1;
@@ -4326,7 +4327,6 @@ static int b43_op_start(struct ieee80211_hw *hw)
struct b43_wldev *dev = wl->current_dev;
int did_init = 0;
int err = 0;
- bool do_rfkill_exit = 0;
/* Kill all old instance specific information to make sure
* the card won't use it in the short timeframe between start
@@ -4340,18 +4340,12 @@ static int b43_op_start(struct ieee80211_hw *hw)
wl->beacon1_uploaded = 0;
wl->beacon_templates_virgin = 1;
- /* First register RFkill.
- * LEDs that are registered later depend on it. */
- b43_rfkill_init(dev);
-
mutex_lock(&wl->mutex);
if (b43_status(dev) < B43_STAT_INITIALIZED) {
err = b43_wireless_core_init(dev);
- if (err) {
- do_rfkill_exit = 1;
+ if (err)
goto out_mutex_unlock;
- }
did_init = 1;
}
@@ -4360,17 +4354,16 @@ static int b43_op_start(struct ieee80211_hw *hw)
if (err) {
if (did_init)
b43_wireless_core_exit(dev);
- do_rfkill_exit = 1;
goto out_mutex_unlock;
}
}
+ /* XXX: only do if device doesn't support rfkill irq */
+ wiphy_rfkill_start_polling(hw->wiphy);
+
out_mutex_unlock:
mutex_unlock(&wl->mutex);
- if (do_rfkill_exit)
- b43_rfkill_exit(dev);
-
return err;
}
@@ -4379,7 +4372,6 @@ static void b43_op_stop(struct ieee80211_hw *hw)
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev = wl->current_dev;
- b43_rfkill_exit(dev);
cancel_work_sync(&(wl->beacon_update_trigger));
mutex_lock(&wl->mutex);
@@ -4449,7 +4441,6 @@ static const struct ieee80211_ops b43_hw_ops = {
.remove_interface = b43_op_remove_interface,
.config = b43_op_config,
.bss_info_changed = b43_op_bss_info_changed,
- .config_interface = b43_op_config_interface,
.configure_filter = b43_op_configure_filter,
.set_key = b43_op_set_key,
.get_stats = b43_op_get_stats,
@@ -4462,6 +4453,7 @@ static const struct ieee80211_ops b43_hw_ops = {
.sta_notify = b43_op_sta_notify,
.sw_scan_start = b43_op_sw_scan_start_notifier,
.sw_scan_complete = b43_op_sw_scan_complete_notifier,
+ .rfkill_poll = b43_rfkill_poll,
};
/* Hard-reset the chip. Do not call this directly.
@@ -4764,6 +4756,7 @@ static int b43_wireless_init(struct ssb_device *dev)
b43err(NULL, "Could not allocate ieee80211 device\n");
goto out;
}
+ wl = hw_to_b43_wl(hw);
/* fill hw info */
hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
@@ -4777,7 +4770,8 @@ static int b43_wireless_init(struct ssb_device *dev)
BIT(NL80211_IFTYPE_WDS) |
BIT(NL80211_IFTYPE_ADHOC);
- hw->queues = b43_modparam_qos ? 4 : 1;
+ hw->queues = modparam_qos ? 4 : 1;
+ wl->mac80211_initially_registered_queues = hw->queues;
hw->max_rates = 2;
SET_IEEE80211_DEV(hw, dev->dev);
if (is_valid_ether_addr(sprom->et1mac))
@@ -4785,9 +4779,7 @@ static int b43_wireless_init(struct ssb_device *dev)
else
SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac);
- /* Get and initialize struct b43_wl */
- wl = hw_to_b43_wl(hw);
- memset(wl, 0, sizeof(*wl));
+ /* Initialize struct b43_wl */
wl->hw = hw;
spin_lock_init(&wl->irq_lock);
rwlock_init(&wl->tx_lock);
@@ -4853,8 +4845,13 @@ static void b43_remove(struct ssb_device *dev)
cancel_work_sync(&wldev->restart_work);
B43_WARN_ON(!wl);
- if (wl->current_dev == wldev)
+ if (wl->current_dev == wldev) {
+ /* Restore the queues count before unregistering, because firmware detect
+ * might have modified it. Restoring is important, so the networking
+ * stack can properly free resources. */
+ wl->hw->queues = wl->mac80211_initially_registered_queues;
ieee80211_unregister_hw(wl->hw);
+ }
b43_one_core_detach(dev);
@@ -4949,7 +4946,7 @@ static struct ssb_driver b43_ssb_driver = {
static void b43_print_driverinfo(void)
{
const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "",
- *feat_leds = "", *feat_rfkill = "";
+ *feat_leds = "";
#ifdef CONFIG_B43_PCI_AUTOSELECT
feat_pci = "P";
@@ -4963,14 +4960,11 @@ static void b43_print_driverinfo(void)
#ifdef CONFIG_B43_LEDS
feat_leds = "L";
#endif
-#ifdef CONFIG_B43_RFKILL
- feat_rfkill = "R";
-#endif
printk(KERN_INFO "Broadcom 43xx driver loaded "
- "[ Features: %s%s%s%s%s, Firmware-ID: "
+ "[ Features: %s%s%s%s, Firmware-ID: "
B43_SUPPORTED_FIRMWARE_ID " ]\n",
feat_pci, feat_pcmcia, feat_nphy,
- feat_leds, feat_rfkill);
+ feat_leds);
}
static int __init b43_init(void)
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index 40abcf5d1b4..950fb1b0546 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -39,7 +39,6 @@
#define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes))
-extern int b43_modparam_qos;
extern int b43_modparam_verbose;
/* Logmessage verbosity levels. Update the b43_modparam_verbose helptext, if
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index c836c077d51..816e028a262 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -480,11 +480,11 @@ static bool b43_aphy_op_supports_hwpctl(struct b43_wldev *dev)
}
static void b43_aphy_op_software_rfkill(struct b43_wldev *dev,
- enum rfkill_state state)
+ bool blocked)
{
struct b43_phy *phy = &dev->phy;
- if (state == RFKILL_STATE_UNBLOCKED) {
+ if (!blocked) {
if (phy->radio_on)
return;
b43_radio_write16(dev, 0x0004, 0x00C0);
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index e176b6e0d9c..6d241622210 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -84,7 +84,7 @@ int b43_phy_init(struct b43_wldev *dev)
phy->channel = ops->get_default_chan(dev);
- ops->software_rfkill(dev, RFKILL_STATE_UNBLOCKED);
+ ops->software_rfkill(dev, false);
err = ops->init(dev);
if (err) {
b43err(dev->wl, "PHY init failed\n");
@@ -104,7 +104,7 @@ err_phy_exit:
if (ops->exit)
ops->exit(dev);
err_block_rf:
- ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED);
+ ops->software_rfkill(dev, true);
return err;
}
@@ -113,7 +113,7 @@ void b43_phy_exit(struct b43_wldev *dev)
{
const struct b43_phy_operations *ops = dev->phy.ops;
- ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED);
+ ops->software_rfkill(dev, true);
if (ops->exit)
ops->exit(dev);
}
@@ -295,18 +295,13 @@ err_restore_cookie:
return err;
}
-void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state)
+void b43_software_rfkill(struct b43_wldev *dev, bool blocked)
{
struct b43_phy *phy = &dev->phy;
- if (state == RFKILL_STATE_HARD_BLOCKED) {
- /* We cannot hardware-block the device */
- state = RFKILL_STATE_SOFT_BLOCKED;
- }
-
b43_mac_suspend(dev);
- phy->ops->software_rfkill(dev, state);
- phy->radio_on = (state == RFKILL_STATE_UNBLOCKED);
+ phy->ops->software_rfkill(dev, blocked);
+ phy->radio_on = !blocked;
b43_mac_enable(dev);
}
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index b2d99101947..44cc918e4fc 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -1,7 +1,7 @@
#ifndef LINUX_B43_PHY_COMMON_H_
#define LINUX_B43_PHY_COMMON_H_
-#include <linux/rfkill.h>
+#include <linux/types.h>
struct b43_wldev;
@@ -159,7 +159,7 @@ struct b43_phy_operations {
/* Radio */
bool (*supports_hwpctl)(struct b43_wldev *dev);
- void (*software_rfkill)(struct b43_wldev *dev, enum rfkill_state state);
+ void (*software_rfkill)(struct b43_wldev *dev, bool blocked);
void (*switch_analog)(struct b43_wldev *dev, bool on);
int (*switch_channel)(struct b43_wldev *dev, unsigned int new_channel);
unsigned int (*get_default_chan)(struct b43_wldev *dev);
@@ -364,7 +364,7 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
/**
* b43_software_rfkill - Turn the radio ON or OFF in software.
*/
-void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state);
+void b43_software_rfkill(struct b43_wldev *dev, bool blocked);
/**
* b43_phy_txpower_check - Check TX power output.
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index e7b98f013b0..5300232449f 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -2592,7 +2592,7 @@ static bool b43_gphy_op_supports_hwpctl(struct b43_wldev *dev)
}
static void b43_gphy_op_software_rfkill(struct b43_wldev *dev,
- enum rfkill_state state)
+ bool blocked)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_g *gphy = phy->g;
@@ -2600,7 +2600,7 @@ static void b43_gphy_op_software_rfkill(struct b43_wldev *dev,
might_sleep();
- if (state == RFKILL_STATE_UNBLOCKED) {
+ if (!blocked) {
/* Turn radio ON */
if (phy->radio_on)
return;
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 58e319d6b1e..ea0d3a3a6a6 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -488,7 +488,7 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
}
static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev,
- enum rfkill_state state)
+ bool blocked)
{
//TODO
}
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 8bcfda5f3f0..be7b5604947 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -579,7 +579,7 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
}
static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
- enum rfkill_state state)
+ bool blocked)
{//TODO
}
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 8cd9776752e..69138e8c1db 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -313,7 +313,7 @@ static struct b43_pio_txqueue *select_queue_by_priority(struct b43_wldev *dev,
{
struct b43_pio_txqueue *q;
- if (b43_modparam_qos) {
+ if (dev->qos_enabled) {
/* 0 = highest priority */
switch (queue_prio) {
default:
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index afad4235869..31e55999893 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -22,15 +22,11 @@
*/
-#include "rfkill.h"
#include "b43.h"
-#include "phy_common.h"
-
-#include <linux/kmod.h>
/* Returns TRUE, if the radio is enabled in hardware. */
-static bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
+bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
{
if (dev->phy.rev >= 3) {
if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI)
@@ -45,166 +41,39 @@ static bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
}
/* The poll callback for the hardware button. */
-static void b43_rfkill_poll(struct input_polled_dev *poll_dev)
+void b43_rfkill_poll(struct ieee80211_hw *hw)
{
- struct b43_wldev *dev = poll_dev->private;
- struct b43_wl *wl = dev->wl;
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev = wl->current_dev;
+ struct ssb_bus *bus = dev->dev->bus;
bool enabled;
- bool report_change = 0;
+ bool brought_up = false;
mutex_lock(&wl->mutex);
if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) {
- mutex_unlock(&wl->mutex);
- return;
+ if (ssb_bus_powerup(bus, 0)) {
+ mutex_unlock(&wl->mutex);
+ return;
+ }
+ ssb_device_enable(dev->dev, 0);
+ brought_up = true;
}
+
enabled = b43_is_hw_radio_enabled(dev);
+
if (unlikely(enabled != dev->radio_hw_enable)) {
dev->radio_hw_enable = enabled;
- report_change = 1;
b43info(wl, "Radio hardware status changed to %s\n",
enabled ? "ENABLED" : "DISABLED");
+ wiphy_rfkill_set_hw_state(hw->wiphy, !enabled);
+ if (enabled != dev->phy.radio_on)
+ b43_software_rfkill(dev, !enabled);
}
- mutex_unlock(&wl->mutex);
- /* send the radio switch event to the system - note both a key press
- * and a release are required */
- if (unlikely(report_change)) {
- input_report_key(poll_dev->input, KEY_WLAN, 1);
- input_report_key(poll_dev->input, KEY_WLAN, 0);
+ if (brought_up) {
+ ssb_device_disable(dev->dev, 0);
+ ssb_bus_may_powerdown(bus);
}
-}
-
-/* Called when the RFKILL toggled in software. */
-static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
-{
- struct b43_wldev *dev = data;
- struct b43_wl *wl = dev->wl;
- int err = -EBUSY;
- if (!wl->rfkill.registered)
- return 0;
-
- mutex_lock(&wl->mutex);
- if (b43_status(dev) < B43_STAT_INITIALIZED)
- goto out_unlock;
- err = 0;
- switch (state) {
- case RFKILL_STATE_UNBLOCKED:
- if (!dev->radio_hw_enable) {
- /* No luck. We can't toggle the hardware RF-kill
- * button from software. */
- err = -EBUSY;
- goto out_unlock;
- }
- if (!dev->phy.radio_on)
- b43_software_rfkill(dev, state);
- break;
- case RFKILL_STATE_SOFT_BLOCKED:
- if (dev->phy.radio_on)
- b43_software_rfkill(dev, state);
- break;
- default:
- b43warn(wl, "Received unexpected rfkill state %d.\n", state);
- break;
- }
-out_unlock:
mutex_unlock(&wl->mutex);
-
- return err;
-}
-
-char *b43_rfkill_led_name(struct b43_wldev *dev)
-{
- struct b43_rfkill *rfk = &(dev->wl->rfkill);
-
- if (!rfk->registered)
- return NULL;
- return rfkill_get_led_name(rfk->rfkill);
-}
-
-void b43_rfkill_init(struct b43_wldev *dev)
-{
- struct b43_wl *wl = dev->wl;
- struct b43_rfkill *rfk = &(wl->rfkill);
- int err;
-
- rfk->registered = 0;
-
- rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
- if (!rfk->rfkill)
- goto out_error;
- snprintf(rfk->name, sizeof(rfk->name),
- "b43-%s", wiphy_name(wl->hw->wiphy));
- rfk->rfkill->name = rfk->name;
- rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;
- rfk->rfkill->data = dev;
- rfk->rfkill->toggle_radio = b43_rfkill_soft_toggle;
- rfk->rfkill->user_claim_unsupported = 1;
-
- rfk->poll_dev = input_allocate_polled_device();
- if (!rfk->poll_dev) {
- rfkill_free(rfk->rfkill);
- goto err_freed_rfk;
- }
-
- rfk->poll_dev->private = dev;
- rfk->poll_dev->poll = b43_rfkill_poll;
- rfk->poll_dev->poll_interval = 1000; /* msecs */
-
- rfk->poll_dev->input->name = rfk->name;
- rfk->poll_dev->input->id.bustype = BUS_HOST;
- rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor;
- rfk->poll_dev->input->evbit[0] = BIT(EV_KEY);
- set_bit(KEY_WLAN, rfk->poll_dev->input->keybit);
-
- err = rfkill_register(rfk->rfkill);
- if (err)
- goto err_free_polldev;
-
-#ifdef CONFIG_RFKILL_INPUT_MODULE
- /* B43 RF-kill isn't useful without the rfkill-input subsystem.
- * Try to load the module. */
- err = request_module("rfkill-input");
- if (err)
- b43warn(wl, "Failed to load the rfkill-input module. "
- "The built-in radio LED will not work.\n");
-#endif /* CONFIG_RFKILL_INPUT */
-
-#if !defined(CONFIG_RFKILL_INPUT) && !defined(CONFIG_RFKILL_INPUT_MODULE)
- b43warn(wl, "The rfkill-input subsystem is not available. "
- "The built-in radio LED will not work.\n");
-#endif
-
- err = input_register_polled_device(rfk->poll_dev);
- if (err)
- goto err_unreg_rfk;
-
- rfk->registered = 1;
-
- return;
-err_unreg_rfk:
- rfkill_unregister(rfk->rfkill);
-err_free_polldev:
- input_free_polled_device(rfk->poll_dev);
- rfk->poll_dev = NULL;
-err_freed_rfk:
- rfk->rfkill = NULL;
-out_error:
- rfk->registered = 0;
- b43warn(wl, "RF-kill button init failed\n");
-}
-
-void b43_rfkill_exit(struct b43_wldev *dev)
-{
- struct b43_rfkill *rfk = &(dev->wl->rfkill);
-
- if (!rfk->registered)
- return;
- rfk->registered = 0;
-
- input_unregister_polled_device(rfk->poll_dev);
- rfkill_unregister(rfk->rfkill);
- input_free_polled_device(rfk->poll_dev);
- rfk->poll_dev = NULL;
- rfk->rfkill = NULL;
}
diff --git a/drivers/net/wireless/b43/rfkill.h b/drivers/net/wireless/b43/rfkill.h
index adacf936d81..f046c3ca051 100644
--- a/drivers/net/wireless/b43/rfkill.h
+++ b/drivers/net/wireless/b43/rfkill.h
@@ -1,52 +1,11 @@
#ifndef B43_RFKILL_H_
#define B43_RFKILL_H_
+struct ieee80211_hw;
struct b43_wldev;
+void b43_rfkill_poll(struct ieee80211_hw *hw);
-#ifdef CONFIG_B43_RFKILL
-
-#include <linux/rfkill.h>
-#include <linux/input-polldev.h>
-
-
-struct b43_rfkill {
- /* The RFKILL subsystem data structure */
- struct rfkill *rfkill;
- /* The poll device for the RFKILL input button */
- struct input_polled_dev *poll_dev;
- /* Did initialization succeed? Used for freeing. */
- bool registered;
- /* The unique name of this rfkill switch */
- char name[sizeof("b43-phy4294967295")];
-};
-
-/* The init function returns void, because we are not interested
- * in failing the b43 init process when rfkill init failed. */
-void b43_rfkill_init(struct b43_wldev *dev);
-void b43_rfkill_exit(struct b43_wldev *dev);
-
-char * b43_rfkill_led_name(struct b43_wldev *dev);
-
-
-#else /* CONFIG_B43_RFKILL */
-/* No RFKILL support. */
-
-struct b43_rfkill {
- /* empty */
-};
-
-static inline void b43_rfkill_init(struct b43_wldev *dev)
-{
-}
-static inline void b43_rfkill_exit(struct b43_wldev *dev)
-{
-}
-static inline char * b43_rfkill_led_name(struct b43_wldev *dev)
-{
- return NULL;
-}
-
-#endif /* CONFIG_B43_RFKILL */
+bool b43_is_hw_radio_enabled(struct b43_wldev *dev);
#endif /* B43_RFKILL_H_ */
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index a63d88841df..55f36a7254d 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -118,7 +118,6 @@ u8 b43_plcp_get_ratecode_ofdm(const u8 bitrate)
void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
const u16 octets, const u8 bitrate)
{
- __le32 *data = &(plcp->data);
__u8 *raw = plcp->raw;
if (b43_is_ofdm_rate(bitrate)) {
@@ -127,7 +126,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
d = b43_plcp_get_ratecode_ofdm(bitrate);
B43_WARN_ON(octets & 0xF000);
d |= (octets << 5);
- *data = cpu_to_le32(d);
+ plcp->data = cpu_to_le32(d);
} else {
u32 plen;
@@ -141,7 +140,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
raw[1] = 0x04;
} else
raw[1] = 0x04;
- *data |= cpu_to_le32(plen << 16);
+ plcp->data |= cpu_to_le32(plen << 16);
raw[0] = b43_plcp_get_ratecode_cck(bitrate);
}
}
diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig
index aef2298d37a..94a46347805 100644
--- a/drivers/net/wireless/b43legacy/Kconfig
+++ b/drivers/net/wireless/b43legacy/Kconfig
@@ -3,7 +3,6 @@ config B43LEGACY
depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA
select SSB
select FW_LOADER
- select HW_RANDOM
---help---
b43legacy is a driver for 802.11b devices from Broadcom (BCM4301 and
BCM4303) and early model 802.11g chips (BCM4306 Ver. 2) used in the
@@ -43,12 +42,11 @@ config B43LEGACY_LEDS
depends on B43LEGACY && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43LEGACY)
default y
-# RFKILL support
-# This config option automatically enables b43legacy RFKILL support,
-# if it's possible.
-config B43LEGACY_RFKILL
+# This config option automatically enables b43 HW-RNG support,
+# if the HW-RNG core is enabled.
+config B43LEGACY_HWRNG
bool
- depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43LEGACY)
+ depends on B43LEGACY && (HW_RANDOM = y || HW_RANDOM = B43LEGACY)
default y
config B43LEGACY_DEBUG
diff --git a/drivers/net/wireless/b43legacy/Makefile b/drivers/net/wireless/b43legacy/Makefile
index 80cdb73bd14..227a77e8436 100644
--- a/drivers/net/wireless/b43legacy/Makefile
+++ b/drivers/net/wireless/b43legacy/Makefile
@@ -6,7 +6,7 @@ b43legacy-y += radio.o
b43legacy-y += sysfs.o
b43legacy-y += xmit.o
# b43 RFKILL button support
-b43legacy-$(CONFIG_B43LEGACY_RFKILL) += rfkill.o
+b43legacy-y += rfkill.o
# b43legacy LED support
b43legacy-$(CONFIG_B43LEGACY_LEDS) += leds.o
# b43legacy debugging
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index 97b0e06dfe2..77fda148ac4 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -59,7 +59,8 @@
#define B43legacy_MMIO_XMITSTAT_1 0x174
#define B43legacy_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */
#define B43legacy_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */
-
+#define B43legacy_MMIO_TSF_CFP_REP 0x188
+#define B43legacy_MMIO_TSF_CFP_START 0x18C
/* 32-bit DMA */
#define B43legacy_MMIO_DMA32_BASE0 0x200
#define B43legacy_MMIO_DMA32_BASE1 0x220
@@ -258,7 +259,6 @@
#define B43legacy_IRQ_ALL 0xFFFFFFFF
#define B43legacy_IRQ_MASKTEMPLATE (B43legacy_IRQ_MAC_SUSPENDED | \
- B43legacy_IRQ_BEACON | \
B43legacy_IRQ_TBTT_INDI | \
B43legacy_IRQ_ATIM_END | \
B43legacy_IRQ_PMQ | \
@@ -596,12 +596,11 @@ struct b43legacy_wl {
/* Stats about the wireless interface */
struct ieee80211_low_level_stats ieee_stats;
+#ifdef CONFIG_B43LEGACY_HWRNG
struct hwrng rng;
u8 rng_initialized;
char rng_name[30 + 1];
-
- /* The RF-kill button */
- struct b43legacy_rfkill rfkill;
+#endif
/* List of all wireless devices on this chip */
struct list_head devlist;
@@ -614,6 +613,8 @@ struct b43legacy_wl {
struct sk_buff *current_beacon;
bool beacon0_uploaded;
bool beacon1_uploaded;
+ bool beacon_templates_virgin; /* Never wrote the templates? */
+ struct work_struct beacon_update_trigger;
};
/* Pointers to the firmware data and meta information about it. */
@@ -690,8 +691,8 @@ struct b43legacy_wldev {
/* Reason code of the last interrupt. */
u32 irq_reason;
u32 dma_reason[6];
- /* saved irq enable/disable state bitfield. */
- u32 irq_savedstate;
+ /* The currently active generic-interrupt mask. */
+ u32 irq_mask;
/* Link Quality calculation context. */
struct b43legacy_noise_calculation noisecalc;
/* if > 0 MAC is suspended. if == 0 MAC is enabled. */
diff --git a/drivers/net/wireless/b43legacy/leds.c b/drivers/net/wireless/b43legacy/leds.c
index 3ea55b18c70..37e9be89356 100644
--- a/drivers/net/wireless/b43legacy/leds.c
+++ b/drivers/net/wireless/b43legacy/leds.c
@@ -28,6 +28,7 @@
#include "b43legacy.h"
#include "leds.h"
+#include "rfkill.h"
static void b43legacy_led_turn_on(struct b43legacy_wldev *dev, u8 led_index,
@@ -86,7 +87,8 @@ static void b43legacy_led_brightness_set(struct led_classdev *led_dev,
static int b43legacy_register_led(struct b43legacy_wldev *dev,
struct b43legacy_led *led,
- const char *name, char *default_trigger,
+ const char *name,
+ const char *default_trigger,
u8 led_index, bool activelow)
{
int err;
@@ -163,10 +165,10 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev,
snprintf(name, sizeof(name),
"b43legacy-%s::radio", wiphy_name(hw->wiphy));
b43legacy_register_led(dev, &dev->led_radio, name,
- b43legacy_rfkill_led_name(dev),
+ ieee80211_get_radio_led_name(hw),
led_index, activelow);
- /* Sync the RF-kill LED state with the switch state. */
- if (dev->radio_hw_enable)
+ /* Sync the RF-kill LED state with radio and switch states. */
+ if (dev->phy.radio_on && b43legacy_is_hw_radio_enabled(dev))
b43legacy_led_turn_on(dev, led_index, activelow);
break;
case B43legacy_LED_WEIRD:
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 879edc78671..e5136fb65dd 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -583,35 +583,6 @@ static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev)
b43legacy_set_slot_time(dev, 20);
}
-/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
- * Returns the _previously_ enabled IRQ mask.
- */
-static inline u32 b43legacy_interrupt_enable(struct b43legacy_wldev *dev,
- u32 mask)
-{
- u32 old_mask;
-
- old_mask = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK);
- b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, old_mask |
- mask);
-
- return old_mask;
-}
-
-/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable.
- * Returns the _previously_ enabled IRQ mask.
- */
-static inline u32 b43legacy_interrupt_disable(struct b43legacy_wldev *dev,
- u32 mask)
-{
- u32 old_mask;
-
- old_mask = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK);
- b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, old_mask & ~mask);
-
- return old_mask;
-}
-
/* Synchronize IRQ top- and bottom-half.
* IRQs must be masked before calling this.
* This must not be called with the irq_lock held.
@@ -955,23 +926,54 @@ static void b43legacy_write_template_common(struct b43legacy_wldev *dev,
size + sizeof(struct b43legacy_plcp_hdr6));
}
+/* Convert a b43legacy antenna number value to the PHY TX control value. */
+static u16 b43legacy_antenna_to_phyctl(int antenna)
+{
+ switch (antenna) {
+ case B43legacy_ANTENNA0:
+ return B43legacy_TX4_PHY_ANT0;
+ case B43legacy_ANTENNA1:
+ return B43legacy_TX4_PHY_ANT1;
+ }
+ return B43legacy_TX4_PHY_ANTLAST;
+}
+
static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev,
u16 ram_offset,
- u16 shm_size_offset, u8 rate)
+ u16 shm_size_offset)
{
unsigned int i, len, variable_len;
const struct ieee80211_mgmt *bcn;
const u8 *ie;
bool tim_found = 0;
+ unsigned int rate;
+ u16 ctl;
+ int antenna;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon);
bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data);
len = min((size_t)dev->wl->current_beacon->len,
0x200 - sizeof(struct b43legacy_plcp_hdr6));
+ rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value;
b43legacy_write_template_common(dev, (const u8 *)bcn, len, ram_offset,
shm_size_offset, rate);
+ /* Write the PHY TX control parameters. */
+ antenna = B43legacy_ANTENNA_DEFAULT;
+ antenna = b43legacy_antenna_to_phyctl(antenna);
+ ctl = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
+ B43legacy_SHM_SH_BEACPHYCTL);
+ /* We can't send beacons with short preamble. Would get PHY errors. */
+ ctl &= ~B43legacy_TX4_PHY_SHORTPRMBL;
+ ctl &= ~B43legacy_TX4_PHY_ANT;
+ ctl &= ~B43legacy_TX4_PHY_ENC;
+ ctl |= antenna;
+ ctl |= B43legacy_TX4_PHY_ENC_CCK;
+ b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
+ B43legacy_SHM_SH_BEACPHYCTL, ctl);
+
/* Find the position of the TIM and the DTIM_period value
* and write them to SHM. */
ie = bcn->u.beacon.variable;
@@ -1013,7 +1015,8 @@ static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev,
b43legacywarn(dev->wl, "Did not find a valid TIM IE in the "
"beacon template packet. AP or IBSS operation "
"may be broken.\n");
- }
+ } else
+ b43legacydbg(dev->wl, "Updated beacon template\n");
}
static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev,
@@ -1025,7 +1028,7 @@ static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev,
__le16 dur;
plcp.data = 0;
- b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->bitrate);
+ b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value);
dur = ieee80211_generic_frame_duration(dev->wl->hw,
dev->wl->vif,
size,
@@ -1129,10 +1132,103 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev,
0x200 - sizeof(struct b43legacy_plcp_hdr6));
b43legacy_write_template_common(dev, probe_resp_data,
size, ram_offset,
- shm_size_offset, rate->bitrate);
+ shm_size_offset, rate->hw_value);
kfree(probe_resp_data);
}
+static void b43legacy_upload_beacon0(struct b43legacy_wldev *dev)
+{
+ struct b43legacy_wl *wl = dev->wl;
+
+ if (wl->beacon0_uploaded)
+ return;
+ b43legacy_write_beacon_template(dev, 0x68, 0x18);
+ /* FIXME: Probe resp upload doesn't really belong here,
+ * but we don't use that feature anyway. */
+ b43legacy_write_probe_resp_template(dev, 0x268, 0x4A,
+ &__b43legacy_ratetable[3]);
+ wl->beacon0_uploaded = 1;
+}
+
+static void b43legacy_upload_beacon1(struct b43legacy_wldev *dev)
+{
+ struct b43legacy_wl *wl = dev->wl;
+
+ if (wl->beacon1_uploaded)
+ return;
+ b43legacy_write_beacon_template(dev, 0x468, 0x1A);
+ wl->beacon1_uploaded = 1;
+}
+
+static void handle_irq_beacon(struct b43legacy_wldev *dev)
+{
+ struct b43legacy_wl *wl = dev->wl;
+ u32 cmd, beacon0_valid, beacon1_valid;
+
+ if (!b43legacy_is_mode(wl, NL80211_IFTYPE_AP))
+ return;
+
+ /* This is the bottom half of the asynchronous beacon update. */
+
+ /* Ignore interrupt in the future. */
+ dev->irq_mask &= ~B43legacy_IRQ_BEACON;
+
+ cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
+ beacon0_valid = (cmd & B43legacy_MACCMD_BEACON0_VALID);
+ beacon1_valid = (cmd & B43legacy_MACCMD_BEACON1_VALID);
+
+ /* Schedule interrupt manually, if busy. */
+ if (beacon0_valid && beacon1_valid) {
+ b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, B43legacy_IRQ_BEACON);
+ dev->irq_mask |= B43legacy_IRQ_BEACON;
+ return;
+ }
+
+ if (unlikely(wl->beacon_templates_virgin)) {
+ /* We never uploaded a beacon before.
+ * Upload both templates now, but only mark one valid. */
+ wl->beacon_templates_virgin = 0;
+ b43legacy_upload_beacon0(dev);
+ b43legacy_upload_beacon1(dev);
+ cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
+ cmd |= B43legacy_MACCMD_BEACON0_VALID;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
+ } else {
+ if (!beacon0_valid) {
+ b43legacy_upload_beacon0(dev);
+ cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
+ cmd |= B43legacy_MACCMD_BEACON0_VALID;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
+ } else if (!beacon1_valid) {
+ b43legacy_upload_beacon1(dev);
+ cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
+ cmd |= B43legacy_MACCMD_BEACON1_VALID;
+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
+ }
+ }
+}
+
+static void b43legacy_beacon_update_trigger_work(struct work_struct *work)
+{
+ struct b43legacy_wl *wl = container_of(work, struct b43legacy_wl,
+ beacon_update_trigger);
+ struct b43legacy_wldev *dev;
+
+ mutex_lock(&wl->mutex);
+ dev = wl->current_dev;
+ if (likely(dev && (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED))) {
+ spin_lock_irq(&wl->irq_lock);
+ /* Update beacon right away or defer to IRQ. */
+ handle_irq_beacon(dev);
+ /* The handler might have updated the IRQ mask. */
+ b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK,
+ dev->irq_mask);
+ mmiowb();
+ spin_unlock_irq(&wl->irq_lock);
+ }
+ mutex_unlock(&wl->mutex);
+}
+
/* Asynchronously update the packet templates in template RAM.
* Locking: Requires wl->irq_lock to be locked. */
static void b43legacy_update_templates(struct b43legacy_wl *wl)
@@ -1156,54 +1252,24 @@ static void b43legacy_update_templates(struct b43legacy_wl *wl)
wl->current_beacon = beacon;
wl->beacon0_uploaded = 0;
wl->beacon1_uploaded = 0;
+ queue_work(wl->hw->workqueue, &wl->beacon_update_trigger);
}
static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev,
u16 beacon_int)
{
b43legacy_time_lock(dev);
- if (dev->dev->id.revision >= 3)
- b43legacy_write32(dev, 0x188, (beacon_int << 16));
- else {
+ if (dev->dev->id.revision >= 3) {
+ b43legacy_write32(dev, B43legacy_MMIO_TSF_CFP_REP,
+ (beacon_int << 16));
+ b43legacy_write32(dev, B43legacy_MMIO_TSF_CFP_START,
+ (beacon_int << 10));
+ } else {
b43legacy_write16(dev, 0x606, (beacon_int >> 6));
b43legacy_write16(dev, 0x610, beacon_int);
}
b43legacy_time_unlock(dev);
-}
-
-static void handle_irq_beacon(struct b43legacy_wldev *dev)
-{
- struct b43legacy_wl *wl = dev->wl;
- u32 cmd;
-
- if (!b43legacy_is_mode(wl, NL80211_IFTYPE_AP))
- return;
-
- /* This is the bottom half of the asynchronous beacon update. */
-
- cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
- if (!(cmd & B43legacy_MACCMD_BEACON0_VALID)) {
- if (!wl->beacon0_uploaded) {
- b43legacy_write_beacon_template(dev, 0x68,
- B43legacy_SHM_SH_BTL0,
- B43legacy_CCK_RATE_1MB);
- b43legacy_write_probe_resp_template(dev, 0x268,
- B43legacy_SHM_SH_PRTLEN,
- &__b43legacy_ratetable[3]);
- wl->beacon0_uploaded = 1;
- }
- cmd |= B43legacy_MACCMD_BEACON0_VALID;
- }
- if (!(cmd & B43legacy_MACCMD_BEACON1_VALID)) {
- if (!wl->beacon1_uploaded) {
- b43legacy_write_beacon_template(dev, 0x468,
- B43legacy_SHM_SH_BTL1,
- B43legacy_CCK_RATE_1MB);
- wl->beacon1_uploaded = 1;
- }
- cmd |= B43legacy_MACCMD_BEACON1_VALID;
- }
- b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
+ b43legacydbg(dev->wl, "Set beacon interval to %u\n", beacon_int);
}
static void handle_irq_ucode_debug(struct b43legacy_wldev *dev)
@@ -1302,7 +1368,7 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev)
if (reason & B43legacy_IRQ_TX_OK)
handle_irq_transmit_status(dev);
- b43legacy_interrupt_enable(dev, dev->irq_savedstate);
+ b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
mmiowb();
spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
}
@@ -1354,18 +1420,18 @@ static irqreturn_t b43legacy_interrupt_handler(int irq, void *dev_id)
struct b43legacy_wldev *dev = dev_id;
u32 reason;
- if (!dev)
- return IRQ_NONE;
+ B43legacy_WARN_ON(!dev);
spin_lock(&dev->wl->irq_lock);
- if (b43legacy_status(dev) < B43legacy_STAT_STARTED)
+ if (unlikely(b43legacy_status(dev) < B43legacy_STAT_STARTED))
+ /* This can only happen on shared IRQ lines. */
goto out;
reason = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
if (reason == 0xffffffff) /* shared IRQ */
goto out;
ret = IRQ_HANDLED;
- reason &= b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK);
+ reason &= dev->irq_mask;
if (!reason)
goto out;
@@ -1389,10 +1455,9 @@ static irqreturn_t b43legacy_interrupt_handler(int irq, void *dev_id)
& 0x0000DC00;
b43legacy_interrupt_ack(dev, reason);
- /* disable all IRQs. They are enabled again in the bottom half. */
- dev->irq_savedstate = b43legacy_interrupt_disable(dev,
- B43legacy_IRQ_ALL);
- /* save the reason code and call our bottom half. */
+ /* Disable all IRQs. They are enabled again in the bottom half. */
+ b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
+ /* Save the reason code and call our bottom half. */
dev->irq_reason = reason;
tasklet_schedule(&dev->isr_tasklet);
out:
@@ -1852,7 +1917,8 @@ void b43legacy_mac_enable(struct b43legacy_wldev *dev)
/* Re-enable IRQs. */
spin_lock_irq(&dev->wl->irq_lock);
- b43legacy_interrupt_enable(dev, dev->irq_savedstate);
+ b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK,
+ dev->irq_mask);
spin_unlock_irq(&dev->wl->irq_lock);
}
}
@@ -1871,10 +1937,9 @@ void b43legacy_mac_suspend(struct b43legacy_wldev *dev)
/* Mask IRQs before suspending MAC. Otherwise
* the MAC stays busy and won't suspend. */
spin_lock_irq(&dev->wl->irq_lock);
- tmp = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL);
+ b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
spin_unlock_irq(&dev->wl->irq_lock);
b43legacy_synchronize_irq(dev);
- dev->irq_savedstate = tmp;
b43legacy_power_saving_ctl_bits(dev, -1, 1);
b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
@@ -2297,6 +2362,7 @@ static void b43legacy_security_init(struct b43legacy_wldev *dev)
dev->max_nr_keys - 8);
}
+#ifdef CONFIG_B43LEGACY_HWRNG
static int b43legacy_rng_read(struct hwrng *rng, u32 *data)
{
struct b43legacy_wl *wl = (struct b43legacy_wl *)rng->priv;
@@ -2312,17 +2378,21 @@ static int b43legacy_rng_read(struct hwrng *rng, u32 *data)
return (sizeof(u16));
}
+#endif
static void b43legacy_rng_exit(struct b43legacy_wl *wl)
{
+#ifdef CONFIG_B43LEGACY_HWRNG
if (wl->rng_initialized)
hwrng_unregister(&wl->rng);
+#endif
}
static int b43legacy_rng_init(struct b43legacy_wl *wl)
{
- int err;
+ int err = 0;
+#ifdef CONFIG_B43LEGACY_HWRNG
snprintf(wl->rng_name, ARRAY_SIZE(wl->rng_name),
"%s_%s", KBUILD_MODNAME, wiphy_name(wl->hw->wiphy));
wl->rng.name = wl->rng_name;
@@ -2336,6 +2406,7 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl)
"number generator (%d)\n", err);
}
+#endif
return err;
}
@@ -2557,7 +2628,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
int antenna_tx;
int antenna_rx;
int err = 0;
- u32 savedirqs;
antenna_tx = B43legacy_ANTENNA_DEFAULT;
antenna_rx = B43legacy_ANTENNA_DEFAULT;
@@ -2597,7 +2667,7 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
spin_unlock_irqrestore(&wl->irq_lock, flags);
goto out_unlock_mutex;
}
- savedirqs = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL);
+ b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
spin_unlock_irqrestore(&wl->irq_lock, flags);
b43legacy_synchronize_irq(dev);
@@ -2619,11 +2689,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
/* Antennas for RX and management frame TX. */
b43legacy_mgmtframe_txantenna(dev, antenna_tx);
- /* Update templates for AP mode. */
- if (b43legacy_is_mode(wl, NL80211_IFTYPE_AP))
- b43legacy_set_beacon_int(dev, conf->beacon_int);
-
-
if (!!conf->radio_enabled != phy->radio_on) {
if (conf->radio_enabled) {
b43legacy_radio_turn_on(dev);
@@ -2641,7 +2706,7 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
}
spin_lock_irqsave(&wl->irq_lock, flags);
- b43legacy_interrupt_enable(dev, savedirqs);
+ b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
mmiowb();
spin_unlock_irqrestore(&wl->irq_lock, flags);
out_unlock_mutex:
@@ -2704,9 +2769,9 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
struct b43legacy_wldev *dev;
struct b43legacy_phy *phy;
unsigned long flags;
- u32 savedirqs;
mutex_lock(&wl->mutex);
+ B43legacy_WARN_ON(wl->vif != vif);
dev = wl->current_dev;
phy = &dev->phy;
@@ -2719,12 +2784,35 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
spin_unlock_irqrestore(&wl->irq_lock, flags);
goto out_unlock_mutex;
}
- savedirqs = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL);
+ b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
+
+ if (changed & BSS_CHANGED_BSSID) {
+ b43legacy_synchronize_irq(dev);
+
+ if (conf->bssid)
+ memcpy(wl->bssid, conf->bssid, ETH_ALEN);
+ else
+ memset(wl->bssid, 0, ETH_ALEN);
+ }
+
+ if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) {
+ if (changed & BSS_CHANGED_BEACON &&
+ (b43legacy_is_mode(wl, NL80211_IFTYPE_AP) ||
+ b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC)))
+ b43legacy_update_templates(wl);
+
+ if (changed & BSS_CHANGED_BSSID)
+ b43legacy_write_mac_bssid_templates(dev);
+ }
spin_unlock_irqrestore(&wl->irq_lock, flags);
- b43legacy_synchronize_irq(dev);
b43legacy_mac_suspend(dev);
+ if (changed & BSS_CHANGED_BEACON_INT &&
+ (b43legacy_is_mode(wl, NL80211_IFTYPE_AP) ||
+ b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC)))
+ b43legacy_set_beacon_int(dev, conf->beacon_int);
+
if (changed & BSS_CHANGED_BASIC_RATES)
b43legacy_update_basic_rates(dev, conf->basic_rates);
@@ -2738,14 +2826,12 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
b43legacy_mac_enable(dev);
spin_lock_irqsave(&wl->irq_lock, flags);
- b43legacy_interrupt_enable(dev, savedirqs);
+ b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
/* XXX: why? */
mmiowb();
spin_unlock_irqrestore(&wl->irq_lock, flags);
out_unlock_mutex:
mutex_unlock(&wl->mutex);
-
- return;
}
static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
@@ -2787,40 +2873,6 @@ static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
spin_unlock_irqrestore(&wl->irq_lock, flags);
}
-static int b43legacy_op_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
- struct b43legacy_wldev *dev = wl->current_dev;
- unsigned long flags;
-
- if (!dev)
- return -ENODEV;
- mutex_lock(&wl->mutex);
- spin_lock_irqsave(&wl->irq_lock, flags);
- B43legacy_WARN_ON(wl->vif != vif);
- if (conf->bssid)
- memcpy(wl->bssid, conf->bssid, ETH_ALEN);
- else
- memset(wl->bssid, 0, ETH_ALEN);
- if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) {
- if (b43legacy_is_mode(wl, NL80211_IFTYPE_AP)) {
- B43legacy_WARN_ON(vif->type != NL80211_IFTYPE_AP);
- if (conf->changed & IEEE80211_IFCC_BEACON)
- b43legacy_update_templates(wl);
- } else if (b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC)) {
- if (conf->changed & IEEE80211_IFCC_BEACON)
- b43legacy_update_templates(wl);
- }
- b43legacy_write_mac_bssid_templates(dev);
- }
- spin_unlock_irqrestore(&wl->irq_lock, flags);
- mutex_unlock(&wl->mutex);
-
- return 0;
-}
-
/* Locking: wl->mutex */
static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
{
@@ -2834,8 +2886,7 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
* setting the status to INITIALIZED, as the interrupt handler
* won't care about IRQs then. */
spin_lock_irqsave(&wl->irq_lock, flags);
- dev->irq_savedstate = b43legacy_interrupt_disable(dev,
- B43legacy_IRQ_ALL);
+ b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK); /* flush */
spin_unlock_irqrestore(&wl->irq_lock, flags);
b43legacy_synchronize_irq(dev);
@@ -2875,7 +2926,7 @@ static int b43legacy_wireless_core_start(struct b43legacy_wldev *dev)
/* Start data flow (TX/RX) */
b43legacy_mac_enable(dev);
- b43legacy_interrupt_enable(dev, dev->irq_savedstate);
+ b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
/* Start maintenance work */
b43legacy_periodic_tasks_setup(dev);
@@ -3038,7 +3089,7 @@ static void setup_struct_wldev_for_init(struct b43legacy_wldev *dev)
/* IRQ related flags */
dev->irq_reason = 0;
memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
- dev->irq_savedstate = B43legacy_IRQ_MASKTEMPLATE;
+ dev->irq_mask = B43legacy_IRQ_MASKTEMPLATE;
dev->mac_suspended = 1;
@@ -3380,11 +3431,6 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
struct b43legacy_wldev *dev = wl->current_dev;
int did_init = 0;
int err = 0;
- bool do_rfkill_exit = 0;
-
- /* First register RFkill.
- * LEDs that are registered later depend on it. */
- b43legacy_rfkill_init(dev);
/* Kill all old instance specific information to make sure
* the card won't use it in the short timeframe between start
@@ -3392,15 +3438,16 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
memset(wl->bssid, 0, ETH_ALEN);
memset(wl->mac_addr, 0, ETH_ALEN);
wl->filter_flags = 0;
+ wl->beacon0_uploaded = 0;
+ wl->beacon1_uploaded = 0;
+ wl->beacon_templates_virgin = 1;
mutex_lock(&wl->mutex);
if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) {
err = b43legacy_wireless_core_init(dev);
- if (err) {
- do_rfkill_exit = 1;
+ if (err)
goto out_mutex_unlock;
- }
did_init = 1;
}
@@ -3409,17 +3456,15 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
if (err) {
if (did_init)
b43legacy_wireless_core_exit(dev);
- do_rfkill_exit = 1;
goto out_mutex_unlock;
}
}
+ wiphy_rfkill_start_polling(hw->wiphy);
+
out_mutex_unlock:
mutex_unlock(&wl->mutex);
- if (do_rfkill_exit)
- b43legacy_rfkill_exit(dev);
-
return err;
}
@@ -3428,7 +3473,7 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw)
struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
struct b43legacy_wldev *dev = wl->current_dev;
- b43legacy_rfkill_exit(dev);
+ cancel_work_sync(&(wl->beacon_update_trigger));
mutex_lock(&wl->mutex);
if (b43legacy_status(dev) >= B43legacy_STAT_STARTED)
@@ -3457,13 +3502,13 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
.remove_interface = b43legacy_op_remove_interface,
.config = b43legacy_op_dev_config,
.bss_info_changed = b43legacy_op_bss_info_changed,
- .config_interface = b43legacy_op_config_interface,
.configure_filter = b43legacy_op_configure_filter,
.get_stats = b43legacy_op_get_stats,
.get_tx_stats = b43legacy_op_get_tx_stats,
.start = b43legacy_op_start,
.stop = b43legacy_op_stop,
.set_tim = b43legacy_op_beacon_set_tim,
+ .rfkill_poll = b43legacy_rfkill_poll,
};
/* Hard-reset the chip. Do not call this directly.
@@ -3760,6 +3805,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
spin_lock_init(&wl->leds_lock);
mutex_init(&wl->mutex);
INIT_LIST_HEAD(&wl->devlist);
+ INIT_WORK(&wl->beacon_update_trigger, b43legacy_beacon_update_trigger_work);
ssb_set_devtypedata(dev, wl);
b43legacyinfo(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id);
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c
index 746d5361bba..51866c9a276 100644
--- a/drivers/net/wireless/b43legacy/pio.c
+++ b/drivers/net/wireless/b43legacy/pio.c
@@ -443,7 +443,7 @@ int b43legacy_pio_init(struct b43legacy_wldev *dev)
pio->queue3 = queue;
if (dev->dev->id.revision < 3)
- dev->irq_savedstate |= B43legacy_IRQ_PIO_WORKAROUND;
+ dev->irq_mask |= B43legacy_IRQ_PIO_WORKAROUND;
b43legacydbg(dev->wl, "PIO initialized\n");
err = 0;
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c
index b32bf6a94f1..8783022db11 100644
--- a/drivers/net/wireless/b43legacy/rfkill.c
+++ b/drivers/net/wireless/b43legacy/rfkill.c
@@ -22,15 +22,12 @@
*/
-#include "rfkill.h"
#include "radio.h"
#include "b43legacy.h"
-#include <linux/kmod.h>
-
/* Returns TRUE, if the radio is enabled in hardware. */
-static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
+bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
{
if (dev->phy.rev >= 3) {
if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI)
@@ -45,165 +42,43 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
}
/* The poll callback for the hardware button. */
-static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev)
+void b43legacy_rfkill_poll(struct ieee80211_hw *hw)
{
- struct b43legacy_wldev *dev = poll_dev->private;
- struct b43legacy_wl *wl = dev->wl;
+ struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
+ struct b43legacy_wldev *dev = wl->current_dev;
+ struct ssb_bus *bus = dev->dev->bus;
bool enabled;
- bool report_change = 0;
+ bool brought_up = false;
mutex_lock(&wl->mutex);
if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) {
- mutex_unlock(&wl->mutex);
- return;
+ if (ssb_bus_powerup(bus, 0)) {
+ mutex_unlock(&wl->mutex);
+ return;
+ }
+ ssb_device_enable(dev->dev, 0);
+ brought_up = true;
}
+
enabled = b43legacy_is_hw_radio_enabled(dev);
+
if (unlikely(enabled != dev->radio_hw_enable)) {
dev->radio_hw_enable = enabled;
- report_change = 1;
b43legacyinfo(wl, "Radio hardware status changed to %s\n",
enabled ? "ENABLED" : "DISABLED");
- }
- mutex_unlock(&wl->mutex);
-
- /* send the radio switch event to the system - note both a key press
- * and a release are required */
- if (unlikely(report_change)) {
- input_report_key(poll_dev->input, KEY_WLAN, 1);
- input_report_key(poll_dev->input, KEY_WLAN, 0);
- }
-}
-
-/* Called when the RFKILL toggled in software.
- * This is called without locking. */
-static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state)
-{
- struct b43legacy_wldev *dev = data;
- struct b43legacy_wl *wl = dev->wl;
- int err = -EBUSY;
-
- if (!wl->rfkill.registered)
- return 0;
-
- mutex_lock(&wl->mutex);
- if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)
- goto out_unlock;
- err = 0;
- switch (state) {
- case RFKILL_STATE_UNBLOCKED:
- if (!dev->radio_hw_enable) {
- /* No luck. We can't toggle the hardware RF-kill
- * button from software. */
- err = -EBUSY;
- goto out_unlock;
+ wiphy_rfkill_set_hw_state(hw->wiphy, !enabled);
+ if (enabled != dev->phy.radio_on) {
+ if (enabled)
+ b43legacy_radio_turn_on(dev);
+ else
+ b43legacy_radio_turn_off(dev, 0);
}
- if (!dev->phy.radio_on)
- b43legacy_radio_turn_on(dev);
- break;
- case RFKILL_STATE_SOFT_BLOCKED:
- if (dev->phy.radio_on)
- b43legacy_radio_turn_off(dev, 0);
- break;
- default:
- b43legacywarn(wl, "Received unexpected rfkill state %d.\n",
- state);
- break;
}
-out_unlock:
- mutex_unlock(&wl->mutex);
-
- return err;
-}
-
-char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev)
-{
- struct b43legacy_rfkill *rfk = &(dev->wl->rfkill);
-
- if (!rfk->registered)
- return NULL;
- return rfkill_get_led_name(rfk->rfkill);
-}
-
-void b43legacy_rfkill_init(struct b43legacy_wldev *dev)
-{
- struct b43legacy_wl *wl = dev->wl;
- struct b43legacy_rfkill *rfk = &(wl->rfkill);
- int err;
-
- rfk->registered = 0;
-
- rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
- if (!rfk->rfkill)
- goto out_error;
- snprintf(rfk->name, sizeof(rfk->name),
- "b43legacy-%s", wiphy_name(wl->hw->wiphy));
- rfk->rfkill->name = rfk->name;
- rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;
- rfk->rfkill->data = dev;
- rfk->rfkill->toggle_radio = b43legacy_rfkill_soft_toggle;
- rfk->rfkill->user_claim_unsupported = 1;
-
- rfk->poll_dev = input_allocate_polled_device();
- if (!rfk->poll_dev) {
- rfkill_free(rfk->rfkill);
- goto err_freed_rfk;
+ if (brought_up) {
+ ssb_device_disable(dev->dev, 0);
+ ssb_bus_may_powerdown(bus);
}
- rfk->poll_dev->private = dev;
- rfk->poll_dev->poll = b43legacy_rfkill_poll;
- rfk->poll_dev->poll_interval = 1000; /* msecs */
-
- rfk->poll_dev->input->name = rfk->name;
- rfk->poll_dev->input->id.bustype = BUS_HOST;
- rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor;
- rfk->poll_dev->input->evbit[0] = BIT(EV_KEY);
- set_bit(KEY_WLAN, rfk->poll_dev->input->keybit);
-
- err = rfkill_register(rfk->rfkill);
- if (err)
- goto err_free_polldev;
-
-#ifdef CONFIG_RFKILL_INPUT_MODULE
- /* B43legacy RF-kill isn't useful without the rfkill-input subsystem.
- * Try to load the module. */
- err = request_module("rfkill-input");
- if (err)
- b43legacywarn(wl, "Failed to load the rfkill-input module."
- "The built-in radio LED will not work.\n");
-#endif /* CONFIG_RFKILL_INPUT */
-
- err = input_register_polled_device(rfk->poll_dev);
- if (err)
- goto err_unreg_rfk;
-
- rfk->registered = 1;
-
- return;
-err_unreg_rfk:
- rfkill_unregister(rfk->rfkill);
-err_free_polldev:
- input_free_polled_device(rfk->poll_dev);
- rfk->poll_dev = NULL;
-err_freed_rfk:
- rfk->rfkill = NULL;
-out_error:
- rfk->registered = 0;
- b43legacywarn(wl, "RF-kill button init failed\n");
-}
-
-void b43legacy_rfkill_exit(struct b43legacy_wldev *dev)
-{
- struct b43legacy_rfkill *rfk = &(dev->wl->rfkill);
-
- if (!rfk->registered)
- return;
- rfk->registered = 0;
-
- input_unregister_polled_device(rfk->poll_dev);
- rfkill_unregister(rfk->rfkill);
- input_free_polled_device(rfk->poll_dev);
- rfk->poll_dev = NULL;
- rfk->rfkill = NULL;
+ mutex_unlock(&wl->mutex);
}
-
diff --git a/drivers/net/wireless/b43legacy/rfkill.h b/drivers/net/wireless/b43legacy/rfkill.h
index 11150a8032f..75585571c54 100644
--- a/drivers/net/wireless/b43legacy/rfkill.h
+++ b/drivers/net/wireless/b43legacy/rfkill.h
@@ -1,59 +1,11 @@
#ifndef B43legacy_RFKILL_H_
#define B43legacy_RFKILL_H_
+struct ieee80211_hw;
struct b43legacy_wldev;
-#ifdef CONFIG_B43LEGACY_RFKILL
+void b43legacy_rfkill_poll(struct ieee80211_hw *hw);
-#include <linux/rfkill.h>
-#include <linux/workqueue.h>
-#include <linux/input-polldev.h>
-
-
-
-struct b43legacy_rfkill {
- /* The RFKILL subsystem data structure */
- struct rfkill *rfkill;
- /* The poll device for the RFKILL input button */
- struct input_polled_dev *poll_dev;
- /* Did initialization succeed? Used for freeing. */
- bool registered;
- /* The unique name of this rfkill switch */
- char name[sizeof("b43legacy-phy4294967295")];
-};
-
-/* The init function returns void, because we are not interested
- * in failing the b43 init process when rfkill init failed. */
-void b43legacy_rfkill_init(struct b43legacy_wldev *dev);
-void b43legacy_rfkill_exit(struct b43legacy_wldev *dev);
-
-char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev);
-
-
-#else /* CONFIG_B43LEGACY_RFKILL */
-/* No RFKILL support. */
-
-struct b43legacy_rfkill {
- /* empty */
-};
-
-static inline void b43legacy_rfkill_alloc(struct b43legacy_wldev *dev)
-{
-}
-static inline void b43legacy_rfkill_free(struct b43legacy_wldev *dev)
-{
-}
-static inline void b43legacy_rfkill_init(struct b43legacy_wldev *dev)
-{
-}
-static inline void b43legacy_rfkill_exit(struct b43legacy_wldev *dev)
-{
-}
-static inline char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev)
-{
- return NULL;
-}
-
-#endif /* CONFIG_B43LEGACY_RFKILL */
+bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev);
#endif /* B43legacy_RFKILL_H_ */
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index 12fca99f757..b8e39dd06e9 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -274,7 +274,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
/* PHY TX Control word */
if (rate_ofdm)
- phy_ctl |= B43legacy_TX4_PHY_OFDM;
+ phy_ctl |= B43legacy_TX4_PHY_ENC_OFDM;
if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
phy_ctl |= B43legacy_TX4_PHY_SHORTPRMBL;
switch (info->antenna_sel_tx) {
diff --git a/drivers/net/wireless/b43legacy/xmit.h b/drivers/net/wireless/b43legacy/xmit.h
index 62e09d02788..91633087a20 100644
--- a/drivers/net/wireless/b43legacy/xmit.h
+++ b/drivers/net/wireless/b43legacy/xmit.h
@@ -67,7 +67,9 @@ struct b43legacy_txhdr_fw3 {
#define B43legacy_TX4_EFT_RTSFBOFDM 0x0010 /* RTS/CTS fallback rate type */
/* PHY TX control word */
-#define B43legacy_TX4_PHY_OFDM 0x0001 /* Data frame rate type */
+#define B43legacy_TX4_PHY_ENC 0x0003 /* Data frame encoding */
+#define B43legacy_TX4_PHY_ENC_CCK 0x0000 /* CCK */
+#define B43legacy_TX4_PHY_ENC_OFDM 0x0001 /* Data frame rate type */
#define B43legacy_TX4_PHY_SHORTPRMBL 0x0010 /* Use short preamble */
#define B43legacy_TX4_PHY_ANT 0x03C0 /* Antenna selection */
#define B43legacy_TX4_PHY_ANT0 0x0000 /* Use antenna 0 */
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 6693423f63f..d313b005114 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -377,7 +377,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct hostap_interface *iface;
local_info_t *local;
- int ret = 1;
+ int ret = NETDEV_TX_BUSY;
u16 fc;
struct hostap_tx_data tx;
ap_tx_ret tx_ret;
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 3dad1cf8f24..ff9b5c88218 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -1423,7 +1423,7 @@ static int prism2_hw_init2(struct net_device *dev, int initial)
prism2_check_sta_fw_version(local);
if (hfa384x_get_rid(dev, HFA384X_RID_CNFOWNMACADDR,
- &dev->dev_addr, 6, 1) < 0) {
+ dev->dev_addr, 6, 1) < 0) {
printk("%s: could not get own MAC address\n",
dev->name);
}
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index cbf15d70320..0e5d51086a4 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -435,7 +435,7 @@ static int prism2_plx_probe(struct pci_dev *pdev,
unsigned long pccard_attr_mem;
unsigned int pccard_attr_len;
void __iomem *attr_mem = NULL;
- unsigned int cor_offset, cor_index;
+ unsigned int cor_offset = 0, cor_index = 0;
u32 reg;
local_info_t *local = NULL;
struct net_device *dev = NULL;
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 97e5647ff05..742432388ca 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -3488,7 +3488,7 @@ static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL);
static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
char *buf)
{
- struct ipw2100_priv *p = d->driver_data;
+ struct ipw2100_priv *p = dev_get_drvdata(d);
return sprintf(buf, "0x%08x\n", (int)p->config);
}
@@ -3497,7 +3497,7 @@ static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
static ssize_t show_status(struct device *d, struct device_attribute *attr,
char *buf)
{
- struct ipw2100_priv *p = d->driver_data;
+ struct ipw2100_priv *p = dev_get_drvdata(d);
return sprintf(buf, "0x%08x\n", (int)p->status);
}
@@ -3506,7 +3506,7 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
static ssize_t show_capability(struct device *d, struct device_attribute *attr,
char *buf)
{
- struct ipw2100_priv *p = d->driver_data;
+ struct ipw2100_priv *p = dev_get_drvdata(d);
return sprintf(buf, "0x%08x\n", (int)p->capability);
}
@@ -4224,7 +4224,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
1 - SW based RF kill active (sysfs)
2 - HW based RF kill active
3 - Both HW and SW baed RF kill active */
- struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data;
+ struct ipw2100_priv *priv = dev_get_drvdata(d);
int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
(rf_kill_active(priv) ? 0x2 : 0x0);
return sprintf(buf, "%i\n", val);
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index bd4dbcfe1bb..44c29b3f672 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -1527,7 +1527,7 @@ static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
static ssize_t show_status(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
return sprintf(buf, "0x%08x\n", (int)p->status);
}
@@ -1536,7 +1536,7 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
char *buf)
{
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
return sprintf(buf, "0x%08x\n", (int)p->config);
}
@@ -1545,7 +1545,7 @@ static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
static ssize_t show_nic_type(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "TYPE: %d\n", priv->nic_type);
}
@@ -1555,7 +1555,7 @@ static ssize_t show_ucode_version(struct device *d,
struct device_attribute *attr, char *buf)
{
u32 len = sizeof(u32), tmp = 0;
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
if (ipw_get_ordinal(p, IPW_ORD_STAT_UCODE_VERSION, &tmp, &len))
return 0;
@@ -1569,7 +1569,7 @@ static ssize_t show_rtc(struct device *d, struct device_attribute *attr,
char *buf)
{
u32 len = sizeof(u32), tmp = 0;
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
if (ipw_get_ordinal(p, IPW_ORD_STAT_RTC, &tmp, &len))
return 0;
@@ -1586,14 +1586,15 @@ static DEVICE_ATTR(rtc, S_IWUSR | S_IRUGO, show_rtc, NULL);
static ssize_t show_eeprom_delay(struct device *d,
struct device_attribute *attr, char *buf)
{
- int n = ((struct ipw_priv *)d->driver_data)->eeprom_delay;
+ struct ipw_priv *p = dev_get_drvdata(d);
+ int n = p->eeprom_delay;
return sprintf(buf, "%i\n", n);
}
static ssize_t store_eeprom_delay(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
sscanf(buf, "%i", &p->eeprom_delay);
return strnlen(buf, count);
}
@@ -1605,7 +1606,7 @@ static ssize_t show_command_event_reg(struct device *d,
struct device_attribute *attr, char *buf)
{
u32 reg = 0;
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT);
return sprintf(buf, "0x%08x\n", reg);
@@ -1615,7 +1616,7 @@ static ssize_t store_command_event_reg(struct device *d,
const char *buf, size_t count)
{
u32 reg;
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
sscanf(buf, "%x", &reg);
ipw_write_reg32(p, IPW_INTERNAL_CMD_EVENT, reg);
@@ -1629,7 +1630,7 @@ static ssize_t show_mem_gpio_reg(struct device *d,
struct device_attribute *attr, char *buf)
{
u32 reg = 0;
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
reg = ipw_read_reg32(p, 0x301100);
return sprintf(buf, "0x%08x\n", reg);
@@ -1639,7 +1640,7 @@ static ssize_t store_mem_gpio_reg(struct device *d,
const char *buf, size_t count)
{
u32 reg;
- struct ipw_priv *p = d->driver_data;
+ struct ipw_priv *p = dev_get_drvdata(d);
sscanf(buf, "%x", &reg);
ipw_write_reg32(p, 0x301100, reg);
@@ -1653,7 +1654,7 @@ static ssize_t show_indirect_dword(struct device *d,
struct device_attribute *attr, char *buf)
{
u32 reg = 0;
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
if (priv->status & STATUS_INDIRECT_DWORD)
reg = ipw_read_reg32(priv, priv->indirect_dword);
@@ -1666,7 +1667,7 @@ static ssize_t store_indirect_dword(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
sscanf(buf, "%x", &priv->indirect_dword);
priv->status |= STATUS_INDIRECT_DWORD;
@@ -1680,7 +1681,7 @@ static ssize_t show_indirect_byte(struct device *d,
struct device_attribute *attr, char *buf)
{
u8 reg = 0;
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
if (priv->status & STATUS_INDIRECT_BYTE)
reg = ipw_read_reg8(priv, priv->indirect_byte);
@@ -1693,7 +1694,7 @@ static ssize_t store_indirect_byte(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
sscanf(buf, "%x", &priv->indirect_byte);
priv->status |= STATUS_INDIRECT_BYTE;
@@ -1707,7 +1708,7 @@ static ssize_t show_direct_dword(struct device *d,
struct device_attribute *attr, char *buf)
{
u32 reg = 0;
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
if (priv->status & STATUS_DIRECT_DWORD)
reg = ipw_read32(priv, priv->direct_dword);
@@ -1720,7 +1721,7 @@ static ssize_t store_direct_dword(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
sscanf(buf, "%x", &priv->direct_dword);
priv->status |= STATUS_DIRECT_DWORD;
@@ -1747,7 +1748,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
1 - SW based RF kill active (sysfs)
2 - HW based RF kill active
3 - Both HW and SW baed RF kill active */
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
(rf_kill_active(priv) ? 0x2 : 0x0);
return sprintf(buf, "%i\n", val);
@@ -1791,7 +1792,7 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ipw_priv *priv = d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
ipw_radio_kill_sw(priv, buf[0] == '1');
@@ -1803,7 +1804,7 @@ static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
char *buf)
{
- struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
int pos = 0, len = 0;
if (priv->config & CFG_SPEED_SCAN) {
while (priv->speed_scan[pos] != 0)
@@ -1818,7 +1819,7 @@ static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
int channel, pos = 0;
const char *p = buf;
@@ -1857,14 +1858,14 @@ static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan,
static ssize_t show_net_stats(struct device *d, struct device_attribute *attr,
char *buf)
{
- struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0');
}
static ssize_t store_net_stats(struct device *d, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
+ struct ipw_priv *priv = dev_get_drvdata(d);
if (buf[0] == '1')
priv->config |= CFG_NET_STATS;
else
@@ -3176,11 +3177,8 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
/* Start the Dma */
rc = ipw_fw_dma_enable(priv);
- if (priv->sram_desc.last_cb_index > 0) {
- /* the DMA is already ready this would be a bug. */
- BUG();
- goto out;
- }
+ /* the DMA is already ready this would be a bug. */
+ BUG_ON(priv->sram_desc.last_cb_index > 0);
do {
chunk = (struct fw_chunk *)(data + offset);
@@ -11526,7 +11524,8 @@ static int ipw_prom_stop(struct net_device *dev)
static int ipw_prom_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
IPW_DEBUG_INFO("prom dev->xmit\n");
- return -EOPNOTSUPP;
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
}
static const struct net_device_ops ipw_prom_netdev_ops = {
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index 92a26922e79..8ce6e961c5d 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -154,10 +154,6 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
goto failed;
}
ieee = netdev_priv(dev);
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
- dev->hard_start_xmit = ieee80211_xmit;
- dev->change_mtu = ieee80211_change_mtu;
-#endif
ieee->dev = dev;
diff --git a/drivers/net/wireless/ipw2x00/libipw_tx.c b/drivers/net/wireless/ipw2x00/libipw_tx.c
index 65a8195b3d9..da2ad5437ce 100644
--- a/drivers/net/wireless/ipw2x00/libipw_tx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_tx.c
@@ -539,7 +539,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&ieee->lock, flags);
netif_stop_queue(dev);
dev->stats.tx_errors++;
- return 1;
+ return NETDEV_TX_BUSY;
}
EXPORT_SYMBOL(ieee80211_xmit);
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 736162324ba..e092af09d6b 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -5,16 +5,11 @@ config IWLWIFI
select FW_LOADER
select MAC80211_LEDS if IWLWIFI_LEDS
select LEDS_CLASS if IWLWIFI_LEDS
- select RFKILL if IWLWIFI_RFKILL
config IWLWIFI_LEDS
bool "Enable LED support in iwlagn and iwl3945 drivers"
depends on IWLWIFI
-config IWLWIFI_RFKILL
- bool "Enable RF kill support in iwlagn and iwl3945 drivers"
- depends on IWLWIFI
-
config IWLWIFI_SPECTRUM_MEASUREMENT
bool "Enable Spectrum Measurement in iwlagn driver"
depends on IWLWIFI
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index d79d97ad61a..1d4e0a226fd 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -4,7 +4,6 @@ iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o
iwlcore-objs += iwl-scan.o
iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
-iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
obj-$(CONFIG_IWLAGN) += iwlagn.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index ac22f59be9e..225e5f88934 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -44,6 +44,15 @@
#include "iwl-core.h"
#include "iwl-dev.h"
+#ifdef CONFIG_IWLWIFI_DEBUG
+static const char *led_type_str[] = {
+ __stringify(IWL_LED_TRG_TX),
+ __stringify(IWL_LED_TRG_RX),
+ __stringify(IWL_LED_TRG_ASSOC),
+ __stringify(IWL_LED_TRG_RADIO),
+ NULL
+};
+#endif /* CONFIG_IWLWIFI_DEBUG */
static const struct {
u16 brightness;
@@ -61,7 +70,7 @@ static const struct {
{10, 110, 110},
{5, 130, 130},
{0, 167, 167},
- /*SOLID_ON*/
+ /* SOLID_ON */
{-1, IWL_LED_SOLID, 0}
};
@@ -143,6 +152,26 @@ static int iwl3945_led_off(struct iwl_priv *priv, int led_id)
}
/*
+ * Set led on in case of association
+ * */
+static int iwl3945_led_associate(struct iwl_priv *priv, int led_id)
+{
+ IWL_DEBUG_LED(priv, "Associated\n");
+
+ priv->allow_blinking = 1;
+ return iwl3945_led_on(priv, led_id);
+}
+/* Set Led off in case of disassociation */
+static int iwl3945_led_disassociate(struct iwl_priv *priv, int led_id)
+{
+ IWL_DEBUG_LED(priv, "Disassociated\n");
+
+ priv->allow_blinking = 0;
+
+ return 0;
+}
+
+/*
* brightness call back function for Tx/Rx LED
*/
static int iwl3945_led_associated(struct iwl_priv *priv, int led_id)
@@ -165,26 +194,21 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
struct iwl_led *led = container_of(led_cdev,
- struct iwl_led, led_dev);
+ struct iwl_led, led_dev);
struct iwl_priv *priv = led->priv;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
+ IWL_DEBUG_LED(priv, "Led type = %s brightness = %d\n",
+ led_type_str[led->type], brightness);
+
switch (brightness) {
case LED_FULL:
- if (led->type == IWL_LED_TRG_ASSOC) {
- priv->allow_blinking = 1;
- IWL_DEBUG_LED(priv, "MAC is associated\n");
- }
if (led->led_on)
led->led_on(priv, IWL_LED_LINK);
break;
case LED_OFF:
- if (led->type == IWL_LED_TRG_ASSOC) {
- priv->allow_blinking = 0;
- IWL_DEBUG_LED(priv, "MAC is disassociated\n");
- }
if (led->led_off)
led->led_off(priv, IWL_LED_LINK);
break;
@@ -197,8 +221,6 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
}
}
-
-
/*
* Register led class with the system
*/
@@ -237,12 +259,12 @@ static int iwl3945_led_register_led(struct iwl_priv *priv,
static inline u8 get_blink_rate(struct iwl_priv *priv)
{
int index;
- u64 current_tpt = priv->rxtxpackets;
- s64 tpt = current_tpt - priv->led_tpt;
+ s64 tpt = priv->rxtxpackets;
if (tpt < 0)
tpt = -tpt;
- priv->led_tpt = current_tpt;
+
+ IWL_DEBUG_LED(priv, "tpt %lld \n", (long long)tpt);
if (!priv->allow_blinking)
index = IWL_MAX_BLINK_TBL;
@@ -250,13 +272,9 @@ static inline u8 get_blink_rate(struct iwl_priv *priv)
for (index = 0; index < IWL_MAX_BLINK_TBL; index++)
if (tpt > (blink_tbl[index].brightness * IWL_1MB_RATE))
break;
- return index;
-}
-static inline int is_rf_kill(struct iwl_priv *priv)
-{
- return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
- test_bit(STATUS_RF_KILL_SW, &priv->status);
+ IWL_DEBUG_LED(priv, "LED BLINK IDX=%d\n", index);
+ return index;
}
/*
@@ -272,7 +290,7 @@ void iwl3945_led_background(struct iwl_priv *priv)
priv->last_blink_time = 0;
return;
}
- if (is_rf_kill(priv)) {
+ if (iwl_is_rfkill(priv)) {
priv->last_blink_time = 0;
return;
}
@@ -341,8 +359,8 @@ int iwl3945_led_register(struct iwl_priv *priv)
IWL_LED_TRG_ASSOC, 0, trigger);
/* for assoc always turn led on */
- priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on;
- priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on;
+ priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_associate;
+ priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_disassociate;
priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
if (ret)
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index af6b9d44477..5eb538d18a8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -38,6 +38,7 @@
#include "iwl-commands.h"
#include "iwl-3945.h"
+#include "iwl-sta.h"
#define RS_NAME "iwl-3945-rs"
@@ -683,11 +684,10 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
if (sta)
rate_mask = sta->supp_rates[sband->band];
- /* Send management frames and broadcast/multicast data using lowest
- * rate. */
+ /* Send management frames and NO_ACK data using lowest rate. */
fc = le16_to_cpu(hdr->frame_control);
if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
- is_multicast_ether_addr(hdr->addr1) ||
+ info->flags & IEEE80211_TX_CTL_NO_ACK ||
!sta || !priv_sta) {
IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
if (!rate_mask)
@@ -696,6 +696,8 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
else
info->control.rates[0].idx =
rate_lowest_index(sband, sta);
+ if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+ info->control.rates[0].count = 1;
return;
}
@@ -713,13 +715,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
!rs_sta->ibss_sta_added) {
- u8 sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
+ u8 sta_id = iwl_find_station(priv, hdr->addr1);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n",
hdr->addr1);
- sta_id = iwl3945_add_station(priv,
- hdr->addr1, 0, CMD_ASYNC);
+ sta_id = iwl_add_station(priv, hdr->addr1, false,
+ CMD_ASYNC, NULL);
}
if (sta_id != IWL_INVALID_STATION)
rs_sta->ibss_sta_added = 1;
@@ -974,7 +976,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
rcu_read_lock();
- sta = ieee80211_find_sta(hw, priv->stations_39[sta_id].sta.sta.addr);
+ sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr);
if (!sta) {
rcu_read_unlock();
return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 527525cc091..46288e72488 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -98,7 +98,6 @@ const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = {
* ... and set IWL_EVT_DISABLE to 1. */
void iwl3945_disable_events(struct iwl_priv *priv)
{
- int ret;
int i;
u32 base; /* SRAM address of event log header */
u32 disable_ptr; /* SRAM address of event-disable bitmap array */
@@ -159,26 +158,17 @@ void iwl3945_disable_events(struct iwl_priv *priv)
return;
}
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- IWL_WARN(priv, "Can not read from adapter at this time.\n");
- return;
- }
-
disable_ptr = iwl_read_targ_mem(priv, base + (4 * sizeof(u32)));
array_size = iwl_read_targ_mem(priv, base + (5 * sizeof(u32)));
- iwl_release_nic_access(priv);
if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) {
IWL_DEBUG_INFO(priv, "Disabling selected uCode log events at 0x%x\n",
disable_ptr);
- ret = iwl_grab_nic_access(priv);
for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++)
iwl_write_targ_mem(priv,
disable_ptr + (i * sizeof(u32)),
evt_disable[i]);
- iwl_release_nic_access(priv);
} else {
IWL_DEBUG_INFO(priv, "Selected uCode log events may be disabled\n");
IWL_DEBUG_INFO(priv, " by writing \"1\"s into disable bitmap\n");
@@ -779,35 +769,6 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
return ;
}
-u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *addr)
-{
- int i, start = IWL_AP_ID;
- int ret = IWL_INVALID_STATION;
- unsigned long flags;
-
- if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) ||
- (priv->iw_mode == NL80211_IFTYPE_AP))
- start = IWL_STA_ID;
-
- if (is_broadcast_ether_addr(addr))
- return priv->hw_params.bcast_sta_id;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- for (i = start; i < priv->hw_params.max_stations; i++)
- if ((priv->stations_39[i].used) &&
- (!compare_ether_addr
- (priv->stations_39[i].sta.sta.addr, addr))) {
- ret = i;
- goto out;
- }
-
- IWL_DEBUG_INFO(priv, "can not find STA %pM (total %d)\n",
- addr, priv->num_stations);
- out:
- spin_unlock_irqrestore(&priv->sta_lock, flags);
- return ret;
-}
-
/**
* iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
*
@@ -885,13 +846,13 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
{
unsigned long flags_spin;
- struct iwl3945_station_entry *station;
+ struct iwl_station_entry *station;
if (sta_id == IWL_INVALID_STATION)
return IWL_INVALID_STATION;
spin_lock_irqsave(&priv->sta_lock, flags_spin);
- station = &priv->stations_39[sta_id];
+ station = &priv->stations[sta_id];
station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
station->sta.rate_n_flags = cpu_to_le16(tx_rate);
@@ -899,8 +860,7 @@ u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
- iwl_send_add_sta(priv,
- (struct iwl_addsta_cmd *)&station->sta, flags);
+ iwl_send_add_sta(priv, &station->sta, flags);
IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n",
sta_id, tx_rate);
return sta_id;
@@ -908,55 +868,30 @@ u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
{
- int ret;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
- }
-
if (src == IWL_PWR_SRC_VAUX) {
if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) {
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
~APMG_PS_CTRL_MSK_PWR_SRC);
- iwl_release_nic_access(priv);
iwl_poll_bit(priv, CSR_GPIO_IN,
CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
CSR_GPIO_IN_BIT_AUX_POWER, 5000);
- } else {
- iwl_release_nic_access(priv);
}
} else {
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
~APMG_PS_CTRL_MSK_PWR_SRC);
- iwl_release_nic_access(priv);
iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */
}
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
+ return 0;
}
static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
{
- int rc;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
-
iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->dma_addr);
iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma);
iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0);
@@ -973,23 +908,11 @@ static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
/* fake read to flush all prev I/O */
iwl_read_direct32(priv, FH39_RSSR_CTRL);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
return 0;
}
static int iwl3945_tx_reset(struct iwl_priv *priv)
{
- int rc;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
/* bypass mode */
iwl_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
@@ -1017,8 +940,6 @@ static int iwl3945_tx_reset(struct iwl_priv *priv)
FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH |
FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
@@ -1061,7 +982,7 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
static int iwl3945_apm_init(struct iwl_priv *priv)
{
- int ret = 0;
+ int ret;
iwl_power_initialize(priv);
@@ -1083,10 +1004,6 @@ static int iwl3945_apm_init(struct iwl_priv *priv)
goto out;
}
- ret = iwl_grab_nic_access(priv);
- if (ret)
- goto out;
-
/* enable DMA */
iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
APMG_CLK_VAL_BSM_CLK_RQT);
@@ -1097,7 +1014,6 @@ static int iwl3945_apm_init(struct iwl_priv *priv)
iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
- iwl_release_nic_access(priv);
out:
return ret;
}
@@ -1110,6 +1026,11 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
spin_lock_irqsave(&priv->lock, flags);
+ /* Determine HW type */
+ pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
+
+ IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
+
if (rev_id & PCI_CFG_REV_ID_BIT_RTP)
IWL_DEBUG_INFO(priv, "RTP type \n");
else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
@@ -1163,7 +1084,6 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
int iwl3945_hw_nic_init(struct iwl_priv *priv)
{
- u8 rev_id;
int rc;
unsigned long flags;
struct iwl_rx_queue *rxq = &priv->rxq;
@@ -1172,12 +1092,6 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
priv->cfg->ops->lib->apm_ops.init(priv);
spin_unlock_irqrestore(&priv->lock, flags);
- /* Determine HW type */
- rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
- if (rc)
- return rc;
- IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
-
rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
if (rc)
return rc;
@@ -1198,22 +1112,13 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
iwl3945_rx_init(priv, rxq);
- spin_lock_irqsave(&priv->lock, flags);
/* Look at using this instead:
rxq->need_update = 1;
iwl_rx_queue_update_write_ptr(priv, rxq);
*/
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
iwl_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7);
- iwl_release_nic_access(priv);
-
- spin_unlock_irqrestore(&priv->lock, flags);
rc = iwl3945_txq_ctx_reset(priv);
if (rc)
@@ -1245,14 +1150,6 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
{
int txq_id;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- if (iwl_grab_nic_access(priv)) {
- spin_unlock_irqrestore(&priv->lock, flags);
- iwl3945_hw_txq_ctx_free(priv);
- return;
- }
/* stop SCD */
iwl_write_prph(priv, ALM_SCD_MODE_REG, 0);
@@ -1265,9 +1162,6 @@ void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
1000);
}
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
iwl3945_hw_txq_ctx_free(priv);
}
@@ -1312,12 +1206,8 @@ static void iwl3945_apm_stop(struct iwl_priv *priv)
static int iwl3945_apm_reset(struct iwl_priv *priv)
{
- int rc;
- unsigned long flags;
-
iwl3945_apm_stop_master(priv);
- spin_lock_irqsave(&priv->lock, flags);
iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
udelay(10);
@@ -1327,36 +1217,31 @@ static int iwl3945_apm_reset(struct iwl_priv *priv)
iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
- rc = iwl_grab_nic_access(priv);
- if (!rc) {
- iwl_write_prph(priv, APMG_CLK_CTRL_REG,
- APMG_CLK_VAL_BSM_CLK_RQT);
+ iwl_write_prph(priv, APMG_CLK_CTRL_REG,
+ APMG_CLK_VAL_BSM_CLK_RQT);
- iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
- iwl_write_prph(priv, APMG_RTC_INT_STT_REG,
+ iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
+ iwl_write_prph(priv, APMG_RTC_INT_STT_REG,
0xFFFFFFFF);
- /* enable DMA */
- iwl_write_prph(priv, APMG_CLK_EN_REG,
- APMG_CLK_VAL_DMA_CLK_RQT |
- APMG_CLK_VAL_BSM_CLK_RQT);
- udelay(10);
+ /* enable DMA */
+ iwl_write_prph(priv, APMG_CLK_EN_REG,
+ APMG_CLK_VAL_DMA_CLK_RQT |
+ APMG_CLK_VAL_BSM_CLK_RQT);
+ udelay(10);
- iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
+ iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_RESET_REQ);
- udelay(5);
- iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
+ udelay(5);
+ iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_RESET_REQ);
- iwl_release_nic_access(priv);
- }
/* Clear the 'host command active' bit... */
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
+ return 0;
}
/**
@@ -1964,6 +1849,193 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
return 0;
}
+static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
+{
+ int rc = 0;
+ struct iwl_rx_packet *res = NULL;
+ struct iwl3945_rxon_assoc_cmd rxon_assoc;
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_RXON_ASSOC,
+ .len = sizeof(rxon_assoc),
+ .meta.flags = CMD_WANT_SKB,
+ .data = &rxon_assoc,
+ };
+ const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
+ const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
+
+ if ((rxon1->flags == rxon2->flags) &&
+ (rxon1->filter_flags == rxon2->filter_flags) &&
+ (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
+ (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
+ IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
+ return 0;
+ }
+
+ rxon_assoc.flags = priv->staging_rxon.flags;
+ rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
+ rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
+ rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
+ rxon_assoc.reserved = 0;
+
+ rc = iwl_send_cmd_sync(priv, &cmd);
+ if (rc)
+ return rc;
+
+ res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+ if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
+ IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
+ rc = -EIO;
+ }
+
+ priv->alloc_rxb_skb--;
+ dev_kfree_skb_any(cmd.meta.u.skb);
+
+ return rc;
+}
+
+/**
+ * iwl3945_commit_rxon - commit staging_rxon to hardware
+ *
+ * The RXON command in staging_rxon is committed to the hardware and
+ * the active_rxon structure is updated with the new data. This
+ * function correctly transitions out of the RXON_ASSOC_MSK state if
+ * a HW tune is required based on the RXON structure changes.
+ */
+static int iwl3945_commit_rxon(struct iwl_priv *priv)
+{
+ /* cast away the const for active_rxon in this function */
+ struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
+ struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
+ int rc = 0;
+ bool new_assoc =
+ !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
+
+ if (!iwl_is_alive(priv))
+ return -1;
+
+ /* always get timestamp with Rx frame */
+ staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;
+
+ /* select antenna */
+ staging_rxon->flags &=
+ ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
+ staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
+
+ rc = iwl_check_rxon_cmd(priv);
+ if (rc) {
+ IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
+ return -EINVAL;
+ }
+
+ /* If we don't need to send a full RXON, we can use
+ * iwl3945_rxon_assoc_cmd which is used to reconfigure filter
+ * and other flags for the current radio configuration. */
+ if (!iwl_full_rxon_required(priv)) {
+ rc = iwl_send_rxon_assoc(priv);
+ if (rc) {
+ IWL_ERR(priv, "Error setting RXON_ASSOC "
+ "configuration (%d).\n", rc);
+ return rc;
+ }
+
+ memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
+
+ return 0;
+ }
+
+ /* If we are currently associated and the new config requires
+ * an RXON_ASSOC and the new config wants the associated mask enabled,
+ * we must clear the associated from the active configuration
+ * before we apply the new config */
+ if (iwl_is_associated(priv) && new_assoc) {
+ IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
+ active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+
+ /*
+ * reserved4 and 5 could have been filled by the iwlcore code.
+ * Let's clear them before pushing to the 3945.
+ */
+ active_rxon->reserved4 = 0;
+ active_rxon->reserved5 = 0;
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
+ sizeof(struct iwl3945_rxon_cmd),
+ &priv->active_rxon);
+
+ /* If the mask clearing failed then we set
+ * active_rxon back to what it was previously */
+ if (rc) {
+ active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
+ IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
+ "configuration (%d).\n", rc);
+ return rc;
+ }
+ }
+
+ IWL_DEBUG_INFO(priv, "Sending RXON\n"
+ "* with%s RXON_FILTER_ASSOC_MSK\n"
+ "* channel = %d\n"
+ "* bssid = %pM\n",
+ (new_assoc ? "" : "out"),
+ le16_to_cpu(staging_rxon->channel),
+ staging_rxon->bssid_addr);
+
+ /*
+ * reserved4 and 5 could have been filled by the iwlcore code.
+ * Let's clear them before pushing to the 3945.
+ */
+ staging_rxon->reserved4 = 0;
+ staging_rxon->reserved5 = 0;
+
+ iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
+
+ /* Apply the new configuration */
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
+ sizeof(struct iwl3945_rxon_cmd),
+ staging_rxon);
+ if (rc) {
+ IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
+ return rc;
+ }
+
+ memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
+
+ iwl_clear_stations_table(priv);
+
+ /* If we issue a new RXON command which required a tune then we must
+ * send a new TXPOWER command or we won't be able to Tx any frames */
+ rc = priv->cfg->ops->lib->send_tx_power(priv);
+ if (rc) {
+ IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
+ return rc;
+ }
+
+ /* Add the broadcast address so we can send broadcast frames */
+ if (iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL) ==
+ IWL_INVALID_STATION) {
+ IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
+ return -EIO;
+ }
+
+ /* If we have set the ASSOC_MSK and we are in BSS mode then
+ * add the IWL_AP_ID to the station rate table */
+ if (iwl_is_associated(priv) &&
+ (priv->iw_mode == NL80211_IFTYPE_STATION))
+ if (iwl_add_station(priv, priv->active_rxon.bssid_addr,
+ true, CMD_SYNC, NULL) == IWL_INVALID_STATION) {
+ IWL_ERR(priv, "Error adding AP address for transmit\n");
+ return -EIO;
+ }
+
+ /* Init the hardware's rate fallback order based on the band */
+ rc = iwl3945_init_hw_rate_table(priv);
+ if (rc) {
+ IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
+ return -EIO;
+ }
+
+ return 0;
+}
+
/* will add 3945 channel switch cmd handling later */
int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel)
{
@@ -2314,14 +2386,6 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
int iwl3945_hw_rxq_stop(struct iwl_priv *priv)
{
int rc;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 0);
rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS,
@@ -2329,28 +2393,17 @@ int iwl3945_hw_rxq_stop(struct iwl_priv *priv)
if (rc < 0)
IWL_ERR(priv, "Can't stop Rx DMA.\n");
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
return 0;
}
int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
{
- int rc;
- unsigned long flags;
int txq_id = txq->q.id;
struct iwl3945_shared *shared_data = priv->shared_virt;
shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr);
- spin_lock_irqsave(&priv->lock, flags);
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
iwl_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0);
iwl_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0);
@@ -2360,11 +2413,9 @@ int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |
FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL |
FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE);
- iwl_release_nic_access(priv);
/* fake read to flush all prev. writes */
iwl_read32(priv, FH39_TSSR_CBB_BASE);
- spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
@@ -2384,13 +2435,25 @@ static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len)
}
}
+
static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
{
- u16 size = (u16)sizeof(struct iwl3945_addsta_cmd);
- memcpy(data, cmd, size);
- return size;
+ struct iwl3945_addsta_cmd *addsta = (struct iwl3945_addsta_cmd *)data;
+ addsta->mode = cmd->mode;
+ memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify));
+ memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo));
+ addsta->station_flags = cmd->station_flags;
+ addsta->station_flags_msk = cmd->station_flags_msk;
+ addsta->tid_disable_tx = cpu_to_le16(0);
+ addsta->rate_n_flags = cmd->rate_n_flags;
+ addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;
+ addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;
+ addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;
+
+ return (u16)sizeof(struct iwl3945_addsta_cmd);
}
+
/**
* iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
*/
@@ -2672,10 +2735,6 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
inst_len = priv->ucode_init.len;
data_len = priv->ucode_init_data.len;
- rc = iwl_grab_nic_access(priv);
- if (rc)
- return rc;
-
iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
@@ -2689,10 +2748,8 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
le32_to_cpu(*image));
rc = iwl3945_verify_bsm(priv);
- if (rc) {
- iwl_release_nic_access(priv);
+ if (rc)
return rc;
- }
/* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
@@ -2724,11 +2781,14 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
iwl_write_prph(priv, BSM_WR_CTRL_REG,
BSM_WR_CTRL_REG_BIT_START_EN);
- iwl_release_nic_access(priv);
-
return 0;
}
+static struct iwl_hcmd_ops iwl3945_hcmd = {
+ .rxon_assoc = iwl3945_send_rxon_assoc,
+ .commit_rxon = iwl3945_commit_rxon,
+};
+
static struct iwl_lib_ops iwl3945_lib = {
.txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl3945_hw_txq_free_tfd,
@@ -2758,6 +2818,9 @@ static struct iwl_lib_ops iwl3945_lib = {
},
.send_tx_power = iwl3945_send_tx_power,
.is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr,
+ .post_associate = iwl3945_post_associate,
+ .isr = iwl_isr_legacy,
+ .config_ap = iwl3945_config_ap,
};
static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
@@ -2767,6 +2830,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
static struct iwl_ops iwl3945_ops = {
.lib = &iwl3945_lib,
+ .hcmd = &iwl3945_hcmd,
.utils = &iwl3945_hcmd_utils,
};
@@ -2779,7 +2843,8 @@ static struct iwl_cfg iwl3945_bg_cfg = {
.eeprom_size = IWL3945_EEPROM_IMG_SIZE,
.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
.ops = &iwl3945_ops,
- .mod_params = &iwl3945_mod_params
+ .mod_params = &iwl3945_mod_params,
+ .use_isr_legacy = true
};
static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2791,7 +2856,8 @@ static struct iwl_cfg iwl3945_abg_cfg = {
.eeprom_size = IWL3945_EEPROM_IMG_SIZE,
.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
.ops = &iwl3945_ops,
- .mod_params = &iwl3945_mod_params
+ .mod_params = &iwl3945_mod_params,
+ .use_isr_legacy = true
};
struct pci_device_id iwl3945_hw_card_ids[] = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 55188844657..fbb3a573463 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -36,10 +36,6 @@
#include <linux/kernel.h>
#include <net/ieee80211_radiotap.h>
-/*used for rfkill*/
-#include <linux/rfkill.h>
-#include <linux/input.h>
-
/* Hardware specific file defines the PCI IDs table for that hardware module */
extern struct pci_device_id iwl3945_hw_card_ids[];
@@ -155,14 +151,12 @@ struct iwl3945_frame {
#define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */
#define STATUS_INT_ENABLED 2
#define STATUS_RF_KILL_HW 3
-#define STATUS_RF_KILL_SW 4
#define STATUS_INIT 5
#define STATUS_ALIVE 6
#define STATUS_READY 7
#define STATUS_TEMPERATURE 8
#define STATUS_GEO_CONFIGURED 9
#define STATUS_EXIT_PENDING 10
-#define STATUS_IN_SUSPEND 11
#define STATUS_STATISTICS 12
#define STATUS_SCANNING 13
#define STATUS_SCAN_ABORTING 14
@@ -203,11 +197,6 @@ struct iwl3945_ibss_seq {
* for use by iwl-*.c
*
*****************************************************************************/
-struct iwl3945_addsta_cmd;
-extern int iwl3945_send_add_station(struct iwl_priv *priv,
- struct iwl3945_addsta_cmd *sta, u8 flags);
-extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid,
- int is_ap, u8 flags);
extern int iwl3945_power_init_handle(struct iwl_priv *priv);
extern int iwl3945_eeprom_init(struct iwl_priv *priv);
extern int iwl3945_calc_db_from_ratio(int sig_ratio);
@@ -278,6 +267,8 @@ extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
extern void iwl3945_disable_events(struct iwl_priv *priv);
extern int iwl4965_get_temperature(const struct iwl_priv *priv);
+extern void iwl3945_post_associate(struct iwl_priv *priv);
+extern void iwl3945_config_ap(struct iwl_priv *priv);
/**
* iwl3945_hw_find_station - Find station id for a given BSSID
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 847a6220c5e..8f3d4bc6a03 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -163,10 +163,6 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
inst_len = priv->ucode_init.len;
data_len = priv->ucode_init_data.len;
- ret = iwl_grab_nic_access(priv);
- if (ret)
- return ret;
-
iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
@@ -179,10 +175,8 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
_iwl_write_prph(priv, reg_offset, le32_to_cpu(*image));
ret = iwl4965_verify_bsm(priv);
- if (ret) {
- iwl_release_nic_access(priv);
+ if (ret)
return ret;
- }
/* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
@@ -211,7 +205,6 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
* (e.g. when powering back up after power-save shutdown) */
iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN);
- iwl_release_nic_access(priv);
return 0;
}
@@ -229,20 +222,12 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
{
dma_addr_t pinst;
dma_addr_t pdata;
- unsigned long flags;
int ret = 0;
/* bits 35:4 for 4965 */
pinst = priv->ucode_code.p_addr >> 4;
pdata = priv->ucode_data_backup.p_addr >> 4;
- spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
- }
-
/* Tell bootstrap uCode where to find image to load */
iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
@@ -253,10 +238,6 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
* that all new ptr/size info is in place */
iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
priv->ucode_code.len | BSM_DRAM_INST_LOAD);
- iwl_release_nic_access(priv);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n");
return ret;
@@ -312,10 +293,12 @@ restart:
queue_work(priv->workqueue, &priv->restart);
}
-static int is_fat_channel(__le32 rxon_flags)
+static bool is_fat_channel(__le32 rxon_flags)
{
- return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) ||
- (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK);
+ int chan_mod = le32_to_cpu(rxon_flags & RXON_FLG_CHANNEL_MODE_MSK)
+ >> RXON_FLG_CHANNEL_MODE_POS;
+ return ((chan_mod == CHANNEL_MODE_PURE_40) ||
+ (chan_mod == CHANNEL_MODE_MIXED));
}
/*
@@ -358,10 +341,6 @@ static int iwl4965_apm_init(struct iwl_priv *priv)
goto out;
}
- ret = iwl_grab_nic_access(priv);
- if (ret)
- goto out;
-
/* enable DMA */
iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
APMG_CLK_VAL_BSM_CLK_RQT);
@@ -372,7 +351,6 @@ static int iwl4965_apm_init(struct iwl_priv *priv)
iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
- iwl_release_nic_access(priv);
out:
return ret;
}
@@ -454,11 +432,9 @@ static void iwl4965_apm_stop(struct iwl_priv *priv)
static int iwl4965_apm_reset(struct iwl_priv *priv)
{
int ret = 0;
- unsigned long flags;
iwl4965_apm_stop_master(priv);
- spin_lock_irqsave(&priv->lock, flags);
iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
@@ -475,9 +451,6 @@ static int iwl4965_apm_reset(struct iwl_priv *priv)
udelay(10);
- ret = iwl_grab_nic_access(priv);
- if (ret)
- goto out;
/* Enable DMA and BSM Clock */
iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT |
APMG_CLK_VAL_BSM_CLK_RQT);
@@ -488,14 +461,10 @@ static int iwl4965_apm_reset(struct iwl_priv *priv)
iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
- iwl_release_nic_access(priv);
-
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
out:
- spin_unlock_irqrestore(&priv->lock, flags);
-
return ret;
}
@@ -681,18 +650,11 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
{
u32 a;
unsigned long flags;
- int ret;
int i, chan;
u32 reg_val;
spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
- }
-
/* Clear 4965's internal Tx Scheduler data base */
priv->scd_base_addr = iwl_read_prph(priv, IWL49_SCD_SRAM_BASE_ADDR);
a = priv->scd_base_addr + IWL49_SCD_CONTEXT_DATA_OFFSET;
@@ -759,10 +721,9 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
}
- iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
+ return 0;
}
static struct iwl_sensitivity_ranges iwl4965_sensitivity = {
@@ -788,6 +749,12 @@ static struct iwl_sensitivity_ranges iwl4965_sensitivity = {
.nrg_th_ofdm = 100,
};
+static void iwl4965_set_ct_threshold(struct iwl_priv *priv)
+{
+ /* want Kelvin */
+ priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
+}
+
/**
* iwl4965_hw_set_hw_params
*
@@ -822,7 +789,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.rx_chains_num = 2;
priv->hw_params.valid_tx_ant = ANT_A | ANT_B;
priv->hw_params.valid_rx_ant = ANT_A | ANT_B;
- priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
+ if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
+ priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
priv->hw_params.sens = &iwl4965_sensitivity;
@@ -1524,7 +1492,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
struct iwl4965_txpowertable_cmd cmd = { 0 };
int ret;
u8 band = 0;
- u8 is_fat = 0;
+ bool is_fat = false;
u8 ctrl_chan_high = 0;
if (test_bit(STATUS_SCANNING, &priv->status)) {
@@ -1602,7 +1570,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
{
int rc;
u8 band = 0;
- u8 is_fat = 0;
+ bool is_fat = false;
u8 ctrl_chan_high = 0;
struct iwl4965_channel_switch_cmd cmd = { 0 };
const struct iwl_channel_info *ch_info;
@@ -1833,8 +1801,6 @@ static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv,
static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
u16 ssn_idx, u8 tx_fifo)
{
- int ret = 0;
-
if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
(IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
IWL_WARN(priv,
@@ -1844,10 +1810,6 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
return -EINVAL;
}
- ret = iwl_grab_nic_access(priv);
- if (ret)
- return ret;
-
iwl4965_tx_queue_stop_scheduler(priv, txq_id);
iwl_clear_bits_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, (1 << txq_id));
@@ -1861,8 +1823,6 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
iwl_txq_ctx_deactivate(priv, txq_id);
iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
- iwl_release_nic_access(priv);
-
return 0;
}
@@ -1904,7 +1864,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
int tx_fifo, int sta_id, int tid, u16 ssn_idx)
{
unsigned long flags;
- int ret;
u16 ra_tid;
if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
@@ -1922,11 +1881,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
- }
/* Stop this Tx queue before configuring it */
iwl4965_tx_queue_stop_scheduler(priv, txq_id);
@@ -1959,7 +1913,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
/* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
- iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
@@ -2268,9 +2221,10 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
cancel_work_sync(&priv->txpower_work);
}
-
static struct iwl_hcmd_ops iwl4965_hcmd = {
.rxon_assoc = iwl4965_send_rxon_assoc,
+ .commit_rxon = iwl_commit_rxon,
+ .set_rxon_chain = iwl_set_rxon_chain,
};
static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
@@ -2323,7 +2277,13 @@ static struct iwl_lib_ops iwl4965_lib = {
},
.send_tx_power = iwl4965_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
- .temperature = iwl4965_temperature_calib,
+ .post_associate = iwl_post_associate,
+ .config_ap = iwl_config_ap,
+ .isr = iwl_isr_legacy,
+ .temp_ops = {
+ .temperature = iwl4965_temperature_calib,
+ .set_ct_kill = iwl4965_set_ct_threshold,
+ },
};
static struct iwl_ops iwl4965_ops = {
@@ -2343,6 +2303,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
.eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
.ops = &iwl4965_ops,
.mod_params = &iwl4965_mod_params,
+ .use_isr_legacy = true
};
/* Module firmware */
@@ -2350,8 +2311,6 @@ MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX));
module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444);
MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(disable, iwl4965_mod_params.disable, int, 0444);
-MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444);
MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
module_param_named(debug, iwl4965_mod_params.debug, uint, 0444);
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 15cac70e36e..4ef6804a455 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -87,6 +87,18 @@
#define IWL50_NUM_AMPDU_QUEUES 10
#define IWL50_FIRST_AMPDU_QUEUE 10
+/* 5150 only */
+#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5)
+
+static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
+{
+ u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv,
+ EEPROM_5000_TEMPERATURE);
+ /* offset = temperature - voltage / coef */
+ s32 offset = (s32)(temp_calib[0] - temp_calib[1] / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
+ return offset;
+}
+
/* Fixed (non-configurable) rx data from phy */
/**
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 9452461ce86..b3c648ce8c7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -124,10 +124,6 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
return ret;
}
- ret = iwl_grab_nic_access(priv);
- if (ret)
- return ret;
-
/* enable DMA */
iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
@@ -137,8 +133,6 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
- iwl_release_nic_access(priv);
-
return ret;
}
@@ -165,12 +159,9 @@ static void iwl5000_apm_stop(struct iwl_priv *priv)
static int iwl5000_apm_reset(struct iwl_priv *priv)
{
int ret = 0;
- unsigned long flags;
iwl5000_apm_stop_master(priv);
- spin_lock_irqsave(&priv->lock, flags);
-
iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
udelay(10);
@@ -193,10 +184,6 @@ static int iwl5000_apm_reset(struct iwl_priv *priv)
goto out;
}
- ret = iwl_grab_nic_access(priv);
- if (ret)
- goto out;
-
/* enable DMA */
iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
@@ -205,11 +192,7 @@ static int iwl5000_apm_reset(struct iwl_priv *priv)
/* disable L1-Active */
iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
-
- iwl_release_nic_access(priv);
-
out:
- spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}
@@ -252,11 +235,9 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
* (PCIe power is lost before PERST# is asserted),
* causing ME FW to lose ownership and not being able to obtain it back.
*/
- iwl_grab_nic_access(priv);
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
- iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
}
@@ -434,15 +415,19 @@ static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
return &priv->eeprom[address];
}
-static s32 iwl5150_get_ct_threshold(struct iwl_priv *priv)
+static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
{
- const s32 volt2temp_coef = -5;
- u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv,
- EEPROM_5000_TEMPERATURE);
- /* offset = temperate - voltage / coef */
- s32 offset = temp_calib[0] - temp_calib[1] / volt2temp_coef;
- s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD) - offset;
- return threshold * volt2temp_coef;
+ const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
+ s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD) -
+ iwl_temp_calib_to_offset(priv);
+
+ priv->hw_params.ct_kill_threshold = threshold * volt2temp_coef;
+}
+
+static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
+{
+ /* want Celsius */
+ priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
}
/*
@@ -533,19 +518,9 @@ static int iwl5000_load_section(struct iwl_priv *priv,
struct fw_desc *image,
u32 dst_addr)
{
- int ret = 0;
- unsigned long flags;
-
dma_addr_t phy_addr = image->p_addr;
u32 byte_cnt = image->len;
- spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
- }
-
iwl_write_direct32(priv,
FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
@@ -574,8 +549,6 @@ static int iwl5000_load_section(struct iwl_priv *priv,
FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
@@ -736,18 +709,11 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
{
u32 a;
unsigned long flags;
- int ret;
int i, chan;
u32 reg_val;
spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
- }
-
priv->scd_base_addr = iwl_read_prph(priv, IWL50_SCD_SRAM_BASE_ADDR);
a = priv->scd_base_addr + IWL50_SCD_CONTEXT_DATA_OFFSET;
for (; a < priv->scd_base_addr + IWL50_SCD_TX_STTS_BITMAP_OFFSET;
@@ -815,7 +781,6 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
iwl_txq_ctx_activate(priv, 8);
iwl_txq_ctx_activate(priv, 9);
- iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -868,17 +833,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
- switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
- case CSR_HW_REV_TYPE_5150:
- /* 5150 wants in Kelvin */
- priv->hw_params.ct_kill_threshold =
- iwl5150_get_ct_threshold(priv);
- break;
- default:
- /* all others want Celsius */
- priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
- break;
- }
+ if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
+ priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
/* Set initial calibration set */
switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
@@ -900,7 +856,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
break;
}
-
return 0;
}
@@ -1006,7 +961,6 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
int tx_fifo, int sta_id, int tid, u16 ssn_idx)
{
unsigned long flags;
- int ret;
u16 ra_tid;
if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
@@ -1024,11 +978,6 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
- }
/* Stop this Tx queue before configuring it */
iwl5000_tx_queue_stop_scheduler(priv, txq_id);
@@ -1064,7 +1013,6 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
/* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
- iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
@@ -1073,8 +1021,6 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
u16 ssn_idx, u8 tx_fifo)
{
- int ret;
-
if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
(IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
IWL_ERR(priv,
@@ -1084,10 +1030,6 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
return -EINVAL;
}
- ret = iwl_grab_nic_access(priv);
- if (ret)
- return ret;
-
iwl5000_tx_queue_stop_scheduler(priv, txq_id);
iwl_clear_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1 << txq_id));
@@ -1101,15 +1043,16 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
iwl_txq_ctx_deactivate(priv, txq_id);
iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
- iwl_release_nic_access(priv);
-
return 0;
}
u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
{
u16 size = (u16)sizeof(struct iwl_addsta_cmd);
- memcpy(data, cmd, size);
+ struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data;
+ memcpy(addsta, cmd, size);
+ /* resrved in 5000 */
+ addsta->rate_n_flags = cpu_to_le16(0);
return size;
}
@@ -1434,6 +1377,17 @@ static void iwl5000_temperature(struct iwl_priv *priv)
priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
}
+static void iwl5150_temperature(struct iwl_priv *priv)
+{
+ u32 vt = 0;
+ s32 offset = iwl_temp_calib_to_offset(priv);
+
+ vt = le32_to_cpu(priv->statistics.general.temperature);
+ vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
+ /* now vt hold the temperature in Kelvin */
+ priv->temperature = KELVIN_TO_CELSIUS(vt);
+}
+
/* Calc max signal level (dBm) among 3 possible receivers */
int iwl5000_calc_rssi(struct iwl_priv *priv,
struct iwl_rx_phy_res *rx_resp)
@@ -1474,6 +1428,8 @@ int iwl5000_calc_rssi(struct iwl_priv *priv,
struct iwl_hcmd_ops iwl5000_hcmd = {
.rxon_assoc = iwl5000_send_rxon_assoc,
+ .commit_rxon = iwl_commit_rxon,
+ .set_rxon_chain = iwl_set_rxon_chain,
};
struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
@@ -1502,7 +1458,6 @@ struct iwl_lib_ops iwl5000_lib = {
.init_alive_start = iwl5000_init_alive_start,
.alive_notify = iwl5000_alive_notify,
.send_tx_power = iwl5000_send_tx_power,
- .temperature = iwl5000_temperature,
.update_chain_flags = iwl_update_chain_flags,
.apm_ops = {
.init = iwl5000_apm_init,
@@ -1527,6 +1482,63 @@ struct iwl_lib_ops iwl5000_lib = {
.calib_version = iwl5000_eeprom_calib_version,
.query_addr = iwl5000_eeprom_query_addr,
},
+ .post_associate = iwl_post_associate,
+ .isr = iwl_isr_ict,
+ .config_ap = iwl_config_ap,
+ .temp_ops = {
+ .temperature = iwl5000_temperature,
+ .set_ct_kill = iwl5000_set_ct_threshold,
+ },
+};
+
+static struct iwl_lib_ops iwl5150_lib = {
+ .set_hw_params = iwl5000_hw_set_hw_params,
+ .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
+ .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
+ .txq_set_sched = iwl5000_txq_set_sched,
+ .txq_agg_enable = iwl5000_txq_agg_enable,
+ .txq_agg_disable = iwl5000_txq_agg_disable,
+ .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
+ .txq_free_tfd = iwl_hw_txq_free_tfd,
+ .txq_init = iwl_hw_tx_queue_init,
+ .rx_handler_setup = iwl5000_rx_handler_setup,
+ .setup_deferred_work = iwl5000_setup_deferred_work,
+ .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
+ .load_ucode = iwl5000_load_ucode,
+ .init_alive_start = iwl5000_init_alive_start,
+ .alive_notify = iwl5000_alive_notify,
+ .send_tx_power = iwl5000_send_tx_power,
+ .update_chain_flags = iwl_update_chain_flags,
+ .apm_ops = {
+ .init = iwl5000_apm_init,
+ .reset = iwl5000_apm_reset,
+ .stop = iwl5000_apm_stop,
+ .config = iwl5000_nic_config,
+ .set_pwr_src = iwl_set_pwr_src,
+ },
+ .eeprom_ops = {
+ .regulatory_bands = {
+ EEPROM_5000_REG_BAND_1_CHANNELS,
+ EEPROM_5000_REG_BAND_2_CHANNELS,
+ EEPROM_5000_REG_BAND_3_CHANNELS,
+ EEPROM_5000_REG_BAND_4_CHANNELS,
+ EEPROM_5000_REG_BAND_5_CHANNELS,
+ EEPROM_5000_REG_BAND_24_FAT_CHANNELS,
+ EEPROM_5000_REG_BAND_52_FAT_CHANNELS
+ },
+ .verify_signature = iwlcore_eeprom_verify_signature,
+ .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
+ .release_semaphore = iwlcore_eeprom_release_semaphore,
+ .calib_version = iwl5000_eeprom_calib_version,
+ .query_addr = iwl5000_eeprom_query_addr,
+ },
+ .post_associate = iwl_post_associate,
+ .isr = iwl_isr_ict,
+ .config_ap = iwl_config_ap,
+ .temp_ops = {
+ .temperature = iwl5150_temperature,
+ .set_ct_kill = iwl5150_set_ct_threshold,
+ },
};
struct iwl_ops iwl5000_ops = {
@@ -1535,6 +1547,12 @@ struct iwl_ops iwl5000_ops = {
.utils = &iwl5000_hcmd_utils,
};
+static struct iwl_ops iwl5150_ops = {
+ .lib = &iwl5150_lib,
+ .hcmd = &iwl5000_hcmd,
+ .utils = &iwl5000_hcmd_utils,
+};
+
struct iwl_mod_params iwl50_mod_params = {
.num_of_queues = IWL50_NUM_QUEUES,
.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
@@ -1630,7 +1648,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
.ucode_api_max = IWL5150_UCODE_API_MAX,
.ucode_api_min = IWL5150_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl5000_ops,
+ .ops = &iwl5150_ops,
.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
@@ -1643,9 +1661,6 @@ struct iwl_cfg iwl5150_agn_cfg = {
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
-module_param_named(disable50, iwl50_mod_params.disable, int, 0444);
-MODULE_PARM_DESC(disable50,
- "manually disable the 50XX radio (default 0 [radio on])");
module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, 0444);
MODULE_PARM_DESC(swcrypto50,
"using software crypto engine (default 0 [hardware])\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index cab7842a73a..ff20e5048a5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -52,7 +52,7 @@
/* max allowed rate miss before sync LQ cmd */
#define IWL_MISSED_RATE_MAX 15
/* max time to accum history 2 seconds */
-#define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ)
+#define IWL_RATE_SCALE_FLUSH_INTVL (3*HZ)
static u8 rs_ht_to_legacy[] = {
IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
@@ -100,6 +100,7 @@ struct iwl_scale_tbl_info {
u8 is_fat; /* 1 = 40 MHz channel width */
u8 is_dup; /* 1 = duplicated data streams */
u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
+ u8 max_search; /* maximun number of tables we can search */
s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
u32 current_rate; /* rate_n_flags, uCode API format */
struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
@@ -135,7 +136,7 @@ struct iwl_lq_sta {
u32 table_count;
u32 total_failed; /* total failed frames, any/all rates */
u32 total_success; /* total successful frames, any/all rates */
- u32 flush_timer; /* time staying in mode before new search */
+ u64 flush_timer; /* time staying in mode before new search */
u8 action_counter; /* # mode-switch actions tried */
u8 is_green;
@@ -160,6 +161,7 @@ struct iwl_lq_sta {
#ifdef CONFIG_MAC80211_DEBUGFS
struct dentry *rs_sta_dbgfs_scale_table_file;
struct dentry *rs_sta_dbgfs_stats_table_file;
+ struct dentry *rs_sta_dbgfs_rate_scale_data_file;
struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
u32 dbg_fixed_rate;
#endif
@@ -167,10 +169,12 @@ struct iwl_lq_sta {
/* used to be in sta_info */
int last_txrate_idx;
+ /* last tx rate_n_flags */
+ u32 last_rate_n_flags;
};
static void rs_rate_scale_perform(struct iwl_priv *priv,
- struct ieee80211_hdr *hdr,
+ struct sk_buff *skb,
struct ieee80211_sta *sta,
struct iwl_lq_sta *lq_sta);
static void rs_fill_link_cmd(const struct iwl_priv *priv,
@@ -191,7 +195,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits
* "G" is the only table that supports CCK (the first 4 rates).
*/
-/*FIXME:RS:need to separate tables for MIMO2/MIMO3*/
+
static s32 expected_tpt_A[IWL_RATE_COUNT] = {
0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186
};
@@ -208,11 +212,11 @@ static s32 expected_tpt_siso20MHzSGI[IWL_RATE_COUNT] = {
0, 0, 0, 0, 46, 46, 82, 110, 132, 168, 192, 202, 211
};
-static s32 expected_tpt_mimo20MHz[IWL_RATE_COUNT] = {
+static s32 expected_tpt_mimo2_20MHz[IWL_RATE_COUNT] = {
0, 0, 0, 0, 74, 74, 123, 155, 179, 214, 236, 244, 251
};
-static s32 expected_tpt_mimo20MHzSGI[IWL_RATE_COUNT] = {
+static s32 expected_tpt_mimo2_20MHzSGI[IWL_RATE_COUNT] = {
0, 0, 0, 0, 81, 81, 131, 164, 188, 222, 243, 251, 257
};
@@ -224,14 +228,50 @@ static s32 expected_tpt_siso40MHzSGI[IWL_RATE_COUNT] = {
0, 0, 0, 0, 83, 83, 135, 169, 193, 229, 250, 257, 264
};
-static s32 expected_tpt_mimo40MHz[IWL_RATE_COUNT] = {
+static s32 expected_tpt_mimo2_40MHz[IWL_RATE_COUNT] = {
0, 0, 0, 0, 123, 123, 182, 214, 235, 264, 279, 285, 289
};
-static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = {
+static s32 expected_tpt_mimo2_40MHzSGI[IWL_RATE_COUNT] = {
0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293
};
+/* Expected throughput metric MIMO3 */
+static s32 expected_tpt_mimo3_20MHz[IWL_RATE_COUNT] = {
+ 0, 0, 0, 0, 99, 99, 153, 186, 208, 239, 256, 263, 268
+};
+
+static s32 expected_tpt_mimo3_20MHzSGI[IWL_RATE_COUNT] = {
+ 0, 0, 0, 0, 106, 106, 162, 194, 215, 246, 262, 268, 273
+};
+
+static s32 expected_tpt_mimo3_40MHz[IWL_RATE_COUNT] = {
+ 0, 0, 0, 0, 152, 152, 211, 239, 255, 279, 290, 294, 297
+};
+
+static s32 expected_tpt_mimo3_40MHzSGI[IWL_RATE_COUNT] = {
+ 0, 0, 0, 0, 160, 160, 219, 245, 261, 284, 294, 297, 300
+};
+
+/* mbps, mcs */
+const static struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
+ {"1", ""},
+ {"2", ""},
+ {"5.5", ""},
+ {"11", ""},
+ {"6", "BPSK 1/2"},
+ {"9", "BPSK 1/2"},
+ {"12", "QPSK 1/2"},
+ {"18", "QPSK 3/4"},
+ {"24", "16QAM 1/2"},
+ {"36", "16QAM 3/4"},
+ {"48", "64QAM 2/3"},
+ {"54", "64QAM 3/4"},
+ {"60", "64QAM 5/6"}
+};
+
+#define MCS_INDEX_PER_STREAM (8)
+
static inline u8 rs_extract_rate(u32 rate_n_flags)
{
return (u8)(rate_n_flags & 0xFF);
@@ -543,6 +583,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
tbl->is_dup = 0;
tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
tbl->lq_type = LQ_NONE;
+ tbl->max_search = IWL_MAX_SEARCH;
/* legacy rate format */
if (!(rate_n_flags & RATE_MCS_HT_MSK)) {
@@ -576,8 +617,10 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
tbl->lq_type = LQ_MIMO2;
/* MIMO3 */
} else {
- if (num_of_ant == 3)
+ if (num_of_ant == 3) {
+ tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
tbl->lq_type = LQ_MIMO3;
+ }
}
}
return 0;
@@ -611,19 +654,19 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
return 1;
}
-/* FIXME:RS: in 4965 we don't use greenfield at all */
-/* FIXME:RS: don't use greenfield for now in TX */
-#if 0
-static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
+/* in 4965 we don't use greenfield at all */
+static inline u8 rs_use_green(struct iwl_priv *priv,
+ struct ieee80211_conf *conf)
{
- return (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) &&
- priv->current_ht_config.is_green_field &&
- !priv->current_ht_config.non_GF_STA_present;
-}
-#endif
-static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
-{
- return 0;
+ u8 is_green;
+
+ if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
+ is_green = 0;
+ else
+ is_green = (conf_is_ht(conf) &&
+ priv->current_ht_config.is_green_field &&
+ !priv->current_ht_config.non_GF_STA_present);
+ return is_green;
}
/**
@@ -735,6 +778,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
tbl->is_fat = 0;
tbl->is_SGI = 0;
+ tbl->max_search = IWL_MAX_SEARCH;
}
rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type);
@@ -793,7 +837,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
if (!ieee80211_is_data(hdr->frame_control) ||
- is_multicast_ether_addr(hdr->addr1))
+ info->flags & IEEE80211_TX_CTL_NO_ACK)
return;
/* This packet was aggregated but doesn't carry rate scale info */
@@ -902,6 +946,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
* else look up the rate that was, finally, successful.
*/
tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags);
+ lq_sta->last_rate_n_flags = tx_rate;
rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);
/* Update frame history window with "success" if Tx got ACKed ... */
@@ -958,7 +1003,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
/* See if there's a better rate or modulation mode to try. */
if (sta && sta->supp_rates[sband->band])
- rs_rate_scale_perform(priv, hdr, sta, lq_sta);
+ rs_rate_scale_perform(priv, skb, sta, lq_sta);
out:
return;
}
@@ -988,6 +1033,8 @@ static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
lq_sta->table_count = 0;
lq_sta->total_failed = 0;
lq_sta->total_success = 0;
+ lq_sta->flush_timer = jiffies;
+ lq_sta->action_counter = 0;
}
/*
@@ -1011,17 +1058,26 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
tbl->expected_tpt = expected_tpt_siso20MHzSGI;
else
tbl->expected_tpt = expected_tpt_siso20MHz;
-
- } else if (is_mimo(tbl->lq_type)) { /* FIXME:need to separate mimo2/3 */
+ } else if (is_mimo2(tbl->lq_type)) {
if (tbl->is_fat && !lq_sta->is_dup)
if (tbl->is_SGI)
- tbl->expected_tpt = expected_tpt_mimo40MHzSGI;
+ tbl->expected_tpt = expected_tpt_mimo2_40MHzSGI;
else
- tbl->expected_tpt = expected_tpt_mimo40MHz;
+ tbl->expected_tpt = expected_tpt_mimo2_40MHz;
else if (tbl->is_SGI)
- tbl->expected_tpt = expected_tpt_mimo20MHzSGI;
+ tbl->expected_tpt = expected_tpt_mimo2_20MHzSGI;
else
- tbl->expected_tpt = expected_tpt_mimo20MHz;
+ tbl->expected_tpt = expected_tpt_mimo2_20MHz;
+ } else if (is_mimo3(tbl->lq_type)) {
+ if (tbl->is_fat && !lq_sta->is_dup)
+ if (tbl->is_SGI)
+ tbl->expected_tpt = expected_tpt_mimo3_40MHzSGI;
+ else
+ tbl->expected_tpt = expected_tpt_mimo3_40MHz;
+ else if (tbl->is_SGI)
+ tbl->expected_tpt = expected_tpt_mimo3_20MHzSGI;
+ else
+ tbl->expected_tpt = expected_tpt_mimo3_20MHz;
} else
tbl->expected_tpt = expected_tpt_G;
}
@@ -1130,7 +1186,7 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
}
/*
- * Set up search table for MIMO
+ * Set up search table for MIMO2
*/
static int rs_switch_to_mimo2(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta,
@@ -1158,10 +1214,10 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
tbl->lq_type = LQ_MIMO2;
tbl->is_dup = lq_sta->is_dup;
tbl->action = 0;
+ tbl->max_search = IWL_MAX_SEARCH;
rate_mask = lq_sta->active_mimo2_rate;
- if (priv->current_ht_config.supported_chan_width
- == IWL_CHANNEL_WIDTH_40MHZ)
+ if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
tbl->is_fat = 1;
else
tbl->is_fat = 0;
@@ -1183,7 +1239,73 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
IWL_DEBUG_RATE(priv, "LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask);
+ if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
+ IWL_DEBUG_RATE(priv, "Can't switch with index %d rate mask %x\n",
+ rate, rate_mask);
+ return -1;
+ }
+ tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
+
+ IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n",
+ tbl->current_rate, is_green);
+ return 0;
+}
+
+/*
+ * Set up search table for MIMO3
+ */
+static int rs_switch_to_mimo3(struct iwl_priv *priv,
+ struct iwl_lq_sta *lq_sta,
+ struct ieee80211_conf *conf,
+ struct ieee80211_sta *sta,
+ struct iwl_scale_tbl_info *tbl, int index)
+{
+ u16 rate_mask;
+ s32 rate;
+ s8 is_green = lq_sta->is_green;
+
+ if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
+ return -1;
+
+ if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
+ == WLAN_HT_CAP_SM_PS_STATIC)
+ return -1;
+
+ /* Need both Tx chains/antennas to support MIMO */
+ if (priv->hw_params.tx_chains_num < 3)
+ return -1;
+
+ IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO3\n");
+
+ tbl->lq_type = LQ_MIMO3;
+ tbl->is_dup = lq_sta->is_dup;
+ tbl->action = 0;
+ tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
+ rate_mask = lq_sta->active_mimo3_rate;
+
+ if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
+ tbl->is_fat = 1;
+ else
+ tbl->is_fat = 0;
+ /* FIXME: - don't toggle SGI here
+ if (tbl->is_fat) {
+ if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
+ tbl->is_SGI = 1;
+ else
+ tbl->is_SGI = 0;
+ } else if (priv->current_ht_config.sgf & HT_SHORT_GI_20MHZ_ONLY)
+ tbl->is_SGI = 1;
+ else
+ tbl->is_SGI = 0;
+ */
+
+ rs_set_expected_tpt_table(lq_sta, tbl);
+
+ rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
+
+ IWL_DEBUG_RATE(priv, "LQ: MIMO3 best rate %d mask %X\n",
+ rate, rate_mask);
if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
IWL_DEBUG_RATE(priv, "Can't switch with index %d rate mask %x\n",
rate, rate_mask);
@@ -1217,10 +1339,10 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
tbl->is_dup = lq_sta->is_dup;
tbl->lq_type = LQ_SISO;
tbl->action = 0;
+ tbl->max_search = IWL_MAX_SEARCH;
rate_mask = lq_sta->active_siso_rate;
- if (priv->current_ht_config.supported_chan_width
- == IWL_CHANNEL_WIDTH_40MHZ)
+ if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
tbl->is_fat = 1;
else
tbl->is_fat = 0;
@@ -1274,15 +1396,15 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
int ret = 0;
+ u8 update_search_tbl_counter = 0;
for (; ;) {
+ lq_sta->action_counter++;
switch (tbl->action) {
case IWL_LEGACY_SWITCH_ANTENNA1:
case IWL_LEGACY_SWITCH_ANTENNA2:
IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n");
- lq_sta->action_counter++;
-
if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 &&
tx_chains_num <= 1) ||
(tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 &&
@@ -1298,6 +1420,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
if (rs_toggle_antenna(valid_tx_ant,
&search_tbl->current_rate, search_tbl)) {
+ update_search_tbl_counter = 1;
rs_set_expected_tpt_table(lq_sta, search_tbl);
goto out;
}
@@ -1342,9 +1465,29 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
goto out;
}
break;
+
+ case IWL_LEGACY_SWITCH_MIMO3_ABC:
+ IWL_DEBUG_RATE(priv, "LQ: Legacy switch to MIMO3\n");
+
+ /* Set up search table to try MIMO3 */
+ memcpy(search_tbl, tbl, sz);
+ search_tbl->is_SGI = 0;
+
+ search_tbl->ant_type = ANT_ABC;
+
+ if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+ break;
+
+ ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
+ search_tbl, index);
+ if (!ret) {
+ lq_sta->action_counter = 0;
+ goto out;
+ }
+ break;
}
tbl->action++;
- if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC)
+ if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
if (tbl->action == start_action)
@@ -1357,8 +1500,10 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
out:
lq_sta->search_better_tbl = 1;
tbl->action++;
- if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC)
+ if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
+ if (update_search_tbl_counter)
+ search_tbl->action = tbl->action;
return 0;
}
@@ -1381,6 +1526,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
u8 start_action = tbl->action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
+ u8 update_search_tbl_counter = 0;
int ret;
for (;;) {
@@ -1401,8 +1547,10 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
memcpy(search_tbl, tbl, sz);
if (rs_toggle_antenna(valid_tx_ant,
- &search_tbl->current_rate, search_tbl))
+ &search_tbl->current_rate, search_tbl)) {
+ update_search_tbl_counter = 1;
goto out;
+ }
break;
case IWL_SISO_SWITCH_MIMO2_AB:
case IWL_SISO_SWITCH_MIMO2_AC:
@@ -1456,10 +1604,25 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
search_tbl->current_rate =
rate_n_flags_from_tbl(priv, search_tbl,
index, is_green);
+ update_search_tbl_counter = 1;
goto out;
+ case IWL_SISO_SWITCH_MIMO3_ABC:
+ IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO3\n");
+ memcpy(search_tbl, tbl, sz);
+ search_tbl->is_SGI = 0;
+ search_tbl->ant_type = ANT_ABC;
+
+ if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+ break;
+
+ ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
+ search_tbl, index);
+ if (!ret)
+ goto out;
+ break;
}
tbl->action++;
- if (tbl->action > IWL_SISO_SWITCH_GI)
+ if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
tbl->action = IWL_SISO_SWITCH_ANTENNA1;
if (tbl->action == start_action)
@@ -1471,15 +1634,18 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
out:
lq_sta->search_better_tbl = 1;
tbl->action++;
- if (tbl->action > IWL_SISO_SWITCH_GI)
+ if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC)
tbl->action = IWL_SISO_SWITCH_ANTENNA1;
+ if (update_search_tbl_counter)
+ search_tbl->action = tbl->action;
+
return 0;
}
/*
- * Try to switch to new modulation mode from MIMO
+ * Try to switch to new modulation mode from MIMO2
*/
-static int rs_move_mimo_to_other(struct iwl_priv *priv,
+static int rs_move_mimo2_to_other(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta,
struct ieee80211_conf *conf,
struct ieee80211_sta *sta, int index)
@@ -1494,6 +1660,7 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
u8 start_action = tbl->action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
+ u8 update_search_tbl_counter = 0;
int ret;
for (;;) {
@@ -1501,7 +1668,7 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
switch (tbl->action) {
case IWL_MIMO2_SWITCH_ANTENNA1:
case IWL_MIMO2_SWITCH_ANTENNA2:
- IWL_DEBUG_RATE(priv, "LQ: MIMO toggle Antennas\n");
+ IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle Antennas\n");
if (tx_chains_num <= 2)
break;
@@ -1511,8 +1678,10 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
memcpy(search_tbl, tbl, sz);
if (rs_toggle_antenna(valid_tx_ant,
- &search_tbl->current_rate, search_tbl))
+ &search_tbl->current_rate, search_tbl)) {
+ update_search_tbl_counter = 1;
goto out;
+ }
break;
case IWL_MIMO2_SWITCH_SISO_A:
case IWL_MIMO2_SWITCH_SISO_B:
@@ -1549,9 +1718,9 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
HT_SHORT_GI_40MHZ))
break;
- IWL_DEBUG_RATE(priv, "LQ: MIMO toggle SGI/NGI\n");
+ IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle SGI/NGI\n");
- /* Set up new search table for MIMO */
+ /* Set up new search table for MIMO2 */
memcpy(search_tbl, tbl, sz);
search_tbl->is_SGI = !tbl->is_SGI;
rs_set_expected_tpt_table(lq_sta, search_tbl);
@@ -1569,11 +1738,27 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
search_tbl->current_rate =
rate_n_flags_from_tbl(priv, search_tbl,
index, is_green);
+ update_search_tbl_counter = 1;
goto out;
+ case IWL_MIMO2_SWITCH_MIMO3_ABC:
+ IWL_DEBUG_RATE(priv, "LQ: MIMO2 switch to MIMO3\n");
+ memcpy(search_tbl, tbl, sz);
+ search_tbl->is_SGI = 0;
+ search_tbl->ant_type = ANT_ABC;
+
+ if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+ break;
+
+ ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
+ search_tbl, index);
+ if (!ret)
+ goto out;
+
+ break;
}
tbl->action++;
- if (tbl->action > IWL_MIMO2_SWITCH_GI)
+ if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)
tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
if (tbl->action == start_action)
@@ -1584,8 +1769,153 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
out:
lq_sta->search_better_tbl = 1;
tbl->action++;
- if (tbl->action > IWL_MIMO2_SWITCH_GI)
+ if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)
tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
+ if (update_search_tbl_counter)
+ search_tbl->action = tbl->action;
+
+ return 0;
+
+}
+
+/*
+ * Try to switch to new modulation mode from MIMO3
+ */
+static int rs_move_mimo3_to_other(struct iwl_priv *priv,
+ struct iwl_lq_sta *lq_sta,
+ struct ieee80211_conf *conf,
+ struct ieee80211_sta *sta, int index)
+{
+ s8 is_green = lq_sta->is_green;
+ struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+ struct iwl_scale_tbl_info *search_tbl =
+ &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
+ struct iwl_rate_scale_data *window = &(tbl->win[index]);
+ u32 sz = (sizeof(struct iwl_scale_tbl_info) -
+ (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
+ u8 start_action = tbl->action;
+ u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
+ u8 tx_chains_num = priv->hw_params.tx_chains_num;
+ int ret;
+ u8 update_search_tbl_counter = 0;
+
+ for (;;) {
+ lq_sta->action_counter++;
+ switch (tbl->action) {
+ case IWL_MIMO3_SWITCH_ANTENNA1:
+ case IWL_MIMO3_SWITCH_ANTENNA2:
+ IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle Antennas\n");
+
+ if (tx_chains_num <= 3)
+ break;
+
+ if (window->success_ratio >= IWL_RS_GOOD_RATIO)
+ break;
+
+ memcpy(search_tbl, tbl, sz);
+ if (rs_toggle_antenna(valid_tx_ant,
+ &search_tbl->current_rate, search_tbl))
+ goto out;
+ break;
+ case IWL_MIMO3_SWITCH_SISO_A:
+ case IWL_MIMO3_SWITCH_SISO_B:
+ case IWL_MIMO3_SWITCH_SISO_C:
+ IWL_DEBUG_RATE(priv, "LQ: MIMO3 switch to SISO\n");
+
+ /* Set up new search table for SISO */
+ memcpy(search_tbl, tbl, sz);
+
+ if (tbl->action == IWL_MIMO3_SWITCH_SISO_A)
+ search_tbl->ant_type = ANT_A;
+ else if (tbl->action == IWL_MIMO3_SWITCH_SISO_B)
+ search_tbl->ant_type = ANT_B;
+ else
+ search_tbl->ant_type = ANT_C;
+
+ if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+ break;
+
+ ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
+ search_tbl, index);
+ if (!ret)
+ goto out;
+
+ break;
+
+ case IWL_MIMO3_SWITCH_MIMO2_AB:
+ case IWL_MIMO3_SWITCH_MIMO2_AC:
+ case IWL_MIMO3_SWITCH_MIMO2_BC:
+ IWL_DEBUG_RATE(priv, "LQ: MIMO3 switch to MIMO2\n");
+
+ memcpy(search_tbl, tbl, sz);
+ search_tbl->is_SGI = 0;
+ if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AB)
+ search_tbl->ant_type = ANT_AB;
+ else if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AC)
+ search_tbl->ant_type = ANT_AC;
+ else
+ search_tbl->ant_type = ANT_BC;
+
+ if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+ break;
+
+ ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
+ search_tbl, index);
+ if (!ret)
+ goto out;
+
+ break;
+
+ case IWL_MIMO3_SWITCH_GI:
+ if (!tbl->is_fat &&
+ !(priv->current_ht_config.sgf &
+ HT_SHORT_GI_20MHZ))
+ break;
+ if (tbl->is_fat &&
+ !(priv->current_ht_config.sgf &
+ HT_SHORT_GI_40MHZ))
+ break;
+
+ IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle SGI/NGI\n");
+
+ /* Set up new search table for MIMO */
+ memcpy(search_tbl, tbl, sz);
+ search_tbl->is_SGI = !tbl->is_SGI;
+ rs_set_expected_tpt_table(lq_sta, search_tbl);
+ /*
+ * If active table already uses the fastest possible
+ * modulation (dual stream with short guard interval),
+ * and it's working well, there's no need to look
+ * for a better type of modulation!
+ */
+ if (tbl->is_SGI) {
+ s32 tpt = lq_sta->last_tpt / 100;
+ if (tpt >= search_tbl->expected_tpt[index])
+ break;
+ }
+ search_tbl->current_rate =
+ rate_n_flags_from_tbl(priv, search_tbl,
+ index, is_green);
+ update_search_tbl_counter = 1;
+ goto out;
+ }
+ tbl->action++;
+ if (tbl->action > IWL_MIMO3_SWITCH_GI)
+ tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
+
+ if (tbl->action == start_action)
+ break;
+ }
+ search_tbl->lq_type = LQ_NONE;
+ return 0;
+ out:
+ lq_sta->search_better_tbl = 1;
+ tbl->action++;
+ if (tbl->action > IWL_MIMO3_SWITCH_GI)
+ tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
+ if (update_search_tbl_counter)
+ search_tbl->action = tbl->action;
+
return 0;
}
@@ -1616,8 +1946,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
/* Elapsed time using current modulation mode */
if (lq_sta->flush_timer)
flush_interval_passed =
- time_after(jiffies,
- (unsigned long)(lq_sta->flush_timer +
+ time_after(jiffies,
+ (unsigned long)(lq_sta->flush_timer +
IWL_RATE_SCALE_FLUSH_INTVL));
/*
@@ -1676,12 +2006,14 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
* Do rate scaling and search for new modulation mode.
*/
static void rs_rate_scale_perform(struct iwl_priv *priv,
- struct ieee80211_hdr *hdr,
+ struct sk_buff *skb,
struct ieee80211_sta *sta,
struct iwl_lq_sta *lq_sta)
{
struct ieee80211_hw *hw = priv->hw;
struct ieee80211_conf *conf = &hw->conf;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
int low = IWL_RATE_INVALID;
int high = IWL_RATE_INVALID;
int index;
@@ -1707,11 +2039,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
- /* Send management frames and broadcast/multicast data using
- * lowest rate. */
+ /* Send management frames and NO_ACK data using lowest rate. */
/* TODO: this could probably be improved.. */
if (!ieee80211_is_data(hdr->frame_control) ||
- is_multicast_ether_addr(hdr->addr1))
+ info->flags & IEEE80211_TX_CTL_NO_ACK)
return;
if (!sta || !lq_sta)
@@ -1732,6 +2063,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
active_tbl = 1 - lq_sta->active_tbl;
tbl = &(lq_sta->lq_info[active_tbl]);
+ if (is_legacy(tbl->lq_type))
+ lq_sta->is_green = 0;
+ else
+ lq_sta->is_green = rs_use_green(priv, conf);
is_green = lq_sta->is_green;
/* current tx rate */
@@ -1951,6 +2286,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
update_lq = 1;
index = low;
}
+
break;
case 1:
/* Increase starting rate, update uCode's rate table */
@@ -1997,8 +2333,10 @@ lq_update:
rs_move_legacy_other(priv, lq_sta, conf, sta, index);
else if (is_siso(tbl->lq_type))
rs_move_siso_to_other(priv, lq_sta, conf, sta, index);
+ else if (is_mimo2(tbl->lq_type))
+ rs_move_mimo2_to_other(priv, lq_sta, conf, sta, index);
else
- rs_move_mimo_to_other(priv, lq_sta, conf, sta, index);
+ rs_move_mimo3_to_other(priv, lq_sta, conf, sta, index);
/* If new "search" mode was selected, set up in uCode table */
if (lq_sta->search_better_tbl) {
@@ -2014,8 +2352,11 @@ lq_update:
tbl->current_rate, index);
rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
- }
+ } else
+ done_search = 1;
+ }
+ if (done_search && !lq_sta->stay_in_tbl) {
/* If the "active" (non-search) mode was legacy,
* and we've tried switching antennas,
* but we haven't been able to try HT modes (not available),
@@ -2023,8 +2364,7 @@ lq_update:
* before next round of mode comparisons. */
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) &&
- lq_sta->action_counter >= 1) {
- lq_sta->action_counter = 0;
+ lq_sta->action_counter > tbl1->max_search) {
IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n");
rs_set_stay_in_table(priv, 1, lq_sta);
}
@@ -2033,7 +2373,7 @@ lq_update:
* have been tried and compared, stay in this best modulation
* mode for a while before next round of mode comparisons. */
if (lq_sta->enable_counter &&
- (lq_sta->action_counter >= IWL_ACTION_LIMIT)) {
+ (lq_sta->action_counter >= tbl1->max_search)) {
if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
(lq_sta->tx_agg_tid_en & (1 << tid)) &&
(tid != MAX_TID_COUNT)) {
@@ -2047,20 +2387,8 @@ lq_update:
lq_sta, sta);
}
}
- lq_sta->action_counter = 0;
rs_set_stay_in_table(priv, 0, lq_sta);
}
-
- /*
- * Else, don't search for a new modulation mode.
- * Put new timestamp in stay-in-modulation-mode flush timer if:
- * 1) Not changing rates right now
- * 2) Not just finishing up a search
- * 3) flush timer is empty
- */
- } else {
- if ((!update_lq) && (!done_search) && (!lq_sta->flush_timer))
- lq_sta->flush_timer = jiffies;
}
out:
@@ -2156,16 +2484,17 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
if (sta)
mask_bit = sta->supp_rates[sband->band];
- /* Send management frames and broadcast/multicast data using lowest
- * rate. */
+ /* Send management frames and NO_ACK data using lowest rate. */
if (!ieee80211_is_data(hdr->frame_control) ||
- is_multicast_ether_addr(hdr->addr1) || !sta || !lq_sta) {
+ info->flags & IEEE80211_TX_CTL_NO_ACK || !sta || !lq_sta) {
if (!mask_bit)
info->control.rates[0].idx =
rate_lowest_index(sband, NULL);
else
info->control.rates[0].idx =
rate_lowest_index(sband, sta);
+ if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+ info->control.rates[0].count = 1;
return;
}
@@ -2178,8 +2507,8 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
hdr->addr1);
- sta_id = iwl_add_station_flags(priv, hdr->addr1,
- 0, CMD_ASYNC, NULL);
+ sta_id = iwl_add_station(priv, hdr->addr1,
+ false, CMD_ASYNC, NULL);
}
if ((sta_id != IWL_INVALID_STATION)) {
lq_sta->lq.sta_id = sta_id;
@@ -2189,12 +2518,33 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
}
}
- if (rate_idx < 0 || rate_idx > IWL_RATE_COUNT)
- rate_idx = rate_lowest_index(sband, sta);
- else if (sband->band == IEEE80211_BAND_5GHZ)
+ if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) {
rate_idx -= IWL_FIRST_OFDM_RATE;
-
+ /* 6M and 9M shared same MCS index */
+ rate_idx = (rate_idx > 0) ? (rate_idx - 1) : 0;
+ if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
+ IWL_RATE_MIMO3_6M_PLCP)
+ rate_idx = rate_idx + (2 * MCS_INDEX_PER_STREAM);
+ else if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
+ IWL_RATE_MIMO2_6M_PLCP)
+ rate_idx = rate_idx + MCS_INDEX_PER_STREAM;
+ info->control.rates[0].flags = IEEE80211_TX_RC_MCS;
+ if (lq_sta->last_rate_n_flags & RATE_MCS_SGI_MSK)
+ info->control.rates[0].flags |= IEEE80211_TX_RC_SHORT_GI;
+ if (lq_sta->last_rate_n_flags & RATE_MCS_DUP_MSK)
+ info->control.rates[0].flags |= IEEE80211_TX_RC_DUP_DATA;
+ if (lq_sta->last_rate_n_flags & RATE_MCS_FAT_MSK)
+ info->control.rates[0].flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+ if (lq_sta->last_rate_n_flags & RATE_MCS_GF_MSK)
+ info->control.rates[0].flags |= IEEE80211_TX_RC_GREEN_FIELD;
+ } else {
+ if (rate_idx < 0 || rate_idx > IWL_RATE_COUNT)
+ rate_idx = rate_lowest_index(sband, sta);
+ else if (sband->band == IEEE80211_BAND_5GHZ)
+ rate_idx -= IWL_FIRST_OFDM_RATE;
+ }
info->control.rates[0].idx = rate_idx;
+
}
static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
@@ -2246,15 +2596,16 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
lq_sta->ibss_sta_added = 0;
if (priv->iw_mode == NL80211_IFTYPE_AP) {
- u8 sta_id = iwl_find_station(priv, sta->addr);
+ u8 sta_id = iwl_find_station(priv,
+ sta->addr);
/* for IBSS the call are from tasklet */
IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
- sta_id = iwl_add_station_flags(priv, sta->addr,
- 0, CMD_ASYNC, NULL);
+ sta_id = iwl_add_station(priv, sta->addr, false,
+ CMD_ASYNC, NULL);
}
if ((sta_id != IWL_INVALID_STATION)) {
lq_sta->lq.sta_id = sta_id;
@@ -2436,9 +2787,10 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
repeat_rate--;
}
- lq_cmd->agg_params.agg_frame_cnt_limit = 64;
- lq_cmd->agg_params.agg_dis_start_th = 3;
- lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000);
+ lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_MAX;
+ lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+ lq_cmd->agg_params.agg_time_limit =
+ cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
}
static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -2539,6 +2891,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
char *buff;
int desc = 0;
int i = 0;
+ int index = 0;
ssize_t ret;
struct iwl_lq_sta *lq_sta = file->private_data;
@@ -2568,8 +2921,11 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3"));
desc += sprintf(buff+desc, " %s",
(tbl->is_fat) ? "40MHz" : "20MHz");
- desc += sprintf(buff+desc, " %s\n", (tbl->is_SGI) ? "SGI" : "");
+ desc += sprintf(buff+desc, " %s %s\n", (tbl->is_SGI) ? "SGI" : "",
+ (lq_sta->is_green) ? "GF enabled" : "");
}
+ desc += sprintf(buff+desc, "last tx rate=0x%X\n",
+ lq_sta->last_rate_n_flags);
desc += sprintf(buff+desc, "general:"
"flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
lq_sta->lq.general_params.flags,
@@ -2590,10 +2946,19 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
lq_sta->lq.general_params.start_rate_index[2],
lq_sta->lq.general_params.start_rate_index[3]);
-
- for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
- desc += sprintf(buff+desc, " rate[%d] 0x%X\n",
- i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
+ for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
+ index = iwl_hwrate_to_plcp_idx(
+ le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
+ if (is_legacy(tbl->lq_type)) {
+ desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n",
+ i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags),
+ iwl_rate_mcs[index].mbps);
+ } else {
+ desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps (%s)\n",
+ i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags),
+ iwl_rate_mcs[index].mbps, iwl_rate_mcs[index].mcs);
+ }
+ }
ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
kfree(buff);
@@ -2620,13 +2985,14 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
return -ENOMEM;
for (i = 0; i < LQ_SIZE; i++) {
- desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n"
+ desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d GF=%d\n"
"rate=0x%X\n",
lq_sta->active_tbl == i ? "*" : "x",
lq_sta->lq_info[i].lq_type,
lq_sta->lq_info[i].is_SGI,
lq_sta->lq_info[i].is_fat,
lq_sta->lq_info[i].is_dup,
+ lq_sta->is_green,
lq_sta->lq_info[i].current_rate);
for (j = 0; j < IWL_RATE_COUNT; j++) {
desc += sprintf(buff+desc,
@@ -2646,6 +3012,43 @@ static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
.open = open_file_generic,
};
+static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
+ char __user *user_buf, size_t count, loff_t *ppos)
+{
+ char buff[120];
+ int desc = 0;
+ ssize_t ret;
+
+ struct iwl_lq_sta *lq_sta = file->private_data;
+ struct iwl_priv *priv;
+ struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl];
+
+ priv = lq_sta->drv;
+
+ if (is_Ht(tbl->lq_type))
+ desc += sprintf(buff+desc,
+ "Bit Rate= %d Mb/s\n",
+ tbl->expected_tpt[lq_sta->last_txrate_idx]);
+ else
+ desc += sprintf(buff+desc,
+ "Bit Rate= %d Mb/s\n",
+ iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
+ desc += sprintf(buff+desc,
+ "Signal Level= %d dBm\tNoise Level= %d dBm\n",
+ priv->last_rx_rssi, priv->last_rx_noise);
+ desc += sprintf(buff+desc,
+ "Tsf= 0x%llx\tBeacon time= 0x%08X\n",
+ priv->last_tsf, priv->last_beacon_time);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+ return ret;
+}
+
+static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
+ .read = rs_sta_dbgfs_rate_scale_data_read,
+ .open = open_file_generic,
+};
+
static void rs_add_debugfs(void *priv, void *priv_sta,
struct dentry *dir)
{
@@ -2656,6 +3059,9 @@ static void rs_add_debugfs(void *priv, void *priv_sta,
lq_sta->rs_sta_dbgfs_stats_table_file =
debugfs_create_file("rate_stats_table", 0600, dir,
lq_sta, &rs_sta_dbgfs_stats_table_ops);
+ lq_sta->rs_sta_dbgfs_rate_scale_data_file =
+ debugfs_create_file("rate_scale_data", 0600, dir,
+ lq_sta, &rs_sta_dbgfs_rate_scale_data_ops);
lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
debugfs_create_u8("tx_agg_tid_enable", 0600, dir,
&lq_sta->tx_agg_tid_en);
@@ -2667,6 +3073,7 @@ static void rs_remove_debugfs(void *priv, void *priv_sta)
struct iwl_lq_sta *lq_sta = priv_sta;
debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
+ debugfs_remove(lq_sta->rs_sta_dbgfs_rate_scale_data_file);
debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
}
#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index ab59acc405d..25050bf315a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -241,6 +241,7 @@ enum {
#define IWL_LEGACY_SWITCH_MIMO2_AB 3
#define IWL_LEGACY_SWITCH_MIMO2_AC 4
#define IWL_LEGACY_SWITCH_MIMO2_BC 5
+#define IWL_LEGACY_SWITCH_MIMO3_ABC 6
/* possible actions when in siso mode */
#define IWL_SISO_SWITCH_ANTENNA1 0
@@ -249,6 +250,8 @@ enum {
#define IWL_SISO_SWITCH_MIMO2_AC 3
#define IWL_SISO_SWITCH_MIMO2_BC 4
#define IWL_SISO_SWITCH_GI 5
+#define IWL_SISO_SWITCH_MIMO3_ABC 6
+
/* possible actions when in mimo mode */
#define IWL_MIMO2_SWITCH_ANTENNA1 0
@@ -257,6 +260,23 @@ enum {
#define IWL_MIMO2_SWITCH_SISO_B 3
#define IWL_MIMO2_SWITCH_SISO_C 4
#define IWL_MIMO2_SWITCH_GI 5
+#define IWL_MIMO2_SWITCH_MIMO3_ABC 6
+
+
+/* possible actions when in mimo3 mode */
+#define IWL_MIMO3_SWITCH_ANTENNA1 0
+#define IWL_MIMO3_SWITCH_ANTENNA2 1
+#define IWL_MIMO3_SWITCH_SISO_A 2
+#define IWL_MIMO3_SWITCH_SISO_B 3
+#define IWL_MIMO3_SWITCH_SISO_C 4
+#define IWL_MIMO3_SWITCH_MIMO2_AB 5
+#define IWL_MIMO3_SWITCH_MIMO2_AC 6
+#define IWL_MIMO3_SWITCH_MIMO2_BC 7
+#define IWL_MIMO3_SWITCH_GI 8
+
+
+#define IWL_MAX_11N_MIMO3_SEARCH IWL_MIMO3_SWITCH_GI
+#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_MIMO3_ABC
/*FIXME:RS:add possible actions for MIMO3*/
@@ -307,6 +327,13 @@ enum iwl_table_type {
#define ANT_BC (ANT_B | ANT_C)
#define ANT_ABC (ANT_AB | ANT_C)
+#define IWL_MAX_MCS_DISPLAY_SIZE 12
+
+struct iwl_rate_mcs_info {
+ char mbps[IWL_MAX_MCS_DISPLAY_SIZE];
+ char mcs[IWL_MAX_MCS_DISPLAY_SIZE];
+};
+
static inline u8 num_of_ant(u8 mask)
{
return !!((mask) & ANT_A) +
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index f46ba247577..a5637c4aa85 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -102,7 +102,7 @@ MODULE_ALIAS("iwl4965");
* function correctly transitions out of the RXON_ASSOC_MSK state if
* a HW tune is required based on the RXON structure changes.
*/
-static int iwl_commit_rxon(struct iwl_priv *priv)
+int iwl_commit_rxon(struct iwl_priv *priv)
{
/* cast away the const for active_rxon in this function */
struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
@@ -190,8 +190,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
iwl_clear_stations_table(priv);
- if (!priv->error_recovering)
- priv->start_calib = 0;
+ priv->start_calib = 0;
/* Add the broadcast address so we can send broadcast frames */
if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
@@ -246,8 +245,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
void iwl_update_chain_flags(struct iwl_priv *priv)
{
- iwl_set_rxon_chain(priv);
- iwl_commit_rxon(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ iwlcore_commit_rxon(priv);
}
static void iwl_clear_free_frames(struct iwl_priv *priv)
@@ -503,24 +503,12 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
int iwl_hw_tx_queue_init(struct iwl_priv *priv,
struct iwl_tx_queue *txq)
{
- int ret;
- unsigned long flags;
int txq_id = txq->q.id;
- spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
- }
-
/* Circular buffer (TFD queue in DRAM) physical base address */
iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
txq->q.dma_addr >> 8);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
return 0;
}
@@ -531,76 +519,6 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv,
*
******************************************************************************/
-static void iwl_ht_conf(struct iwl_priv *priv,
- struct ieee80211_bss_conf *bss_conf)
-{
- struct ieee80211_sta_ht_cap *ht_conf;
- struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
- struct ieee80211_sta *sta;
-
- IWL_DEBUG_MAC80211(priv, "enter: \n");
-
- if (!iwl_conf->is_ht)
- return;
-
-
- /*
- * It is totally wrong to base global information on something
- * that is valid only when associated, alas, this driver works
- * that way and I don't know how to fix it.
- */
-
- rcu_read_lock();
- sta = ieee80211_find_sta(priv->hw, priv->bssid);
- if (!sta) {
- rcu_read_unlock();
- return;
- }
- ht_conf = &sta->ht_cap;
-
- if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
- iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
- if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
- iwl_conf->sgf |= HT_SHORT_GI_40MHZ;
-
- iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
- iwl_conf->max_amsdu_size =
- !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
-
- iwl_conf->supported_chan_width =
- !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
-
- /*
- * XXX: The HT configuration needs to be moved into iwl_mac_config()
- * to be done there correctly.
- */
-
- iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
- if (conf_is_ht40_minus(&priv->hw->conf))
- iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- else if (conf_is_ht40_plus(&priv->hw->conf))
- iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-
- /* If no above or below channel supplied disable FAT channel */
- if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE &&
- iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW)
- iwl_conf->supported_chan_width = 0;
-
- iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
-
- memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
-
- iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0;
- iwl_conf->ht_protection =
- bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
- iwl_conf->non_GF_STA_present =
- !!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
-
- rcu_read_unlock();
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
#define MAX_UCODE_BEACON_INTERVAL 4096
static u16 iwl_adjust_beacon_interval(u16 beacon_val)
@@ -636,7 +554,8 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv)
beacon_int = iwl_adjust_beacon_interval(priv->beacon_int);
priv->rxon_timing.atim_window = 0;
} else {
- beacon_int = iwl_adjust_beacon_interval(conf->beacon_int);
+ beacon_int = iwl_adjust_beacon_interval(
+ priv->vif->bss_conf.beacon_int);
/* TODO: we need to get atim_window from upper stack
* for now we set to 0 */
@@ -657,23 +576,6 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv)
le16_to_cpu(priv->rxon_timing.atim_window));
}
-static int iwl_set_mode(struct iwl_priv *priv, int mode)
-{
- iwl_connection_init_rx_config(priv, mode);
- iwl_set_rxon_chain(priv);
- memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
-
- iwl_clear_stations_table(priv);
-
- /* dont commit rxon if rf-kill is on*/
- if (!iwl_is_ready_rf(priv))
- return -EAGAIN;
-
- iwl_commit_rxon(priv);
-
- return 0;
-}
-
/******************************************************************************
*
* Generic RX handler implementations
@@ -795,6 +697,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
unsigned long status = priv->status;
+ unsigned long reg_flags;
IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n",
(flags & HW_CARD_DISABLED) ? "Kill" : "On",
@@ -806,32 +709,25 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
- if (!iwl_grab_nic_access(priv)) {
- iwl_write_direct32(
- priv, HBUS_TARG_MBX_C,
- HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
-
- iwl_release_nic_access(priv);
- }
+ iwl_write_direct32(priv, HBUS_TARG_MBX_C,
+ HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
if (!(flags & RXON_CARD_DISABLED)) {
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
- if (!iwl_grab_nic_access(priv)) {
- iwl_write_direct32(
- priv, HBUS_TARG_MBX_C,
+ iwl_write_direct32(priv, HBUS_TARG_MBX_C,
HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
- iwl_release_nic_access(priv);
- }
}
if (flags & RF_CARD_DISABLED) {
iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
iwl_read32(priv, CSR_UCODE_DRV_GP1);
+ spin_lock_irqsave(&priv->reg_lock, reg_flags);
if (!iwl_grab_nic_access(priv))
iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
}
}
@@ -841,33 +737,19 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
clear_bit(STATUS_RF_KILL_HW, &priv->status);
- if (flags & SW_CARD_DISABLED)
- set_bit(STATUS_RF_KILL_SW, &priv->status);
- else
- clear_bit(STATUS_RF_KILL_SW, &priv->status);
-
if (!(flags & RXON_CARD_DISABLED))
iwl_scan_cancel(priv);
if ((test_bit(STATUS_RF_KILL_HW, &status) !=
- test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
- (test_bit(STATUS_RF_KILL_SW, &status) !=
- test_bit(STATUS_RF_KILL_SW, &priv->status)))
- queue_work(priv->workqueue, &priv->rf_kill);
+ test_bit(STATUS_RF_KILL_HW, &priv->status)))
+ wiphy_rfkill_set_hw_state(priv->hw->wiphy,
+ test_bit(STATUS_RF_KILL_HW, &priv->status));
else
wake_up_interruptible(&priv->wait_command_queue);
}
int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
{
- int ret;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (ret)
- goto err;
-
if (src == IWL_PWR_SRC_VAUX) {
if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
@@ -879,10 +761,7 @@ int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
~APMG_PS_CTRL_MSK_PWR_SRC);
}
- iwl_release_nic_access(priv);
-err:
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
+ return 0;
}
/**
@@ -946,6 +825,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
unsigned long flags;
u8 fill_rx = 0;
u32 count = 8;
+ int total_empty;
/* uCode's read index (stored in shared DRAM) indicates the last Rx
* buffer that the driver may process (last buffer filled by ucode). */
@@ -956,7 +836,12 @@ void iwl_rx_handle(struct iwl_priv *priv)
if (i == r)
IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
- if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+ /* calculate total frames need to be restock after handling RX */
+ total_empty = r - priv->rxq.write_actual;
+ if (total_empty < 0)
+ total_empty += RX_QUEUE_SIZE;
+
+ if (total_empty > (RX_QUEUE_SIZE / 2))
fill_rx = 1;
while (i != r) {
@@ -995,6 +880,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
+ priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
} else {
/* No handling needed */
IWL_DEBUG_RX(priv,
@@ -1032,7 +918,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
count++;
if (count >= 8) {
priv->rxq.read = i;
- iwl_rx_queue_restock(priv);
+ iwl_rx_replenish_now(priv);
count = 0;
}
}
@@ -1040,7 +926,10 @@ void iwl_rx_handle(struct iwl_priv *priv)
/* Backtrack one entry */
priv->rxq.read = i;
- iwl_rx_queue_restock(priv);
+ if (fill_rx)
+ iwl_rx_replenish_now(priv);
+ else
+ iwl_rx_queue_restock(priv);
}
/* call this function to flush any scheduled tasklet */
@@ -1051,24 +940,7 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
tasklet_kill(&priv->irq_tasklet);
}
-static void iwl_error_recovery(struct iwl_priv *priv)
-{
- unsigned long flags;
-
- memcpy(&priv->staging_rxon, &priv->recovery_rxon,
- sizeof(priv->staging_rxon));
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
-
- iwl_rxon_add_station(priv, priv->bssid, 1);
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
- priv->error_recovering = 0;
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static void iwl_irq_tasklet(struct iwl_priv *priv)
+static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
{
u32 inta, handled = 0;
u32 inta_fh;
@@ -1116,6 +988,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Tell the device to stop sending interrupts */
iwl_disable_interrupts(priv);
+ priv->isr_stats.hw++;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_HW_ERR;
@@ -1128,13 +1001,17 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
#ifdef CONFIG_IWLWIFI_DEBUG
if (priv->debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
- if (inta & CSR_INT_BIT_SCD)
+ if (inta & CSR_INT_BIT_SCD) {
IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
"the frame/frames.\n");
+ priv->isr_stats.sch++;
+ }
/* Alive notification via Rx interrupt will do the real work */
- if (inta & CSR_INT_BIT_ALIVE)
+ if (inta & CSR_INT_BIT_ALIVE) {
IWL_DEBUG_ISR(priv, "Alive interrupt\n");
+ priv->isr_stats.alive++;
+ }
}
#endif
/* Safely ignore these bits for debug checks below */
@@ -1150,6 +1027,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
hw_rf_kill ? "disable radio" : "enable radio");
+ priv->isr_stats.rfkill++;
+
/* driver only loads ucode once setting the interface up.
* the driver allows loading the ucode even if the radio
* is killed. Hence update the killswitch state here. The
@@ -1160,7 +1039,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
set_bit(STATUS_RF_KILL_HW, &priv->status);
else
clear_bit(STATUS_RF_KILL_HW, &priv->status);
- queue_work(priv->workqueue, &priv->rf_kill);
+ wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
}
handled |= CSR_INT_BIT_RF_KILL;
@@ -1169,6 +1048,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Chip got too hot and stopped itself */
if (inta & CSR_INT_BIT_CT_KILL) {
IWL_ERR(priv, "Microcode CT kill error detected.\n");
+ priv->isr_stats.ctkill++;
handled |= CSR_INT_BIT_CT_KILL;
}
@@ -1176,6 +1056,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
if (inta & CSR_INT_BIT_SW_ERR) {
IWL_ERR(priv, "Microcode SW error detected. "
" Restarting 0x%X.\n", inta);
+ priv->isr_stats.sw++;
+ priv->isr_stats.sw_err = inta;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
@@ -1191,6 +1073,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
iwl_txq_update_write_ptr(priv, &priv->txq[4]);
iwl_txq_update_write_ptr(priv, &priv->txq[5]);
+ priv->isr_stats.wakeup++;
+
handled |= CSR_INT_BIT_WAKEUP;
}
@@ -1199,23 +1083,27 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
* notifications from uCode come through here*/
if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
iwl_rx_handle(priv);
+ priv->isr_stats.rx++;
handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
}
if (inta & CSR_INT_BIT_FH_TX) {
IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+ priv->isr_stats.tx++;
handled |= CSR_INT_BIT_FH_TX;
/* FH finished to write, send event */
priv->ucode_write_complete = 1;
wake_up_interruptible(&priv->wait_command_queue);
}
- if (inta & ~handled)
+ if (inta & ~handled) {
IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
+ priv->isr_stats.unhandled++;
+ }
- if (inta & ~CSR_INI_SET_MASK) {
+ if (inta & ~(priv->inta_mask)) {
IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
- inta & ~CSR_INI_SET_MASK);
+ inta & ~priv->inta_mask);
IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh);
}
@@ -1236,6 +1124,200 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
}
+/* tasklet for iwlagn interrupt */
+static void iwl_irq_tasklet(struct iwl_priv *priv)
+{
+ u32 inta = 0;
+ u32 handled = 0;
+ unsigned long flags;
+#ifdef CONFIG_IWLWIFI_DEBUG
+ u32 inta_mask;
+#endif
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* Ack/clear/reset pending uCode interrupts.
+ * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
+ */
+ iwl_write32(priv, CSR_INT, priv->inta);
+
+ inta = priv->inta;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->debug_level & IWL_DL_ISR) {
+ /* just for debug */
+ inta_mask = iwl_read32(priv, CSR_INT_MASK);
+ IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x\n ",
+ inta, inta_mask);
+ }
+#endif
+ /* saved interrupt in inta variable now we can reset priv->inta */
+ priv->inta = 0;
+
+ /* Now service all interrupt bits discovered above. */
+ if (inta & CSR_INT_BIT_HW_ERR) {
+ IWL_ERR(priv, "Microcode HW error detected. Restarting.\n");
+
+ /* Tell the device to stop sending interrupts */
+ iwl_disable_interrupts(priv);
+
+ priv->isr_stats.hw++;
+ iwl_irq_handle_error(priv);
+
+ handled |= CSR_INT_BIT_HW_ERR;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return;
+ }
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->debug_level & (IWL_DL_ISR)) {
+ /* NIC fires this, but we don't use it, redundant with WAKEUP */
+ if (inta & CSR_INT_BIT_SCD) {
+ IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
+ "the frame/frames.\n");
+ priv->isr_stats.sch++;
+ }
+
+ /* Alive notification via Rx interrupt will do the real work */
+ if (inta & CSR_INT_BIT_ALIVE) {
+ IWL_DEBUG_ISR(priv, "Alive interrupt\n");
+ priv->isr_stats.alive++;
+ }
+ }
+#endif
+ /* Safely ignore these bits for debug checks below */
+ inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
+
+ /* HW RF KILL switch toggled */
+ if (inta & CSR_INT_BIT_RF_KILL) {
+ int hw_rf_kill = 0;
+ if (!(iwl_read32(priv, CSR_GP_CNTRL) &
+ CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
+ hw_rf_kill = 1;
+
+ IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
+ hw_rf_kill ? "disable radio" : "enable radio");
+
+ priv->isr_stats.rfkill++;
+
+ /* driver only loads ucode once setting the interface up.
+ * the driver allows loading the ucode even if the radio
+ * is killed. Hence update the killswitch state here. The
+ * rfkill handler will care about restarting if needed.
+ */
+ if (!test_bit(STATUS_ALIVE, &priv->status)) {
+ if (hw_rf_kill)
+ set_bit(STATUS_RF_KILL_HW, &priv->status);
+ else
+ clear_bit(STATUS_RF_KILL_HW, &priv->status);
+ wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
+ }
+
+ handled |= CSR_INT_BIT_RF_KILL;
+ }
+
+ /* Chip got too hot and stopped itself */
+ if (inta & CSR_INT_BIT_CT_KILL) {
+ IWL_ERR(priv, "Microcode CT kill error detected.\n");
+ priv->isr_stats.ctkill++;
+ handled |= CSR_INT_BIT_CT_KILL;
+ }
+
+ /* Error detected by uCode */
+ if (inta & CSR_INT_BIT_SW_ERR) {
+ IWL_ERR(priv, "Microcode SW error detected. "
+ " Restarting 0x%X.\n", inta);
+ priv->isr_stats.sw++;
+ priv->isr_stats.sw_err = inta;
+ iwl_irq_handle_error(priv);
+ handled |= CSR_INT_BIT_SW_ERR;
+ }
+
+ /* uCode wakes up after power-down sleep */
+ if (inta & CSR_INT_BIT_WAKEUP) {
+ IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
+ iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
+ iwl_txq_update_write_ptr(priv, &priv->txq[0]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[1]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[2]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[3]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[4]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[5]);
+
+ priv->isr_stats.wakeup++;
+
+ handled |= CSR_INT_BIT_WAKEUP;
+ }
+
+ /* All uCode command responses, including Tx command responses,
+ * Rx "responses" (frame-received notification), and other
+ * notifications from uCode come through here*/
+ if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX |
+ CSR_INT_BIT_RX_PERIODIC)) {
+ IWL_DEBUG_ISR(priv, "Rx interrupt\n");
+ if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
+ handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
+ iwl_write32(priv, CSR_FH_INT_STATUS,
+ CSR49_FH_INT_RX_MASK);
+ }
+ if (inta & CSR_INT_BIT_RX_PERIODIC) {
+ handled |= CSR_INT_BIT_RX_PERIODIC;
+ iwl_write32(priv, CSR_INT, CSR_INT_BIT_RX_PERIODIC);
+ }
+ /* Sending RX interrupt require many steps to be done in the
+ * the device:
+ * 1- write interrupt to current index in ICT table.
+ * 2- dma RX frame.
+ * 3- update RX shared data to indicate last write index.
+ * 4- send interrupt.
+ * This could lead to RX race, driver could receive RX interrupt
+ * but the shared data changes does not reflect this.
+ * this could lead to RX race, RX periodic will solve this race
+ */
+ iwl_write32(priv, CSR_INT_PERIODIC_REG,
+ CSR_INT_PERIODIC_DIS);
+ iwl_rx_handle(priv);
+ /* Only set RX periodic if real RX is received. */
+ if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX))
+ iwl_write32(priv, CSR_INT_PERIODIC_REG,
+ CSR_INT_PERIODIC_ENA);
+
+ priv->isr_stats.rx++;
+ }
+
+ if (inta & CSR_INT_BIT_FH_TX) {
+ iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK);
+ IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+ priv->isr_stats.tx++;
+ handled |= CSR_INT_BIT_FH_TX;
+ /* FH finished to write, send event */
+ priv->ucode_write_complete = 1;
+ wake_up_interruptible(&priv->wait_command_queue);
+ }
+
+ if (inta & ~handled) {
+ IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
+ priv->isr_stats.unhandled++;
+ }
+
+ if (inta & ~(priv->inta_mask)) {
+ IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
+ inta & ~priv->inta_mask);
+ }
+
+
+ /* Re-enable all interrupts */
+ /* only Re-enable if diabled by irq */
+ if (test_bit(STATUS_INT_ENABLED, &priv->status))
+ iwl_enable_interrupts(priv);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+}
+
+
/******************************************************************************
*
* uCode download functions
@@ -1501,10 +1583,6 @@ static int iwl_read_ucode(struct iwl_priv *priv)
return ret;
}
-/* temporary */
-static int iwl_mac_beacon_update(struct ieee80211_hw *hw,
- struct sk_buff *skb);
-
/**
* iwl_alive_start - called after REPLY_ALIVE notification received
* from protocol/runtime uCode (initialization uCode's
@@ -1561,7 +1639,10 @@ static void iwl_alive_start(struct iwl_priv *priv)
} else {
/* Initialize our rx_config data */
iwl_connection_init_rx_config(priv, priv->iw_mode);
- iwl_set_rxon_chain(priv);
+
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
}
@@ -1571,7 +1652,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl_reset_run_time_calib(priv);
/* Configure the adapter for unassociated operation */
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
/* At this point, the NIC is initialized and operational */
iwl_rf_kill_ct_config(priv);
@@ -1582,9 +1663,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
set_bit(STATUS_READY, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
- if (priv->error_recovering)
- iwl_error_recovery(priv);
-
iwl_power_update_mode(priv, 1);
/* reassociate for ADHOC mode */
@@ -1642,36 +1720,30 @@ static void __iwl_down(struct iwl_priv *priv)
ieee80211_stop_queues(priv->hw);
/* If we have not previously called iwl_init() then
- * clear all bits but the RF Kill and SUSPEND bits and return */
+ * clear all bits but the RF Kill bit and return */
if (!iwl_is_init(priv)) {
priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
- test_bit(STATUS_RF_KILL_SW, &priv->status) <<
- STATUS_RF_KILL_SW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
- test_bit(STATUS_IN_SUSPEND, &priv->status) <<
- STATUS_IN_SUSPEND |
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
STATUS_EXIT_PENDING;
goto exit;
}
- /* ...otherwise clear out all the status bits but the RF Kill and
- * SUSPEND bits and continue taking the NIC down. */
+ /* ...otherwise clear out all the status bits but the RF Kill
+ * bit and continue taking the NIC down. */
priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
- test_bit(STATUS_RF_KILL_SW, &priv->status) <<
- STATUS_RF_KILL_SW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
- test_bit(STATUS_IN_SUSPEND, &priv->status) <<
- STATUS_IN_SUSPEND |
test_bit(STATUS_FW_ERROR, &priv->status) <<
STATUS_FW_ERROR |
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
STATUS_EXIT_PENDING;
+ /* device going down, Stop using ICT table */
+ iwl_disable_ict(priv);
spin_lock_irqsave(&priv->lock, flags);
iwl_clear_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
@@ -1680,18 +1752,13 @@ static void __iwl_down(struct iwl_priv *priv)
iwl_txq_ctx_stop(priv);
iwl_rxq_stop(priv);
- spin_lock_irqsave(&priv->lock, flags);
- if (!iwl_grab_nic_access(priv)) {
- iwl_write_prph(priv, APMG_CLK_DIS_REG,
- APMG_CLK_VAL_DMA_CLK_RQT);
- iwl_release_nic_access(priv);
- }
- spin_unlock_irqrestore(&priv->lock, flags);
+ iwl_write_prph(priv, APMG_CLK_DIS_REG,
+ APMG_CLK_VAL_DMA_CLK_RQT);
udelay(5);
/* FIXME: apm_ops.suspend(priv) */
- if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+ if (exit_pending)
priv->cfg->ops->lib->apm_ops.stop(priv);
else
priv->cfg->ops->lib->apm_ops.reset(priv);
@@ -1715,6 +1782,49 @@ static void iwl_down(struct iwl_priv *priv)
iwl_cancel_deferred_work(priv);
}
+#define HW_READY_TIMEOUT (50)
+
+static int iwl_set_hw_ready(struct iwl_priv *priv)
+{
+ int ret = 0;
+
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
+
+ /* See if we got it */
+ ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
+ CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
+ HW_READY_TIMEOUT);
+ if (ret != -ETIMEDOUT)
+ priv->hw_ready = true;
+ else
+ priv->hw_ready = false;
+
+ IWL_DEBUG_INFO(priv, "hardware %s\n",
+ (priv->hw_ready == 1) ? "ready" : "not ready");
+ return ret;
+}
+
+static int iwl_prepare_card_hw(struct iwl_priv *priv)
+{
+ int ret = 0;
+
+ IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter \n");
+
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_PREPARE);
+
+ ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+ ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
+ CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
+
+ if (ret != -ETIMEDOUT)
+ iwl_set_hw_ready(priv);
+
+ return ret;
+}
+
#define MAX_HW_RESTARTS 5
static int __iwl_up(struct iwl_priv *priv)
@@ -1732,6 +1842,13 @@ static int __iwl_up(struct iwl_priv *priv)
return -EIO;
}
+ iwl_prepare_card_hw(priv);
+
+ if (!priv->hw_ready) {
+ IWL_WARN(priv, "Exit HW not ready\n");
+ return -EIO;
+ }
+
/* If platform's RF_KILL switch is NOT set to KILL */
if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
clear_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -1739,9 +1856,10 @@ static int __iwl_up(struct iwl_priv *priv)
set_bit(STATUS_RF_KILL_HW, &priv->status);
if (iwl_is_rfkill(priv)) {
+ wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
+
iwl_enable_interrupts(priv);
- IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n",
- test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
+ IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
return 0;
}
@@ -1787,9 +1905,6 @@ static int __iwl_up(struct iwl_priv *priv)
continue;
}
- /* Clear out the uCode error bit if it is set */
- clear_bit(STATUS_FW_ERROR, &priv->status);
-
/* start card; "initialize" will load runtime ucode */
iwl_nic_start(priv);
@@ -1836,6 +1951,9 @@ static void iwl_bg_alive_start(struct work_struct *data)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
+ /* enable dram interrupt */
+ iwl_reset_ict(priv);
+
mutex_lock(&priv->mutex);
iwl_alive_start(priv);
mutex_unlock(&priv->mutex);
@@ -1874,7 +1992,6 @@ static void iwl_bg_up(struct work_struct *data)
mutex_lock(&priv->mutex);
__iwl_up(priv);
mutex_unlock(&priv->mutex);
- iwl_rfkill_set_hw_state(priv);
}
static void iwl_bg_restart(struct work_struct *data)
@@ -1884,8 +2001,17 @@ static void iwl_bg_restart(struct work_struct *data)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- iwl_down(priv);
- queue_work(priv->workqueue, &priv->up);
+ if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
+ mutex_lock(&priv->mutex);
+ priv->vif = NULL;
+ priv->is_open = 0;
+ mutex_unlock(&priv->mutex);
+ iwl_down(priv);
+ ieee80211_restart_hw(priv->hw);
+ } else {
+ iwl_down(priv);
+ queue_work(priv->workqueue, &priv->up);
+ }
}
static void iwl_bg_rx_replenish(struct work_struct *data)
@@ -1903,7 +2029,7 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
#define IWL_DELAY_NEXT_SCAN (HZ*2)
-static void iwl_post_associate(struct iwl_priv *priv)
+void iwl_post_associate(struct iwl_priv *priv)
{
struct ieee80211_conf *conf = NULL;
int ret = 0;
@@ -1925,13 +2051,12 @@ static void iwl_post_associate(struct iwl_priv *priv)
if (!priv->vif || !priv->is_open)
return;
- iwl_power_cancel_timeout(priv);
iwl_scan_cancel_timeout(priv, 200);
conf = ieee80211_get_hw_conf(priv->hw);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
iwl_setup_rxon_timing(priv);
ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
@@ -1944,7 +2069,9 @@ static void iwl_post_associate(struct iwl_priv *priv)
iwl_set_rxon_ht(priv, &priv->current_ht_config);
- iwl_set_rxon_chain(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
@@ -1966,7 +2093,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
}
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
switch (priv->iw_mode) {
case NL80211_IFTYPE_STATION:
@@ -1999,7 +2126,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
* If chain noise has already been run, then we need to enable
* power management here */
if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
- iwl_power_enable_management(priv);
+ iwl_power_update_mode(priv, 0);
/* Enable Rx differential gain and sensitivity calibrations */
iwl_chain_noise_reset(priv);
@@ -2042,8 +2169,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
mutex_unlock(&priv->mutex);
- iwl_rfkill_set_hw_state(priv);
-
if (ret)
return ret;
@@ -2052,9 +2177,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
IWL_DEBUG_INFO(priv, "Start UP work done.\n");
- if (test_bit(STATUS_IN_SUSPEND, &priv->status))
- return 0;
-
/* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
* mac80211 will not be run successfully. */
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
@@ -2080,10 +2202,8 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
IWL_DEBUG_MAC80211(priv, "enter\n");
- if (!priv->is_open) {
- IWL_DEBUG_MAC80211(priv, "leave - skip\n");
+ if (!priv->is_open)
return;
- }
priv->is_open = 0;
@@ -2123,175 +2243,7 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}
-static int iwl_mac_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
-
- IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
-
- if (priv->vif) {
- IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
- return -EOPNOTSUPP;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->vif = conf->vif;
- priv->iw_mode = conf->type;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- mutex_lock(&priv->mutex);
-
- if (conf->mac_addr) {
- IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
- memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
- }
-
- if (iwl_set_mode(priv, conf->type) == -EAGAIN)
- /* we are not ready, will run again when ready */
- set_bit(STATUS_MODE_PENDING, &priv->status);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- return 0;
-}
-
-/**
- * iwl_mac_config - mac80211 config callback
- *
- * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to
- * be set inappropriately and the driver currently sets the hardware up to
- * use it whenever needed.
- */
-static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
-{
- struct iwl_priv *priv = hw->priv;
- const struct iwl_channel_info *ch_info;
- struct ieee80211_conf *conf = &hw->conf;
- unsigned long flags = 0;
- int ret = 0;
- u16 ch;
- int scan_active = 0;
-
- mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
- conf->channel->hw_value, changed);
-
- if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
- test_bit(STATUS_SCANNING, &priv->status))) {
- scan_active = 1;
- IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
- }
-
-
- /* during scanning mac80211 will delay channel setting until
- * scan finish with changed = 0
- */
- if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
- if (scan_active)
- goto set_ch_out;
-
- ch = ieee80211_frequency_to_channel(conf->channel->center_freq);
- ch_info = iwl_get_channel_info(priv, conf->channel->band, ch);
- if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
- ret = -EINVAL;
- goto set_ch_out;
- }
-
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
- !is_channel_ibss(ch_info)) {
- IWL_ERR(priv, "channel %d in band %d not "
- "IBSS channel\n",
- conf->channel->hw_value, conf->channel->band);
- ret = -EINVAL;
- goto set_ch_out;
- }
-
- priv->current_ht_config.is_ht = conf_is_ht(conf);
-
- spin_lock_irqsave(&priv->lock, flags);
-
-
- /* if we are switching from ht to 2.4 clear flags
- * from any ht related info since 2.4 does not
- * support ht */
- if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
- priv->staging_rxon.flags = 0;
-
- iwl_set_rxon_channel(priv, conf->channel);
-
- iwl_set_flags_for_band(priv, conf->channel->band);
- spin_unlock_irqrestore(&priv->lock, flags);
- set_ch_out:
- /* The list of supported rates and rate mask can be different
- * for each band; since the band may have changed, reset
- * the rate mask to what mac80211 lists */
- iwl_set_rate(priv);
- }
-
- if (changed & IEEE80211_CONF_CHANGE_PS) {
- if (conf->flags & IEEE80211_CONF_PS)
- ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3);
- else
- ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM);
- if (ret)
- IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
-
- }
-
- if (changed & IEEE80211_CONF_CHANGE_POWER) {
- IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
- priv->tx_power_user_lmt, conf->power_level);
-
- iwl_set_tx_power(priv, conf->power_level, false);
- }
-
- /* call to ensure that 4965 rx_chain is set properly in monitor mode */
- iwl_set_rxon_chain(priv);
-
- if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
- if (conf->radio_enabled &&
- iwl_radio_kill_sw_enable_radio(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
- "waiting for uCode\n");
- goto out;
- }
-
- if (!conf->radio_enabled)
- iwl_radio_kill_sw_disable_radio(priv);
- }
-
- if (!conf->radio_enabled) {
- IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
- goto out;
- }
-
- if (!iwl_is_ready(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- goto out;
- }
-
- if (scan_active)
- goto out;
-
- if (memcmp(&priv->active_rxon,
- &priv->staging_rxon, sizeof(priv->staging_rxon)))
- iwl_commit_rxon(priv);
- else
- IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n");
-
-
-out:
- IWL_DEBUG_MAC80211(priv, "leave\n");
- mutex_unlock(&priv->mutex);
- return ret;
-}
-
-static void iwl_config_ap(struct iwl_priv *priv)
+void iwl_config_ap(struct iwl_priv *priv)
{
int ret = 0;
unsigned long flags;
@@ -2304,7 +2256,7 @@ static void iwl_config_ap(struct iwl_priv *priv)
/* RXON - unassoc (to set timing command) */
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
/* RXON Timing */
iwl_setup_rxon_timing(priv);
@@ -2314,7 +2266,8 @@ static void iwl_config_ap(struct iwl_priv *priv)
IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
- iwl_set_rxon_chain(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
/* FIXME: what should be the assoc_id for AP? */
priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
@@ -2340,7 +2293,7 @@ static void iwl_config_ap(struct iwl_priv *priv)
}
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
spin_lock_irqsave(&priv->lock, flags);
iwl_activate_qos(priv, 1);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -2353,194 +2306,6 @@ static void iwl_config_ap(struct iwl_priv *priv)
* clear sta table, add BCAST sta... */
}
-
-static int iwl_mac_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
- int rc;
-
- if (conf == NULL)
- return -EIO;
-
- if (priv->vif != vif) {
- IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
- return 0;
- }
-
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
- conf->changed & IEEE80211_IFCC_BEACON) {
- struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
- if (!beacon)
- return -ENOMEM;
- mutex_lock(&priv->mutex);
- rc = iwl_mac_beacon_update(hw, beacon);
- mutex_unlock(&priv->mutex);
- if (rc)
- return rc;
- }
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- mutex_lock(&priv->mutex);
-
- if (conf->bssid)
- IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
-
-/*
- * very dubious code was here; the probe filtering flag is never set:
- *
- if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) &&
- !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
- */
-
- if (priv->iw_mode == NL80211_IFTYPE_AP) {
- if (!conf->bssid) {
- conf->bssid = priv->mac_addr;
- memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
- IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
- conf->bssid);
- }
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
- }
-
- if (iwl_is_rfkill(priv))
- goto done;
-
- if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
- !is_multicast_ether_addr(conf->bssid)) {
- /* If there is currently a HW scan going on in the background
- * then we need to cancel it else the RXON below will fail. */
- if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARN(priv, "Aborted scan still in progress "
- "after 100ms\n");
- IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
- mutex_unlock(&priv->mutex);
- return -EAGAIN;
- }
- memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN);
-
- /* TODO: Audit driver for usage of these members and see
- * if mac80211 deprecates them (priv->bssid looks like it
- * shouldn't be there, but I haven't scanned the IBSS code
- * to verify) - jpk */
- memcpy(priv->bssid, conf->bssid, ETH_ALEN);
-
- if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl_config_ap(priv);
- else {
- rc = iwl_commit_rxon(priv);
- if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
- iwl_rxon_add_station(
- priv, priv->active_rxon.bssid_addr, 1);
- }
-
- } else {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
- }
-
- done:
- IWL_DEBUG_MAC80211(priv, "leave\n");
- mutex_unlock(&priv->mutex);
-
- return 0;
-}
-
-static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- mutex_lock(&priv->mutex);
-
- if (iwl_is_ready_rf(priv)) {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
- }
- if (priv->vif == conf->vif) {
- priv->vif = NULL;
- memset(priv->bssid, 0, ETH_ALEN);
- }
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
-}
-
-#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
-static void iwl_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changes)
-{
- struct iwl_priv *priv = hw->priv;
-
- IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
-
- if (changes & BSS_CHANGED_ERP_PREAMBLE) {
- IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
- bss_conf->use_short_preamble);
- if (bss_conf->use_short_preamble)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- }
-
- if (changes & BSS_CHANGED_ERP_CTS_PROT) {
- IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
- if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
- priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
- else
- priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
- }
-
- if (changes & BSS_CHANGED_HT) {
- iwl_ht_conf(priv, bss_conf);
- iwl_set_rxon_chain(priv);
- }
-
- if (changes & BSS_CHANGED_ASSOC) {
- IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
- /* This should never happen as this function should
- * never be called from interrupt context. */
- if (WARN_ON_ONCE(in_interrupt()))
- return;
- if (bss_conf->assoc) {
- priv->assoc_id = bss_conf->aid;
- priv->beacon_int = bss_conf->beacon_int;
- priv->power_data.dtim_period = bss_conf->dtim_period;
- priv->timestamp = bss_conf->timestamp;
- priv->assoc_capability = bss_conf->assoc_capability;
-
- /* we have just associated, don't start scan too early
- * leave time for EAPOL exchange to complete
- */
- priv->next_scan_jiffies = jiffies +
- IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
- mutex_lock(&priv->mutex);
- iwl_post_associate(priv);
- mutex_unlock(&priv->mutex);
- } else {
- priv->assoc_id = 0;
- IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc);
- }
- } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
- IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes);
- iwl_send_rxon_assoc(priv);
- }
-
-}
-
static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
struct ieee80211_key_conf *keyconf, const u8 *addr,
u32 iv32, u16 *phase1key)
@@ -2623,49 +2388,6 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return ret;
}
-static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
- const struct ieee80211_tx_queue_params *params)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- int q;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- if (queue >= AC_NUM) {
- IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
- return 0;
- }
-
- q = AC_NUM - 1 - queue;
-
- spin_lock_irqsave(&priv->lock, flags);
-
- priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
- priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
- priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
- priv->qos_data.def_qos_parm.ac[q].edca_txop =
- cpu_to_le16((params->txop * 32));
-
- priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
- priv->qos_data.qos_active = 1;
-
- if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl_activate_qos(priv, 1);
- else if (priv->assoc_id && iwl_is_associated(priv))
- iwl_activate_qos(priv, 0);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- return 0;
-}
-
static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
enum ieee80211_ampdu_mlme_action action,
struct ieee80211_sta *sta, u16 tid, u16 *ssn)
@@ -2708,41 +2430,6 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
return 0;
}
-static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
- struct ieee80211_tx_queue_stats *stats)
-{
- struct iwl_priv *priv = hw->priv;
- int i, avail;
- struct iwl_tx_queue *txq;
- struct iwl_queue *q;
- unsigned long flags;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- for (i = 0; i < AC_NUM; i++) {
- txq = &priv->txq[i];
- q = &txq->q;
- avail = iwl_queue_space(q);
-
- stats[i].len = q->n_window - avail;
- stats[i].limit = q->n_window - q->high_mark;
- stats[i].count = q->n_window;
-
- }
- spin_unlock_irqrestore(&priv->lock, flags);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
- return 0;
-}
-
static int iwl_mac_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats)
{
@@ -2755,120 +2442,6 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw,
return 0;
}
-static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
-
- mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- spin_lock_irqsave(&priv->lock, flags);
- memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
- spin_unlock_irqrestore(&priv->lock, flags);
-
- iwl_reset_qos(priv);
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->assoc_id = 0;
- priv->assoc_capability = 0;
- priv->assoc_station_added = 0;
-
- /* new association get rid of ibss beacon skb */
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = NULL;
-
- priv->beacon_int = priv->hw->conf.beacon_int;
- priv->timestamp = 0;
- if ((priv->iw_mode == NL80211_IFTYPE_STATION))
- priv->beacon_int = 0;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- mutex_unlock(&priv->mutex);
- return;
- }
-
- /* we are restarting association process
- * clear RXON_FILTER_ASSOC_MSK bit
- */
- if (priv->iw_mode != NL80211_IFTYPE_AP) {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl_commit_rxon(priv);
- }
-
- iwl_power_update_mode(priv, 0);
-
- /* Per mac80211.h: This is only used in IBSS mode... */
- if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
-
- /* switch to CAM during association period.
- * the ucode will block any association/authentication
- * frome during assiciation period if it can not hear
- * the AP because of PM. the timer enable PM back is
- * association do not complete
- */
- if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN |
- IEEE80211_CHAN_RADAR))
- iwl_power_disable_management(priv, 3000);
-
- IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
- mutex_unlock(&priv->mutex);
- return;
- }
-
- iwl_set_rate(priv);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
-static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- __le64 timestamp;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
- IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
- return -EIO;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = skb;
-
- priv->assoc_id = 0;
- timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
- priv->timestamp = le64_to_cpu(timestamp);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- spin_unlock_irqrestore(&priv->lock, flags);
-
- iwl_reset_qos(priv);
-
- iwl_post_associate(priv);
-
-
- return 0;
-}
-
/*****************************************************************************
*
* sysfs attributes
@@ -2888,7 +2461,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
static ssize_t show_debug_level(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%08X\n", priv->debug_level);
}
@@ -2896,7 +2469,7 @@ static ssize_t store_debug_level(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
unsigned long val;
int ret;
@@ -2919,7 +2492,7 @@ static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
static ssize_t show_version(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
struct iwl_alive_resp *palive = &priv->card_alive;
ssize_t pos = 0;
u16 eeprom_ver;
@@ -2936,8 +2509,10 @@ static ssize_t show_version(struct device *d,
if (priv->eeprom) {
eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
- pos += sprintf(buf + pos, "EEPROM version: 0x%x\n",
- eeprom_ver);
+ pos += sprintf(buf + pos, "NVM Type: %s, version: 0x%x\n",
+ (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
+ ? "OTP" : "EEPROM", eeprom_ver);
+
} else {
pos += sprintf(buf + pos, "EEPROM not initialzed\n");
}
@@ -2950,7 +2525,7 @@ static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL);
static ssize_t show_temperature(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
if (!iwl_is_alive(priv))
return -EAGAIN;
@@ -2963,7 +2538,7 @@ static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
static ssize_t show_tx_power(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
if (!iwl_is_ready_rf(priv))
return sprintf(buf, "off\n");
@@ -2975,7 +2550,7 @@ static ssize_t store_tx_power(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
unsigned long val;
int ret;
@@ -2993,7 +2568,7 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
static ssize_t show_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
}
@@ -3002,7 +2577,7 @@ static ssize_t store_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
unsigned long val;
u32 flags;
int ret = strict_strtoul(buf, 0, &val);
@@ -3018,7 +2593,7 @@ static ssize_t store_flags(struct device *d,
else {
IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags);
priv->staging_rxon.flags = cpu_to_le32(flags);
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
}
}
mutex_unlock(&priv->mutex);
@@ -3031,7 +2606,7 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags);
static ssize_t show_filter_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%04X\n",
le32_to_cpu(priv->active_rxon.filter_flags));
@@ -3041,7 +2616,7 @@ static ssize_t store_filter_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
unsigned long val;
u32 filter_flags;
int ret = strict_strtoul(buf, 0, &val);
@@ -3059,7 +2634,7 @@ static ssize_t store_filter_flags(struct device *d,
"0x%04X\n", filter_flags);
priv->staging_rxon.filter_flags =
cpu_to_le32(filter_flags);
- iwl_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
}
}
mutex_unlock(&priv->mutex);
@@ -3102,32 +2677,37 @@ static ssize_t show_power_level(struct device *d,
{
struct iwl_priv *priv = dev_get_drvdata(d);
int mode = priv->power_data.user_power_setting;
- int system = priv->power_data.system_power_setting;
int level = priv->power_data.power_mode;
char *p = buf;
- switch (system) {
- case IWL_POWER_SYS_AUTO:
- p += sprintf(p, "SYSTEM:auto");
- break;
- case IWL_POWER_SYS_AC:
- p += sprintf(p, "SYSTEM:ac");
- break;
- case IWL_POWER_SYS_BATTERY:
- p += sprintf(p, "SYSTEM:battery");
- break;
- }
-
- p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
- "fixed" : "auto");
- p += sprintf(p, "\tINDEX:%d", level);
- p += sprintf(p, "\n");
+ p += sprintf(p, "INDEX:%d\t", level);
+ p += sprintf(p, "USER:%d\n", mode);
return p - buf + 1;
}
static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
store_power_level);
+static ssize_t show_qos(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct iwl_priv *priv = dev_get_drvdata(d);
+ char *p = buf;
+ int q;
+
+ for (q = 0; q < AC_NUM; q++) {
+ p += sprintf(p, "\tcw_min\tcw_max\taifsn\ttxop\n");
+ p += sprintf(p, "AC[%d]\t%u\t%u\t%u\t%u\n", q,
+ priv->qos_data.def_qos_parm.ac[q].cw_min,
+ priv->qos_data.def_qos_parm.ac[q].cw_max,
+ priv->qos_data.def_qos_parm.ac[q].aifsn,
+ priv->qos_data.def_qos_parm.ac[q].edca_txop);
+ }
+
+ return p - buf + 1;
+}
+
+static DEVICE_ATTR(qos, S_IRUGO, show_qos, NULL);
static ssize_t show_statistics(struct device *d,
struct device_attribute *attr, char *buf)
@@ -3183,14 +2763,12 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->up, iwl_bg_up);
INIT_WORK(&priv->restart, iwl_bg_restart);
INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
- INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
iwl_setup_scan_deferred_work(priv);
- iwl_setup_power_deferred_work(priv);
if (priv->cfg->ops->lib->setup_deferred_work)
priv->cfg->ops->lib->setup_deferred_work(priv);
@@ -3199,8 +2777,12 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
priv->statistics_periodic.data = (unsigned long)priv;
priv->statistics_periodic.function = iwl_bg_statistics_periodic;
- tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
- iwl_irq_tasklet, (unsigned long)priv);
+ if (!priv->cfg->use_isr_legacy)
+ tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+ iwl_irq_tasklet, (unsigned long)priv);
+ else
+ tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+ iwl_irq_tasklet_legacy, (unsigned long)priv);
}
static void iwl_cancel_deferred_work(struct iwl_priv *priv)
@@ -3210,7 +2792,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
cancel_delayed_work_sync(&priv->init_alive_start);
cancel_delayed_work(&priv->scan_check);
- cancel_delayed_work_sync(&priv->set_power_save);
cancel_delayed_work(&priv->alive_start);
cancel_work_sync(&priv->beacon_update);
del_timer_sync(&priv->statistics_periodic);
@@ -3227,7 +2808,7 @@ static struct attribute *iwl_sysfs_entries[] = {
&dev_attr_debug_level.attr,
#endif
&dev_attr_version.attr,
-
+ &dev_attr_qos.attr,
NULL
};
@@ -3243,7 +2824,6 @@ static struct ieee80211_ops iwl_hw_ops = {
.add_interface = iwl_mac_add_interface,
.remove_interface = iwl_mac_remove_interface,
.config = iwl_mac_config,
- .config_interface = iwl_mac_config_interface,
.configure_filter = iwl_configure_filter,
.set_key = iwl_mac_set_key,
.update_tkip_key = iwl_mac_update_tkip_key,
@@ -3291,6 +2871,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
priv->cfg = cfg;
priv->pci_dev = pdev;
+ priv->inta_mask = CSR_INI_SET_MASK;
#ifdef CONFIG_IWLWIFI_DEBUG
priv->debug_level = priv->cfg->mod_params->debug;
@@ -3341,6 +2922,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
(unsigned long long) pci_resource_len(pdev, 0));
IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base);
+ /* this spin lock will be used in apm_ops.init and EEPROM access
+ * we should init now
+ */
+ spin_lock_init(&priv->reg_lock);
iwl_hw_detect(priv);
IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n",
priv->cfg->name, priv->hw_rev);
@@ -3349,6 +2934,12 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* PCI Tx retries from interfering with C3 CPU state */
pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
+ iwl_prepare_card_hw(priv);
+ if (!priv->hw_ready) {
+ IWL_WARN(priv, "Failed, HW not ready\n");
+ goto out_iounmap;
+ }
+
/* amp init */
err = priv->cfg->ops->lib->apm_ops.init(priv);
if (err < 0) {
@@ -3390,18 +2981,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto out_free_eeprom;
/* At this point both hw and priv are initialized. */
- /**********************************
- * 7. Initialize module parameters
- **********************************/
-
- /* Disable radio (SW RF KILL) via parameter when loading driver */
- if (priv->cfg->mod_params->disable) {
- set_bit(STATUS_RF_KILL_SW, &priv->status);
- IWL_DEBUG_INFO(priv, "Radio disabled.\n");
- }
-
/********************
- * 8. Setup services
+ * 7. Setup services
********************/
spin_lock_irqsave(&priv->lock, flags);
iwl_disable_interrupts(priv);
@@ -3409,8 +2990,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_enable_msi(priv->pci_dev);
- err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
- DRV_NAME, priv);
+ iwl_alloc_isr_ict(priv);
+ err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr,
+ IRQF_SHARED, DRV_NAME, priv);
if (err) {
IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
goto out_disable_msi;
@@ -3425,7 +3007,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iwl_setup_rx_handlers(priv);
/**********************************
- * 9. Setup and register mac80211
+ * 8. Setup and register mac80211
**********************************/
/* enable interrupts if needed: hw bug w/a */
@@ -3443,7 +3025,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err = iwl_dbgfs_register(priv, DRV_NAME);
if (err)
- IWL_ERR(priv, "failed to create debugfs files\n");
+ IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
/* If platform's RF_KILL switch is NOT set to KILL */
if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
@@ -3451,12 +3033,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
else
set_bit(STATUS_RF_KILL_HW, &priv->status);
- err = iwl_rfkill_init(priv);
- if (err)
- IWL_ERR(priv, "Unable to initialize RFKILL system. "
- "Ignoring error: %d\n", err);
- else
- iwl_rfkill_set_hw_state(priv);
+ wiphy_rfkill_set_hw_state(priv->hw->wiphy,
+ test_bit(STATUS_RF_KILL_HW, &priv->status));
iwl_power_initialize(priv);
return 0;
@@ -3467,6 +3045,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
out_free_irq:
free_irq(priv->pci_dev->irq, priv);
+ iwl_free_isr_ict(priv);
out_disable_msi:
pci_disable_msi(priv->pci_dev);
iwl_uninit_drv(priv);
@@ -3519,7 +3098,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
iwl_synchronize_irq(priv);
- iwl_rfkill_unregister(priv);
iwl_dealloc_ucode_pci(priv);
if (priv->rxq.bd)
@@ -3548,51 +3126,14 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
iwl_uninit_drv(priv);
+ iwl_free_isr_ict(priv);
+
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
ieee80211_free_hw(priv->hw);
}
-#ifdef CONFIG_PM
-
-static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct iwl_priv *priv = pci_get_drvdata(pdev);
-
- if (priv->is_open) {
- set_bit(STATUS_IN_SUSPEND, &priv->status);
- iwl_mac_stop(priv->hw);
- priv->is_open = 1;
- }
-
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
- return 0;
-}
-
-static int iwl_pci_resume(struct pci_dev *pdev)
-{
- struct iwl_priv *priv = pci_get_drvdata(pdev);
- int ret;
-
- pci_set_power_state(pdev, PCI_D0);
- ret = pci_enable_device(pdev);
- if (ret)
- return ret;
- pci_restore_state(pdev);
- iwl_enable_interrupts(priv);
-
- if (priv->is_open)
- iwl_mac_start(priv->hw);
-
- clear_bit(STATUS_IN_SUSPEND, &priv->status);
- return 0;
-}
-
-#endif /* CONFIG_PM */
/*****************************************************************************
*
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 735f3f19928..a5d63672ad3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -857,7 +857,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
priv->cfg->ops->lib->update_chain_flags(priv);
data->state = IWL_CHAIN_NOISE_DONE;
- iwl_power_enable_management(priv);
+ iwl_power_update_mode(priv, 0);
}
EXPORT_SYMBOL(iwl_chain_noise_calibration);
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 29d40746da6..c87033bf3ad 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -614,8 +614,18 @@ enum {
#define RXON_FLG_CHANNEL_MODE_POS (25)
#define RXON_FLG_CHANNEL_MODE_MSK cpu_to_le32(0x3 << 25)
-#define RXON_FLG_CHANNEL_MODE_PURE_40_MSK cpu_to_le32(0x1 << 25)
-#define RXON_FLG_CHANNEL_MODE_MIXED_MSK cpu_to_le32(0x2 << 25)
+
+/* channel mode */
+enum {
+ CHANNEL_MODE_LEGACY = 0,
+ CHANNEL_MODE_PURE_40 = 1,
+ CHANNEL_MODE_MIXED = 2,
+ CHANNEL_MODE_RESERVED = 3,
+};
+#define RXON_FLG_CHANNEL_MODE_LEGACY cpu_to_le32(CHANNEL_MODE_LEGACY << RXON_FLG_CHANNEL_MODE_POS)
+#define RXON_FLG_CHANNEL_MODE_PURE_40 cpu_to_le32(CHANNEL_MODE_PURE_40 << RXON_FLG_CHANNEL_MODE_POS)
+#define RXON_FLG_CHANNEL_MODE_MIXED cpu_to_le32(CHANNEL_MODE_MIXED << RXON_FLG_CHANNEL_MODE_POS)
+
/* CTS to self (if spec allows) flag */
#define RXON_FLG_SELF_CTS_EN cpu_to_le32(0x1<<30)
@@ -1057,7 +1067,7 @@ struct iwl_addsta_cmd {
* Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
__le16 tid_disable_tx;
- __le16 reserved1;
+ __le16 rate_n_flags; /* 3945 only */
/* TID for which to add block-ack support.
* Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
@@ -1903,6 +1913,18 @@ struct iwl_link_qual_general_params {
u8 start_rate_index[LINK_QUAL_AC_NUM];
} __attribute__ ((packed));
+#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
+#define LINK_QUAL_AGG_TIME_LIMIT_MAX (65535)
+#define LINK_QUAL_AGG_TIME_LIMIT_MIN (0)
+
+#define LINK_QUAL_AGG_DISABLE_START_DEF (3)
+#define LINK_QUAL_AGG_DISABLE_START_MAX (255)
+#define LINK_QUAL_AGG_DISABLE_START_MIN (0)
+
+#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (31)
+#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (64)
+#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0)
+
/**
* struct iwl_link_qual_agg_params
*
@@ -2469,11 +2491,12 @@ struct iwl_ssid_ie {
u8 ssid[32];
} __attribute__ ((packed));
-#define PROBE_OPTION_MAX_API1 0x4
-#define PROBE_OPTION_MAX 0x14
+#define PROBE_OPTION_MAX_3945 4
+#define PROBE_OPTION_MAX 20
#define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF)
#define IWL_GOOD_CRC_TH cpu_to_le16(1)
#define IWL_MAX_SCAN_SIZE 1024
+#define IWL_MAX_PROBE_REQUEST 200
/*
* REPLY_SCAN_CMD = 0x80 (command)
@@ -2552,7 +2575,7 @@ struct iwl3945_scan_cmd {
struct iwl3945_tx_cmd tx_cmd;
/* For directed active scans (set to all-0s otherwise) */
- struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_API1];
+ struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_3945];
/*
* Probe request frame, followed by channel list.
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index c54fb93e9d7..f9d16ca5b3d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -36,9 +36,9 @@
#include "iwl-debug.h"
#include "iwl-core.h"
#include "iwl-io.h"
-#include "iwl-rfkill.h"
#include "iwl-power.h"
#include "iwl-sta.h"
+#include "iwl-helpers.h"
MODULE_DESCRIPTION("iwl core");
@@ -59,6 +59,8 @@ MODULE_LICENSE("GPL");
IWL_RATE_##pp##M_INDEX, \
IWL_RATE_##np##M_INDEX }
+static irqreturn_t iwl_isr(int irq, void *data);
+
/*
* Parameter order:
* rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
@@ -273,6 +275,14 @@ void iwl_activate_qos(struct iwl_priv *priv, u8 force)
}
EXPORT_SYMBOL(iwl_activate_qos);
+/*
+ * AC CWmin CW max AIFSN TXOP Limit TXOP Limit
+ * (802.11b) (802.11a/g)
+ * AC_BK 15 1023 7 0 0
+ * AC_BE 15 1023 3 0 0
+ * AC_VI 7 15 2 6.016ms 3.008ms
+ * AC_VO 3 7 2 3.264ms 1.504ms
+ */
void iwl_reset_qos(struct iwl_priv *priv)
{
u16 cw_min = 15;
@@ -304,6 +314,7 @@ void iwl_reset_qos(struct iwl_priv *priv)
if (priv->qos_data.qos_active)
aifs = 3;
+ /* AC_BE */
priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min);
priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max);
priv->qos_data.def_qos_parm.ac[0].aifsn = aifs;
@@ -311,6 +322,7 @@ void iwl_reset_qos(struct iwl_priv *priv)
priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;
if (priv->qos_data.qos_active) {
+ /* AC_BK */
i = 1;
priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min);
priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max);
@@ -318,11 +330,12 @@ void iwl_reset_qos(struct iwl_priv *priv)
priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
+ /* AC_VI */
i = 2;
priv->qos_data.def_qos_parm.ac[i].cw_min =
cpu_to_le16((cw_min + 1) / 2 - 1);
priv->qos_data.def_qos_parm.ac[i].cw_max =
- cpu_to_le16(cw_max);
+ cpu_to_le16(cw_min);
priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
if (is_legacy)
priv->qos_data.def_qos_parm.ac[i].edca_txop =
@@ -332,11 +345,12 @@ void iwl_reset_qos(struct iwl_priv *priv)
cpu_to_le16(3008);
priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
+ /* AC_VO */
i = 3;
priv->qos_data.def_qos_parm.ac[i].cw_min =
cpu_to_le16((cw_min + 1) / 4 - 1);
priv->qos_data.def_qos_parm.ac[i].cw_max =
- cpu_to_le16((cw_max + 1) / 2 - 1);
+ cpu_to_le16((cw_min + 1) / 2 - 1);
priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
if (is_legacy)
@@ -591,10 +605,10 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv,
if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
return !(ch_info->fat_extension_channel &
- IEEE80211_CHAN_NO_FAT_ABOVE);
+ IEEE80211_CHAN_NO_HT40PLUS);
else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW)
return !(ch_info->fat_extension_channel &
- IEEE80211_CHAN_NO_FAT_BELOW);
+ IEEE80211_CHAN_NO_HT40MINUS);
return 0;
}
@@ -605,19 +619,23 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config;
if ((!iwl_ht_conf->is_ht) ||
- (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) ||
- (iwl_ht_conf->extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE))
+ (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ))
return 0;
+ /* We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40
+ * the bit will not set if it is pure 40MHz case
+ */
if (sta_ht_inf) {
- if ((!sta_ht_inf->ht_supported) ||
- (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)))
+ if (!sta_ht_inf->ht_supported)
return 0;
}
- return iwl_is_channel_extension(priv, priv->band,
- le16_to_cpu(priv->staging_rxon.channel),
- iwl_ht_conf->extension_chan_offset);
+ if (iwl_ht_conf->ht_protection & IEEE80211_HT_OP_MODE_PROTECTION_20MHZ)
+ return 1;
+ else
+ return iwl_is_channel_extension(priv, priv->band,
+ le16_to_cpu(priv->staging_rxon.channel),
+ iwl_ht_conf->extension_chan_offset);
}
EXPORT_SYMBOL(iwl_is_fat_tx_allowed);
@@ -735,6 +753,8 @@ int iwl_full_rxon_required(struct iwl_priv *priv)
priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
(priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
+ (priv->staging_rxon.ofdm_ht_triple_stream_basic_rates !=
+ priv->active_rxon.ofdm_ht_triple_stream_basic_rates) ||
(priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
return 1;
@@ -785,43 +805,53 @@ EXPORT_SYMBOL(iwl_rate_get_lowest_plcp);
void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
{
struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
- u32 val;
if (!ht_info->is_ht) {
- rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
- RXON_FLG_CHANNEL_MODE_PURE_40_MSK |
+ rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
RXON_FLG_FAT_PROT_MSK |
RXON_FLG_HT_PROT_MSK);
return;
}
- /* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */
- if (iwl_is_fat_tx_allowed(priv, NULL))
- rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED_MSK;
- else
- rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
- RXON_FLG_CHANNEL_MODE_PURE_40_MSK);
-
- /* Note: control channel is opposite of extension channel */
- switch (ht_info->extension_chan_offset) {
- case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
- rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
- break;
- case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
- rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
- break;
- case IEEE80211_HT_PARAM_CHA_SEC_NONE:
- default:
- rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK;
- break;
+ /* FIXME: if the definition of ht_protection changed, the "translation"
+ * will be needed for rxon->flags
+ */
+ rxon->flags |= cpu_to_le32(ht_info->ht_protection << RXON_FLG_HT_OPERATING_MODE_POS);
+
+ /* Set up channel bandwidth:
+ * 20 MHz only, 20/40 mixed or pure 40 if fat ok */
+ /* clear the HT channel mode before set the mode */
+ rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
+ RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
+ if (iwl_is_fat_tx_allowed(priv, NULL)) {
+ /* pure 40 fat */
+ if (rxon->flags & RXON_FLG_FAT_PROT_MSK)
+ rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
+ else {
+ /* Note: control channel is opposite of extension channel */
+ switch (ht_info->extension_chan_offset) {
+ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+ rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
+ rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;
+ break;
+ case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+ rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
+ rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;
+ break;
+ case IEEE80211_HT_PARAM_CHA_SEC_NONE:
+ default:
+ /* channel location only valid if in Mixed mode */
+ IWL_ERR(priv, "invalid extension channel offset\n");
+ break;
+ }
+ }
+ } else {
+ rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY;
}
- val = ht_info->ht_protection;
-
- rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS);
-
- iwl_set_rxon_chain(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
IWL_DEBUG_ASSOC(priv, "supported HT rate 0x%X 0x%X 0x%X "
"rxon flags 0x%X operation mode :0x%X "
@@ -901,10 +931,11 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
* never called for monitor mode. The only way mac80211 informs us about
* monitor mode is through configuring filters (call to configure_filter).
*/
-static bool iwl_is_monitor_mode(struct iwl_priv *priv)
+bool iwl_is_monitor_mode(struct iwl_priv *priv)
{
return !!(priv->staging_rxon.filter_flags & RXON_FILTER_PROMISC_MSK);
}
+EXPORT_SYMBOL(iwl_is_monitor_mode);
/**
* iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
@@ -956,10 +987,10 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
if (iwl_is_monitor_mode(priv) &&
!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) &&
((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)) {
- rx_chain = 0x07 << RXON_RX_CHAIN_VALID_POS;
- rx_chain |= 0x06 << RXON_RX_CHAIN_FORCE_SEL_POS;
- rx_chain |= 0x07 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
- rx_chain |= 0x01 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
+ rx_chain = ANT_ABC << RXON_RX_CHAIN_VALID_POS;
+ rx_chain |= ANT_BC << RXON_RX_CHAIN_FORCE_SEL_POS;
+ rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+ rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
}
priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
@@ -1068,11 +1099,6 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
RXON_FILTER_ACCEPT_GRP_MSK;
break;
- case NL80211_IFTYPE_MONITOR:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
- priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
- RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
- break;
default:
IWL_ERR(priv, "Unsupported interface type %d\n", mode);
break;
@@ -1111,16 +1137,18 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
priv->staging_rxon.cck_basic_rates =
(IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
- priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
- RXON_FLG_CHANNEL_MODE_PURE_40_MSK);
+ /* clear both MIX and PURE40 mode flag */
+ priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
+ RXON_FLG_CHANNEL_MODE_PURE_40);
memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN);
priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff;
priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff;
+ priv->staging_rxon.ofdm_ht_triple_stream_basic_rates = 0xff;
}
EXPORT_SYMBOL(iwl_connection_init_rx_config);
-void iwl_set_rate(struct iwl_priv *priv)
+static void iwl_set_rate(struct iwl_priv *priv)
{
const struct ieee80211_supported_band *hw = NULL;
struct ieee80211_rate *rate;
@@ -1166,7 +1194,6 @@ void iwl_set_rate(struct iwl_priv *priv)
priv->staging_rxon.ofdm_basic_rates =
(IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
}
-EXPORT_SYMBOL(iwl_set_rate);
void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
{
@@ -1230,11 +1257,6 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
"Restarting adapter due to uCode error.\n");
- if (iwl_is_associated(priv)) {
- memcpy(&priv->recovery_rxon, &priv->active_rxon,
- sizeof(priv->recovery_rxon));
- priv->error_recovering = 1;
- }
if (priv->cfg->mod_params->restart_fw)
queue_work(priv->workqueue, &priv->restart);
}
@@ -1298,19 +1320,20 @@ int iwl_setup_mac(struct iwl_priv *priv)
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM |
IEEE80211_HW_AMPDU_AGGREGATION |
- IEEE80211_HW_SPECTRUM_MGMT |
- IEEE80211_HW_SUPPORTS_PS;
+ IEEE80211_HW_SPECTRUM_MGMT;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
hw->wiphy->custom_regulatory = true;
- hw->wiphy->max_scan_ssids = 1;
+
+ hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
+ /* we create the 802.11 header and a zero-length SSID element */
+ hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
- hw->conf.beacon_int = 100;
hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
@@ -1357,7 +1380,6 @@ int iwl_init_drv(struct iwl_priv *priv)
priv->ibss_beacon = NULL;
spin_lock_init(&priv->lock);
- spin_lock_init(&priv->power_data.lock);
spin_lock_init(&priv->sta_lock);
spin_lock_init(&priv->hcmd_lock);
@@ -1378,7 +1400,9 @@ int iwl_init_drv(struct iwl_priv *priv)
priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;
/* Choose which receivers/antennas to use */
- iwl_set_rxon_chain(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
iwl_init_scan_params(priv);
iwl_reset_qos(priv);
@@ -1475,11 +1499,273 @@ void iwl_enable_interrupts(struct iwl_priv *priv)
{
IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
set_bit(STATUS_INT_ENABLED, &priv->status);
- iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
+ iwl_write32(priv, CSR_INT_MASK, priv->inta_mask);
}
EXPORT_SYMBOL(iwl_enable_interrupts);
-irqreturn_t iwl_isr(int irq, void *data)
+
+#define ICT_COUNT (PAGE_SIZE/sizeof(u32))
+
+/* Free dram table */
+void iwl_free_isr_ict(struct iwl_priv *priv)
+{
+ if (priv->ict_tbl_vir) {
+ pci_free_consistent(priv->pci_dev, (sizeof(u32) * ICT_COUNT) +
+ PAGE_SIZE, priv->ict_tbl_vir,
+ priv->ict_tbl_dma);
+ priv->ict_tbl_vir = NULL;
+ }
+}
+EXPORT_SYMBOL(iwl_free_isr_ict);
+
+
+/* allocate dram shared table it is a PAGE_SIZE aligned
+ * also reset all data related to ICT table interrupt.
+ */
+int iwl_alloc_isr_ict(struct iwl_priv *priv)
+{
+
+ if (priv->cfg->use_isr_legacy)
+ return 0;
+ /* allocate shrared data table */
+ priv->ict_tbl_vir = pci_alloc_consistent(priv->pci_dev, (sizeof(u32) *
+ ICT_COUNT) + PAGE_SIZE,
+ &priv->ict_tbl_dma);
+ if (!priv->ict_tbl_vir)
+ return -ENOMEM;
+
+ /* align table to PAGE_SIZE boundry */
+ priv->aligned_ict_tbl_dma = ALIGN(priv->ict_tbl_dma, PAGE_SIZE);
+
+ IWL_DEBUG_ISR(priv, "ict dma addr %Lx dma aligned %Lx diff %d\n",
+ (unsigned long long)priv->ict_tbl_dma,
+ (unsigned long long)priv->aligned_ict_tbl_dma,
+ (int)(priv->aligned_ict_tbl_dma - priv->ict_tbl_dma));
+
+ priv->ict_tbl = priv->ict_tbl_vir +
+ (priv->aligned_ict_tbl_dma - priv->ict_tbl_dma);
+
+ IWL_DEBUG_ISR(priv, "ict vir addr %p vir aligned %p diff %d\n",
+ priv->ict_tbl, priv->ict_tbl_vir,
+ (int)(priv->aligned_ict_tbl_dma - priv->ict_tbl_dma));
+
+ /* reset table and index to all 0 */
+ memset(priv->ict_tbl_vir,0, (sizeof(u32) * ICT_COUNT) + PAGE_SIZE);
+ priv->ict_index = 0;
+
+ /* add periodic RX interrupt */
+ priv->inta_mask |= CSR_INT_BIT_RX_PERIODIC;
+ return 0;
+}
+EXPORT_SYMBOL(iwl_alloc_isr_ict);
+
+/* Device is going up inform it about using ICT interrupt table,
+ * also we need to tell the driver to start using ICT interrupt.
+ */
+int iwl_reset_ict(struct iwl_priv *priv)
+{
+ u32 val;
+ unsigned long flags;
+
+ if (!priv->ict_tbl_vir)
+ return 0;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_disable_interrupts(priv);
+
+ memset(&priv->ict_tbl[0],0, sizeof(u32) * ICT_COUNT);
+
+ val = priv->aligned_ict_tbl_dma >> PAGE_SHIFT;
+
+ val |= CSR_DRAM_INT_TBL_ENABLE;
+ val |= CSR_DRAM_INIT_TBL_WRAP_CHECK;
+
+ IWL_DEBUG_ISR(priv, "CSR_DRAM_INT_TBL_REG =0x%X "
+ "aligned dma address %Lx\n",
+ val, (unsigned long long)priv->aligned_ict_tbl_dma);
+
+ iwl_write32(priv, CSR_DRAM_INT_TBL_REG, val);
+ priv->use_ict = true;
+ priv->ict_index = 0;
+ iwl_write32(priv, CSR_INT, priv->inta_mask);
+ iwl_enable_interrupts(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_reset_ict);
+
+/* Device is going down disable ict interrupt usage */
+void iwl_disable_ict(struct iwl_priv *priv)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->use_ict = false;
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+EXPORT_SYMBOL(iwl_disable_ict);
+
+/* interrupt handler using ict table, with this interrupt driver will
+ * stop using INTA register to get device's interrupt, reading this register
+ * is expensive, device will write interrupts in ICT dram table, increment
+ * index then will fire interrupt to driver, driver will OR all ICT table
+ * entries from current index up to table entry with 0 value. the result is
+ * the interrupt we need to service, driver will set the entries back to 0 and
+ * set index.
+ */
+irqreturn_t iwl_isr_ict(int irq, void *data)
+{
+ struct iwl_priv *priv = data;
+ u32 inta, inta_mask;
+ u32 val = 0;
+
+ if (!priv)
+ return IRQ_NONE;
+
+ /* dram interrupt table not set yet,
+ * use legacy interrupt.
+ */
+ if (!priv->use_ict)
+ return iwl_isr(irq, data);
+
+ spin_lock(&priv->lock);
+
+ /* Disable (but don't clear!) interrupts here to avoid
+ * back-to-back ISRs and sporadic interrupts from our NIC.
+ * If we have something to service, the tasklet will re-enable ints.
+ * If we *don't* have something, we'll re-enable before leaving here.
+ */
+ inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
+ iwl_write32(priv, CSR_INT_MASK, 0x00000000);
+
+
+ /* Ignore interrupt if there's nothing in NIC to service.
+ * This may be due to IRQ shared with another device,
+ * or due to sporadic interrupts thrown from our NIC. */
+ if (!priv->ict_tbl[priv->ict_index]) {
+ IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
+ goto none;
+ }
+
+ /* read all entries that not 0 start with ict_index */
+ while (priv->ict_tbl[priv->ict_index]) {
+
+ val |= priv->ict_tbl[priv->ict_index];
+ IWL_DEBUG_ISR(priv, "ICT index %d value 0x%08X\n",
+ priv->ict_index,
+ priv->ict_tbl[priv->ict_index]);
+ priv->ict_tbl[priv->ict_index] = 0;
+ priv->ict_index = iwl_queue_inc_wrap(priv->ict_index,
+ ICT_COUNT);
+
+ }
+
+ /* We should not get this value, just ignore it. */
+ if (val == 0xffffffff)
+ val = 0;
+
+ inta = (0xff & val) | ((0xff00 & val) << 16);
+ IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
+ inta, inta_mask, val);
+
+ inta &= priv->inta_mask;
+ priv->inta |= inta;
+
+ /* iwl_irq_tasklet() will service interrupts and re-enable them */
+ if (likely(inta))
+ tasklet_schedule(&priv->irq_tasklet);
+ else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta) {
+ /* Allow interrupt if was disabled by this handler and
+ * no tasklet was schedules, We should not enable interrupt,
+ * tasklet will enable it.
+ */
+ iwl_enable_interrupts(priv);
+ }
+
+ spin_unlock(&priv->lock);
+ return IRQ_HANDLED;
+
+ none:
+ /* re-enable interrupts here since we don't have anything to service.
+ * only Re-enable if disabled by irq.
+ */
+ if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta)
+ iwl_enable_interrupts(priv);
+
+ spin_unlock(&priv->lock);
+ return IRQ_NONE;
+}
+EXPORT_SYMBOL(iwl_isr_ict);
+
+
+static irqreturn_t iwl_isr(int irq, void *data)
+{
+ struct iwl_priv *priv = data;
+ u32 inta, inta_mask;
+#ifdef CONFIG_IWLWIFI_DEBUG
+ u32 inta_fh;
+#endif
+ if (!priv)
+ return IRQ_NONE;
+
+ spin_lock(&priv->lock);
+
+ /* Disable (but don't clear!) interrupts here to avoid
+ * back-to-back ISRs and sporadic interrupts from our NIC.
+ * If we have something to service, the tasklet will re-enable ints.
+ * If we *don't* have something, we'll re-enable before leaving here. */
+ inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
+ iwl_write32(priv, CSR_INT_MASK, 0x00000000);
+
+ /* Discover which interrupts are active/pending */
+ inta = iwl_read32(priv, CSR_INT);
+
+ /* Ignore interrupt if there's nothing in NIC to service.
+ * This may be due to IRQ shared with another device,
+ * or due to sporadic interrupts thrown from our NIC. */
+ if (!inta) {
+ IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
+ goto none;
+ }
+
+ if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
+ /* Hardware disappeared. It might have already raised
+ * an interrupt */
+ IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
+ goto unplugged;
+ }
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->debug_level & (IWL_DL_ISR)) {
+ inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+ IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, "
+ "fh 0x%08x\n", inta, inta_mask, inta_fh);
+ }
+#endif
+
+ priv->inta |= inta;
+ /* iwl_irq_tasklet() will service interrupts and re-enable them */
+ if (likely(inta))
+ tasklet_schedule(&priv->irq_tasklet);
+ else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta)
+ iwl_enable_interrupts(priv);
+
+ unplugged:
+ spin_unlock(&priv->lock);
+ return IRQ_HANDLED;
+
+ none:
+ /* re-enable interrupts here since we don't have anything to service. */
+ /* only Re-enable if diabled by irq and no schedules tasklet. */
+ if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta)
+ iwl_enable_interrupts(priv);
+
+ spin_unlock(&priv->lock);
+ return IRQ_NONE;
+}
+
+irqreturn_t iwl_isr_legacy(int irq, void *data)
{
struct iwl_priv *priv = data;
u32 inta, inta_mask;
@@ -1536,7 +1822,7 @@ irqreturn_t iwl_isr(int irq, void *data)
spin_unlock(&priv->lock);
return IRQ_NONE;
}
-EXPORT_SYMBOL(iwl_isr);
+EXPORT_SYMBOL(iwl_isr_legacy);
int iwl_send_bt_config(struct iwl_priv *priv)
{
@@ -1580,10 +1866,6 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
- ret = iwl_grab_nic_access(priv);
- if (ret)
- return ret;
-
for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
/* read data comes through single port, auto-incr addr */
/* NOTE: Use the debugless read so we don't flood kernel log
@@ -1599,8 +1881,6 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
}
}
- iwl_release_nic_access(priv);
-
return ret;
}
@@ -1618,10 +1898,6 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
- ret = iwl_grab_nic_access(priv);
- if (ret)
- return ret;
-
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
IWL49_RTC_INST_LOWER_BOUND);
@@ -1642,8 +1918,6 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
}
}
- iwl_release_nic_access(priv);
-
if (!errcnt)
IWL_DEBUG_INFO(priv,
"ucode image in INSTRUCTION memory is good\n");
@@ -1752,7 +2026,6 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
u32 data2, line;
u32 desc, time, count, base, data1;
u32 blink1, blink2, ilink1, ilink2;
- int ret;
if (priv->ucode_type == UCODE_INIT)
base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
@@ -1764,12 +2037,6 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
return;
}
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- IWL_WARN(priv, "Can not read from adapter at this time.\n");
- return;
- }
-
count = iwl_read_targ_mem(priv, base);
if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
@@ -1796,7 +2063,6 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
ilink1, ilink2);
- iwl_release_nic_access(priv);
}
EXPORT_SYMBOL(iwl_dump_nic_error_log);
@@ -1805,7 +2071,6 @@ EXPORT_SYMBOL(iwl_dump_nic_error_log);
/**
* iwl_print_event_log - Dump error event log to syslog
*
- * NOTE: Must be called with iwl_grab_nic_access() already obtained!
*/
static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
u32 num_events, u32 mode)
@@ -1851,7 +2116,6 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
void iwl_dump_nic_event_log(struct iwl_priv *priv)
{
- int ret;
u32 base; /* SRAM byte address of event log header */
u32 capacity; /* event log capacity in # entries */
u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */
@@ -1869,12 +2133,6 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
return;
}
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- IWL_WARN(priv, "Can not read from adapter at this time.\n");
- return;
- }
-
/* event log header */
capacity = iwl_read_targ_mem(priv, base);
mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
@@ -1886,7 +2144,6 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
/* bail out if nothing in log */
if (size == 0) {
IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
- iwl_release_nic_access(priv);
return;
}
@@ -1901,7 +2158,6 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
/* (then/else) start at top of log */
iwl_print_event_log(priv, 0, next_entry, mode);
- iwl_release_nic_access(priv);
}
EXPORT_SYMBOL(iwl_dump_nic_event_log);
@@ -1954,161 +2210,680 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
}
EXPORT_SYMBOL(iwl_send_card_state);
-void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv)
+void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- unsigned long flags;
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
+ IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
+ sleep->pm_sleep_mode, sleep->pm_wakeup_src);
+#endif
+}
+EXPORT_SYMBOL(iwl_rx_pm_sleep_notif);
- if (test_bit(STATUS_RF_KILL_SW, &priv->status))
- return;
+void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
+ "notification for %s:\n",
+ le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
+ iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+}
+EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif);
- IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO OFF\n");
+void iwl_rx_reply_error(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- iwl_scan_cancel(priv);
- /* FIXME: This is a workaround for AP */
- if (priv->iw_mode != NL80211_IFTYPE_AP) {
- spin_lock_irqsave(&priv->lock, flags);
- iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
- CSR_UCODE_SW_BIT_RFKILL);
- spin_unlock_irqrestore(&priv->lock, flags);
- /* call the host command only if no hw rf-kill set */
- if (!test_bit(STATUS_RF_KILL_HW, &priv->status) &&
- iwl_is_ready(priv))
- iwl_send_card_state(priv,
- CARD_STATE_CMD_DISABLE, 0);
- set_bit(STATUS_RF_KILL_SW, &priv->status);
- /* make sure mac80211 stop sending Tx frame */
- if (priv->mac80211_registered)
- ieee80211_stop_queues(priv->hw);
- }
+ IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
+ "seq 0x%04X ser 0x%08X\n",
+ le32_to_cpu(pkt->u.err_resp.error_type),
+ get_cmd_string(pkt->u.err_resp.cmd_id),
+ pkt->u.err_resp.cmd_id,
+ le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
+ le32_to_cpu(pkt->u.err_resp.error_info));
}
-EXPORT_SYMBOL(iwl_radio_kill_sw_disable_radio);
+EXPORT_SYMBOL(iwl_rx_reply_error);
+
+void iwl_clear_isr_stats(struct iwl_priv *priv)
+{
+ memset(&priv->isr_stats, 0, sizeof(priv->isr_stats));
+}
+EXPORT_SYMBOL(iwl_clear_isr_stats);
-int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
+int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *params)
{
+ struct iwl_priv *priv = hw->priv;
unsigned long flags;
+ int q;
+
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+ return -EIO;
+ }
- if (!test_bit(STATUS_RF_KILL_SW, &priv->status))
+ if (queue >= AC_NUM) {
+ IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
return 0;
+ }
- IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO ON\n");
+ q = AC_NUM - 1 - queue;
spin_lock_irqsave(&priv->lock, flags);
- iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
- /* If the driver is up it will receive CARD_STATE_NOTIFICATION
- * notification where it will clear SW rfkill status.
- * Setting it here would break the handler. Only if the
- * interface is down we can set here since we don't
- * receive any further notification.
- */
- if (!priv->is_open)
- clear_bit(STATUS_RF_KILL_SW, &priv->status);
- spin_unlock_irqrestore(&priv->lock, flags);
+ priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
+ priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
+ priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
+ priv->qos_data.def_qos_parm.ac[q].edca_txop =
+ cpu_to_le16((params->txop * 32));
- /* wake up ucode */
- msleep(10);
+ priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
+ priv->qos_data.qos_active = 1;
+
+ if (priv->iw_mode == NL80211_IFTYPE_AP)
+ iwl_activate_qos(priv, 1);
+ else if (priv->assoc_id && iwl_is_associated(priv))
+ iwl_activate_qos(priv, 0);
- spin_lock_irqsave(&priv->lock, flags);
- iwl_read32(priv, CSR_UCODE_DRV_GP1);
- if (!iwl_grab_nic_access(priv))
- iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
- if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
- IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - "
- "disabled by HW switch\n");
- return 0;
- }
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+ return 0;
+}
+EXPORT_SYMBOL(iwl_mac_conf_tx);
+
+static void iwl_ht_conf(struct iwl_priv *priv,
+ struct ieee80211_bss_conf *bss_conf)
+{
+ struct ieee80211_sta_ht_cap *ht_conf;
+ struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
+ struct ieee80211_sta *sta;
+
+ IWL_DEBUG_MAC80211(priv, "enter: \n");
+
+ if (!iwl_conf->is_ht)
+ return;
+
- /* when driver is up while rfkill is on, it wont receive
- * any CARD_STATE_NOTIFICATION notifications so we have to
- * restart it in here
+ /*
+ * It is totally wrong to base global information on something
+ * that is valid only when associated, alas, this driver works
+ * that way and I don't know how to fix it.
*/
- if (priv->is_open && !test_bit(STATUS_ALIVE, &priv->status)) {
- clear_bit(STATUS_RF_KILL_SW, &priv->status);
- if (!iwl_is_rfkill(priv))
- queue_work(priv->workqueue, &priv->up);
+
+ rcu_read_lock();
+ sta = ieee80211_find_sta(priv->hw, priv->bssid);
+ if (!sta) {
+ rcu_read_unlock();
+ return;
}
+ ht_conf = &sta->ht_cap;
+
+ if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
+ iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
+ if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
+ iwl_conf->sgf |= HT_SHORT_GI_40MHZ;
- /* If the driver is already loaded, it will receive
- * CARD_STATE_NOTIFICATION notifications and the handler will
- * call restart to reload the driver.
+ iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
+ iwl_conf->max_amsdu_size =
+ !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
+
+ iwl_conf->supported_chan_width =
+ !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
+
+ /*
+ * XXX: The HT configuration needs to be moved into iwl_mac_config()
+ * to be done there correctly.
*/
- return 1;
+
+ iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
+ if (conf_is_ht40_minus(&priv->hw->conf))
+ iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+ else if (conf_is_ht40_plus(&priv->hw->conf))
+ iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+
+ /* If no above or below channel supplied disable FAT channel */
+ if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE &&
+ iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW)
+ iwl_conf->supported_chan_width = 0;
+
+ iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
+
+ memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
+
+ iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0;
+ iwl_conf->ht_protection =
+ bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
+ iwl_conf->non_GF_STA_present =
+ !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+
+ rcu_read_unlock();
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
-EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio);
-void iwl_bg_rf_kill(struct work_struct *work)
+#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
+void iwl_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changes)
{
- struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill);
+ struct iwl_priv *priv = hw->priv;
+ int ret;
- wake_up_interruptible(&priv->wait_command_queue);
+ IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ if (!iwl_is_alive(priv))
return;
mutex_lock(&priv->mutex);
- if (!iwl_is_rfkill(priv)) {
- IWL_DEBUG_RF_KILL(priv,
- "HW and/or SW RF Kill no longer active, restarting "
- "device\n");
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status) &&
- test_bit(STATUS_ALIVE, &priv->status))
- queue_work(priv->workqueue, &priv->restart);
- } else {
- /* make sure mac80211 stop sending Tx frame */
- if (priv->mac80211_registered)
- ieee80211_stop_queues(priv->hw);
+ if (changes & BSS_CHANGED_BEACON &&
+ priv->iw_mode == NL80211_IFTYPE_AP) {
+ dev_kfree_skb(priv->ibss_beacon);
+ priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
+ }
+
+ if ((changes & BSS_CHANGED_BSSID) && !iwl_is_rfkill(priv)) {
+ /* If there is currently a HW scan going on in the background
+ * then we need to cancel it else the RXON below will fail. */
+ if (iwl_scan_cancel_timeout(priv, 100)) {
+ IWL_WARN(priv, "Aborted scan still in progress "
+ "after 100ms\n");
+ IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+ memcpy(priv->staging_rxon.bssid_addr,
+ bss_conf->bssid, ETH_ALEN);
+
+ /* TODO: Audit driver for usage of these members and see
+ * if mac80211 deprecates them (priv->bssid looks like it
+ * shouldn't be there, but I haven't scanned the IBSS code
+ * to verify) - jpk */
+ memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
+
+ if (priv->iw_mode == NL80211_IFTYPE_AP)
+ iwlcore_config_ap(priv);
+ else {
+ int rc = iwlcore_commit_rxon(priv);
+ if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
+ iwl_rxon_add_station(
+ priv, priv->active_rxon.bssid_addr, 1);
+ }
+ } else if (!iwl_is_rfkill(priv)) {
+ iwl_scan_cancel_timeout(priv, 100);
+ priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv);
+ }
+
+ if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
+ changes & BSS_CHANGED_BEACON) {
+ struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
+
+ if (beacon)
+ iwl_mac_beacon_update(hw, beacon);
+ }
- if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
- IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - "
- "disabled by SW switch\n");
+ mutex_unlock(&priv->mutex);
+
+ if (changes & BSS_CHANGED_ERP_PREAMBLE) {
+ IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
+ bss_conf->use_short_preamble);
+ if (bss_conf->use_short_preamble)
+ priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- IWL_WARN(priv, "Radio Frequency Kill Switch is On:\n"
- "Kill switch must be turned off for "
- "wireless networking to work.\n");
+ priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ }
+
+ if (changes & BSS_CHANGED_ERP_CTS_PROT) {
+ IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
+ if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
+ priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
+ else
+ priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+ }
+
+ if (changes & BSS_CHANGED_HT) {
+ iwl_ht_conf(priv, bss_conf);
+
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ }
+
+ if (changes & BSS_CHANGED_ASSOC) {
+ IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
+ /* This should never happen as this function should
+ * never be called from interrupt context. */
+ if (WARN_ON_ONCE(in_interrupt()))
+ return;
+ if (bss_conf->assoc) {
+ priv->assoc_id = bss_conf->aid;
+ priv->beacon_int = bss_conf->beacon_int;
+ priv->power_data.dtim_period = bss_conf->dtim_period;
+ priv->timestamp = bss_conf->timestamp;
+ priv->assoc_capability = bss_conf->assoc_capability;
+
+ /* we have just associated, don't start scan too early
+ * leave time for EAPOL exchange to complete
+ */
+ priv->next_scan_jiffies = jiffies +
+ IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
+ mutex_lock(&priv->mutex);
+ priv->cfg->ops->lib->post_associate(priv);
+ mutex_unlock(&priv->mutex);
+ } else {
+ priv->assoc_id = 0;
+ IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc);
+ }
+ } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
+ IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes);
+ ret = iwl_send_rxon_assoc(priv);
+ if (!ret)
+ /* Sync active_rxon with latest change. */
+ memcpy((void *)&priv->active_rxon,
+ &priv->staging_rxon,
+ sizeof(struct iwl_rxon_cmd));
+ }
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+}
+EXPORT_SYMBOL(iwl_bss_info_changed);
+
+int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct iwl_priv *priv = hw->priv;
+ unsigned long flags;
+ __le64 timestamp;
+
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+ return -EIO;
+ }
+
+ if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
+ IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
+ return -EIO;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (priv->ibss_beacon)
+ dev_kfree_skb(priv->ibss_beacon);
+
+ priv->ibss_beacon = skb;
+
+ priv->assoc_id = 0;
+ timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+ priv->timestamp = le64_to_cpu(timestamp);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ iwl_reset_qos(priv);
+
+ priv->cfg->ops->lib->post_associate(priv);
+
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_mac_beacon_update);
+
+int iwl_set_mode(struct iwl_priv *priv, int mode)
+{
+ if (mode == NL80211_IFTYPE_ADHOC) {
+ const struct iwl_channel_info *ch_info;
+
+ ch_info = iwl_get_channel_info(priv,
+ priv->band,
+ le16_to_cpu(priv->staging_rxon.channel));
+
+ if (!ch_info || !is_channel_ibss(ch_info)) {
+ IWL_ERR(priv, "channel %d not IBSS channel\n",
+ le16_to_cpu(priv->staging_rxon.channel));
+ return -EINVAL;
+ }
+ }
+
+ iwl_connection_init_rx_config(priv, mode);
+
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
+ memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+
+ iwl_clear_stations_table(priv);
+
+ /* dont commit rxon if rf-kill is on*/
+ if (!iwl_is_ready_rf(priv))
+ return -EAGAIN;
+
+ iwlcore_commit_rxon(priv);
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_set_mode);
+
+int iwl_mac_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct iwl_priv *priv = hw->priv;
+ unsigned long flags;
+
+ IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
+
+ if (priv->vif) {
+ IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
+ return -EOPNOTSUPP;
}
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->vif = conf->vif;
+ priv->iw_mode = conf->type;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ mutex_lock(&priv->mutex);
+
+ if (conf->mac_addr) {
+ IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
+ memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
+ }
+
+ if (iwl_set_mode(priv, conf->type) == -EAGAIN)
+ /* we are not ready, will run again when ready */
+ set_bit(STATUS_MODE_PENDING, &priv->status);
+
mutex_unlock(&priv->mutex);
- iwl_rfkill_set_hw_state(priv);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+ return 0;
}
-EXPORT_SYMBOL(iwl_bg_rf_kill);
+EXPORT_SYMBOL(iwl_mac_add_interface);
-void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
+void iwl_mac_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
{
-#ifdef CONFIG_IWLWIFI_DEBUG
- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
- IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
- sleep->pm_sleep_mode, sleep->pm_wakeup_src);
-#endif
+ struct iwl_priv *priv = hw->priv;
+
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ mutex_lock(&priv->mutex);
+
+ if (iwl_is_ready_rf(priv)) {
+ iwl_scan_cancel_timeout(priv, 100);
+ priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv);
+ }
+ if (priv->vif == conf->vif) {
+ priv->vif = NULL;
+ memset(priv->bssid, 0, ETH_ALEN);
+ }
+ mutex_unlock(&priv->mutex);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+
}
-EXPORT_SYMBOL(iwl_rx_pm_sleep_notif);
+EXPORT_SYMBOL(iwl_mac_remove_interface);
-void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
+/**
+ * iwl_mac_config - mac80211 config callback
+ *
+ * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to
+ * be set inappropriately and the driver currently sets the hardware up to
+ * use it whenever needed.
+ */
+int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
{
- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
- "notification for %s:\n",
- le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
- iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+ struct iwl_priv *priv = hw->priv;
+ const struct iwl_channel_info *ch_info;
+ struct ieee80211_conf *conf = &hw->conf;
+ unsigned long flags = 0;
+ int ret = 0;
+ u16 ch;
+ int scan_active = 0;
+
+ mutex_lock(&priv->mutex);
+
+ IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
+ conf->channel->hw_value, changed);
+
+ if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
+ test_bit(STATUS_SCANNING, &priv->status))) {
+ scan_active = 1;
+ IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
+ }
+
+
+ /* during scanning mac80211 will delay channel setting until
+ * scan finish with changed = 0
+ */
+ if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
+ if (scan_active)
+ goto set_ch_out;
+
+ ch = ieee80211_frequency_to_channel(conf->channel->center_freq);
+ ch_info = iwl_get_channel_info(priv, conf->channel->band, ch);
+ if (!is_channel_valid(ch_info)) {
+ IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
+ ret = -EINVAL;
+ goto set_ch_out;
+ }
+
+ if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
+ !is_channel_ibss(ch_info)) {
+ IWL_ERR(priv, "channel %d in band %d not "
+ "IBSS channel\n",
+ conf->channel->hw_value, conf->channel->band);
+ ret = -EINVAL;
+ goto set_ch_out;
+ }
+
+ priv->current_ht_config.is_ht = conf_is_ht(conf);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+
+ /* if we are switching from ht to 2.4 clear flags
+ * from any ht related info since 2.4 does not
+ * support ht */
+ if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
+ priv->staging_rxon.flags = 0;
+
+ iwl_set_rxon_channel(priv, conf->channel);
+
+ iwl_set_flags_for_band(priv, conf->channel->band);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ set_ch_out:
+ /* The list of supported rates and rate mask can be different
+ * for each band; since the band may have changed, reset
+ * the rate mask to what mac80211 lists */
+ iwl_set_rate(priv);
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_PS &&
+ priv->iw_mode == NL80211_IFTYPE_STATION) {
+ priv->power_data.power_disabled =
+ !(conf->flags & IEEE80211_CONF_PS);
+ ret = iwl_power_update_mode(priv, 0);
+ if (ret)
+ IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
+ priv->tx_power_user_lmt, conf->power_level);
+
+ iwl_set_tx_power(priv, conf->power_level, false);
+ }
+
+ /* call to ensure that 4965 rx_chain is set properly in monitor mode */
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
+ if (!iwl_is_ready(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
+ goto out;
+ }
+
+ if (scan_active)
+ goto out;
+
+ if (memcmp(&priv->active_rxon,
+ &priv->staging_rxon, sizeof(priv->staging_rxon)))
+ iwlcore_commit_rxon(priv);
+ else
+ IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration.\n");
+
+
+out:
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+ mutex_unlock(&priv->mutex);
+ return ret;
}
-EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif);
+EXPORT_SYMBOL(iwl_mac_config);
-void iwl_rx_reply_error(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
+int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
+ struct ieee80211_tx_queue_stats *stats)
{
- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_priv *priv = hw->priv;
+ int i, avail;
+ struct iwl_tx_queue *txq;
+ struct iwl_queue *q;
+ unsigned long flags;
- IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
- "seq 0x%04X ser 0x%08X\n",
- le32_to_cpu(pkt->u.err_resp.error_type),
- get_cmd_string(pkt->u.err_resp.cmd_id),
- pkt->u.err_resp.cmd_id,
- le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
- le32_to_cpu(pkt->u.err_resp.error_info));
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+ return -EIO;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ for (i = 0; i < AC_NUM; i++) {
+ txq = &priv->txq[i];
+ q = &txq->q;
+ avail = iwl_queue_space(q);
+
+ stats[i].len = q->n_window - avail;
+ stats[i].limit = q->n_window - q->high_mark;
+ stats[i].count = q->n_window;
+
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+
+ return 0;
}
-EXPORT_SYMBOL(iwl_rx_reply_error);
+EXPORT_SYMBOL(iwl_mac_get_tx_stats);
+
+void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
+{
+ struct iwl_priv *priv = hw->priv;
+ unsigned long flags;
+
+ mutex_lock(&priv->mutex);
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ spin_lock_irqsave(&priv->lock, flags);
+ memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ iwl_reset_qos(priv);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->assoc_id = 0;
+ priv->assoc_capability = 0;
+ priv->assoc_station_added = 0;
+
+ /* new association get rid of ibss beacon skb */
+ if (priv->ibss_beacon)
+ dev_kfree_skb(priv->ibss_beacon);
+
+ priv->ibss_beacon = NULL;
+
+ priv->beacon_int = priv->vif->bss_conf.beacon_int;
+ priv->timestamp = 0;
+ if ((priv->iw_mode == NL80211_IFTYPE_STATION))
+ priv->beacon_int = 0;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+
+ /* we are restarting association process
+ * clear RXON_FILTER_ASSOC_MSK bit
+ */
+ if (priv->iw_mode != NL80211_IFTYPE_AP) {
+ iwl_scan_cancel_timeout(priv, 100);
+ priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv);
+ }
+
+ if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
+ IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+
+ iwl_set_rate(priv);
+
+ mutex_unlock(&priv->mutex);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+}
+EXPORT_SYMBOL(iwl_mac_reset_tsf);
+
+#ifdef CONFIG_PM
+
+int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct iwl_priv *priv = pci_get_drvdata(pdev);
+
+ /*
+ * This function is called when system goes into suspend state
+ * mac80211 will call iwl_mac_stop() from the mac80211 suspend function
+ * first but since iwl_mac_stop() has no knowledge of who the caller is,
+ * it will not call apm_ops.stop() to stop the DMA operation.
+ * Calling apm_ops.stop here to make sure we stop the DMA.
+ */
+ priv->cfg->ops->lib->apm_ops.stop(priv);
+
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_pci_suspend);
+
+int iwl_pci_resume(struct pci_dev *pdev)
+{
+ struct iwl_priv *priv = pci_get_drvdata(pdev);
+ int ret;
+
+ pci_set_power_state(pdev, PCI_D0);
+ ret = pci_enable_device(pdev);
+ if (ret)
+ return ret;
+ pci_restore_state(pdev);
+ iwl_enable_interrupts(priv);
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_pci_resume);
+#endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index a8eac8c3c1f..dabf663e36e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -85,7 +85,10 @@ struct iwl_cmd;
struct iwl_hcmd_ops {
int (*rxon_assoc)(struct iwl_priv *priv);
+ int (*commit_rxon)(struct iwl_priv *priv);
+ void (*set_rxon_chain)(struct iwl_priv *priv);
};
+
struct iwl_hcmd_utils_ops {
u16 (*get_hcmd_size)(u8 cmd_id, u16 len);
u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data);
@@ -100,6 +103,19 @@ struct iwl_hcmd_utils_ops {
struct iwl_rx_phy_res *rx_resp);
};
+struct iwl_apm_ops {
+ int (*init)(struct iwl_priv *priv);
+ int (*reset)(struct iwl_priv *priv);
+ void (*stop)(struct iwl_priv *priv);
+ void (*config)(struct iwl_priv *priv);
+ int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
+};
+
+struct iwl_temp_ops {
+ void (*temperature)(struct iwl_priv *priv);
+ void (*set_ct_kill)(struct iwl_priv *priv);
+};
+
struct iwl_lib_ops {
/* set hw dependent parameters */
int (*set_hw_params)(struct iwl_priv *priv);
@@ -137,20 +153,21 @@ struct iwl_lib_ops {
int (*is_valid_rtc_data_addr)(u32 addr);
/* 1st ucode load */
int (*load_ucode)(struct iwl_priv *priv);
- /* power management */
- struct {
- int (*init)(struct iwl_priv *priv);
- int (*reset)(struct iwl_priv *priv);
- void (*stop)(struct iwl_priv *priv);
- void (*config)(struct iwl_priv *priv);
- int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
- } apm_ops;
+ /* power management */
+ struct iwl_apm_ops apm_ops;
+
/* power */
int (*send_tx_power) (struct iwl_priv *priv);
void (*update_chain_flags)(struct iwl_priv *priv);
- void (*temperature) (struct iwl_priv *priv);
+ void (*post_associate) (struct iwl_priv *priv);
+ void (*config_ap) (struct iwl_priv *priv);
+ irqreturn_t (*isr) (int irq, void *data);
+
/* eeprom operations (as defined in iwl-eeprom.h) */
struct iwl_eeprom_ops eeprom_ops;
+
+ /* temperature */
+ struct iwl_temp_ops temp_ops;
};
struct iwl_ops {
@@ -160,13 +177,12 @@ struct iwl_ops {
};
struct iwl_mod_params {
- int disable; /* def: 0 = enable radio */
int sw_crypto; /* def: 0 = using hardware encryption */
u32 debug; /* def: 0 = minimal debug log messages */
int disable_hw_scan; /* def: 0 = use h/w scan */
int num_of_queues; /* def: HW dependent */
int num_of_ampdu_queues;/* def: HW dependent */
- int disable_11n; /* def: 0 = disable 11n capabilities */
+ int disable_11n; /* def: 0 = 11n capabilities enabled */
int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
int antenna; /* def: 0 = both antennas (use diversity) */
int restart_fw; /* def: 1 = restart firmware */
@@ -214,6 +230,7 @@ struct iwl_cfg {
u8 valid_tx_ant;
u8 valid_rx_ant;
bool need_pll_cfg;
+ bool use_isr_legacy;
};
/***************************
@@ -225,6 +242,8 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
void iwl_hw_detect(struct iwl_priv *priv);
void iwl_reset_qos(struct iwl_priv *priv);
void iwl_activate_qos(struct iwl_priv *priv, u8 force);
+int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *params);
void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
int iwl_check_rxon_cmd(struct iwl_priv *priv);
int iwl_full_rxon_required(struct iwl_priv *priv);
@@ -249,6 +268,24 @@ int iwl_setup_mac(struct iwl_priv *priv);
int iwl_set_hw_params(struct iwl_priv *priv);
int iwl_init_drv(struct iwl_priv *priv);
void iwl_uninit_drv(struct iwl_priv *priv);
+bool iwl_is_monitor_mode(struct iwl_priv *priv);
+void iwl_post_associate(struct iwl_priv *priv);
+void iwl_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changes);
+int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
+int iwl_commit_rxon(struct iwl_priv *priv);
+int iwl_set_mode(struct iwl_priv *priv, int mode);
+int iwl_mac_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf);
+void iwl_mac_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf);
+int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
+void iwl_config_ap(struct iwl_priv *priv);
+int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
+ struct ieee80211_tx_queue_stats *stats);
+void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
/*****************************************************
* RX handlers.
@@ -271,10 +308,11 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
struct iwl_rx_queue *q);
void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
void iwl_rx_replenish(struct iwl_priv *priv);
+void iwl_rx_replenish_now(struct iwl_priv *priv);
int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
int iwl_rx_queue_restock(struct iwl_priv *priv);
int iwl_rx_queue_space(const struct iwl_rx_queue *q);
-void iwl_rx_allocate(struct iwl_priv *priv);
+void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority);
void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
/* Handlers */
@@ -310,14 +348,6 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
****************************************************/
int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
-/*****************************************************
- * RF -Kill - here and not in iwl-rfkill.h to be available when
- * RF-kill subsystem is not compiled.
- ****************************************************/
-void iwl_bg_rf_kill(struct work_struct *work);
-void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv);
-int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv);
-
/*******************************************************************************
* Rate
******************************************************************************/
@@ -328,8 +358,6 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
-void iwl_set_rate(struct iwl_priv *priv);
-
u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx);
static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
@@ -358,8 +386,8 @@ int iwl_scan_cancel(struct iwl_priv *priv);
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
int iwl_scan_initiate(struct iwl_priv *priv);
int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
-u16 iwl_fill_probe_req(struct iwl_priv *priv, enum ieee80211_band band,
- struct ieee80211_mgmt *frame, int left);
+u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
+ const u8 *ie, int ie_len, int left);
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
enum ieee80211_band band,
@@ -423,7 +451,13 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags,
*****************************************************/
void iwl_disable_interrupts(struct iwl_priv *priv);
void iwl_enable_interrupts(struct iwl_priv *priv);
-irqreturn_t iwl_isr(int irq, void *data);
+irqreturn_t iwl_isr_legacy(int irq, void *data);
+int iwl_reset_ict(struct iwl_priv *priv);
+void iwl_disable_ict(struct iwl_priv *priv);
+int iwl_alloc_isr_ict(struct iwl_priv *priv);
+void iwl_free_isr_ict(struct iwl_priv *priv);
+irqreturn_t iwl_isr_ict(int irq, void *data);
+
static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
{
int pos;
@@ -432,12 +466,17 @@ static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
return pci_lnk_ctl;
}
+#ifdef CONFIG_PM
+int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
+int iwl_pci_resume(struct pci_dev *pdev);
+#endif /* CONFIG_PM */
/*****************************************************
* Error Handling Debugging
******************************************************/
void iwl_dump_nic_error_log(struct iwl_priv *priv);
void iwl_dump_nic_event_log(struct iwl_priv *priv);
+void iwl_clear_isr_stats(struct iwl_priv *priv);
/*****************************************************
* GEOS
@@ -451,14 +490,12 @@ void iwlcore_free_geos(struct iwl_priv *priv);
#define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */
#define STATUS_INT_ENABLED 2
#define STATUS_RF_KILL_HW 3
-#define STATUS_RF_KILL_SW 4
#define STATUS_INIT 5
#define STATUS_ALIVE 6
#define STATUS_READY 7
#define STATUS_TEMPERATURE 8
#define STATUS_GEO_CONFIGURED 9
#define STATUS_EXIT_PENDING 10
-#define STATUS_IN_SUSPEND 11
#define STATUS_STATISTICS 12
#define STATUS_SCANNING 13
#define STATUS_SCAN_ABORTING 14
@@ -487,11 +524,6 @@ static inline int iwl_is_init(struct iwl_priv *priv)
return test_bit(STATUS_INIT, &priv->status);
}
-static inline int iwl_is_rfkill_sw(struct iwl_priv *priv)
-{
- return test_bit(STATUS_RF_KILL_SW, &priv->status);
-}
-
static inline int iwl_is_rfkill_hw(struct iwl_priv *priv)
{
return test_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -499,7 +531,7 @@ static inline int iwl_is_rfkill_hw(struct iwl_priv *priv)
static inline int iwl_is_rfkill(struct iwl_priv *priv)
{
- return iwl_is_rfkill_hw(priv) || iwl_is_rfkill_sw(priv);
+ return iwl_is_rfkill_hw(priv);
}
static inline int iwl_is_ready_rf(struct iwl_priv *priv)
@@ -528,7 +560,14 @@ static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
{
return priv->cfg->ops->hcmd->rxon_assoc(priv);
}
-
+static inline int iwlcore_commit_rxon(struct iwl_priv *priv)
+{
+ return priv->cfg->ops->hcmd->commit_rxon(priv);
+}
+static inline void iwlcore_config_ap(struct iwl_priv *priv)
+{
+ priv->cfg->ops->lib->config_ap(priv);
+}
static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
struct iwl_priv *priv, enum ieee80211_band band)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 6e983149b83..f03dae1b2f3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -89,6 +89,7 @@
/* EEPROM reads */
#define CSR_EEPROM_REG (CSR_BASE+0x02c)
#define CSR_EEPROM_GP (CSR_BASE+0x030)
+#define CSR_OTP_GP_REG (CSR_BASE+0x034)
#define CSR_GIO_REG (CSR_BASE+0x03C)
#define CSR_GP_UCODE (CSR_BASE+0x044)
#define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054)
@@ -96,8 +97,10 @@
#define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c)
#define CSR_UCODE_DRV_GP2 (CSR_BASE+0x060)
#define CSR_LED_REG (CSR_BASE+0x094)
+#define CSR_DRAM_INT_TBL_REG (CSR_BASE+0x0A0)
#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100)
+#define CSR_INT_PERIODIC_REG (CSR_BASE+0x005)
/* Analog phase-lock-loop configuration */
#define CSR_ANA_PLL_CFG (CSR_BASE+0x20c)
/*
@@ -123,16 +126,18 @@
#define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000)
#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000)
-#define CSR_HW_IF_CONFIG_REG_BIT_PCI_OWN_SEM (0x00400000)
-#define CSR_HW_IF_CONFIG_REG_BIT_ME_OWN (0x02000000)
-#define CSR_HW_IF_CONFIG_REG_BIT_WAKE_ME (0x08000000)
+#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000)
+#define CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE (0x02000000)
+#define CSR_HW_IF_CONFIG_REG_PREPARE (0x08000000)
+#define CSR_INT_PERIODIC_DIS (0x00)
+#define CSR_INT_PERIODIC_ENA (0xFF)
/* interrupt flags in INTA, set by uCode or hardware (e.g. dma),
* acknowledged (reset) by host writing "1" to flagged bits. */
#define CSR_INT_BIT_FH_RX (1 << 31) /* Rx DMA, cmd responses, FH_INT[17:16] */
#define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */
-#define CSR_INT_BIT_DNLD (1 << 28) /* uCode Download */
+#define CSR_INT_BIT_RX_PERIODIC (1 << 28) /* Rx periodic */
#define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */
#define CSR_INT_BIT_SCD (1 << 26) /* TXQ pointer advanced */
#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */
@@ -226,6 +231,10 @@
#define CSR_EEPROM_GP_VALID_MSK (0x00000007)
#define CSR_EEPROM_GP_BAD_SIGNATURE (0x00000000)
#define CSR_EEPROM_GP_IF_OWNER_MSK (0x00000180)
+#define CSR_OTP_GP_REG_DEVICE_SELECT (0x00010000) /* 0 - EEPROM, 1 - OTP */
+#define CSR_OTP_GP_REG_OTP_ACCESS_MODE (0x00020000) /* 0 - absolute, 1 - relative */
+#define CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK (0x00100000) /* bit 20 */
+#define CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK (0x00200000) /* bit 21 */
/* CSR GIO */
#define CSR_GIO_REG_VAL_L0S_ENABLED (0x00000002)
@@ -251,6 +260,11 @@
/* HPET MEM debug */
#define CSR_DBG_HPET_MEM_REG_VAL (0xFFFF0000)
+
+/* DRAM INT TABLE */
+#define CSR_DRAM_INT_TBL_ENABLE (1 << 31)
+#define CSR_DRAM_INIT_TBL_WRAP_CHECK (1 << 27)
+
/*=== HBUS (Host-side Bus) ===*/
#define HBUS_BASE (0x400)
/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 65d1a7f2db9..2cf014f523b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -68,13 +68,14 @@ struct iwl_debugfs {
struct dentry *dir_rf;
struct dir_data_files {
struct dentry *file_sram;
- struct dentry *file_eeprom;
+ struct dentry *file_nvm;
struct dentry *file_stations;
struct dentry *file_rx_statistics;
struct dentry *file_tx_statistics;
struct dentry *file_log_event;
struct dentry *file_channels;
struct dentry *file_status;
+ struct dentry *file_interrupt;
} dbgfs_data_files;
struct dir_rf_files {
struct dentry *file_disable_sensitivity;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 64eb585f157..11e08c06891 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -172,7 +172,6 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
const size_t bufsz = sizeof(buf);
- iwl_grab_nic_access(priv);
for (i = priv->dbgfs->sram_len; i > 0; i -= 4) {
val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \
priv->dbgfs->sram_len - i);
@@ -192,7 +191,6 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
}
pos += scnprintf(buf + pos, bufsz - pos, "\n");
- iwl_release_nic_access(priv);
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
return ret;
@@ -292,7 +290,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
return ret;
}
-static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
+static ssize_t iwl_dbgfs_nvm_read(struct file *file,
char __user *user_buf,
size_t count,
loff_t *ppos)
@@ -306,7 +304,7 @@ static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
buf_size = 4 * eeprom_len + 256;
if (eeprom_len % 16) {
- IWL_ERR(priv, "EEPROM size is not multiple of 16.\n");
+ IWL_ERR(priv, "NVM size is not multiple of 16.\n");
return -ENODATA;
}
@@ -318,6 +316,13 @@ static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
}
ptr = priv->eeprom;
+ if (!ptr) {
+ IWL_ERR(priv, "Invalid EEPROM/OTP memory\n");
+ return -ENOMEM;
+ }
+ pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s\n",
+ (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
+ ? "OTP" : "EEPROM");
for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
@@ -375,51 +380,53 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
}
supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ);
- channels = supp_band->channels;
-
- pos += scnprintf(buf + pos, bufsz - pos,
- "Displaying %d channels in 2.4GHz band 802.11bg):\n",
- supp_band->n_channels);
+ if (supp_band) {
+ channels = supp_band->channels;
- for (i = 0; i < supp_band->n_channels; i++)
pos += scnprintf(buf + pos, bufsz - pos,
- "%d: %ddBm: BSS%s%s, %s.\n",
- ieee80211_frequency_to_channel(
- channels[i].center_freq),
- channels[i].max_power,
- channels[i].flags & IEEE80211_CHAN_RADAR ?
- " (IEEE 802.11h required)" : "",
- (!(channels[i].flags & IEEE80211_CHAN_NO_IBSS)
- || (channels[i].flags &
- IEEE80211_CHAN_RADAR)) ? "" :
- ", IBSS",
- channels[i].flags &
- IEEE80211_CHAN_PASSIVE_SCAN ?
- "passive only" : "active/passive");
+ "Displaying %d channels in 2.4GHz band 802.11bg):\n",
+ supp_band->n_channels);
+ for (i = 0; i < supp_band->n_channels; i++)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "%d: %ddBm: BSS%s%s, %s.\n",
+ ieee80211_frequency_to_channel(
+ channels[i].center_freq),
+ channels[i].max_power,
+ channels[i].flags & IEEE80211_CHAN_RADAR ?
+ " (IEEE 802.11h required)" : "",
+ ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
+ || (channels[i].flags &
+ IEEE80211_CHAN_RADAR)) ? "" :
+ ", IBSS",
+ channels[i].flags &
+ IEEE80211_CHAN_PASSIVE_SCAN ?
+ "passive only" : "active/passive");
+ }
supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
- channels = supp_band->channels;
-
- pos += scnprintf(buf + pos, bufsz - pos,
- "Displaying %d channels in 5.2GHz band (802.11a)\n",
- supp_band->n_channels);
+ if (supp_band) {
+ channels = supp_band->channels;
- for (i = 0; i < supp_band->n_channels; i++)
pos += scnprintf(buf + pos, bufsz - pos,
- "%d: %ddBm: BSS%s%s, %s.\n",
- ieee80211_frequency_to_channel(
- channels[i].center_freq),
- channels[i].max_power,
- channels[i].flags & IEEE80211_CHAN_RADAR ?
- " (IEEE 802.11h required)" : "",
- ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
- || (channels[i].flags &
- IEEE80211_CHAN_RADAR)) ? "" :
- ", IBSS",
- channels[i].flags &
- IEEE80211_CHAN_PASSIVE_SCAN ?
- "passive only" : "active/passive");
+ "Displaying %d channels in 5.2GHz band (802.11a)\n",
+ supp_band->n_channels);
+ for (i = 0; i < supp_band->n_channels; i++)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "%d: %ddBm: BSS%s%s, %s.\n",
+ ieee80211_frequency_to_channel(
+ channels[i].center_freq),
+ channels[i].max_power,
+ channels[i].flags & IEEE80211_CHAN_RADAR ?
+ " (IEEE 802.11h required)" : "",
+ ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
+ || (channels[i].flags &
+ IEEE80211_CHAN_RADAR)) ? "" :
+ ", IBSS",
+ channels[i].flags &
+ IEEE80211_CHAN_PASSIVE_SCAN ?
+ "passive only" : "active/passive");
+ }
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
kfree(buf);
return ret;
@@ -442,8 +449,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
test_bit(STATUS_INT_ENABLED, &priv->status));
pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
test_bit(STATUS_RF_KILL_HW, &priv->status));
- pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_SW:\t %d\n",
- test_bit(STATUS_RF_KILL_SW, &priv->status));
pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
test_bit(STATUS_INIT, &priv->status));
pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
@@ -456,8 +461,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
test_bit(STATUS_GEO_CONFIGURED, &priv->status));
pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
test_bit(STATUS_EXIT_PENDING, &priv->status));
- pos += scnprintf(buf + pos, bufsz - pos, "STATUS_IN_SUSPEND:\t %d\n",
- test_bit(STATUS_IN_SUSPEND, &priv->status));
pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
test_bit(STATUS_STATISTICS, &priv->status));
pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
@@ -475,14 +478,104 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
+static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos) {
+
+ struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+ int pos = 0;
+ int cnt = 0;
+ char *buf;
+ int bufsz = 24 * 64; /* 24 items * 64 char per item */
+ ssize_t ret;
+
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "Interrupt Statistics Report:\n");
+
+ pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
+ priv->isr_stats.hw);
+ pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
+ priv->isr_stats.sw);
+ if (priv->isr_stats.sw > 0) {
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\tLast Restarting Code: 0x%X\n",
+ priv->isr_stats.sw_err);
+ }
+#ifdef CONFIG_IWLWIFI_DEBUG
+ pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
+ priv->isr_stats.sch);
+ pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
+ priv->isr_stats.alive);
+#endif
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "HW RF KILL switch toggled:\t %u\n",
+ priv->isr_stats.rfkill);
+
+ pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
+ priv->isr_stats.ctkill);
+
+ pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
+ priv->isr_stats.wakeup);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "Rx command responses:\t\t %u\n",
+ priv->isr_stats.rx);
+ for (cnt = 0; cnt < REPLY_MAX; cnt++) {
+ if (priv->isr_stats.rx_handlers[cnt] > 0)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\tRx handler[%36s]:\t\t %u\n",
+ get_cmd_string(cnt),
+ priv->isr_stats.rx_handlers[cnt]);
+ }
+
+ pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
+ priv->isr_stats.tx);
+
+ pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
+ priv->isr_stats.unhandled);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_priv *priv = file->private_data;
+ char buf[8];
+ int buf_size;
+ u32 reset_flag;
+
+ memset(buf, 0, sizeof(buf));
+ buf_size = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ if (sscanf(buf, "%x", &reset_flag) != 1)
+ return -EFAULT;
+ if (reset_flag == 0)
+ iwl_clear_isr_stats(priv);
+
+ return count;
+}
+
+
DEBUGFS_READ_WRITE_FILE_OPS(sram);
DEBUGFS_WRITE_FILE_OPS(log_event);
-DEBUGFS_READ_FILE_OPS(eeprom);
+DEBUGFS_READ_FILE_OPS(nvm);
DEBUGFS_READ_FILE_OPS(stations);
DEBUGFS_READ_FILE_OPS(rx_statistics);
DEBUGFS_READ_FILE_OPS(tx_statistics);
DEBUGFS_READ_FILE_OPS(channels);
DEBUGFS_READ_FILE_OPS(status);
+DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
/*
* Create the debugfs files and directories
@@ -510,7 +603,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_DIR(data, dbgfs->dir_drv);
DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv);
- DEBUGFS_ADD_FILE(eeprom, data);
+ DEBUGFS_ADD_FILE(nvm, data);
DEBUGFS_ADD_FILE(sram, data);
DEBUGFS_ADD_FILE(log_event, data);
DEBUGFS_ADD_FILE(stations, data);
@@ -518,6 +611,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(tx_statistics, data);
DEBUGFS_ADD_FILE(channels, data);
DEBUGFS_ADD_FILE(status, data);
+ DEBUGFS_ADD_FILE(interrupt, data);
DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
&priv->disable_chain_noise_cal);
@@ -540,7 +634,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
if (!priv->dbgfs)
return;
- DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom);
+ DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram);
@@ -548,6 +642,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
+ DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt);
DEBUGFS_REMOVE(priv->dbgfs->dir_data);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index cf7f0db58fc..e2d620f0b6e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -41,7 +41,6 @@
#include "iwl-prph.h"
#include "iwl-fh.h"
#include "iwl-debug.h"
-#include "iwl-rfkill.h"
#include "iwl-4965-hw.h"
#include "iwl-3945-hw.h"
#include "iwl-3945-led.h"
@@ -289,11 +288,11 @@ struct iwl_frame {
#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
enum {
- /* CMD_SIZE_NORMAL = 0, */
+ CMD_SYNC = 0,
+ CMD_SIZE_NORMAL = 0,
+ CMD_NO_SKB = 0,
CMD_SIZE_HUGE = (1 << 0),
- /* CMD_SYNC = 0, */
CMD_ASYNC = (1 << 1),
- /* CMD_NO_SKB = 0, */
CMD_WANT_SKB = (1 << 2),
};
@@ -381,6 +380,7 @@ struct iwl_rx_queue {
u32 read;
u32 write;
u32 free_count;
+ u32 write_actual;
struct list_head rx_free;
struct list_head rx_used;
int need_update;
@@ -498,22 +498,13 @@ struct iwl_qos_info {
#define STA_PS_STATUS_WAKE 0
#define STA_PS_STATUS_SLEEP 1
-struct iwl3945_tid_data {
- u16 seq_number;
-};
-
-struct iwl3945_hw_key {
- enum ieee80211_key_alg alg;
- int keylen;
- u8 key[32];
-};
struct iwl3945_station_entry {
struct iwl3945_addsta_cmd sta;
- struct iwl3945_tid_data tid[MAX_TID_COUNT];
+ struct iwl_tid_data tid[MAX_TID_COUNT];
u8 used;
u8 ps_status;
- struct iwl3945_hw_key keyinfo;
+ struct iwl_hw_key keyinfo;
};
struct iwl_station_entry {
@@ -822,6 +813,26 @@ enum {
MEASUREMENT_ACTIVE = (1 << 1),
};
+enum iwl_nvm_type {
+ NVM_DEVICE_TYPE_EEPROM = 0,
+ NVM_DEVICE_TYPE_OTP,
+};
+
+/* interrupt statistics */
+struct isr_statistics {
+ u32 hw;
+ u32 sw;
+ u32 sw_err;
+ u32 sch;
+ u32 alive;
+ u32 rfkill;
+ u32 ctkill;
+ u32 wakeup;
+ u32 rx;
+ u32 rx_handlers[REPLY_MAX];
+ u32 tx;
+ u32 unhandled;
+};
#define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */
@@ -877,15 +888,14 @@ struct iwl_priv {
unsigned long scan_start_tsf;
void *scan;
int scan_bands;
- int one_direct_scan;
- u8 direct_ssid_len;
- u8 direct_ssid[IW_ESSID_MAX_SIZE];
+ struct cfg80211_scan_request *scan_request;
u8 scan_tx_ant[IEEE80211_NUM_BANDS];
u8 mgmt_tx_ant;
/* spinlock */
spinlock_t lock; /* protect general shared data */
spinlock_t hcmd_lock; /* protect hcmd */
+ spinlock_t reg_lock; /* protect hw register access */
struct mutex mutex;
/* basic pci-network driver stuff */
@@ -919,16 +929,12 @@ struct iwl_priv {
const struct iwl_rxon_cmd active_rxon;
struct iwl_rxon_cmd staging_rxon;
- int error_recovering;
struct iwl_rxon_cmd recovery_rxon;
/* 1st responses from initialize and runtime uCode images.
* 4965's initialize alive response contains some calibration data. */
struct iwl_init_alive_resp card_alive_init;
struct iwl_alive_resp card_alive;
-#if defined(CONFIG_IWLWIFI_RFKILL)
- struct rfkill *rfkill;
-#endif
#ifdef CONFIG_IWLWIFI_LEDS
unsigned long last_blink_time;
@@ -978,6 +984,9 @@ struct iwl_priv {
u64 bytes;
} tx_stats[3], rx_stats[3];
+ /* counts interrupts */
+ struct isr_statistics isr_stats;
+
struct iwl_power_mgr power_data;
struct iwl_notif_statistics statistics;
@@ -1017,6 +1026,7 @@ struct iwl_priv {
/* eeprom */
u8 *eeprom;
+ int nvm_device_type;
struct iwl_eeprom_calib_info *calib_info;
enum nl80211_iftype iw_mode;
@@ -1034,7 +1044,16 @@ struct iwl_priv {
/*End*/
struct iwl_hw_params hw_params;
+ /* INT ICT Table */
+ u32 *ict_tbl;
+ dma_addr_t ict_tbl_dma;
+ dma_addr_t aligned_ict_tbl_dma;
+ int ict_index;
+ void *ict_tbl_vir;
+ u32 inta;
+ bool use_ict;
+ u32 inta_mask;
/* Current association information needed to configure the
* hardware */
u16 assoc_id;
@@ -1049,7 +1068,6 @@ struct iwl_priv {
struct work_struct calibrated_work;
struct work_struct scan_completed;
struct work_struct rx_replenish;
- struct work_struct rf_kill;
struct work_struct abort_scan;
struct work_struct update_link_led;
struct work_struct auth_work;
@@ -1059,7 +1077,6 @@ struct iwl_priv {
struct tasklet_struct irq_tasklet;
- struct delayed_work set_power_save;
struct delayed_work init_alive_start;
struct delayed_work alive_start;
struct delayed_work scan_check;
@@ -1090,14 +1107,12 @@ struct iwl_priv {
u32 disable_tx_power_cal;
struct work_struct run_time_calib_work;
struct timer_list statistics_periodic;
-
+ bool hw_ready;
/*For 3945*/
#define IWL_DEFAULT_TX_POWER 0x0F
struct iwl3945_notif_statistics statistics_39;
- struct iwl3945_station_entry stations_39[IWL_STATION_COUNT];
-
u32 sta_supp_rates;
}; /*iwl_priv */
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 75517d05df0..7d7554a2f34 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -152,6 +152,32 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwlcore_eeprom_verify_signature);
+static int iwlcore_get_nvm_type(struct iwl_priv *priv)
+{
+ u32 otpgp;
+ int nvm_type;
+
+ /* OTP only valid for CP/PP and after */
+ switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+ case CSR_HW_REV_TYPE_3945:
+ case CSR_HW_REV_TYPE_4965:
+ case CSR_HW_REV_TYPE_5300:
+ case CSR_HW_REV_TYPE_5350:
+ case CSR_HW_REV_TYPE_5100:
+ case CSR_HW_REV_TYPE_5150:
+ nvm_type = NVM_DEVICE_TYPE_EEPROM;
+ break;
+ default:
+ otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
+ if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT)
+ nvm_type = NVM_DEVICE_TYPE_OTP;
+ else
+ nvm_type = NVM_DEVICE_TYPE_EEPROM;
+ break;
+ }
+ return nvm_type;
+}
+
/*
* The device's EEPROM semaphore prevents conflicts between driver and uCode
* when accessing the EEPROM; each access is a series of pulses to/from the
@@ -198,6 +224,31 @@ const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
}
EXPORT_SYMBOL(iwlcore_eeprom_query_addr);
+static int iwl_init_otp_access(struct iwl_priv *priv)
+{
+ int ret;
+
+ /* Enable 40MHz radio clock */
+ _iwl_write32(priv, CSR_GP_CNTRL,
+ _iwl_read32(priv, CSR_GP_CNTRL) |
+ CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+
+ /* wait for clock to be ready */
+ ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ 25000);
+ if (ret < 0)
+ IWL_ERR(priv, "Time out access OTP\n");
+ else {
+ iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
+ APMG_PS_CTRL_VAL_RESET_REQ);
+ udelay(5);
+ iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
+ APMG_PS_CTRL_VAL_RESET_REQ);
+ }
+ return ret;
+}
+
/**
* iwl_eeprom_init - read EEPROM contents
*
@@ -209,11 +260,18 @@ int iwl_eeprom_init(struct iwl_priv *priv)
{
u16 *e;
u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
- int sz = priv->cfg->eeprom_size;
+ int sz;
int ret;
u16 addr;
+ u32 otpgp;
+
+ priv->nvm_device_type = iwlcore_get_nvm_type(priv);
/* allocate eeprom */
+ if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
+ priv->cfg->eeprom_size =
+ OTP_BLOCK_SIZE * OTP_LOWER_BLOCKS_TOTAL;
+ sz = priv->cfg->eeprom_size;
priv->eeprom = kzalloc(sz, GFP_KERNEL);
if (!priv->eeprom) {
ret = -ENOMEM;
@@ -235,30 +293,77 @@ int iwl_eeprom_init(struct iwl_priv *priv)
ret = -ENOENT;
goto err;
}
-
- /* eeprom is an array of 16bit values */
- for (addr = 0; addr < sz; addr += sizeof(u16)) {
- u32 r;
-
- _iwl_write32(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
-
- ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_READ_VALID_MSK,
- IWL_EEPROM_ACCESS_TIMEOUT);
- if (ret < 0) {
- IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
- goto done;
+ if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) {
+ ret = iwl_init_otp_access(priv);
+ if (ret) {
+ IWL_ERR(priv, "Failed to initialize OTP access.\n");
+ ret = -ENOENT;
+ goto err;
+ }
+ _iwl_write32(priv, CSR_EEPROM_GP,
+ iwl_read32(priv, CSR_EEPROM_GP) &
+ ~CSR_EEPROM_GP_IF_OWNER_MSK);
+ /* clear */
+ _iwl_write32(priv, CSR_OTP_GP_REG,
+ iwl_read32(priv, CSR_OTP_GP_REG) |
+ CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
+ CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
+
+ for (addr = 0; addr < sz; addr += sizeof(u16)) {
+ u32 r;
+
+ _iwl_write32(priv, CSR_EEPROM_REG,
+ CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
+
+ ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
+ CSR_EEPROM_REG_READ_VALID_MSK,
+ IWL_EEPROM_ACCESS_TIMEOUT);
+ if (ret < 0) {
+ IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
+ goto done;
+ }
+ r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
+ /* check for ECC errors: */
+ otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
+ if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
+ /* stop in this case */
+ IWL_ERR(priv, "Uncorrectable OTP ECC error, Abort OTP read\n");
+ goto done;
+ }
+ if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
+ /* continue in this case */
+ _iwl_write32(priv, CSR_OTP_GP_REG,
+ iwl_read32(priv, CSR_OTP_GP_REG) |
+ CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
+ IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
+ }
+ e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
+ }
+ } else {
+ /* eeprom is an array of 16bit values */
+ for (addr = 0; addr < sz; addr += sizeof(u16)) {
+ u32 r;
+
+ _iwl_write32(priv, CSR_EEPROM_REG,
+ CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
+
+ ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
+ CSR_EEPROM_REG_READ_VALID_MSK,
+ IWL_EEPROM_ACCESS_TIMEOUT);
+ if (ret < 0) {
+ IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
+ goto done;
+ }
+ r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
+ e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
}
- r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
- e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
}
ret = 0;
done:
priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
err:
if (ret)
- kfree(priv->eeprom);
+ iwl_eeprom_free(priv);
alloc_err:
return ret;
}
@@ -285,7 +390,7 @@ int iwl_eeprom_check_version(struct iwl_priv *priv)
return 0;
err:
- IWL_ERR(priv, "Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
+ IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
eeprom_ver, priv->cfg->eeprom_ver,
calib_ver, priv->cfg->eeprom_calib_ver);
return -EINVAL;
@@ -301,6 +406,8 @@ EXPORT_SYMBOL(iwl_eeprom_query_addr);
u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
{
+ if (!priv->eeprom)
+ return 0;
return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
}
EXPORT_SYMBOL(iwl_eeprom_query16);
@@ -481,8 +588,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
/* First write that fat is not enabled, and then enable
* one by one */
ch_info->fat_extension_channel =
- (IEEE80211_CHAN_NO_FAT_ABOVE |
- IEEE80211_CHAN_NO_FAT_BELOW);
+ (IEEE80211_CHAN_NO_HT40PLUS |
+ IEEE80211_CHAN_NO_HT40MINUS);
if (!(is_channel_valid(ch_info))) {
IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - "
@@ -561,7 +668,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
fat_extension_chan = 0;
else
fat_extension_chan =
- IEEE80211_CHAN_NO_FAT_BELOW;
+ IEEE80211_CHAN_NO_HT40MINUS;
/* Set up driver's info for lower half */
iwl_set_fat_chan_info(priv, ieeeband,
@@ -573,7 +680,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
iwl_set_fat_chan_info(priv, ieeeband,
(eeprom_ch_index[ch] + 4),
&(eeprom_ch_info[ch]),
- IEEE80211_CHAN_NO_FAT_ABOVE);
+ IEEE80211_CHAN_NO_HT40PLUS);
}
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 3479153d96c..195b4ef12c2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -179,6 +179,10 @@ struct iwl_eeprom_channel {
#define EEPROM_5050_TX_POWER_VERSION (4)
#define EEPROM_5050_EEPROM_VERSION (0x21E)
+/* OTP */
+#define OTP_LOWER_BLOCKS_TOTAL (3)
+#define OTP_BLOCK_SIZE (0x400)
+
/* 2.4 GHz */
extern const u8 iwl_eeprom_band_1[14];
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 083ea1ffbe8..d30cb0275d1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -131,9 +131,23 @@ static inline void __iwl_set_bit(const char *f, u32 l,
IWL_DEBUG_IO(priv, "set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
_iwl_write32(priv, reg, val);
}
-#define iwl_set_bit(p, r, m) __iwl_set_bit(__FILE__, __LINE__, p, r, m)
+static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
+{
+ unsigned long reg_flags;
+
+ spin_lock_irqsave(&p->reg_lock, reg_flags);
+ __iwl_set_bit(__FILE__, __LINE__, p, r, m);
+ spin_unlock_irqrestore(&p->reg_lock, reg_flags);
+}
#else
-#define iwl_set_bit(p, r, m) _iwl_set_bit(p, r, m)
+static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
+{
+ unsigned long reg_flags;
+
+ spin_lock_irqsave(&p->reg_lock, reg_flags);
+ _iwl_set_bit(p, r, m);
+ spin_unlock_irqrestore(&p->reg_lock, reg_flags);
+}
#endif
static inline void _iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
@@ -148,19 +162,30 @@ static inline void __iwl_clear_bit(const char *f, u32 l,
IWL_DEBUG_IO(priv, "clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
_iwl_write32(priv, reg, val);
}
-#define iwl_clear_bit(p, r, m) __iwl_clear_bit(__FILE__, __LINE__, p, r, m)
+static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
+{
+ unsigned long reg_flags;
+
+ spin_lock_irqsave(&p->reg_lock, reg_flags);
+ __iwl_clear_bit(__FILE__, __LINE__, p, r, m);
+ spin_unlock_irqrestore(&p->reg_lock, reg_flags);
+}
#else
-#define iwl_clear_bit(p, r, m) _iwl_clear_bit(p, r, m)
+static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
+{
+ unsigned long reg_flags;
+
+ spin_lock_irqsave(&p->reg_lock, reg_flags);
+ _iwl_clear_bit(p, r, m);
+ spin_unlock_irqrestore(&p->reg_lock, reg_flags);
+}
#endif
static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
{
int ret;
u32 val;
-#ifdef CONFIG_IWLWIFI_DEBUG
- if (atomic_read(&priv->restrict_refcnt))
- return 0;
-#endif
+
/* this bit wakes up the NIC */
_iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
@@ -170,12 +195,10 @@ static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
if (ret < 0) {
val = _iwl_read32(priv, CSR_GP_CNTRL);
IWL_ERR(priv, "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
+ _iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
return -EIO;
}
-#ifdef CONFIG_IWLWIFI_DEBUG
- atomic_inc(&priv->restrict_refcnt);
-#endif
return 0;
}
@@ -183,9 +206,6 @@ static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
static inline int __iwl_grab_nic_access(const char *f, u32 l,
struct iwl_priv *priv)
{
- if (atomic_read(&priv->restrict_refcnt))
- IWL_ERR(priv, "Grabbing access while already held %s %d.\n", f, l);
-
IWL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l);
return _iwl_grab_nic_access(priv);
}
@@ -198,18 +218,13 @@ static inline int __iwl_grab_nic_access(const char *f, u32 l,
static inline void _iwl_release_nic_access(struct iwl_priv *priv)
{
-#ifdef CONFIG_IWLWIFI_DEBUG
- if (atomic_dec_and_test(&priv->restrict_refcnt))
-#endif
- _iwl_clear_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ _iwl_clear_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
}
#ifdef CONFIG_IWLWIFI_DEBUG
static inline void __iwl_release_nic_access(const char *f, u32 l,
struct iwl_priv *priv)
{
- if (atomic_read(&priv->restrict_refcnt) <= 0)
- IWL_ERR(priv, "Release unheld nic access at line %s %d.\n", f, l);
IWL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l);
_iwl_release_nic_access(priv);
@@ -230,16 +245,37 @@ static inline u32 __iwl_read_direct32(const char *f, u32 l,
struct iwl_priv *priv, u32 reg)
{
u32 value = _iwl_read_direct32(priv, reg);
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERR(priv, "Nic access not held from %s %d\n", f, l);
IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
f, l);
return value;
}
-#define iwl_read_direct32(priv, reg) \
- __iwl_read_direct32(__FILE__, __LINE__, priv, reg)
+static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
+{
+ u32 value;
+ unsigned long reg_flags;
+
+ spin_lock_irqsave(&priv->reg_lock, reg_flags);
+ iwl_grab_nic_access(priv);
+ value = __iwl_read_direct32(__FILE__, __LINE__, priv, reg);
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
+ return value;
+}
+
#else
-#define iwl_read_direct32 _iwl_read_direct32
+static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
+{
+ u32 value;
+ unsigned long reg_flags;
+
+ spin_lock_irqsave(&priv->reg_lock, reg_flags);
+ iwl_grab_nic_access(priv);
+ value = _iwl_read_direct32(priv, reg);
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
+ return value;
+
+}
#endif
static inline void _iwl_write_direct32(struct iwl_priv *priv,
@@ -247,19 +283,17 @@ static inline void _iwl_write_direct32(struct iwl_priv *priv,
{
_iwl_write32(priv, reg, value);
}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static void __iwl_write_direct32(const char *f , u32 line,
- struct iwl_priv *priv, u32 reg, u32 value)
+static inline void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value)
{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
- _iwl_write_direct32(priv, reg, value);
+ unsigned long reg_flags;
+
+ spin_lock_irqsave(&priv->reg_lock, reg_flags);
+ if (!iwl_grab_nic_access(priv)) {
+ _iwl_write_direct32(priv, reg, value);
+ iwl_release_nic_access(priv);
+ }
+ spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
}
-#define iwl_write_direct32(priv, reg, value) \
- __iwl_write_direct32(__func__, __LINE__, priv, reg, value)
-#else
-#define iwl_write_direct32 _iwl_write_direct32
-#endif
static inline void iwl_write_reg_buf(struct iwl_priv *priv,
u32 reg, u32 len, u32 *values)
@@ -268,14 +302,23 @@ static inline void iwl_write_reg_buf(struct iwl_priv *priv,
if ((priv != NULL) && (values != NULL)) {
for (; 0 < len; len -= count, reg += count, values++)
- _iwl_write_direct32(priv, reg, *values);
+ iwl_write_direct32(priv, reg, *values);
}
}
static inline int _iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr,
u32 mask, int timeout)
{
- return _iwl_poll_bit(priv, addr, mask, mask, timeout);
+ int t = 0;
+
+ do {
+ if ((iwl_read_direct32(priv, addr) & mask) == mask)
+ return t;
+ udelay(IWL_POLL_INTERVAL);
+ t += IWL_POLL_INTERVAL;
+ } while (t < timeout);
+
+ return -ETIMEDOUT;
}
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -305,20 +348,18 @@ static inline u32 _iwl_read_prph(struct iwl_priv *priv, u32 reg)
rmb();
return _iwl_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline u32 __iwl_read_prph(const char *f, u32 line,
- struct iwl_priv *priv, u32 reg)
+static inline u32 iwl_read_prph(struct iwl_priv *priv, u32 reg)
{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
- return _iwl_read_prph(priv, reg);
-}
+ unsigned long reg_flags;
+ u32 val;
-#define iwl_read_prph(priv, reg) \
- __iwl_read_prph(__func__, __LINE__, priv, reg)
-#else
-#define iwl_read_prph _iwl_read_prph
-#endif
+ spin_lock_irqsave(&priv->reg_lock, reg_flags);
+ iwl_grab_nic_access(priv);
+ val = _iwl_read_prph(priv, reg);
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
+ return val;
+}
static inline void _iwl_write_prph(struct iwl_priv *priv,
u32 addr, u32 val)
@@ -328,83 +369,107 @@ static inline void _iwl_write_prph(struct iwl_priv *priv,
wmb();
_iwl_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_write_prph(const char *f, u32 line,
- struct iwl_priv *priv, u32 addr, u32 val)
+
+static inline void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
- _iwl_write_prph(priv, addr, val);
-}
+ unsigned long reg_flags;
-#define iwl_write_prph(priv, addr, val) \
- __iwl_write_prph(__func__, __LINE__, priv, addr, val);
-#else
-#define iwl_write_prph _iwl_write_prph
-#endif
+ spin_lock_irqsave(&priv->reg_lock, reg_flags);
+ if (!iwl_grab_nic_access(priv)) {
+ _iwl_write_prph(priv, addr, val);
+ iwl_release_nic_access(priv);
+ }
+ spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
+}
#define _iwl_set_bits_prph(priv, reg, mask) \
_iwl_write_prph(priv, reg, (_iwl_read_prph(priv, reg) | mask))
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_set_bits_prph(const char *f, u32 line,
- struct iwl_priv *priv,
- u32 reg, u32 mask)
+
+static inline void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
+ unsigned long reg_flags;
+ spin_lock_irqsave(&priv->reg_lock, reg_flags);
+ iwl_grab_nic_access(priv);
_iwl_set_bits_prph(priv, reg, mask);
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
}
-#define iwl_set_bits_prph(priv, reg, mask) \
- __iwl_set_bits_prph(__func__, __LINE__, priv, reg, mask)
-#else
-#define iwl_set_bits_prph _iwl_set_bits_prph
-#endif
#define _iwl_set_bits_mask_prph(priv, reg, bits, mask) \
_iwl_write_prph(priv, reg, ((_iwl_read_prph(priv, reg) & mask) | bits))
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_set_bits_mask_prph(const char *f, u32 line,
- struct iwl_priv *priv, u32 reg, u32 bits, u32 mask)
+static inline void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
+ u32 bits, u32 mask)
{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
+ unsigned long reg_flags;
+
+ spin_lock_irqsave(&priv->reg_lock, reg_flags);
+ iwl_grab_nic_access(priv);
_iwl_set_bits_mask_prph(priv, reg, bits, mask);
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
}
-#define iwl_set_bits_mask_prph(priv, reg, bits, mask) \
- __iwl_set_bits_mask_prph(__func__, __LINE__, priv, reg, bits, mask)
-#else
-#define iwl_set_bits_mask_prph _iwl_set_bits_mask_prph
-#endif
static inline void iwl_clear_bits_prph(struct iwl_priv
*priv, u32 reg, u32 mask)
{
- u32 val = _iwl_read_prph(priv, reg);
+ unsigned long reg_flags;
+ u32 val;
+
+ spin_lock_irqsave(&priv->reg_lock, reg_flags);
+ iwl_grab_nic_access(priv);
+ val = _iwl_read_prph(priv, reg);
_iwl_write_prph(priv, reg, (val & ~mask));
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
}
static inline u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
{
- iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
+ unsigned long reg_flags;
+ u32 value;
+
+ spin_lock_irqsave(&priv->reg_lock, reg_flags);
+ iwl_grab_nic_access(priv);
+
+ _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
rmb();
- return iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ value = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
+ return value;
}
static inline void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
{
- iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
- wmb();
- iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
+ unsigned long reg_flags;
+
+ spin_lock_irqsave(&priv->reg_lock, reg_flags);
+ if (!iwl_grab_nic_access(priv)) {
+ _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
+ wmb();
+ _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
+ iwl_release_nic_access(priv);
+ }
+ spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
}
static inline void iwl_write_targ_mem_buf(struct iwl_priv *priv, u32 addr,
u32 len, u32 *values)
{
- iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
- wmb();
- for (; 0 < len; len -= sizeof(u32), values++)
- iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
+ unsigned long reg_flags;
+
+ spin_lock_irqsave(&priv->reg_lock, reg_flags);
+ if (!iwl_grab_nic_access(priv)) {
+ _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
+ wmb();
+ for (; 0 < len; len -= sizeof(u32), values++)
+ _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
+
+ iwl_release_nic_access(priv);
+ }
+ spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
}
#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 19680f72087..5e64252f80f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -176,10 +176,6 @@ static int iwl_led_associate(struct iwl_priv *priv, int led_id)
static int iwl_led_disassociate(struct iwl_priv *priv, int led_id)
{
priv->allow_blinking = 0;
- if (iwl_is_rfkill(priv))
- iwl4965_led_off_reg(priv, led_id);
- else
- iwl4965_led_on_reg(priv, led_id);
return 0;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 47c894530eb..f2ea3f05f6e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -41,38 +41,33 @@
#include "iwl-power.h"
/*
- * Setting power level allow the card to go to sleep when not busy
- * there are three factor that decide the power level to go to, they
- * are list here with its priority
- * 1- critical_power_setting this will be set according to card temperature.
- * 2- system_power_setting this will be set by system PM manager.
- * 3- user_power_setting this will be set by user either by writing to sys or
- * mac80211
+ * Setting power level allow the card to go to sleep when not busy.
*
- * if system_power_setting and user_power_setting is set to auto
- * the power level will be decided according to association status and battery
- * status.
+ * The power level is set to INDEX_1 (the least deep state) by
+ * default, and will, in the future, be the deepest state unless
+ * otherwise required by pm_qos network latency requirements.
*
+ * Using INDEX_1 without pm_qos is ok because mac80211 will disable
+ * PS when even checking every beacon for the TIM bit would exceed
+ * the required latency.
*/
-#define MSEC_TO_USEC 1024
#define IWL_POWER_RANGE_0_MAX (2)
#define IWL_POWER_RANGE_1_MAX (10)
-
-#define IWL_POWER_ON_BATTERY IWL_POWER_INDEX_5
-#define IWL_POWER_ON_AC_DISASSOC IWL_POWER_MODE_CAM
-#define IWL_POWER_ON_AC_ASSOC IWL_POWER_MODE_CAM
-
-
-#define IWL_CT_KILL_TEMPERATURE 110
-#define IWL_MIN_POWER_TEMPERATURE 100
-#define IWL_REDUCED_POWER_TEMPERATURE 95
-
+#define NOSLP cpu_to_le16(0), 0, 0
+#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
+#define TU_TO_USEC 1024
+#define SLP_TOUT(T) cpu_to_le32((T) * TU_TO_USEC)
+#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \
+ cpu_to_le32(X1), \
+ cpu_to_le32(X2), \
+ cpu_to_le32(X3), \
+ cpu_to_le32(X4)}
/* default power management (not Tx power) table values */
-/* for TIM 0-10 */
-static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {
+/* for DTIM period 0 through IWL_POWER_RANGE_0_MAX */
+static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = {
{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
@@ -82,8 +77,8 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {
};
-/* for TIM = 3-10 */
-static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {
+/* for DTIM period IWL_POWER_RANGE_0_MAX + 1 through IWL_POWER_RANGE_1_MAX */
+static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = {
{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0},
@@ -92,8 +87,8 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {
{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2}
};
-/* for TIM > 11 */
-static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {
+/* for DTIM period > IWL_POWER_RANGE_1_MAX */
+static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {
{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
@@ -106,39 +101,15 @@ static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {
/* set card power command */
static int iwl_set_power(struct iwl_priv *priv, void *cmd)
{
- return iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD,
- sizeof(struct iwl_powertable_cmd),
- cmd, NULL);
-}
-/* decide the right power level according to association status
- * and battery status
- */
-static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
-{
- u16 mode;
-
- switch (priv->power_data.user_power_setting) {
- case IWL_POWER_AUTO:
- /* if running on battery */
- if (priv->power_data.is_battery_active)
- mode = IWL_POWER_ON_BATTERY;
- else if (iwl_is_associated(priv))
- mode = IWL_POWER_ON_AC_ASSOC;
- else
- mode = IWL_POWER_ON_AC_DISASSOC;
- break;
- default:
- mode = priv->power_data.user_power_setting;
- break;
- }
- return mode;
+ return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD,
+ sizeof(struct iwl_powertable_cmd), cmd);
}
/* initialize to default */
static void iwl_power_init_handle(struct iwl_priv *priv)
{
struct iwl_power_mgr *pow_data;
- int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
+ int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_NUM;
struct iwl_powertable_cmd *cmd;
int i;
u16 lctl;
@@ -157,7 +128,7 @@ static void iwl_power_init_handle(struct iwl_priv *priv)
IWL_DEBUG_POWER(priv, "adjust power command flags\n");
- for (i = 0; i < IWL_POWER_MAX; i++) {
+ for (i = 0; i < IWL_POWER_NUM; i++) {
cmd = &pow_data->pwr_range_0[i].cmd;
if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
@@ -247,33 +218,12 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
- /* If on battery, set to 3,
- * if plugged into AC power, set to CAM ("continuously aware mode"),
- * else user level */
-
- switch (setting->system_power_setting) {
- case IWL_POWER_SYS_AUTO:
- final_mode = iwl_get_auto_power_mode(priv);
- break;
- case IWL_POWER_SYS_BATTERY:
- final_mode = IWL_POWER_INDEX_3;
- break;
- case IWL_POWER_SYS_AC:
- final_mode = IWL_POWER_MODE_CAM;
- break;
- default:
- final_mode = IWL_POWER_INDEX_3;
- WARN_ON(1);
- }
-
- if (setting->critical_power_setting > final_mode)
- final_mode = setting->critical_power_setting;
+ final_mode = priv->power_data.user_power_setting;
- /* driver only support CAM for non STA network */
- if (priv->iw_mode != NL80211_IFTYPE_STATION)
+ if (setting->power_disabled)
final_mode = IWL_POWER_MODE_CAM;
- if (iwl_is_ready_rf(priv) && !setting->power_disabled &&
+ if (iwl_is_ready_rf(priv) &&
((setting->power_mode != final_mode) || force)) {
struct iwl_powertable_cmd cmd;
@@ -290,8 +240,6 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
if (final_mode == IWL_POWER_MODE_CAM)
clear_bit(STATUS_POWER_PMI, &priv->status);
- else
- set_bit(STATUS_POWER_PMI, &priv->status);
if (priv->cfg->ops->lib->update_chain_flags && update_chains)
priv->cfg->ops->lib->update_chain_flags(priv);
@@ -307,51 +255,10 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
}
EXPORT_SYMBOL(iwl_power_update_mode);
-/* Allow other iwl code to disable/enable power management active
- * this will be useful for rate scale to disable PM during heavy
- * Tx/Rx activities
- */
-int iwl_power_disable_management(struct iwl_priv *priv, u32 ms)
-{
- u16 prev_mode;
- int ret = 0;
-
- if (priv->power_data.power_disabled)
- return -EBUSY;
-
- prev_mode = priv->power_data.user_power_setting;
- priv->power_data.user_power_setting = IWL_POWER_MODE_CAM;
- ret = iwl_power_update_mode(priv, 0);
- priv->power_data.power_disabled = 1;
- priv->power_data.user_power_setting = prev_mode;
- cancel_delayed_work(&priv->set_power_save);
- if (ms)
- queue_delayed_work(priv->workqueue, &priv->set_power_save,
- msecs_to_jiffies(ms));
-
-
- return ret;
-}
-EXPORT_SYMBOL(iwl_power_disable_management);
-
-/* Allow other iwl code to disable/enable power management active
- * this will be useful for rate scale to disable PM during high
- * volume activities
- */
-int iwl_power_enable_management(struct iwl_priv *priv)
-{
- int ret = 0;
-
- priv->power_data.power_disabled = 0;
- ret = iwl_power_update_mode(priv, 0);
- return ret;
-}
-EXPORT_SYMBOL(iwl_power_enable_management);
-
/* set user_power_setting */
int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
{
- if (mode > IWL_POWER_MAX)
+ if (mode >= IWL_POWER_NUM)
return -EINVAL;
priv->power_data.user_power_setting = mode;
@@ -360,86 +267,12 @@ int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
}
EXPORT_SYMBOL(iwl_power_set_user_mode);
-/* set system_power_setting. This should be set by over all
- * PM application.
- */
-int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode)
-{
- if (mode < IWL_POWER_SYS_MAX)
- priv->power_data.system_power_setting = mode;
- else
- return -EINVAL;
- return iwl_power_update_mode(priv, 0);
-}
-EXPORT_SYMBOL(iwl_power_set_system_mode);
-
/* initialize to default */
void iwl_power_initialize(struct iwl_priv *priv)
{
iwl_power_init_handle(priv);
- priv->power_data.user_power_setting = IWL_POWER_AUTO;
- priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO;
- priv->power_data.power_disabled = 0;
- priv->power_data.is_battery_active = 0;
- priv->power_data.critical_power_setting = 0;
+ priv->power_data.user_power_setting = IWL_POWER_INDEX_1;
+ /* default to disabled until mac80211 says otherwise */
+ priv->power_data.power_disabled = 1;
}
EXPORT_SYMBOL(iwl_power_initialize);
-
-/* set critical_power_setting according to temperature value */
-int iwl_power_temperature_change(struct iwl_priv *priv)
-{
- int ret = 0;
- s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature);
- u16 new_critical = priv->power_data.critical_power_setting;
-
- if (temperature > IWL_CT_KILL_TEMPERATURE)
- return 0;
- else if (temperature > IWL_MIN_POWER_TEMPERATURE)
- new_critical = IWL_POWER_INDEX_5;
- else if (temperature > IWL_REDUCED_POWER_TEMPERATURE)
- new_critical = IWL_POWER_INDEX_3;
- else
- new_critical = IWL_POWER_MODE_CAM;
-
- if (new_critical != priv->power_data.critical_power_setting)
- priv->power_data.critical_power_setting = new_critical;
-
- if (priv->power_data.critical_power_setting >
- priv->power_data.power_mode)
- ret = iwl_power_update_mode(priv, 0);
-
- return ret;
-}
-EXPORT_SYMBOL(iwl_power_temperature_change);
-
-static void iwl_bg_set_power_save(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work,
- struct iwl_priv, set_power_save.work);
- IWL_DEBUG_POWER(priv, "update power\n");
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- mutex_lock(&priv->mutex);
-
- /* on starting association we disable power management
- * until association, if association failed then this
- * timer will expire and enable PM again.
- */
- if (!iwl_is_associated(priv))
- iwl_power_enable_management(priv);
-
- mutex_unlock(&priv->mutex);
-}
-void iwl_setup_power_deferred_work(struct iwl_priv *priv)
-{
- INIT_DELAYED_WORK(&priv->set_power_save, iwl_bg_set_power_save);
-}
-EXPORT_SYMBOL(iwl_setup_power_deferred_work);
-
-void iwl_power_cancel_timeout(struct iwl_priv *priv)
-{
- cancel_delayed_work(&priv->set_power_save);
-}
-EXPORT_SYMBOL(iwl_power_cancel_timeout);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index 18963392121..37ba3bb7a25 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -40,56 +40,29 @@ enum {
IWL_POWER_INDEX_3,
IWL_POWER_INDEX_4,
IWL_POWER_INDEX_5,
- IWL_POWER_AUTO,
- IWL_POWER_MAX = IWL_POWER_AUTO,
+ IWL_POWER_NUM
};
-enum {
- IWL_POWER_SYS_AUTO,
- IWL_POWER_SYS_AC,
- IWL_POWER_SYS_BATTERY,
- IWL_POWER_SYS_MAX,
-};
-
-
/* Power management (not Tx power) structures */
-#define NOSLP cpu_to_le16(0), 0, 0
-#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
-#define SLP_TOUT(T) cpu_to_le32((T) * MSEC_TO_USEC)
-#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \
- cpu_to_le32(X1), \
- cpu_to_le32(X2), \
- cpu_to_le32(X3), \
- cpu_to_le32(X4)}
struct iwl_power_vec_entry {
struct iwl_powertable_cmd cmd;
u8 no_dtim;
};
struct iwl_power_mgr {
- spinlock_t lock;
- struct iwl_power_vec_entry pwr_range_0[IWL_POWER_MAX];
- struct iwl_power_vec_entry pwr_range_1[IWL_POWER_MAX];
- struct iwl_power_vec_entry pwr_range_2[IWL_POWER_MAX];
+ struct iwl_power_vec_entry pwr_range_0[IWL_POWER_NUM];
+ struct iwl_power_vec_entry pwr_range_1[IWL_POWER_NUM];
+ struct iwl_power_vec_entry pwr_range_2[IWL_POWER_NUM];
u32 dtim_period;
/* final power level that used to calculate final power command */
u8 power_mode;
- u8 user_power_setting; /* set by user through mac80211 or sysfs */
- u8 system_power_setting; /* set by kernel system tools */
- u8 critical_power_setting; /* set if driver over heated */
- u8 is_battery_active; /* DC/AC power */
- u8 power_disabled; /* flag to disable using power saving level */
+ u8 user_power_setting; /* set by user through sysfs */
+ u8 power_disabled; /* set by mac80211's CONF_PS */
};
-void iwl_setup_power_deferred_work(struct iwl_priv *priv);
-void iwl_power_cancel_timeout(struct iwl_priv *priv);
int iwl_power_update_mode(struct iwl_priv *priv, bool force);
-int iwl_power_disable_management(struct iwl_priv *priv, u32 ms);
-int iwl_power_enable_management(struct iwl_priv *priv);
int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
-int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode);
void iwl_power_initialize(struct iwl_priv *priv);
-int iwl_power_temperature_change(struct iwl_priv *priv);
#endif /* __iwl_power_setting_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
deleted file mode 100644
index 2ad9faf1508..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ipw3945 project, as well
- * as portions of the ieee80211 subsystem header files.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *****************************************************************************/
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <net/mac80211.h>
-
-#include "iwl-eeprom.h"
-#include "iwl-dev.h"
-#include "iwl-core.h"
-
-/* software rf-kill from user */
-static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
-{
- struct iwl_priv *priv = data;
- int err = 0;
-
- if (!priv->rfkill)
- return 0;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return 0;
-
- IWL_DEBUG_RF_KILL(priv, "we received soft RFKILL set to state %d\n", state);
- mutex_lock(&priv->mutex);
-
- switch (state) {
- case RFKILL_STATE_UNBLOCKED:
- if (iwl_is_rfkill_hw(priv)) {
- err = -EBUSY;
- goto out_unlock;
- }
- iwl_radio_kill_sw_enable_radio(priv);
- break;
- case RFKILL_STATE_SOFT_BLOCKED:
- iwl_radio_kill_sw_disable_radio(priv);
- break;
- default:
- IWL_WARN(priv, "we received unexpected RFKILL state %d\n",
- state);
- break;
- }
-out_unlock:
- mutex_unlock(&priv->mutex);
-
- return err;
-}
-
-int iwl_rfkill_init(struct iwl_priv *priv)
-{
- struct device *device = wiphy_dev(priv->hw->wiphy);
- int ret = 0;
-
- BUG_ON(device == NULL);
-
- IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n");
- priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
- if (!priv->rfkill) {
- IWL_ERR(priv, "Unable to allocate RFKILL device.\n");
- ret = -ENOMEM;
- goto error;
- }
-
- priv->rfkill->name = priv->cfg->name;
- priv->rfkill->data = priv;
- priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
- priv->rfkill->toggle_radio = iwl_rfkill_soft_rf_kill;
- priv->rfkill->user_claim_unsupported = 1;
-
- priv->rfkill->dev.class->suspend = NULL;
- priv->rfkill->dev.class->resume = NULL;
-
- ret = rfkill_register(priv->rfkill);
- if (ret) {
- IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret);
- goto free_rfkill;
- }
-
- IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n");
- return ret;
-
-free_rfkill:
- if (priv->rfkill != NULL)
- rfkill_free(priv->rfkill);
- priv->rfkill = NULL;
-
-error:
- IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n");
- return ret;
-}
-EXPORT_SYMBOL(iwl_rfkill_init);
-
-void iwl_rfkill_unregister(struct iwl_priv *priv)
-{
-
- if (priv->rfkill)
- rfkill_unregister(priv->rfkill);
-
- priv->rfkill = NULL;
-}
-EXPORT_SYMBOL(iwl_rfkill_unregister);
-
-/* set RFKILL to the right state. */
-void iwl_rfkill_set_hw_state(struct iwl_priv *priv)
-{
- if (!priv->rfkill)
- return;
-
- if (iwl_is_rfkill_hw(priv)) {
- rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
- return;
- }
-
- if (!iwl_is_rfkill_sw(priv))
- rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
- else
- rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
-}
-EXPORT_SYMBOL(iwl_rfkill_set_hw_state);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
deleted file mode 100644
index 633dafb4bf1..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ipw3945 project, as well
- * as portions of the ieee80211 subsystem header files.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *****************************************************************************/
-#ifndef __iwl_rf_kill_h__
-#define __iwl_rf_kill_h__
-
-struct iwl_priv;
-
-#include <linux/rfkill.h>
-
-#ifdef CONFIG_IWLWIFI_RFKILL
-
-void iwl_rfkill_set_hw_state(struct iwl_priv *priv);
-void iwl_rfkill_unregister(struct iwl_priv *priv);
-int iwl_rfkill_init(struct iwl_priv *priv);
-#else
-static inline void iwl_rfkill_set_hw_state(struct iwl_priv *priv) {}
-static inline void iwl_rfkill_unregister(struct iwl_priv *priv) {}
-static inline int iwl_rfkill_init(struct iwl_priv *priv) { return 0; }
-#endif
-
-
-
-#endif /* __iwl_rf_kill_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 8f65908f66f..2b8d40b37a1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -145,18 +145,14 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
goto exit_unlock;
}
- ret = iwl_grab_nic_access(priv);
- if (ret)
- goto exit_unlock;
-
- /* Device expects a multiple of 8 */
- iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write & ~0x7);
- iwl_release_nic_access(priv);
+ q->write_actual = (q->write & ~0x7);
+ iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write_actual);
/* Else device is assumed to be awake */
} else {
/* Device expects a multiple of 8 */
- iwl_write32(priv, rx_wrt_ptr_reg, q->write & ~0x7);
+ q->write_actual = (q->write & ~0x7);
+ iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write_actual);
}
q->need_update = 0;
@@ -218,7 +214,7 @@ int iwl_rx_queue_restock(struct iwl_priv *priv)
/* If we've added more space for the firmware to place data, tell it.
* Increment device's write pointer in multiples of 8. */
- if (write != (rxq->write & ~0x7)) {
+ if (rxq->write_actual != (rxq->write & ~0x7)) {
spin_lock_irqsave(&rxq->lock, flags);
rxq->need_update = 1;
spin_unlock_irqrestore(&rxq->lock, flags);
@@ -238,7 +234,7 @@ EXPORT_SYMBOL(iwl_rx_queue_restock);
* Also restock the Rx queue via iwl_rx_queue_restock.
* This is called as a scheduled work item (except for during initialization)
*/
-void iwl_rx_allocate(struct iwl_priv *priv)
+void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
{
struct iwl_rx_queue *rxq = &priv->rxq;
struct list_head *element;
@@ -260,7 +256,8 @@ void iwl_rx_allocate(struct iwl_priv *priv)
/* Alloc a new receive buffer */
rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
- GFP_KERNEL);
+ priority);
+
if (!rxb->skb) {
IWL_CRIT(priv, "Can not allocate SKB buffers\n");
/* We don't reschedule replenish work here -- we will
@@ -295,7 +292,7 @@ void iwl_rx_replenish(struct iwl_priv *priv)
{
unsigned long flags;
- iwl_rx_allocate(priv);
+ iwl_rx_allocate(priv, GFP_KERNEL);
spin_lock_irqsave(&priv->lock, flags);
iwl_rx_queue_restock(priv);
@@ -303,6 +300,14 @@ void iwl_rx_replenish(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_rx_replenish);
+void iwl_rx_replenish_now(struct iwl_priv *priv)
+{
+ iwl_rx_allocate(priv, GFP_ATOMIC);
+
+ iwl_rx_queue_restock(priv);
+}
+EXPORT_SYMBOL(iwl_rx_replenish_now);
+
/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
* If an SKB has been detached, the POOL needs to have its SKB set to NULL
@@ -358,6 +363,7 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
/* Set us so that we have processed and used all buffers, but have
* not restocked the Rx queue with fresh buffers */
rxq->read = rxq->write = 0;
+ rxq->write_actual = 0;
rxq->free_count = 0;
rxq->need_update = 0;
return 0;
@@ -396,6 +402,7 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
/* Set us so that we have processed and used all buffers, but have
* not restocked the Rx queue with fresh buffers */
rxq->read = rxq->write = 0;
+ rxq->write_actual = 0;
rxq->free_count = 0;
spin_unlock_irqrestore(&rxq->lock, flags);
}
@@ -403,18 +410,12 @@ EXPORT_SYMBOL(iwl_rx_queue_reset);
int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
{
- int ret;
- unsigned long flags;
u32 rb_size;
const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
- const u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT why this stalls RX */
+ u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
- spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
- }
+ if (!priv->cfg->use_isr_legacy)
+ rb_timeout = RX_RB_TIMEOUT;
if (priv->cfg->mod_params->amsdu_size_8K)
rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
@@ -452,35 +453,19 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
(rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
(rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
- iwl_release_nic_access(priv);
-
iwl_write32(priv, CSR_INT_COALESCING, 0x40);
- spin_unlock_irqrestore(&priv->lock, flags);
-
return 0;
}
int iwl_rxq_stop(struct iwl_priv *priv)
{
- int ret;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (unlikely(ret)) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
- }
/* stop Rx DMA */
iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
return 0;
}
EXPORT_SYMBOL(iwl_rxq_stop);
@@ -582,8 +567,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
iwl_leds_background(priv);
- if (priv->cfg->ops->lib->temperature && change)
- priv->cfg->ops->lib->temperature(priv);
+ if (priv->cfg->ops->lib->temp_ops.temperature && change)
+ priv->cfg->ops->lib->temp_ops.temperature(priv);
}
EXPORT_SYMBOL(iwl_rx_statistics);
@@ -1102,13 +1087,6 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
if (rx_start->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
rx_status.flag |= RX_FLAG_SHORTPRE;
- /* Take shortcut when only in monitor mode */
- if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
- iwl_pass_packet_to_mac80211(priv, include_phy,
- rxb, &rx_status);
- return;
- }
-
network_packet = iwl_is_network_packet(priv, header);
if (network_packet) {
priv->last_rx_rssi = rx_status.signal;
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 6330b91e37c..e26875dbe85 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -445,13 +445,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
unsigned long flags;
struct iwl_priv *priv = hw->priv;
int ret;
- u8 *ssid = NULL;
- size_t ssid_len = 0;
-
- if (req->n_ssids) {
- ssid = req->ssids[0].ssid;
- ssid_len = req->ssids[0].ssid_len;
- }
IWL_DEBUG_MAC80211(priv, "enter\n");
@@ -485,13 +478,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
goto out_unlock;
}
- if (ssid_len) {
- priv->one_direct_scan = 1;
- priv->direct_ssid_len = ssid_len;
- memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
- } else {
- priv->one_direct_scan = 0;
- }
+ priv->scan_request = req;
ret = iwl_scan_initiate(priv);
@@ -530,73 +517,14 @@ void iwl_bg_scan_check(struct work_struct *data)
EXPORT_SYMBOL(iwl_bg_scan_check);
/**
- * iwl_supported_rate_to_ie - fill in the supported rate in IE field
- *
- * return : set the bit for each supported rate insert in ie
- */
-static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
- u16 basic_rate, int *left)
-{
- u16 ret_rates = 0, bit;
- int i;
- u8 *cnt = ie;
- u8 *rates = ie + 1;
-
- for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
- if (bit & supported_rate) {
- ret_rates |= bit;
- rates[*cnt] = iwl_rates[i].ieee |
- ((bit & basic_rate) ? 0x80 : 0x00);
- (*cnt)++;
- (*left)--;
- if ((*left <= 0) ||
- (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
- break;
- }
- }
-
- return ret_rates;
-}
-
-
-static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
- u8 *pos, int *left)
-{
- struct ieee80211_ht_cap *ht_cap;
-
- if (!sband || !sband->ht_cap.ht_supported)
- return;
-
- if (*left < sizeof(struct ieee80211_ht_cap))
- return;
-
- *pos++ = sizeof(struct ieee80211_ht_cap);
- ht_cap = (struct ieee80211_ht_cap *) pos;
-
- ht_cap->cap_info = cpu_to_le16(sband->ht_cap.cap);
- memcpy(&ht_cap->mcs, &sband->ht_cap.mcs, 16);
- ht_cap->ampdu_params_info =
- (sband->ht_cap.ampdu_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) |
- ((sband->ht_cap.ampdu_density << 2) &
- IEEE80211_HT_AMPDU_PARM_DENSITY);
- *left -= sizeof(struct ieee80211_ht_cap);
-}
-
-/**
* iwl_fill_probe_req - fill in all required fields and IE for probe request
*/
-u16 iwl_fill_probe_req(struct iwl_priv *priv,
- enum ieee80211_band band,
- struct ieee80211_mgmt *frame,
- int left)
+u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
+ const u8 *ies, int ie_len, int left)
{
int len = 0;
u8 *pos = NULL;
- u16 active_rates, ret_rates, cck_rates, active_rate_basic;
- const struct ieee80211_supported_band *sband =
- iwl_get_hw_mode(priv, band);
-
/* Make sure there is enough space for the probe request,
* two mandatory IEs and the data */
@@ -624,62 +552,12 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv,
len += 2;
- /* fill in supported rate */
- left -= 2;
- if (left < 0)
- return 0;
-
- *pos++ = WLAN_EID_SUPP_RATES;
- *pos = 0;
-
- /* exclude 60M rate */
- active_rates = priv->rates_mask;
- active_rates &= ~IWL_RATE_60M_MASK;
-
- active_rate_basic = active_rates & IWL_BASIC_RATES_MASK;
-
- cck_rates = IWL_CCK_RATES_MASK & active_rates;
- ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,
- active_rate_basic, &left);
- active_rates &= ~ret_rates;
-
- ret_rates = iwl_supported_rate_to_ie(pos, active_rates,
- active_rate_basic, &left);
- active_rates &= ~ret_rates;
-
- len += 2 + *pos;
- pos += (*pos) + 1;
+ if (WARN_ON(left < ie_len))
+ return len;
- if (active_rates == 0)
- goto fill_end;
-
- /* fill in supported extended rate */
- /* ...next IE... */
- left -= 2;
- if (left < 0)
- return 0;
- /* ... fill it in... */
- *pos++ = WLAN_EID_EXT_SUPP_RATES;
- *pos = 0;
- iwl_supported_rate_to_ie(pos, active_rates, active_rate_basic, &left);
- if (*pos > 0) {
- len += 2 + *pos;
- pos += (*pos) + 1;
- } else {
- pos--;
- }
-
- fill_end:
-
- left -= 2;
- if (left < 0)
- return 0;
-
- *pos++ = WLAN_EID_HT_CAPABILITY;
- *pos = 0;
- iwl_ht_cap_to_ie(sband, pos, &left);
- if (*pos > 0)
- len += 2 + *pos;
+ memcpy(pos, ies, ie_len);
+ len += ie_len;
+ left -= ie_len;
return (u16)len;
}
@@ -699,11 +577,13 @@ static void iwl_bg_request_scan(struct work_struct *data)
int ret = 0;
u32 rate_flags = 0;
u16 cmd_len;
+ u16 rx_chain = 0;
enum ieee80211_band band;
- u8 n_probes = 2;
- u8 rx_chain = priv->hw_params.valid_rx_ant;
+ u8 n_probes = 0;
+ u8 rx_ant = priv->hw_params.valid_rx_ant;
u8 rate;
- DECLARE_SSID_BUF(ssid);
+ bool is_active = false;
+ int chan_mod;
conf = ieee80211_get_hw_conf(priv->hw);
@@ -795,19 +675,25 @@ static void iwl_bg_request_scan(struct work_struct *data)
scan_suspend_time, interval);
}
- /* We should add the ability for user to lock to PASSIVE ONLY */
- if (priv->one_direct_scan) {
- IWL_DEBUG_SCAN(priv, "Start direct scan for '%s'\n",
- print_ssid(ssid, priv->direct_ssid,
- priv->direct_ssid_len));
- scan->direct_scan[0].id = WLAN_EID_SSID;
- scan->direct_scan[0].len = priv->direct_ssid_len;
- memcpy(scan->direct_scan[0].ssid,
- priv->direct_ssid, priv->direct_ssid_len);
- n_probes++;
- } else {
- IWL_DEBUG_SCAN(priv, "Start indirect scan.\n");
- }
+ if (priv->scan_request->n_ssids) {
+ int i, p = 0;
+ IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
+ for (i = 0; i < priv->scan_request->n_ssids; i++) {
+ /* always does wildcard anyway */
+ if (!priv->scan_request->ssids[i].ssid_len)
+ continue;
+ scan->direct_scan[p].id = WLAN_EID_SSID;
+ scan->direct_scan[p].len =
+ priv->scan_request->ssids[i].ssid_len;
+ memcpy(scan->direct_scan[p].ssid,
+ priv->scan_request->ssids[i].ssid,
+ priv->scan_request->ssids[i].ssid_len);
+ n_probes++;
+ p++;
+ }
+ is_active = true;
+ } else
+ IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
@@ -817,7 +703,9 @@ static void iwl_bg_request_scan(struct work_struct *data)
if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
band = IEEE80211_BAND_2GHZ;
scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
- if (priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) {
+ chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK)
+ >> RXON_FLG_CHANNEL_MODE_POS;
+ if (chan_mod == CHANNEL_MODE_PURE_40) {
rate = IWL_RATE_6M_PLCP;
} else {
rate = IWL_RATE_1M_PLCP;
@@ -827,13 +715,18 @@ static void iwl_bg_request_scan(struct work_struct *data)
} else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
band = IEEE80211_BAND_5GHZ;
rate = IWL_RATE_6M_PLCP;
- scan->good_CRC_th = IWL_GOOD_CRC_TH;
+ /*
+ * If active scaning is requested but a certain channel
+ * is marked passive, we can do active scanning if we
+ * detect transmissions.
+ */
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
/* Force use of chains B and C (0x6) for scan Rx for 4965
* Avoid A (0x1) because of its off-channel reception on A-band.
*/
if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
- rx_chain = 0x6;
+ rx_ant = ANT_BC;
} else {
IWL_WARN(priv, "Invalid scan band count\n");
goto done;
@@ -845,26 +738,27 @@ static void iwl_bg_request_scan(struct work_struct *data)
scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
/* MIMO is not used here, but value is required */
- scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK |
- cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) |
- (rx_chain << RXON_RX_CHAIN_FORCE_SEL_POS) |
- (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS));
-
- cmd_len = iwl_fill_probe_req(priv, band,
- (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(*scan));
+ rx_chain |= ANT_ABC << RXON_RX_CHAIN_VALID_POS;
+ rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+ rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
+ rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
+ scan->rx_chain = cpu_to_le16(rx_chain);
+ cmd_len = iwl_fill_probe_req(priv,
+ (struct ieee80211_mgmt *)scan->data,
+ priv->scan_request->ie,
+ priv->scan_request->ie_len,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan));
scan->tx_cmd.len = cpu_to_le16(cmd_len);
- if (priv->iw_mode == NL80211_IFTYPE_MONITOR)
+ if (iwl_is_monitor_mode(priv))
scan->filter_flags = RXON_FILTER_PROMISC_MSK;
scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
RXON_FILTER_BCON_AWARE_MSK);
scan->channel_count =
- iwl_get_channels_for_scan(priv, band, 1, /* active */
- n_probes,
+ iwl_get_channels_for_scan(priv, band, is_active, n_probes,
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
if (scan->channel_count == 0) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 44ab03a12e4..2addf735b19 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -86,8 +86,7 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
spin_lock_irqsave(&priv->sta_lock, flags);
- if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
- !(priv->stations_39[sta_id].used & IWL_STA_DRIVER_ACTIVE))
+ if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n",
sta_id);
@@ -228,15 +227,16 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
}
/**
- * iwl_add_station_flags - Add station to tables in driver and device
+ * iwl_add_station - Add station to tables in driver and device
*/
-u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
- u8 flags, struct ieee80211_sta_ht_cap *ht_info)
+u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
+ struct ieee80211_sta_ht_cap *ht_info)
{
- int i;
- int sta_id = IWL_INVALID_STATION;
struct iwl_station_entry *station;
unsigned long flags_spin;
+ int i;
+ int sta_id = IWL_INVALID_STATION;
+ u16 rate;
spin_lock_irqsave(&priv->sta_lock, flags_spin);
if (is_ap)
@@ -288,6 +288,12 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
priv->iw_mode != NL80211_IFTYPE_ADHOC)
iwl_set_ht_add_station(priv, sta_id, ht_info);
+ /* 3945 only */
+ rate = (priv->band == IEEE80211_BAND_5GHZ) ?
+ IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP;
+ /* Turn on both antennas for the station... */
+ station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);
+
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
/* Add station to device's station table */
@@ -295,7 +301,7 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
return sta_id;
}
-EXPORT_SYMBOL(iwl_add_station_flags);
+EXPORT_SYMBOL(iwl_add_station);
static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
{
@@ -408,7 +414,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
/**
* iwl_remove_station - Remove driver's knowledge of station.
*/
-int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
+int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
{
int sta_id = IWL_INVALID_STATION;
int i, ret = -EINVAL;
@@ -490,7 +496,7 @@ void iwl_clear_stations_table(struct iwl_priv *priv)
/* keep track of static keys */
for (i = 0; i < WEP_KEYS_MAX ; i++) {
if (priv->wep_keys[i].key_size)
- test_and_set_bit(i, &priv->ucode_key_table);
+ set_bit(i, &priv->ucode_key_table);
}
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -946,7 +952,7 @@ EXPORT_SYMBOL(iwl_send_lq_cmd);
* calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
* which requires station table entry to exist).
*/
-static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
+static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap)
{
int i, r;
struct iwl_link_quality_cmd link_cmd = {
@@ -979,8 +985,9 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
link_cmd.general_params.single_stream_ant_msk =
first_antenna(priv->hw_params.valid_tx_ant);
link_cmd.general_params.dual_stream_ant_msk = 3;
- link_cmd.agg_params.agg_dis_start_th = 3;
- link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000);
+ link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+ link_cmd.agg_params.agg_time_limit =
+ cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
/* Update the rate scaling for control frame Tx to AP */
link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
@@ -995,7 +1002,7 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
* there is only one AP station with id= IWL_AP_ID
* NOTE: mutex must be held before calling this function
*/
-int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
+int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
{
struct ieee80211_sta *sta;
struct ieee80211_sta_ht_cap ht_config;
@@ -1020,8 +1027,7 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
rcu_read_unlock();
}
- sta_id = iwl_add_station_flags(priv, addr, is_ap,
- 0, cur_ht_config);
+ sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config);
/* Set up default rate scaling table in device's station table */
iwl_sta_init_lq(priv, addr, is_ap);
@@ -1067,8 +1073,8 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
return sta_id;
/* Create new station table entry */
- sta_id = iwl_add_station_flags(priv, hdr->addr1,
- 0, CMD_ASYNC, NULL);
+ sta_id = iwl_add_station(priv, hdr->addr1, false,
+ CMD_ASYNC, NULL);
if (sta_id != IWL_INVALID_STATION)
return sta_id;
@@ -1079,11 +1085,6 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
return priv->hw_params.bcast_sta_id;
- /* If we are in monitor mode, use BCAST. This is required for
- * packet injection. */
- case NL80211_IFTYPE_MONITOR:
- return priv->hw_params.bcast_sta_id;
-
default:
IWL_WARN(priv, "Unknown mode of operation: %d\n",
priv->iw_mode);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 59a586b6b56..6deebade636 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -51,16 +51,15 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf,
const u8 *addr, u32 iv32, u16 *phase1key);
-int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
-int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
+int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
+int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
void iwl_clear_stations_table(struct iwl_priv *priv);
int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
int iwl_send_add_sta(struct iwl_priv *priv,
struct iwl_addsta_cmd *sta, u8 flags);
-u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr,
- int is_ap, u8 flags,
+u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
struct ieee80211_sta_ht_cap *ht_info);
void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
int iwl_sta_rx_agg_start(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 71d5b8a1a73..85ae7a62109 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -102,13 +102,8 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
return ret;
}
- /* restore this queue's parameters in nic hardware. */
- ret = iwl_grab_nic_access(priv);
- if (ret)
- return ret;
iwl_write_direct32(priv, HBUS_TARG_WRPTR,
txq->q.write_ptr | (txq_id << 8));
- iwl_release_nic_access(priv);
/* else not in power-save mode, uCode will never sleep when we're
* trying to tx (during RFKILL, we're not trying to tx). */
@@ -429,11 +424,6 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
goto error_kw;
}
spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (unlikely(ret)) {
- spin_unlock_irqrestore(&priv->lock, flags);
- goto error_reset;
- }
/* Turn off all Tx DMA fifos */
priv->cfg->ops->lib->txq_set_sched(priv, 0);
@@ -441,7 +431,6 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
/* Tell NIC where to find the "keep warm" buffer */
iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
- iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
/* Alloc and init all Tx queues, including the command queue (#4) */
@@ -460,7 +449,6 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
error:
iwl_hw_txq_ctx_free(priv);
- error_reset:
iwl_free_dma_ptr(priv, &priv->kw);
error_kw:
iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
@@ -478,10 +466,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv)
/* Turn off all Tx DMA fifos */
spin_lock_irqsave(&priv->lock, flags);
- if (iwl_grab_nic_access(priv)) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return;
- }
priv->cfg->ops->lib->txq_set_sched(priv, 0);
@@ -492,7 +476,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv)
FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
1000);
}
- iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
/* Deallocate memory for all Tx queues */
@@ -728,7 +711,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* drop all data frame if we are not associated */
if (ieee80211_is_data(fc) &&
- (priv->iw_mode != NL80211_IFTYPE_MONITOR ||
+ (!iwl_is_monitor_mode(priv) ||
!(info->flags & IEEE80211_TX_CTL_INJECTED)) && /* packet injection */
(!iwl_is_associated(priv) ||
((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id) ||
@@ -1183,8 +1166,10 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
__func__, ra, tid);
sta_id = iwl_find_station(priv, ra);
- if (sta_id == IWL_INVALID_STATION)
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_ERR(priv, "Start AGG on invalid station\n");
return -ENXIO;
+ }
if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) {
IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n");
@@ -1192,8 +1177,10 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
}
txq_id = iwl_txq_ctx_activate_free(priv);
- if (txq_id == -1)
+ if (txq_id == -1) {
+ IWL_ERR(priv, "No free aggregation queue available\n");
return -ENXIO;
+ }
spin_lock_irqsave(&priv->sta_lock, flags);
tid_data = &priv->stations[sta_id].tid[tid];
@@ -1207,7 +1194,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
return ret;
if (tid_data->tfds_in_queue == 0) {
- IWL_ERR(priv, "HW queue is empty\n");
+ IWL_DEBUG_HT(priv, "HW queue is empty\n");
tid_data->agg.state = IWL_AGG_ON;
ieee80211_start_tx_ba_cb_irqsafe(priv->hw, ra, tid);
} else {
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index ff4d0e41d7c..83d31606dd0 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -95,188 +95,6 @@ struct iwl_mod_params iwl3945_mod_params = {
/* the rest are 0 by default */
};
-/*************** STATION TABLE MANAGEMENT ****
- * mac80211 should be examined to determine if sta_info is duplicating
- * the functionality provided here
- */
-
-/**************************************************************/
-#if 0 /* temporary disable till we add real remove station */
-/**
- * iwl3945_remove_station - Remove driver's knowledge of station.
- *
- * NOTE: This does not remove station from device's station table.
- */
-static u8 iwl3945_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
-{
- int index = IWL_INVALID_STATION;
- int i;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
-
- if (is_ap)
- index = IWL_AP_ID;
- else if (is_broadcast_ether_addr(addr))
- index = priv->hw_params.bcast_sta_id;
- else
- for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
- if (priv->stations_39[i].used &&
- !compare_ether_addr(priv->stations_39[i].sta.sta.addr,
- addr)) {
- index = i;
- break;
- }
-
- if (unlikely(index == IWL_INVALID_STATION))
- goto out;
-
- if (priv->stations_39[index].used) {
- priv->stations_39[index].used = 0;
- priv->num_stations--;
- }
-
- BUG_ON(priv->num_stations < 0);
-
-out:
- spin_unlock_irqrestore(&priv->sta_lock, flags);
- return 0;
-}
-#endif
-
-/**
- * iwl3945_clear_stations_table - Clear the driver's station table
- *
- * NOTE: This does not clear or otherwise alter the device's station table.
- */
-static void iwl3945_clear_stations_table(struct iwl_priv *priv)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
-
- priv->num_stations = 0;
- memset(priv->stations_39, 0, sizeof(priv->stations_39));
-
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-}
-
-/**
- * iwl3945_add_station - Add station to station tables in driver and device
- */
-u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
-{
- int i;
- int index = IWL_INVALID_STATION;
- struct iwl3945_station_entry *station;
- unsigned long flags_spin;
- u8 rate;
-
- spin_lock_irqsave(&priv->sta_lock, flags_spin);
- if (is_ap)
- index = IWL_AP_ID;
- else if (is_broadcast_ether_addr(addr))
- index = priv->hw_params.bcast_sta_id;
- else
- for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
- if (!compare_ether_addr(priv->stations_39[i].sta.sta.addr,
- addr)) {
- index = i;
- break;
- }
-
- if (!priv->stations_39[i].used &&
- index == IWL_INVALID_STATION)
- index = i;
- }
-
- /* These two conditions has the same outcome but keep them separate
- since they have different meaning */
- if (unlikely(index == IWL_INVALID_STATION)) {
- spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
- return index;
- }
-
- if (priv->stations_39[index].used &&
- !compare_ether_addr(priv->stations_39[index].sta.sta.addr, addr)) {
- spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
- return index;
- }
-
- IWL_DEBUG_ASSOC(priv, "Add STA ID %d: %pM\n", index, addr);
- station = &priv->stations_39[index];
- station->used = 1;
- priv->num_stations++;
-
- /* Set up the REPLY_ADD_STA command to send to device */
- memset(&station->sta, 0, sizeof(struct iwl3945_addsta_cmd));
- memcpy(station->sta.sta.addr, addr, ETH_ALEN);
- station->sta.mode = 0;
- station->sta.sta.sta_id = index;
- station->sta.station_flags = 0;
-
- if (priv->band == IEEE80211_BAND_5GHZ)
- rate = IWL_RATE_6M_PLCP;
- else
- rate = IWL_RATE_1M_PLCP;
-
- /* Turn on both antennas for the station... */
- station->sta.rate_n_flags =
- iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
-
- spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
-
- /* Add station to device's station table */
- iwl_send_add_sta(priv,
- (struct iwl_addsta_cmd *)&station->sta, flags);
- return index;
-
-}
-
-static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
-{
- int rc = 0;
- struct iwl_rx_packet *res = NULL;
- struct iwl3945_rxon_assoc_cmd rxon_assoc;
- struct iwl_host_cmd cmd = {
- .id = REPLY_RXON_ASSOC,
- .len = sizeof(rxon_assoc),
- .meta.flags = CMD_WANT_SKB,
- .data = &rxon_assoc,
- };
- const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
- const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
-
- if ((rxon1->flags == rxon2->flags) &&
- (rxon1->filter_flags == rxon2->filter_flags) &&
- (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
- (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
- IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
- return 0;
- }
-
- rxon_assoc.flags = priv->staging_rxon.flags;
- rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
- rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
- rxon_assoc.reserved = 0;
-
- rc = iwl_send_cmd_sync(priv, &cmd);
- if (rc)
- return rc;
-
- res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
- if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
- rc = -EIO;
- }
-
- priv->alloc_rxb_skb--;
- dev_kfree_skb_any(cmd.meta.u.skb);
-
- return rc;
-}
-
/**
* iwl3945_get_antenna_flags - Get antenna flags for RXON command
* @priv: eeprom and antenna fields are used to determine antenna flags
@@ -314,150 +132,6 @@ __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
return 0; /* "diversity" is default if error */
}
-/**
- * iwl3945_commit_rxon - commit staging_rxon to hardware
- *
- * The RXON command in staging_rxon is committed to the hardware and
- * the active_rxon structure is updated with the new data. This
- * function correctly transitions out of the RXON_ASSOC_MSK state if
- * a HW tune is required based on the RXON structure changes.
- */
-static int iwl3945_commit_rxon(struct iwl_priv *priv)
-{
- /* cast away the const for active_rxon in this function */
- struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
- struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
- int rc = 0;
- bool new_assoc =
- !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
-
- if (!iwl_is_alive(priv))
- return -1;
-
- /* always get timestamp with Rx frame */
- staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;
-
- /* select antenna */
- staging_rxon->flags &=
- ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
- staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
-
- rc = iwl_check_rxon_cmd(priv);
- if (rc) {
- IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
- return -EINVAL;
- }
-
- /* If we don't need to send a full RXON, we can use
- * iwl3945_rxon_assoc_cmd which is used to reconfigure filter
- * and other flags for the current radio configuration. */
- if (!iwl_full_rxon_required(priv)) {
- rc = iwl3945_send_rxon_assoc(priv);
- if (rc) {
- IWL_ERR(priv, "Error setting RXON_ASSOC "
- "configuration (%d).\n", rc);
- return rc;
- }
-
- memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
-
- return 0;
- }
-
- /* If we are currently associated and the new config requires
- * an RXON_ASSOC and the new config wants the associated mask enabled,
- * we must clear the associated from the active configuration
- * before we apply the new config */
- if (iwl_is_associated(priv) && new_assoc) {
- IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
- active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-
- /*
- * reserved4 and 5 could have been filled by the iwlcore code.
- * Let's clear them before pushing to the 3945.
- */
- active_rxon->reserved4 = 0;
- active_rxon->reserved5 = 0;
- rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl3945_rxon_cmd),
- &priv->active_rxon);
-
- /* If the mask clearing failed then we set
- * active_rxon back to what it was previously */
- if (rc) {
- active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
- IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
- "configuration (%d).\n", rc);
- return rc;
- }
- }
-
- IWL_DEBUG_INFO(priv, "Sending RXON\n"
- "* with%s RXON_FILTER_ASSOC_MSK\n"
- "* channel = %d\n"
- "* bssid = %pM\n",
- (new_assoc ? "" : "out"),
- le16_to_cpu(staging_rxon->channel),
- staging_rxon->bssid_addr);
-
- /*
- * reserved4 and 5 could have been filled by the iwlcore code.
- * Let's clear them before pushing to the 3945.
- */
- staging_rxon->reserved4 = 0;
- staging_rxon->reserved5 = 0;
-
- iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
-
- /* Apply the new configuration */
- rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl3945_rxon_cmd),
- staging_rxon);
- if (rc) {
- IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
- return rc;
- }
-
- memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
-
- iwl3945_clear_stations_table(priv);
-
- /* If we issue a new RXON command which required a tune then we must
- * send a new TXPOWER command or we won't be able to Tx any frames */
- rc = priv->cfg->ops->lib->send_tx_power(priv);
- if (rc) {
- IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
- return rc;
- }
-
- /* Add the broadcast address so we can send broadcast frames */
- if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) ==
- IWL_INVALID_STATION) {
- IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
- return -EIO;
- }
-
- /* If we have set the ASSOC_MSK and we are in BSS mode then
- * add the IWL_AP_ID to the station rate table */
- if (iwl_is_associated(priv) &&
- (priv->iw_mode == NL80211_IFTYPE_STATION))
- if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr,
- 1, 0)
- == IWL_INVALID_STATION) {
- IWL_ERR(priv, "Error adding AP address for transmit\n");
- return -EIO;
- }
-
- /* Init the hardware's rate fallback order based on the band */
- rc = iwl3945_init_hw_rate_table(priv);
- if (rc) {
- IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
- return -EIO;
- }
-
- return 0;
-}
-
static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf,
u8 sta_id)
@@ -477,32 +151,31 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
key_flags &= ~STA_KEY_FLG_INVALID;
spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations_39[sta_id].keyinfo.alg = keyconf->alg;
- priv->stations_39[sta_id].keyinfo.keylen = keyconf->keylen;
- memcpy(priv->stations_39[sta_id].keyinfo.key, keyconf->key,
+ priv->stations[sta_id].keyinfo.alg = keyconf->alg;
+ priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
+ memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
keyconf->keylen);
- memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key,
+ memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
keyconf->keylen);
- if ((priv->stations_39[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+ if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
== STA_KEY_FLG_NO_ENC)
- priv->stations_39[sta_id].sta.key.key_offset =
+ priv->stations[sta_id].sta.key.key_offset =
iwl_get_free_ucode_key_index(priv);
/* else, we are overriding an existing key => no need to allocated room
* in uCode. */
- WARN(priv->stations_39[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+ WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
"no space for a new key");
- priv->stations_39[sta_id].sta.key.key_flags = key_flags;
- priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
- priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ priv->stations[sta_id].sta.key.key_flags = key_flags;
+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n");
- ret = iwl_send_add_sta(priv,
- (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, CMD_ASYNC);
+ ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -528,17 +201,16 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
unsigned long flags;
spin_lock_irqsave(&priv->sta_lock, flags);
- memset(&priv->stations_39[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key));
- memset(&priv->stations_39[sta_id].sta.key, 0,
+ memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
+ memset(&priv->stations[sta_id].sta.key, 0,
sizeof(struct iwl4965_keyinfo));
- priv->stations_39[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
- priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
- priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
spin_unlock_irqrestore(&priv->sta_lock, flags);
IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");
- iwl_send_add_sta(priv,
- (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0);
+ iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0);
return 0;
}
@@ -739,7 +411,8 @@ static void iwl3945_setup_rxon_timing(struct iwl_priv *priv)
priv->rxon_timing.atim_window = 0;
} else {
priv->rxon_timing.beacon_interval =
- iwl3945_adjust_beacon_interval(conf->beacon_int);
+ iwl3945_adjust_beacon_interval(
+ priv->vif->bss_conf.beacon_int);
/* TODO: we need to get atim_window from upper stack
* for now we set to 0 */
priv->rxon_timing.atim_window = 0;
@@ -758,35 +431,6 @@ static void iwl3945_setup_rxon_timing(struct iwl_priv *priv)
le16_to_cpu(priv->rxon_timing.atim_window));
}
-static int iwl3945_set_mode(struct iwl_priv *priv, int mode)
-{
- if (mode == NL80211_IFTYPE_ADHOC) {
- const struct iwl_channel_info *ch_info;
-
- ch_info = iwl_get_channel_info(priv,
- priv->band,
- le16_to_cpu(priv->staging_rxon.channel));
-
- if (!ch_info || !is_channel_ibss(ch_info)) {
- IWL_ERR(priv, "channel %d not IBSS channel\n",
- le16_to_cpu(priv->staging_rxon.channel));
- return -EINVAL;
- }
- }
-
- iwl_connection_init_rx_config(priv, mode);
-
- iwl3945_clear_stations_table(priv);
-
- /* don't commit rxon if rf-kill is on*/
- if (!iwl_is_ready_rf(priv))
- return -EAGAIN;
-
- iwl3945_commit_rxon(priv);
-
- return 0;
-}
-
static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
struct ieee80211_tx_info *info,
struct iwl_cmd *cmd,
@@ -794,8 +438,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
int sta_id)
{
struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
- struct iwl3945_hw_key *keyinfo =
- &priv->stations_39[sta_id].keyinfo;
+ struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo;
switch (keyinfo->alg) {
case ALG_CCMP:
@@ -893,64 +536,6 @@ static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
tx->next_frame_len = 0;
}
-/**
- * iwl3945_get_sta_id - Find station's index within station table
- */
-static int iwl3945_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
-{
- int sta_id;
- u16 fc = le16_to_cpu(hdr->frame_control);
-
- /* If this frame is broadcast or management, use broadcast station id */
- if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
- is_multicast_ether_addr(hdr->addr1))
- return priv->hw_params.bcast_sta_id;
-
- switch (priv->iw_mode) {
-
- /* If we are a client station in a BSS network, use the special
- * AP station entry (that's the only station we communicate with) */
- case NL80211_IFTYPE_STATION:
- return IWL_AP_ID;
-
- /* If we are an AP, then find the station, or use BCAST */
- case NL80211_IFTYPE_AP:
- sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
- if (sta_id != IWL_INVALID_STATION)
- return sta_id;
- return priv->hw_params.bcast_sta_id;
-
- /* If this frame is going out to an IBSS network, find the station,
- * or create a new station table entry */
- case NL80211_IFTYPE_ADHOC: {
- /* Create new station table entry */
- sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
- if (sta_id != IWL_INVALID_STATION)
- return sta_id;
-
- sta_id = iwl3945_add_station(priv, hdr->addr1, 0, CMD_ASYNC);
-
- if (sta_id != IWL_INVALID_STATION)
- return sta_id;
-
- IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
- "Defaulting to broadcast...\n",
- hdr->addr1);
- iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
- return priv->hw_params.bcast_sta_id;
- }
- /* If we are in monitor mode, use BCAST. This is required for
- * packet injection. */
- case NL80211_IFTYPE_MONITOR:
- return priv->hw_params.bcast_sta_id;
-
- default:
- IWL_WARN(priv, "Unknown mode of operation: %d\n",
- priv->iw_mode);
- return priv->hw_params.bcast_sta_id;
- }
-}
-
/*
* start REPLY_TX command process
*/
@@ -1004,7 +589,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* drop all data frame if we are not associated */
if (ieee80211_is_data(fc) &&
- (priv->iw_mode != NL80211_IFTYPE_MONITOR) && /* packet injection */
+ (!iwl_is_monitor_mode(priv)) && /* packet injection */
(!iwl_is_associated(priv) ||
((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) {
IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
@@ -1016,7 +601,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
hdr_len = ieee80211_hdrlen(fc);
/* Find (or create) index into station table for destination station */
- sta_id = iwl3945_get_sta_id(priv, hdr);
+ sta_id = iwl_get_sta_id(priv, hdr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
@@ -1028,7 +613,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (ieee80211_is_data_qos(fc)) {
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
- seq_number = priv->stations_39[sta_id].tid[tid].seq_number &
+ seq_number = priv->stations[sta_id].tid[tid].seq_number &
IEEE80211_SCTL_SEQ;
hdr->seq_ctrl = cpu_to_le16(seq_number) |
(hdr->seq_ctrl &
@@ -1088,7 +673,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1;
if (qc)
- priv->stations_39[sta_id].tid[tid].seq_number = seq_number;
+ priv->stations[sta_id].tid[tid].seq_number = seq_number;
} else {
wait_write_ptr = 1;
txq->need_update = 0;
@@ -1424,18 +1009,12 @@ static void iwl3945_rx_card_state_notif(struct iwl_priv *priv,
clear_bit(STATUS_RF_KILL_HW, &priv->status);
- if (flags & SW_CARD_DISABLED)
- set_bit(STATUS_RF_KILL_SW, &priv->status);
- else
- clear_bit(STATUS_RF_KILL_SW, &priv->status);
-
iwl_scan_cancel(priv);
if ((test_bit(STATUS_RF_KILL_HW, &status) !=
- test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
- (test_bit(STATUS_RF_KILL_SW, &status) !=
- test_bit(STATUS_RF_KILL_SW, &priv->status)))
- queue_work(priv->workqueue, &priv->rf_kill);
+ test_bit(STATUS_RF_KILL_HW, &priv->status)))
+ wiphy_rfkill_set_hw_state(priv->hw->wiphy,
+ test_bit(STATUS_RF_KILL_HW, &priv->status));
else
wake_up_interruptible(&priv->wait_command_queue);
}
@@ -1591,7 +1170,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
/* If we've added more space for the firmware to place data, tell it.
* Increment device's write pointer in multiples of 8. */
- if ((write != (rxq->write & ~0x7))
+ if ((rxq->write_actual != (rxq->write & ~0x7))
|| (abs(rxq->write - rxq->read) > 7)) {
spin_lock_irqsave(&rxq->lock, flags);
rxq->need_update = 1;
@@ -1612,21 +1191,30 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
* Also restock the Rx queue via iwl3945_rx_queue_restock.
* This is called as a scheduled work item (except for during initialization)
*/
-static void iwl3945_rx_allocate(struct iwl_priv *priv)
+static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
{
struct iwl_rx_queue *rxq = &priv->rxq;
struct list_head *element;
struct iwl_rx_mem_buffer *rxb;
unsigned long flags;
- spin_lock_irqsave(&rxq->lock, flags);
- while (!list_empty(&rxq->rx_used)) {
+
+ while (1) {
+ spin_lock_irqsave(&rxq->lock, flags);
+
+ if (list_empty(&rxq->rx_used)) {
+ spin_unlock_irqrestore(&rxq->lock, flags);
+ return;
+ }
+
element = rxq->rx_used.next;
rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+ list_del(element);
+ spin_unlock_irqrestore(&rxq->lock, flags);
/* Alloc a new receive buffer */
rxb->skb =
alloc_skb(priv->hw_params.rx_buf_size,
- __GFP_NOWARN | GFP_ATOMIC);
+ priority);
if (!rxb->skb) {
if (net_ratelimit())
IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
@@ -1644,18 +1232,18 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv)
*/
skb_reserve(rxb->skb, 4);
- priv->alloc_rxb_skb++;
- list_del(element);
-
/* Get physical address of RB/SKB */
rxb->real_dma_addr = pci_map_single(priv->pci_dev,
rxb->skb->data,
priv->hw_params.rx_buf_size,
PCI_DMA_FROMDEVICE);
+
+ spin_lock_irqsave(&rxq->lock, flags);
list_add_tail(&rxb->list, &rxq->rx_free);
+ priv->alloc_rxb_skb++;
rxq->free_count++;
+ spin_unlock_irqrestore(&rxq->lock, flags);
}
- spin_unlock_irqrestore(&rxq->lock, flags);
}
void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
@@ -1685,33 +1273,30 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
* not restocked the Rx queue with fresh buffers */
rxq->read = rxq->write = 0;
rxq->free_count = 0;
+ rxq->write_actual = 0;
spin_unlock_irqrestore(&rxq->lock, flags);
}
-/*
- * this should be called while priv->lock is locked
- */
-static void __iwl3945_rx_replenish(void *data)
-{
- struct iwl_priv *priv = data;
-
- iwl3945_rx_allocate(priv);
- iwl3945_rx_queue_restock(priv);
-}
-
-
void iwl3945_rx_replenish(void *data)
{
struct iwl_priv *priv = data;
unsigned long flags;
- iwl3945_rx_allocate(priv);
+ iwl3945_rx_allocate(priv, GFP_KERNEL);
spin_lock_irqsave(&priv->lock, flags);
iwl3945_rx_queue_restock(priv);
spin_unlock_irqrestore(&priv->lock, flags);
}
+static void iwl3945_rx_replenish_now(struct iwl_priv *priv)
+{
+ iwl3945_rx_allocate(priv, GFP_ATOMIC);
+
+ iwl3945_rx_queue_restock(priv);
+}
+
+
/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
* If an SKB has been detached, the POOL needs to have its SKB set to NULL
* This free routine walks the list of POOL entries and if SKB is set to
@@ -1834,13 +1419,19 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
unsigned long flags;
u8 fill_rx = 0;
u32 count = 8;
+ int total_empty = 0;
/* uCode's read index (stored in shared DRAM) indicates the last Rx
* buffer that the driver may process (last buffer filled by ucode). */
r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
i = rxq->read;
- if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+ /* calculate total frames need to be restock after handling RX */
+ total_empty = r - priv->rxq.write_actual;
+ if (total_empty < 0)
+ total_empty += RX_QUEUE_SIZE;
+
+ if (total_empty > (RX_QUEUE_SIZE / 2))
fill_rx = 1;
/* Rx interrupt, but nothing sent from uCode */
if (i == r)
@@ -1879,6 +1470,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
"r = %d, i = %d, %s, 0x%02x\n", r, i,
get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
+ priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
} else {
/* No handling needed */
IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR,
@@ -1916,7 +1508,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
count++;
if (count >= 8) {
priv->rxq.read = i;
- __iwl3945_rx_replenish(priv);
+ iwl3945_rx_replenish_now(priv);
count = 0;
}
}
@@ -1924,7 +1516,10 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
/* Backtrack one entry */
priv->rxq.read = i;
- iwl3945_rx_queue_restock(priv);
+ if (fill_rx)
+ iwl3945_rx_replenish_now(priv);
+ else
+ iwl3945_rx_queue_restock(priv);
}
/* call this function to flush any scheduled tasklet */
@@ -1963,7 +1558,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
u32 i;
u32 desc, time, count, base, data1;
u32 blink1, blink2, ilink1, ilink2;
- int rc;
base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
@@ -1972,11 +1566,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
return;
}
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- IWL_WARN(priv, "Can not read from adapter at this time.\n");
- return;
- }
count = iwl_read_targ_mem(priv, base);
@@ -2011,8 +1600,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
ilink1, ilink2, data1);
}
- iwl_release_nic_access(priv);
-
}
#define EVENT_START_OFFSET (6 * sizeof(u32))
@@ -2020,7 +1607,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
/**
* iwl3945_print_event_log - Dump error event log to syslog
*
- * NOTE: Must be called with iwl_grab_nic_access() already obtained!
*/
static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
u32 num_events, u32 mode)
@@ -2063,7 +1649,6 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
{
- int rc;
u32 base; /* SRAM byte address of event log header */
u32 capacity; /* event log capacity in # entries */
u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */
@@ -2077,12 +1662,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
return;
}
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- IWL_WARN(priv, "Can not read from adapter at this time.\n");
- return;
- }
-
/* event log header */
capacity = iwl_read_targ_mem(priv, base);
mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
@@ -2094,7 +1673,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
/* bail out if nothing in log */
if (size == 0) {
IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
- iwl_release_nic_access(priv);
return;
}
@@ -2110,24 +1688,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
/* (then/else) start at top of log */
iwl3945_print_event_log(priv, 0, next_entry, mode);
- iwl_release_nic_access(priv);
-}
-
-static void iwl3945_error_recovery(struct iwl_priv *priv)
-{
- unsigned long flags;
-
- memcpy(&priv->staging_rxon, &priv->recovery_rxon,
- sizeof(priv->staging_rxon));
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
-
- iwl3945_add_station(priv, priv->bssid, 1, 0);
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
- priv->error_recovering = 0;
- spin_unlock_irqrestore(&priv->lock, flags);
}
static void iwl3945_irq_tasklet(struct iwl_priv *priv)
@@ -2178,6 +1738,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
/* Tell the device to stop sending interrupts */
iwl_disable_interrupts(priv);
+ priv->isr_stats.hw++;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_HW_ERR;
@@ -2190,13 +1751,17 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
#ifdef CONFIG_IWLWIFI_DEBUG
if (priv->debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
- if (inta & CSR_INT_BIT_SCD)
+ if (inta & CSR_INT_BIT_SCD) {
IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
"the frame/frames.\n");
+ priv->isr_stats.sch++;
+ }
/* Alive notification via Rx interrupt will do the real work */
- if (inta & CSR_INT_BIT_ALIVE)
+ if (inta & CSR_INT_BIT_ALIVE) {
IWL_DEBUG_ISR(priv, "Alive interrupt\n");
+ priv->isr_stats.alive++;
+ }
}
#endif
/* Safely ignore these bits for debug checks below */
@@ -2206,6 +1771,8 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
if (inta & CSR_INT_BIT_SW_ERR) {
IWL_ERR(priv, "Microcode SW error detected. "
"Restarting 0x%X.\n", inta);
+ priv->isr_stats.sw++;
+ priv->isr_stats.sw_err = inta;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
@@ -2221,6 +1788,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
iwl_txq_update_write_ptr(priv, &priv->txq[4]);
iwl_txq_update_write_ptr(priv, &priv->txq[5]);
+ priv->isr_stats.wakeup++;
handled |= CSR_INT_BIT_WAKEUP;
}
@@ -2229,27 +1797,28 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
* notifications from uCode come through here*/
if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
iwl3945_rx_handle(priv);
+ priv->isr_stats.rx++;
handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
}
if (inta & CSR_INT_BIT_FH_TX) {
IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+ priv->isr_stats.tx++;
iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6));
- if (!iwl_grab_nic_access(priv)) {
- iwl_write_direct32(priv, FH39_TCSR_CREDIT
- (FH39_SRVC_CHNL), 0x0);
- iwl_release_nic_access(priv);
- }
+ iwl_write_direct32(priv, FH39_TCSR_CREDIT
+ (FH39_SRVC_CHNL), 0x0);
handled |= CSR_INT_BIT_FH_TX;
}
- if (inta & ~handled)
+ if (inta & ~handled) {
IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
+ priv->isr_stats.unhandled++;
+ }
- if (inta & ~CSR_INI_SET_MASK) {
+ if (inta & ~priv->inta_mask) {
IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
- inta & ~CSR_INI_SET_MASK);
+ inta & ~priv->inta_mask);
IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh);
}
@@ -2413,10 +1982,6 @@ static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 le
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
- rc = iwl_grab_nic_access(priv);
- if (rc)
- return rc;
-
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
IWL39_RTC_INST_LOWER_BOUND);
@@ -2437,7 +2002,6 @@ static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 le
}
}
- iwl_release_nic_access(priv);
if (!errcnt)
IWL_DEBUG_INFO(priv,
@@ -2461,10 +2025,6 @@ static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
- rc = iwl_grab_nic_access(priv);
- if (rc)
- return rc;
-
for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
/* read data comes through single port, auto-incr addr */
/* NOTE: Use the debugless read so we don't flood kernel log
@@ -2485,8 +2045,6 @@ static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
}
}
- iwl_release_nic_access(priv);
-
return rc;
}
@@ -2810,20 +2368,11 @@ static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv)
{
dma_addr_t pinst;
dma_addr_t pdata;
- int rc = 0;
- unsigned long flags;
/* bits 31:0 for 3945 */
pinst = priv->ucode_code.p_addr;
pdata = priv->ucode_data_backup.p_addr;
- spin_lock_irqsave(&priv->lock, flags);
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
-
/* Tell bootstrap uCode where to find image to load */
iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
@@ -2835,13 +2384,9 @@ static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv)
iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
priv->ucode_code.len | BSM_DRAM_INST_LOAD);
- iwl_release_nic_access(priv);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n");
- return rc;
+ return 0;
}
/**
@@ -2887,11 +2432,6 @@ static void iwl3945_init_alive_start(struct iwl_priv *priv)
queue_work(priv->workqueue, &priv->restart);
}
-
-/* temporary */
-static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw,
- struct sk_buff *skb);
-
/**
* iwl3945_alive_start - called after REPLY_ALIVE notification received
* from protocol/runtime uCode (initialization uCode's
@@ -2899,7 +2439,6 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw,
*/
static void iwl3945_alive_start(struct iwl_priv *priv)
{
- int rc = 0;
int thermal_spin = 0;
u32 rfkill;
@@ -2922,17 +2461,10 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
goto restart;
}
- iwl3945_clear_stations_table(priv);
-
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- IWL_WARN(priv, "Can not read RFKILL status from adapter\n");
- return;
- }
+ iwl_clear_stations_table(priv);
rfkill = iwl_read_prph(priv, APMG_RFKILL_REG);
IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill);
- iwl_release_nic_access(priv);
if (rfkill & 0x1) {
clear_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -2952,9 +2484,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
/* After the ALIVE response, we can send commands to 3945 uCode */
set_bit(STATUS_ALIVE, &priv->status);
- /* Clear out the uCode error bit if it is set */
- clear_bit(STATUS_FW_ERROR, &priv->status);
-
if (iwl_is_rfkill(priv))
return;
@@ -2981,7 +2510,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
iwl_send_bt_config(priv);
/* Configure the adapter for unassociated operation */
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
iwl3945_reg_txpower_periodic(priv);
@@ -2991,17 +2520,17 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
set_bit(STATUS_READY, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
- if (priv->error_recovering)
- iwl3945_error_recovery(priv);
-
/* reassociate for ADHOC mode */
if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
priv->vif);
if (beacon)
- iwl3945_mac_beacon_update(priv->hw, beacon);
+ iwl_mac_beacon_update(priv->hw, beacon);
}
+ if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
+ iwl_set_mode(priv, priv->iw_mode);
+
return;
restart:
@@ -3024,7 +2553,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
set_bit(STATUS_EXIT_PENDING, &priv->status);
iwl3945_led_unregister(priv);
- iwl3945_clear_stations_table(priv);
+ iwl_clear_stations_table(priv);
/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
@@ -3047,31 +2576,23 @@ static void __iwl3945_down(struct iwl_priv *priv)
ieee80211_stop_queues(priv->hw);
/* If we have not previously called iwl3945_init() then
- * clear all bits but the RF Kill and SUSPEND bits and return */
+ * clear all bits but the RF Kill bits and return */
if (!iwl_is_init(priv)) {
priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
- test_bit(STATUS_RF_KILL_SW, &priv->status) <<
- STATUS_RF_KILL_SW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
- test_bit(STATUS_IN_SUSPEND, &priv->status) <<
- STATUS_IN_SUSPEND |
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
STATUS_EXIT_PENDING;
goto exit;
}
- /* ...otherwise clear out all the status bits but the RF Kill and
- * SUSPEND bits and continue taking the NIC down. */
+ /* ...otherwise clear out all the status bits but the RF Kill
+ * bit and continue taking the NIC down. */
priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
- test_bit(STATUS_RF_KILL_SW, &priv->status) <<
- STATUS_RF_KILL_SW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
- test_bit(STATUS_IN_SUSPEND, &priv->status) <<
- STATUS_IN_SUSPEND |
test_bit(STATUS_FW_ERROR, &priv->status) <<
STATUS_FW_ERROR |
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
@@ -3085,17 +2606,12 @@ static void __iwl3945_down(struct iwl_priv *priv)
iwl3945_hw_txq_ctx_stop(priv);
iwl3945_hw_rxq_stop(priv);
- spin_lock_irqsave(&priv->lock, flags);
- if (!iwl_grab_nic_access(priv)) {
- iwl_write_prph(priv, APMG_CLK_DIS_REG,
- APMG_CLK_VAL_DMA_CLK_RQT);
- iwl_release_nic_access(priv);
- }
- spin_unlock_irqrestore(&priv->lock, flags);
+ iwl_write_prph(priv, APMG_CLK_DIS_REG,
+ APMG_CLK_VAL_DMA_CLK_RQT);
udelay(5);
- if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+ if (exit_pending)
priv->cfg->ops->lib->apm_ops.stop(priv);
else
priv->cfg->ops->lib->apm_ops.reset(priv);
@@ -3131,12 +2647,6 @@ static int __iwl3945_up(struct iwl_priv *priv)
return -EIO;
}
- if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
- IWL_WARN(priv, "Radio disabled by SW RF kill (module "
- "parameter)\n");
- return -ENODEV;
- }
-
if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
IWL_ERR(priv, "ucode not available for device bring up\n");
return -EIO;
@@ -3148,10 +2658,8 @@ static int __iwl3945_up(struct iwl_priv *priv)
clear_bit(STATUS_RF_KILL_HW, &priv->status);
else {
set_bit(STATUS_RF_KILL_HW, &priv->status);
- if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
- IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
- return -ENODEV;
- }
+ IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
+ return -ENODEV;
}
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
@@ -3187,7 +2695,7 @@ static int __iwl3945_up(struct iwl_priv *priv)
for (i = 0; i < MAX_HW_RESTARTS; i++) {
- iwl3945_clear_stations_table(priv);
+ iwl_clear_stations_table(priv);
/* load bootstrap state machine,
* load bootstrap program into processor's memory,
@@ -3255,15 +2763,14 @@ static void iwl3945_rfkill_poll(struct work_struct *data)
{
struct iwl_priv *priv =
container_of(data, struct iwl_priv, rfkill_poll.work);
- unsigned long status = priv->status;
if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
clear_bit(STATUS_RF_KILL_HW, &priv->status);
else
set_bit(STATUS_RF_KILL_HW, &priv->status);
- if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status))
- queue_work(priv->workqueue, &priv->rf_kill);
+ wiphy_rfkill_set_hw_state(priv->hw->wiphy,
+ test_bit(STATUS_RF_KILL_HW, &priv->status));
queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
round_jiffies_relative(2 * HZ));
@@ -3283,9 +2790,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
int rc = 0;
struct iwl3945_scan_cmd *scan;
struct ieee80211_conf *conf = NULL;
- u8 n_probes = 2;
+ u8 n_probes = 0;
enum ieee80211_band band;
- DECLARE_SSID_BUF(ssid);
+ bool is_active = false;
conf = ieee80211_get_hw_conf(priv->hw);
@@ -3386,18 +2893,25 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
scan_suspend_time, interval);
}
- /* We should add the ability for user to lock to PASSIVE ONLY */
- if (priv->one_direct_scan) {
- IWL_DEBUG_SCAN(priv, "Kicking off one direct scan for '%s'\n",
- print_ssid(ssid, priv->direct_ssid,
- priv->direct_ssid_len));
- scan->direct_scan[0].id = WLAN_EID_SSID;
- scan->direct_scan[0].len = priv->direct_ssid_len;
- memcpy(scan->direct_scan[0].ssid,
- priv->direct_ssid, priv->direct_ssid_len);
- n_probes++;
+ if (priv->scan_request->n_ssids) {
+ int i, p = 0;
+ IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
+ for (i = 0; i < priv->scan_request->n_ssids; i++) {
+ /* always does wildcard anyway */
+ if (!priv->scan_request->ssids[i].ssid_len)
+ continue;
+ scan->direct_scan[p].id = WLAN_EID_SSID;
+ scan->direct_scan[p].len =
+ priv->scan_request->ssids[i].ssid_len;
+ memcpy(scan->direct_scan[p].ssid,
+ priv->scan_request->ssids[i].ssid,
+ priv->scan_request->ssids[i].ssid_len);
+ n_probes++;
+ p++;
+ }
+ is_active = true;
} else
- IWL_DEBUG_SCAN(priv, "Kicking off one indirect scan.\n");
+ IWL_DEBUG_SCAN(priv, "Kicking off passive scan.\n");
/* We don't build a direct scan probe request; the uCode will do
* that based on the direct_mask added to each channel entry */
@@ -3414,7 +2928,12 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
band = IEEE80211_BAND_2GHZ;
} else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
- scan->good_CRC_th = IWL_GOOD_CRC_TH;
+ /*
+ * If active scaning is requested but a certain channel
+ * is marked passive, we can do active scanning if we
+ * detect transmissions.
+ */
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
band = IEEE80211_BAND_5GHZ;
} else {
IWL_WARN(priv, "Invalid scan band count\n");
@@ -3422,19 +2941,20 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
}
scan->tx_cmd.len = cpu_to_le16(
- iwl_fill_probe_req(priv, band,
- (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(*scan)));
+ iwl_fill_probe_req(priv,
+ (struct ieee80211_mgmt *)scan->data,
+ priv->scan_request->ie,
+ priv->scan_request->ie_len,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan)));
/* select Rx antennas */
scan->flags |= iwl3945_get_antenna_flags(priv);
- if (priv->iw_mode == NL80211_IFTYPE_MONITOR)
+ if (iwl_is_monitor_mode(priv))
scan->filter_flags = RXON_FILTER_PROMISC_MSK;
scan->channel_count =
- iwl3945_get_channels_for_scan(priv, band, 1, /* active */
- n_probes,
+ iwl3945_get_channels_for_scan(priv, band, is_active, n_probes,
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
if (scan->channel_count == 0) {
@@ -3482,7 +3002,6 @@ static void iwl3945_bg_up(struct work_struct *data)
mutex_lock(&priv->mutex);
__iwl3945_up(priv);
mutex_unlock(&priv->mutex);
- iwl_rfkill_set_hw_state(priv);
}
static void iwl3945_bg_restart(struct work_struct *data)
@@ -3492,8 +3011,17 @@ static void iwl3945_bg_restart(struct work_struct *data)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- iwl3945_down(priv);
- queue_work(priv->workqueue, &priv->up);
+ if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
+ mutex_lock(&priv->mutex);
+ priv->vif = NULL;
+ priv->is_open = 0;
+ mutex_unlock(&priv->mutex);
+ iwl3945_down(priv);
+ ieee80211_restart_hw(priv->hw);
+ } else {
+ iwl3945_down(priv);
+ queue_work(priv->workqueue, &priv->up);
+ }
}
static void iwl3945_bg_rx_replenish(struct work_struct *data)
@@ -3511,7 +3039,7 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
#define IWL_DELAY_NEXT_SCAN (HZ*2)
-static void iwl3945_post_associate(struct iwl_priv *priv)
+void iwl3945_post_associate(struct iwl_priv *priv)
{
int rc = 0;
struct ieee80211_conf *conf = NULL;
@@ -3536,7 +3064,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
conf = ieee80211_get_hw_conf(priv->hw);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
iwl3945_setup_rxon_timing(priv);
@@ -3569,7 +3097,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
}
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
switch (priv->iw_mode) {
case NL80211_IFTYPE_STATION:
@@ -3579,7 +3107,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
case NL80211_IFTYPE_ADHOC:
priv->assoc_id = 1;
- iwl3945_add_station(priv, priv->bssid, 0, 0);
+ iwl_add_station(priv, priv->bssid, 0, CMD_SYNC, NULL);
iwl3945_sync_sta(priv, IWL_STA_ID,
(priv->band == IEEE80211_BAND_5GHZ) ?
IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
@@ -3601,8 +3129,6 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
}
-static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed);
-
/*****************************************************************************
*
* mac80211 entry point functions
@@ -3638,16 +3164,11 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
mutex_unlock(&priv->mutex);
- iwl_rfkill_set_hw_state(priv);
-
if (ret)
goto out_release_irq;
IWL_DEBUG_INFO(priv, "Start UP work.\n");
- if (test_bit(STATUS_IN_SUSPEND, &priv->status))
- return 0;
-
/* Wait for START_ALIVE from ucode. Otherwise callbacks from
* mac80211 will not be run successfully. */
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
@@ -3726,144 +3247,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}
-static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
-
- IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
-
- if (priv->vif) {
- IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
- return -EOPNOTSUPP;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->vif = conf->vif;
- priv->iw_mode = conf->type;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- mutex_lock(&priv->mutex);
-
- if (conf->mac_addr) {
- IWL_DEBUG_MAC80211(priv, "Set: %pM\n", conf->mac_addr);
- memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
- }
-
- if (iwl_is_ready(priv))
- iwl3945_set_mode(priv, conf->type);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- return 0;
-}
-
-/**
- * iwl3945_mac_config - mac80211 config callback
- *
- * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to
- * be set inappropriately and the driver currently sets the hardware up to
- * use it whenever needed.
- */
-static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
-{
- struct iwl_priv *priv = hw->priv;
- const struct iwl_channel_info *ch_info;
- struct ieee80211_conf *conf = &hw->conf;
- unsigned long flags;
- int ret = 0;
-
- mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211(priv, "enter to channel %d\n",
- conf->channel->hw_value);
-
- if (!iwl_is_ready(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- ret = -EIO;
- goto out;
- }
-
- if (unlikely(!iwl3945_mod_params.disable_hw_scan &&
- test_bit(STATUS_SCANNING, &priv->status))) {
- IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
- set_bit(STATUS_CONF_PENDING, &priv->status);
- mutex_unlock(&priv->mutex);
- return 0;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- ch_info = iwl_get_channel_info(priv, conf->channel->band,
- conf->channel->hw_value);
- if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN(priv,
- "Channel %d [%d] is INVALID for this band.\n",
- conf->channel->hw_value, conf->channel->band);
- IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
- spin_unlock_irqrestore(&priv->lock, flags);
- ret = -EINVAL;
- goto out;
- }
-
- iwl_set_rxon_channel(priv, conf->channel);
-
- iwl_set_flags_for_band(priv, conf->channel->band);
-
- /* The list of supported rates and rate mask can be different
- * for each phymode; since the phymode may have changed, reset
- * the rate mask to what mac80211 lists */
- iwl_set_rate(priv);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
-#ifdef IEEE80211_CONF_CHANNEL_SWITCH
- if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) {
- iwl3945_hw_channel_switch(priv, conf->channel);
- goto out;
- }
-#endif
-
- if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
- if (conf->radio_enabled &&
- iwl_radio_kill_sw_enable_radio(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
- "waiting for uCode\n");
- goto out;
- }
-
- if (!conf->radio_enabled) {
- iwl_radio_kill_sw_disable_radio(priv);
- IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
- goto out;
- }
- }
-
- if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF kill\n");
- ret = -EIO;
- goto out;
- }
-
- iwl_set_rate(priv);
-
- if (memcmp(&priv->active_rxon,
- &priv->staging_rxon, sizeof(priv->staging_rxon)))
- iwl3945_commit_rxon(priv);
- else
- IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration\n");
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
-out:
- clear_bit(STATUS_CONF_PENDING, &priv->status);
- mutex_unlock(&priv->mutex);
- return ret;
-}
-
-static void iwl3945_config_ap(struct iwl_priv *priv)
+void iwl3945_config_ap(struct iwl_priv *priv)
{
int rc = 0;
@@ -3875,7 +3259,7 @@ static void iwl3945_config_ap(struct iwl_priv *priv)
/* RXON - unassoc (to set timing command) */
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
/* RXON Timing */
memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
@@ -3911,8 +3295,8 @@ static void iwl3945_config_ap(struct iwl_priv *priv)
}
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
- iwl3945_add_station(priv, iwl_bcast_addr, 0, 0);
+ iwlcore_commit_rxon(priv);
+ iwl_add_station(priv, iwl_bcast_addr, 0, CMD_SYNC, NULL);
}
iwl3945_send_beacon_cmd(priv);
@@ -3921,189 +3305,6 @@ static void iwl3945_config_ap(struct iwl_priv *priv)
* clear sta table, add BCAST sta... */
}
-static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
- int rc;
-
- if (conf == NULL)
- return -EIO;
-
- if (priv->vif != vif) {
- IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
- return 0;
- }
-
- /* handle this temporarily here */
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
- conf->changed & IEEE80211_IFCC_BEACON) {
- struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
- if (!beacon)
- return -ENOMEM;
- mutex_lock(&priv->mutex);
- rc = iwl3945_mac_beacon_update(hw, beacon);
- mutex_unlock(&priv->mutex);
- if (rc)
- return rc;
- }
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- mutex_lock(&priv->mutex);
-
- if (conf->bssid)
- IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
-
-/*
- * very dubious code was here; the probe filtering flag is never set:
- *
- if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) &&
- !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
- */
-
- if (priv->iw_mode == NL80211_IFTYPE_AP) {
- if (!conf->bssid) {
- conf->bssid = priv->mac_addr;
- memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
- IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
- conf->bssid);
- }
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
- }
-
- if (iwl_is_rfkill(priv))
- goto done;
-
- if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
- !is_multicast_ether_addr(conf->bssid)) {
- /* If there is currently a HW scan going on in the background
- * then we need to cancel it else the RXON below will fail. */
- if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARN(priv, "Aborted scan still in progress "
- "after 100ms\n");
- IWL_DEBUG_MAC80211(priv, "leaving:scan abort failed\n");
- mutex_unlock(&priv->mutex);
- return -EAGAIN;
- }
- memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN);
-
- /* TODO: Audit driver for usage of these members and see
- * if mac80211 deprecates them (priv->bssid looks like it
- * shouldn't be there, but I haven't scanned the IBSS code
- * to verify) - jpk */
- memcpy(priv->bssid, conf->bssid, ETH_ALEN);
-
- if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl3945_config_ap(priv);
- else {
- rc = iwl3945_commit_rxon(priv);
- if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
- iwl3945_add_station(priv,
- priv->active_rxon.bssid_addr, 1, 0);
- }
-
- } else {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
- }
-
- done:
- IWL_DEBUG_MAC80211(priv, "leave\n");
- mutex_unlock(&priv->mutex);
-
- return 0;
-}
-
-static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- mutex_lock(&priv->mutex);
-
- if (iwl_is_ready_rf(priv)) {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
- }
- if (priv->vif == conf->vif) {
- priv->vif = NULL;
- memset(priv->bssid, 0, ETH_ALEN);
- }
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
-#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
-
-static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changes)
-{
- struct iwl_priv *priv = hw->priv;
-
- IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
-
- if (changes & BSS_CHANGED_ERP_PREAMBLE) {
- IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
- bss_conf->use_short_preamble);
- if (bss_conf->use_short_preamble)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- priv->staging_rxon.flags &=
- ~RXON_FLG_SHORT_PREAMBLE_MSK;
- }
-
- if (changes & BSS_CHANGED_ERP_CTS_PROT) {
- IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n",
- bss_conf->use_cts_prot);
- if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
- priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
- else
- priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
- }
-
- if (changes & BSS_CHANGED_ASSOC) {
- IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
- /* This should never happen as this function should
- * never be called from interrupt context. */
- if (WARN_ON_ONCE(in_interrupt()))
- return;
- if (bss_conf->assoc) {
- priv->assoc_id = bss_conf->aid;
- priv->beacon_int = bss_conf->beacon_int;
- priv->timestamp = bss_conf->timestamp;
- priv->assoc_capability = bss_conf->assoc_capability;
- priv->power_data.dtim_period = bss_conf->dtim_period;
- priv->next_scan_jiffies = jiffies +
- IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
- mutex_lock(&priv->mutex);
- iwl3945_post_associate(priv);
- mutex_unlock(&priv->mutex);
- } else {
- priv->assoc_id = 0;
- IWL_DEBUG_MAC80211(priv,
- "DISASSOC %d\n", bss_conf->assoc);
- }
- } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
- IWL_DEBUG_MAC80211(priv,
- "Associated Changes %d\n", changes);
- iwl3945_send_rxon_assoc(priv);
- }
-
-}
-
static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -4126,7 +3327,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
static_key = !iwl_is_associated(priv);
if (!static_key) {
- sta_id = iwl3945_hw_find_station(priv, addr);
+ sta_id = iwl_find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
addr);
@@ -4162,185 +3363,6 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return ret;
}
-static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
- const struct ieee80211_tx_queue_params *params)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- int q;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- if (queue >= AC_NUM) {
- IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
- return 0;
- }
-
- q = AC_NUM - 1 - queue;
-
- spin_lock_irqsave(&priv->lock, flags);
-
- priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
- priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
- priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
- priv->qos_data.def_qos_parm.ac[q].edca_txop =
- cpu_to_le16((params->txop * 32));
-
- priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
- priv->qos_data.qos_active = 1;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- mutex_lock(&priv->mutex);
- if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl_activate_qos(priv, 1);
- else if (priv->assoc_id && iwl_is_associated(priv))
- iwl_activate_qos(priv, 0);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- return 0;
-}
-
-static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
- struct ieee80211_tx_queue_stats *stats)
-{
- struct iwl_priv *priv = hw->priv;
- int i, avail;
- struct iwl_tx_queue *txq;
- struct iwl_queue *q;
- unsigned long flags;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- for (i = 0; i < AC_NUM; i++) {
- txq = &priv->txq[i];
- q = &txq->q;
- avail = iwl_queue_space(q);
-
- stats[i].len = q->n_window - avail;
- stats[i].limit = q->n_window - q->high_mark;
- stats[i].count = q->n_window;
-
- }
- spin_unlock_irqrestore(&priv->lock, flags);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
- return 0;
-}
-
-static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
-
- mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- iwl_reset_qos(priv);
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->assoc_id = 0;
- priv->assoc_capability = 0;
-
- /* new association get rid of ibss beacon skb */
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = NULL;
-
- priv->beacon_int = priv->hw->conf.beacon_int;
- priv->timestamp = 0;
- if ((priv->iw_mode == NL80211_IFTYPE_STATION))
- priv->beacon_int = 0;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- mutex_unlock(&priv->mutex);
- return;
- }
-
- /* we are restarting association process
- * clear RXON_FILTER_ASSOC_MSK bit
- */
- if (priv->iw_mode != NL80211_IFTYPE_AP) {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
- }
-
- /* Per mac80211.h: This is only used in IBSS mode... */
- if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
-
- IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
- mutex_unlock(&priv->mutex);
- return;
- }
-
- iwl_set_rate(priv);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
-}
-
-static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- __le64 timestamp;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
- IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
- return -EIO;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = skb;
-
- priv->assoc_id = 0;
- timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
- priv->timestamp = le64_to_cpu(timestamp);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- spin_unlock_irqrestore(&priv->lock, flags);
-
- iwl_reset_qos(priv);
-
- iwl3945_post_associate(priv);
-
-
- return 0;
-}
-
/*****************************************************************************
*
* sysfs attributes
@@ -4359,7 +3381,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
static ssize_t show_debug_level(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%08X\n", priv->debug_level);
}
@@ -4367,7 +3389,7 @@ static ssize_t store_debug_level(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
unsigned long val;
int ret;
@@ -4388,7 +3410,7 @@ static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
static ssize_t show_temperature(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
if (!iwl_is_alive(priv))
return -EAGAIN;
@@ -4401,7 +3423,7 @@ static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
static ssize_t show_tx_power(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
}
@@ -4409,7 +3431,7 @@ static ssize_t store_tx_power(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
char *p = (char *)buf;
u32 val;
@@ -4427,7 +3449,7 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
static ssize_t show_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
}
@@ -4436,7 +3458,7 @@ static ssize_t store_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
u32 flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
@@ -4448,7 +3470,7 @@ static ssize_t store_flags(struct device *d,
IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
flags);
priv->staging_rxon.flags = cpu_to_le32(flags);
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
}
}
mutex_unlock(&priv->mutex);
@@ -4461,7 +3483,7 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags);
static ssize_t show_filter_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%04X\n",
le32_to_cpu(priv->active_rxon.filter_flags));
@@ -4471,7 +3493,7 @@ static ssize_t store_filter_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
u32 filter_flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
@@ -4484,7 +3506,7 @@ static ssize_t store_filter_flags(struct device *d,
"0x%04X\n", filter_flags);
priv->staging_rxon.filter_flags =
cpu_to_le32(filter_flags);
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
}
}
mutex_unlock(&priv->mutex);
@@ -4624,26 +3646,11 @@ static ssize_t show_power_level(struct device *d,
{
struct iwl_priv *priv = dev_get_drvdata(d);
int mode = priv->power_data.user_power_setting;
- int system = priv->power_data.system_power_setting;
int level = priv->power_data.power_mode;
char *p = buf;
- switch (system) {
- case IWL_POWER_SYS_AUTO:
- p += sprintf(p, "SYSTEM:auto");
- break;
- case IWL_POWER_SYS_AC:
- p += sprintf(p, "SYSTEM:ac");
- break;
- case IWL_POWER_SYS_BATTERY:
- p += sprintf(p, "SYSTEM:battery");
- break;
- }
-
- p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
- "fixed" : "auto");
- p += sprintf(p, "\tINDEX:%d", level);
- p += sprintf(p, "\n");
+ p += sprintf(p, "INDEX:%d\t", level);
+ p += sprintf(p, "USER:%d\n", mode);
return p - buf + 1;
}
@@ -4756,7 +3763,7 @@ static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna);
static ssize_t show_status(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
if (!iwl_is_alive(priv))
return -EAGAIN;
return sprintf(buf, "0x%08x\n", (int)priv->status);
@@ -4768,10 +3775,11 @@ static ssize_t dump_error_log(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
+ struct iwl_priv *priv = dev_get_drvdata(d);
char *p = (char *)buf;
if (p[0] == '1')
- iwl3945_dump_nic_error_log((struct iwl_priv *)d->driver_data);
+ iwl3945_dump_nic_error_log(priv);
return strnlen(buf, count);
}
@@ -4782,10 +3790,11 @@ static ssize_t dump_event_log(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
+ struct iwl_priv *priv = dev_get_drvdata(d);
char *p = (char *)buf;
if (p[0] == '1')
- iwl3945_dump_nic_event_log((struct iwl_priv *)d->driver_data);
+ iwl3945_dump_nic_event_log(priv);
return strnlen(buf, count);
}
@@ -4807,7 +3816,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->up, iwl3945_bg_up);
INIT_WORK(&priv->restart, iwl3945_bg_restart);
INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish);
- INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
@@ -4864,16 +3872,15 @@ static struct ieee80211_ops iwl3945_hw_ops = {
.tx = iwl3945_mac_tx,
.start = iwl3945_mac_start,
.stop = iwl3945_mac_stop,
- .add_interface = iwl3945_mac_add_interface,
- .remove_interface = iwl3945_mac_remove_interface,
- .config = iwl3945_mac_config,
- .config_interface = iwl3945_mac_config_interface,
+ .add_interface = iwl_mac_add_interface,
+ .remove_interface = iwl_mac_remove_interface,
+ .config = iwl_mac_config,
.configure_filter = iwl_configure_filter,
.set_key = iwl3945_mac_set_key,
- .get_tx_stats = iwl3945_mac_get_tx_stats,
- .conf_tx = iwl3945_mac_conf_tx,
- .reset_tsf = iwl3945_mac_reset_tsf,
- .bss_info_changed = iwl3945_bss_info_changed,
+ .get_tx_stats = iwl_mac_get_tx_stats,
+ .conf_tx = iwl_mac_conf_tx,
+ .reset_tsf = iwl_mac_reset_tsf,
+ .bss_info_changed = iwl_bss_info_changed,
.hw_scan = iwl_mac_hw_scan
};
@@ -4886,7 +3893,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
priv->ibss_beacon = NULL;
spin_lock_init(&priv->lock);
- spin_lock_init(&priv->power_data.lock);
spin_lock_init(&priv->sta_lock);
spin_lock_init(&priv->hcmd_lock);
@@ -4895,7 +3901,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
mutex_init(&priv->mutex);
/* Clear the driver's (not device's) station table */
- iwl3945_clear_stations_table(priv);
+ iwl_clear_stations_table(priv);
priv->data_retry_limit = -1;
priv->ieee_channels = NULL;
@@ -4966,13 +3972,13 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
hw->wiphy->custom_regulatory = true;
- hw->wiphy->max_scan_ssids = 1; /* WILL FIX */
+ hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
+ /* we create the 802.11 header and a zero-length SSID element */
+ hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
- hw->conf.beacon_int = 100;
-
if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&priv->bands[IEEE80211_BAND_2GHZ];
@@ -5037,6 +4043,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
priv->cfg = cfg;
priv->pci_dev = pdev;
+ priv->inta_mask = CSR_INI_SET_MASK;
#ifdef CONFIG_IWLWIFI_DEBUG
priv->debug_level = iwl3945_mod_params.debug;
@@ -5083,6 +4090,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
* PCI Tx retries from interfering with C3 CPU state */
pci_write_config_byte(pdev, 0x41, 0x00);
+ /* this spin lock will be used in apm_ops.init and EEPROM access
+ * we should init now
+ */
+ spin_lock_init(&priv->reg_lock);
+
/* amp init */
err = priv->cfg->ops->lib->apm_ops.init(priv);
if (err < 0) {
@@ -5128,20 +4140,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n",
priv->cfg->name);
- /***********************************
- * 7. Initialize Module Parameters
- * **********************************/
-
- /* Initialize module parameter values here */
- /* Disable radio (SW RF KILL) via parameter when loading driver */
- if (iwl3945_mod_params.disable) {
- set_bit(STATUS_RF_KILL_SW, &priv->status);
- IWL_DEBUG_INFO(priv, "Radio disabled.\n");
- }
-
-
/***********************
- * 8. Setup Services
+ * 7. Setup Services
* ********************/
spin_lock_irqsave(&priv->lock, flags);
@@ -5150,8 +4150,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
pci_enable_msi(priv->pci_dev);
- err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
- DRV_NAME, priv);
+ err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr,
+ IRQF_SHARED, DRV_NAME, priv);
if (err) {
IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
goto out_disable_msi;
@@ -5169,7 +4169,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
iwl3945_setup_rx_handlers(priv);
/*********************************
- * 9. Setup and Register mac80211
+ * 8. Setup and Register mac80211
* *******************************/
iwl_enable_interrupts(priv);
@@ -5178,12 +4178,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
if (err)
goto out_remove_sysfs;
- err = iwl_rfkill_init(priv);
+ err = iwl_dbgfs_register(priv, DRV_NAME);
if (err)
- IWL_ERR(priv, "Unable to initialize RFKILL system. "
- "Ignoring error: %d\n", err);
- else
- iwl_rfkill_set_hw_state(priv);
+ IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
/* Start monitoring the killswitch */
queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
@@ -5228,6 +4225,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
+ iwl_dbgfs_unregister(priv);
+
set_bit(STATUS_EXIT_PENDING, &priv->status);
if (priv->mac80211_registered) {
@@ -5248,7 +4247,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
- iwl_rfkill_unregister(priv);
cancel_delayed_work_sync(&priv->rfkill_poll);
iwl3945_dealloc_ucode_pci(priv);
@@ -5258,7 +4256,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
iwl3945_hw_txq_ctx_free(priv);
iwl3945_unset_hw_params(priv);
- iwl3945_clear_stations_table(priv);
+ iwl_clear_stations_table(priv);
/*netif_stop_queue(dev); */
flush_workqueue(priv->workqueue);
@@ -5286,43 +4284,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
ieee80211_free_hw(priv->hw);
}
-#ifdef CONFIG_PM
-
-static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct iwl_priv *priv = pci_get_drvdata(pdev);
-
- if (priv->is_open) {
- set_bit(STATUS_IN_SUSPEND, &priv->status);
- iwl3945_mac_stop(priv->hw);
- priv->is_open = 1;
- }
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
- return 0;
-}
-
-static int iwl3945_pci_resume(struct pci_dev *pdev)
-{
- struct iwl_priv *priv = pci_get_drvdata(pdev);
- int ret;
-
- pci_set_power_state(pdev, PCI_D0);
- ret = pci_enable_device(pdev);
- if (ret)
- return ret;
- pci_restore_state(pdev);
-
- if (priv->is_open)
- iwl3945_mac_start(priv->hw);
-
- clear_bit(STATUS_IN_SUSPEND, &priv->status);
- return 0;
-}
-
-#endif /* CONFIG_PM */
/*****************************************************************************
*
@@ -5336,8 +4297,8 @@ static struct pci_driver iwl3945_driver = {
.probe = iwl3945_pci_probe,
.remove = __devexit_p(iwl3945_pci_remove),
#ifdef CONFIG_PM
- .suspend = iwl3945_pci_suspend,
- .resume = iwl3945_pci_resume,
+ .suspend = iwl_pci_suspend,
+ .resume = iwl_pci_resume,
#endif
};
@@ -5378,8 +4339,6 @@ MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX));
module_param_named(antenna, iwl3945_mod_params.antenna, int, 0444);
MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(disable, iwl3945_mod_params.disable, int, 0444);
-MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444);
MODULE_PARM_DESC(swcrypto,
"using software crypto (default 1 [software])\n");
diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig
new file mode 100644
index 00000000000..1eccb6df46d
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/Kconfig
@@ -0,0 +1,23 @@
+config IWM
+ tristate "Intel Wireless Multicomm 3200 WiFi driver"
+ depends on MMC && WLAN_80211 && EXPERIMENTAL
+ depends on CFG80211
+ select WIRELESS_EXT
+ select FW_LOADER
+
+config IWM_DEBUG
+ bool "Enable full debugging output in iwmc3200wifi"
+ depends on IWM && DEBUG_FS
+ ---help---
+ This option will enable debug tracing and setting for iwm
+
+ You can set the debug level and module through debugfs. By
+ default all modules are set to the IWL_DL_ERR level.
+ To see the list of debug modules and levels, see iwm/debug.h
+
+ For example, if you want the full MLME debug output:
+ echo 0xff > /debug/iwm/phyN/debug/mlme
+
+ Or, if you want the full debug, for all modules:
+ echo 0xff > /debug/iwm/phyN/debug/level
+ echo 0xff > /debug/iwm/phyN/debug/modules
diff --git a/drivers/net/wireless/iwmc3200wifi/Makefile b/drivers/net/wireless/iwmc3200wifi/Makefile
new file mode 100644
index 00000000000..927f022545c
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_IWM) := iwmc3200wifi.o
+iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o
+iwmc3200wifi-objs += commands.o wext.o cfg80211.o eeprom.o
+
+iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o
diff --git a/drivers/net/wireless/iwmc3200wifi/bus.h b/drivers/net/wireless/iwmc3200wifi/bus.h
new file mode 100644
index 00000000000..836663eec25
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/bus.h
@@ -0,0 +1,57 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef __IWM_BUS_H__
+#define __IWM_BUS_H__
+
+#include "iwm.h"
+
+struct iwm_if_ops {
+ int (*enable)(struct iwm_priv *iwm);
+ int (*disable)(struct iwm_priv *iwm);
+ int (*send_chunk)(struct iwm_priv *iwm, u8* buf, int count);
+
+ int (*debugfs_init)(struct iwm_priv *iwm, struct dentry *parent_dir);
+ void (*debugfs_exit)(struct iwm_priv *iwm);
+
+ const char *umac_name;
+ const char *calib_lmac_name;
+ const char *lmac_name;
+};
+
+static inline int iwm_bus_send_chunk(struct iwm_priv *iwm, u8 *buf, int count)
+{
+ return iwm->bus_ops->send_chunk(iwm, buf, count);
+}
+
+static inline int iwm_bus_enable(struct iwm_priv *iwm)
+{
+ return iwm->bus_ops->enable(iwm);
+}
+
+static inline int iwm_bus_disable(struct iwm_priv *iwm)
+{
+ return iwm->bus_ops->disable(iwm);
+}
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
new file mode 100644
index 00000000000..96f714e6e12
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -0,0 +1,409 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
+
+#include "iwm.h"
+#include "commands.h"
+#include "cfg80211.h"
+#include "debug.h"
+
+#define RATETAB_ENT(_rate, _rateid, _flags) \
+ { \
+ .bitrate = (_rate), \
+ .hw_value = (_rateid), \
+ .flags = (_flags), \
+ }
+
+#define CHAN2G(_channel, _freq, _flags) { \
+ .band = IEEE80211_BAND_2GHZ, \
+ .center_freq = (_freq), \
+ .hw_value = (_channel), \
+ .flags = (_flags), \
+ .max_antenna_gain = 0, \
+ .max_power = 30, \
+}
+
+#define CHAN5G(_channel, _flags) { \
+ .band = IEEE80211_BAND_5GHZ, \
+ .center_freq = 5000 + (5 * (_channel)), \
+ .hw_value = (_channel), \
+ .flags = (_flags), \
+ .max_antenna_gain = 0, \
+ .max_power = 30, \
+}
+
+static struct ieee80211_rate iwm_rates[] = {
+ RATETAB_ENT(10, 0x1, 0),
+ RATETAB_ENT(20, 0x2, 0),
+ RATETAB_ENT(55, 0x4, 0),
+ RATETAB_ENT(110, 0x8, 0),
+ RATETAB_ENT(60, 0x10, 0),
+ RATETAB_ENT(90, 0x20, 0),
+ RATETAB_ENT(120, 0x40, 0),
+ RATETAB_ENT(180, 0x80, 0),
+ RATETAB_ENT(240, 0x100, 0),
+ RATETAB_ENT(360, 0x200, 0),
+ RATETAB_ENT(480, 0x400, 0),
+ RATETAB_ENT(540, 0x800, 0),
+};
+
+#define iwm_a_rates (iwm_rates + 4)
+#define iwm_a_rates_size 8
+#define iwm_g_rates (iwm_rates + 0)
+#define iwm_g_rates_size 12
+
+static struct ieee80211_channel iwm_2ghz_channels[] = {
+ CHAN2G(1, 2412, 0),
+ CHAN2G(2, 2417, 0),
+ CHAN2G(3, 2422, 0),
+ CHAN2G(4, 2427, 0),
+ CHAN2G(5, 2432, 0),
+ CHAN2G(6, 2437, 0),
+ CHAN2G(7, 2442, 0),
+ CHAN2G(8, 2447, 0),
+ CHAN2G(9, 2452, 0),
+ CHAN2G(10, 2457, 0),
+ CHAN2G(11, 2462, 0),
+ CHAN2G(12, 2467, 0),
+ CHAN2G(13, 2472, 0),
+ CHAN2G(14, 2484, 0),
+};
+
+static struct ieee80211_channel iwm_5ghz_a_channels[] = {
+ CHAN5G(34, 0), CHAN5G(36, 0),
+ CHAN5G(38, 0), CHAN5G(40, 0),
+ CHAN5G(42, 0), CHAN5G(44, 0),
+ CHAN5G(46, 0), CHAN5G(48, 0),
+ CHAN5G(52, 0), CHAN5G(56, 0),
+ CHAN5G(60, 0), CHAN5G(64, 0),
+ CHAN5G(100, 0), CHAN5G(104, 0),
+ CHAN5G(108, 0), CHAN5G(112, 0),
+ CHAN5G(116, 0), CHAN5G(120, 0),
+ CHAN5G(124, 0), CHAN5G(128, 0),
+ CHAN5G(132, 0), CHAN5G(136, 0),
+ CHAN5G(140, 0), CHAN5G(149, 0),
+ CHAN5G(153, 0), CHAN5G(157, 0),
+ CHAN5G(161, 0), CHAN5G(165, 0),
+ CHAN5G(184, 0), CHAN5G(188, 0),
+ CHAN5G(192, 0), CHAN5G(196, 0),
+ CHAN5G(200, 0), CHAN5G(204, 0),
+ CHAN5G(208, 0), CHAN5G(212, 0),
+ CHAN5G(216, 0),
+};
+
+static struct ieee80211_supported_band iwm_band_2ghz = {
+ .channels = iwm_2ghz_channels,
+ .n_channels = ARRAY_SIZE(iwm_2ghz_channels),
+ .bitrates = iwm_g_rates,
+ .n_bitrates = iwm_g_rates_size,
+};
+
+static struct ieee80211_supported_band iwm_band_5ghz = {
+ .channels = iwm_5ghz_a_channels,
+ .n_channels = ARRAY_SIZE(iwm_5ghz_a_channels),
+ .bitrates = iwm_a_rates,
+ .n_bitrates = iwm_a_rates_size,
+};
+
+int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
+{
+ struct wiphy *wiphy = iwm_to_wiphy(iwm);
+ struct iwm_bss_info *bss, *next;
+ struct iwm_umac_notif_bss_info *umac_bss;
+ struct ieee80211_mgmt *mgmt;
+ struct ieee80211_channel *channel;
+ struct ieee80211_supported_band *band;
+ s32 signal;
+ int freq;
+
+ list_for_each_entry_safe(bss, next, &iwm->bss_list, node) {
+ umac_bss = bss->bss;
+ mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
+
+ if (umac_bss->band == UMAC_BAND_2GHZ)
+ band = wiphy->bands[IEEE80211_BAND_2GHZ];
+ else if (umac_bss->band == UMAC_BAND_5GHZ)
+ band = wiphy->bands[IEEE80211_BAND_5GHZ];
+ else {
+ IWM_ERR(iwm, "Invalid band: %d\n", umac_bss->band);
+ return -EINVAL;
+ }
+
+ freq = ieee80211_channel_to_frequency(umac_bss->channel);
+ channel = ieee80211_get_channel(wiphy, freq);
+ signal = umac_bss->rssi * 100;
+
+ if (!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
+ le16_to_cpu(umac_bss->frame_len),
+ signal, GFP_KERNEL))
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int iwm_cfg80211_change_iface(struct wiphy *wiphy, int ifindex,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
+{
+ struct net_device *ndev;
+ struct wireless_dev *wdev;
+ struct iwm_priv *iwm;
+ u32 old_mode;
+
+ /* we're under RTNL */
+ ndev = __dev_get_by_index(&init_net, ifindex);
+ if (!ndev)
+ return -ENODEV;
+
+ wdev = ndev->ieee80211_ptr;
+ iwm = ndev_to_iwm(ndev);
+ old_mode = iwm->conf.mode;
+
+ switch (type) {
+ case NL80211_IFTYPE_STATION:
+ iwm->conf.mode = UMAC_MODE_BSS;
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ iwm->conf.mode = UMAC_MODE_IBSS;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ wdev->iftype = type;
+
+ if ((old_mode == iwm->conf.mode) || !iwm->umac_profile)
+ return 0;
+
+ iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);
+
+ if (iwm->umac_profile_active) {
+ int ret = iwm_invalidate_mlme_profile(iwm);
+ if (ret < 0)
+ IWM_ERR(iwm, "Couldn't invalidate profile\n");
+ }
+
+ return 0;
+}
+
+static int iwm_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+ struct cfg80211_scan_request *request)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(ndev);
+ int ret;
+
+ if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
+ IWM_ERR(iwm, "Scan while device is not ready\n");
+ return -EIO;
+ }
+
+ if (test_bit(IWM_STATUS_SCANNING, &iwm->status)) {
+ IWM_ERR(iwm, "Scanning already\n");
+ return -EAGAIN;
+ }
+
+ if (test_bit(IWM_STATUS_SCAN_ABORTING, &iwm->status)) {
+ IWM_ERR(iwm, "Scanning being aborted\n");
+ return -EAGAIN;
+ }
+
+ set_bit(IWM_STATUS_SCANNING, &iwm->status);
+
+ ret = iwm_scan_ssids(iwm, request->ssids, request->n_ssids);
+ if (ret) {
+ clear_bit(IWM_STATUS_SCANNING, &iwm->status);
+ return ret;
+ }
+
+ iwm->scan_request = request;
+ return 0;
+}
+
+static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+ struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+
+ if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
+ (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
+ int ret;
+
+ iwm->conf.rts_threshold = wiphy->rts_threshold;
+
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+ CFG_RTS_THRESHOLD,
+ iwm->conf.rts_threshold);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
+ (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
+ int ret;
+
+ iwm->conf.frag_threshold = wiphy->frag_threshold;
+
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
+ CFG_FRAG_THRESHOLD,
+ iwm->conf.frag_threshold);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_ibss_params *params)
+{
+ struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+ struct ieee80211_channel *chan = params->channel;
+ struct cfg80211_bss *bss;
+
+ if (!test_bit(IWM_STATUS_READY, &iwm->status))
+ return -EIO;
+
+ /* UMAC doesn't support creating IBSS network with specified bssid.
+ * This should be removed after we have join only mode supported. */
+ if (params->bssid)
+ return -EOPNOTSUPP;
+
+ bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
+ params->ssid, params->ssid_len);
+ if (!bss) {
+ iwm_scan_one_ssid(iwm, params->ssid, params->ssid_len);
+ schedule_timeout_interruptible(2 * HZ);
+ bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
+ params->ssid, params->ssid_len);
+ }
+ /* IBSS join only mode is not supported by UMAC ATM */
+ if (bss) {
+ cfg80211_put_bss(bss);
+ return -EOPNOTSUPP;
+ }
+
+ iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
+ iwm->umac_profile->ibss.band = chan->band;
+ iwm->umac_profile->ibss.channel = iwm->channel;
+ iwm->umac_profile->ssid.ssid_len = params->ssid_len;
+ memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
+
+ if (params->bssid)
+ memcpy(&iwm->umac_profile->bssid[0], params->bssid, ETH_ALEN);
+
+ return iwm_send_mlme_profile(iwm);
+}
+
+static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+{
+ struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+
+ if (iwm->umac_profile_active)
+ return iwm_invalidate_mlme_profile(iwm);
+
+ return 0;
+}
+
+static struct cfg80211_ops iwm_cfg80211_ops = {
+ .change_virtual_intf = iwm_cfg80211_change_iface,
+ .scan = iwm_cfg80211_scan,
+ .set_wiphy_params = iwm_cfg80211_set_wiphy_params,
+ .join_ibss = iwm_cfg80211_join_ibss,
+ .leave_ibss = iwm_cfg80211_leave_ibss,
+};
+
+struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
+{
+ int ret = 0;
+ struct wireless_dev *wdev;
+
+ /*
+ * We're trying to have the following memory
+ * layout:
+ *
+ * +-------------------------+
+ * | struct wiphy |
+ * +-------------------------+
+ * | struct iwm_priv |
+ * +-------------------------+
+ * | bus private data |
+ * | (e.g. iwm_priv_sdio) |
+ * +-------------------------+
+ *
+ */
+
+ wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
+ if (!wdev) {
+ dev_err(dev, "Couldn't allocate wireless device\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ wdev->wiphy = wiphy_new(&iwm_cfg80211_ops,
+ sizeof(struct iwm_priv) + sizeof_bus);
+ if (!wdev->wiphy) {
+ dev_err(dev, "Couldn't allocate wiphy device\n");
+ ret = -ENOMEM;
+ goto out_err_new;
+ }
+
+ set_wiphy_dev(wdev->wiphy, dev);
+ wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX;
+ wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC);
+ wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz;
+ wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &iwm_band_5ghz;
+ wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+ ret = wiphy_register(wdev->wiphy);
+ if (ret < 0) {
+ dev_err(dev, "Couldn't register wiphy device\n");
+ goto out_err_register;
+ }
+
+ return wdev;
+
+ out_err_register:
+ wiphy_free(wdev->wiphy);
+
+ out_err_new:
+ kfree(wdev);
+
+ return ERR_PTR(ret);
+}
+
+void iwm_wdev_free(struct iwm_priv *iwm)
+{
+ struct wireless_dev *wdev = iwm_to_wdev(iwm);
+
+ if (!wdev)
+ return;
+
+ wiphy_unregister(wdev->wiphy);
+ wiphy_free(wdev->wiphy);
+ kfree(wdev);
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.h b/drivers/net/wireless/iwmc3200wifi/cfg80211.h
new file mode 100644
index 00000000000..56a34145acb
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.h
@@ -0,0 +1,31 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef __IWM_CFG80211_H__
+#define __IWM_CFG80211_H__
+
+int iwm_cfg80211_inform_bss(struct iwm_priv *iwm);
+struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev);
+void iwm_wdev_free(struct iwm_priv *iwm);
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
new file mode 100644
index 00000000000..834a7f544e5
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -0,0 +1,920 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/wireless.h>
+#include <linux/etherdevice.h>
+#include <linux/ieee80211.h>
+
+#include "iwm.h"
+#include "bus.h"
+#include "hal.h"
+#include "umac.h"
+#include "commands.h"
+#include "debug.h"
+
+static int iwm_send_lmac_ptrough_cmd(struct iwm_priv *iwm,
+ u8 lmac_cmd_id,
+ const void *lmac_payload,
+ u16 lmac_payload_size,
+ u8 resp)
+{
+ struct iwm_udma_wifi_cmd udma_cmd = UDMA_LMAC_INIT;
+ struct iwm_umac_cmd umac_cmd;
+ struct iwm_lmac_cmd lmac_cmd;
+
+ lmac_cmd.id = lmac_cmd_id;
+
+ umac_cmd.id = UMAC_CMD_OPCODE_WIFI_PASS_THROUGH;
+ umac_cmd.resp = resp;
+
+ return iwm_hal_send_host_cmd(iwm, &udma_cmd, &umac_cmd, &lmac_cmd,
+ lmac_payload, lmac_payload_size);
+}
+
+int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size,
+ bool resp)
+{
+ struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
+ struct iwm_umac_cmd umac_cmd;
+
+ umac_cmd.id = UMAC_CMD_OPCODE_WIFI_IF_WRAPPER;
+ umac_cmd.resp = resp;
+
+ return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd,
+ payload, payload_size);
+}
+
+static struct coex_event iwm_sta_xor_prio_tbl[COEX_EVENTS_NUM] =
+{
+ {4, 3, 0, COEX_UNASSOC_IDLE_FLAGS},
+ {4, 3, 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
+ {4, 3, 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
+ {4, 3, 0, COEX_CALIBRATION_FLAGS},
+ {4, 3, 0, COEX_PERIODIC_CALIBRATION_FLAGS},
+ {4, 3, 0, COEX_CONNECTION_ESTAB_FLAGS},
+ {4, 3, 0, COEX_ASSOCIATED_IDLE_FLAGS},
+ {4, 3, 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
+ {4, 3, 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
+ {4, 3, 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
+ {6, 3, 0, COEX_XOR_RF_ON_FLAGS},
+ {4, 3, 0, COEX_RF_OFF_FLAGS},
+ {6, 6, 0, COEX_STAND_ALONE_DEBUG_FLAGS},
+ {4, 3, 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
+ {4, 3, 0, COEX_RSRVD1_FLAGS},
+ {4, 3, 0, COEX_RSRVD2_FLAGS}
+};
+
+static struct coex_event iwm_sta_cm_prio_tbl[COEX_EVENTS_NUM] =
+{
+ {1, 1, 0, COEX_UNASSOC_IDLE_FLAGS},
+ {4, 3, 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
+ {3, 3, 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
+ {5, 5, 0, COEX_CALIBRATION_FLAGS},
+ {4, 4, 0, COEX_PERIODIC_CALIBRATION_FLAGS},
+ {5, 4, 0, COEX_CONNECTION_ESTAB_FLAGS},
+ {4, 4, 0, COEX_ASSOCIATED_IDLE_FLAGS},
+ {4, 4, 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
+ {4, 4, 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
+ {4, 4, 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
+ {1, 1, 0, COEX_RF_ON_FLAGS},
+ {1, 1, 0, COEX_RF_OFF_FLAGS},
+ {6, 6, 0, COEX_STAND_ALONE_DEBUG_FLAGS},
+ {5, 4, 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
+ {1, 1, 0, COEX_RSRVD1_FLAGS},
+ {1, 1, 0, COEX_RSRVD2_FLAGS}
+};
+
+int iwm_send_prio_table(struct iwm_priv *iwm)
+{
+ struct iwm_coex_prio_table_cmd coex_table_cmd;
+ u32 coex_enabled, mode_enabled;
+
+ memset(&coex_table_cmd, 0, sizeof(struct iwm_coex_prio_table_cmd));
+
+ coex_table_cmd.flags = COEX_FLAGS_STA_TABLE_VALID_MSK;
+
+ switch (iwm->conf.coexist_mode) {
+ case COEX_MODE_XOR:
+ case COEX_MODE_CM:
+ coex_enabled = 1;
+ break;
+ default:
+ coex_enabled = 0;
+ break;
+ }
+
+ switch (iwm->conf.mode) {
+ case UMAC_MODE_BSS:
+ case UMAC_MODE_IBSS:
+ mode_enabled = 1;
+ break;
+ default:
+ mode_enabled = 0;
+ break;
+ }
+
+ if (coex_enabled && mode_enabled) {
+ coex_table_cmd.flags |= COEX_FLAGS_COEX_ENABLE_MSK |
+ COEX_FLAGS_ASSOC_WAKEUP_UMASK_MSK |
+ COEX_FLAGS_UNASSOC_WAKEUP_UMASK_MSK;
+
+ switch (iwm->conf.coexist_mode) {
+ case COEX_MODE_XOR:
+ memcpy(coex_table_cmd.sta_prio, iwm_sta_xor_prio_tbl,
+ sizeof(iwm_sta_xor_prio_tbl));
+ break;
+ case COEX_MODE_CM:
+ memcpy(coex_table_cmd.sta_prio, iwm_sta_cm_prio_tbl,
+ sizeof(iwm_sta_cm_prio_tbl));
+ break;
+ default:
+ IWM_ERR(iwm, "Invalid coex_mode 0x%x\n",
+ iwm->conf.coexist_mode);
+ break;
+ }
+ } else
+ IWM_WARN(iwm, "coexistense disabled\n");
+
+ return iwm_send_lmac_ptrough_cmd(iwm, COEX_PRIORITY_TABLE_CMD,
+ &coex_table_cmd,
+ sizeof(struct iwm_coex_prio_table_cmd), 1);
+}
+
+int iwm_send_init_calib_cfg(struct iwm_priv *iwm, u8 calib_requested)
+{
+ struct iwm_lmac_cal_cfg_cmd cal_cfg_cmd;
+
+ memset(&cal_cfg_cmd, 0, sizeof(struct iwm_lmac_cal_cfg_cmd));
+
+ cal_cfg_cmd.ucode_cfg.init.enable = cpu_to_le32(calib_requested);
+ cal_cfg_cmd.ucode_cfg.init.start = cpu_to_le32(calib_requested);
+ cal_cfg_cmd.ucode_cfg.init.send_res = cpu_to_le32(calib_requested);
+ cal_cfg_cmd.ucode_cfg.flags =
+ cpu_to_le32(CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_AFTER_MSK);
+
+ return iwm_send_lmac_ptrough_cmd(iwm, CALIBRATION_CFG_CMD, &cal_cfg_cmd,
+ sizeof(struct iwm_lmac_cal_cfg_cmd), 1);
+}
+
+int iwm_send_periodic_calib_cfg(struct iwm_priv *iwm, u8 calib_requested)
+{
+ struct iwm_lmac_cal_cfg_cmd cal_cfg_cmd;
+
+ memset(&cal_cfg_cmd, 0, sizeof(struct iwm_lmac_cal_cfg_cmd));
+
+ cal_cfg_cmd.ucode_cfg.periodic.enable = cpu_to_le32(calib_requested);
+ cal_cfg_cmd.ucode_cfg.periodic.start = cpu_to_le32(calib_requested);
+
+ return iwm_send_lmac_ptrough_cmd(iwm, CALIBRATION_CFG_CMD, &cal_cfg_cmd,
+ sizeof(struct iwm_lmac_cal_cfg_cmd), 0);
+}
+
+int iwm_store_rxiq_calib_result(struct iwm_priv *iwm)
+{
+ struct iwm_calib_rxiq *rxiq;
+ u8 *eeprom_rxiq = iwm_eeprom_access(iwm, IWM_EEPROM_CALIB_RXIQ);
+ int grplen = sizeof(struct iwm_calib_rxiq_group);
+
+ rxiq = kzalloc(sizeof(struct iwm_calib_rxiq), GFP_KERNEL);
+ if (!rxiq) {
+ IWM_ERR(iwm, "Couldn't alloc memory for RX IQ\n");
+ return -ENOMEM;
+ }
+
+ eeprom_rxiq = iwm_eeprom_access(iwm, IWM_EEPROM_CALIB_RXIQ);
+ if (IS_ERR(eeprom_rxiq)) {
+ IWM_ERR(iwm, "Couldn't access EEPROM RX IQ entry\n");
+ return PTR_ERR(eeprom_rxiq);
+ }
+
+ iwm->calib_res[SHILOH_PHY_CALIBRATE_RX_IQ_CMD].buf = (u8 *)rxiq;
+ iwm->calib_res[SHILOH_PHY_CALIBRATE_RX_IQ_CMD].size = sizeof(*rxiq);
+
+ rxiq->hdr.opcode = SHILOH_PHY_CALIBRATE_RX_IQ_CMD;
+ rxiq->hdr.first_grp = 0;
+ rxiq->hdr.grp_num = 1;
+ rxiq->hdr.all_data_valid = 1;
+
+ memcpy(&rxiq->group[0], eeprom_rxiq, 4 * grplen);
+ memcpy(&rxiq->group[4], eeprom_rxiq + 6 * grplen, grplen);
+
+ return 0;
+}
+
+int iwm_send_calib_results(struct iwm_priv *iwm)
+{
+ int i, ret = 0;
+
+ for (i = PHY_CALIBRATE_OPCODES_NUM; i < CALIBRATION_CMD_NUM; i++) {
+ if (test_bit(i - PHY_CALIBRATE_OPCODES_NUM,
+ &iwm->calib_done_map)) {
+ IWM_DBG_CMD(iwm, DBG,
+ "Send calibration %d result\n", i);
+ ret |= iwm_send_lmac_ptrough_cmd(iwm,
+ REPLY_PHY_CALIBRATION_CMD,
+ iwm->calib_res[i].buf,
+ iwm->calib_res[i].size, 0);
+
+ kfree(iwm->calib_res[i].buf);
+ iwm->calib_res[i].buf = NULL;
+ iwm->calib_res[i].size = 0;
+ }
+ }
+
+ return ret;
+}
+
+int iwm_send_umac_reset(struct iwm_priv *iwm, __le32 reset_flags, bool resp)
+{
+ struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
+ struct iwm_umac_cmd umac_cmd;
+ struct iwm_umac_cmd_reset reset;
+
+ reset.flags = reset_flags;
+
+ umac_cmd.id = UMAC_CMD_OPCODE_RESET;
+ umac_cmd.resp = resp;
+
+ return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, &reset,
+ sizeof(struct iwm_umac_cmd_reset));
+}
+
+int iwm_umac_set_config_fix(struct iwm_priv *iwm, u16 tbl, u16 key, u32 value)
+{
+ struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
+ struct iwm_umac_cmd umac_cmd;
+ struct iwm_umac_cmd_set_param_fix param;
+
+ if ((tbl != UMAC_PARAM_TBL_CFG_FIX) &&
+ (tbl != UMAC_PARAM_TBL_FA_CFG_FIX))
+ return -EINVAL;
+
+ umac_cmd.id = UMAC_CMD_OPCODE_SET_PARAM_FIX;
+ umac_cmd.resp = 0;
+
+ param.tbl = cpu_to_le16(tbl);
+ param.key = cpu_to_le16(key);
+ param.value = cpu_to_le32(value);
+
+ return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, &param,
+ sizeof(struct iwm_umac_cmd_set_param_fix));
+}
+
+int iwm_umac_set_config_var(struct iwm_priv *iwm, u16 key,
+ void *payload, u16 payload_size)
+{
+ struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
+ struct iwm_umac_cmd umac_cmd;
+ struct iwm_umac_cmd_set_param_var *param_hdr;
+ u8 *param;
+ int ret;
+
+ param = kzalloc(payload_size +
+ sizeof(struct iwm_umac_cmd_set_param_var), GFP_KERNEL);
+ if (!param) {
+ IWM_ERR(iwm, "Couldn't allocate param\n");
+ return -ENOMEM;
+ }
+
+ param_hdr = (struct iwm_umac_cmd_set_param_var *)param;
+
+ umac_cmd.id = UMAC_CMD_OPCODE_SET_PARAM_VAR;
+ umac_cmd.resp = 0;
+
+ param_hdr->tbl = cpu_to_le16(UMAC_PARAM_TBL_CFG_VAR);
+ param_hdr->key = cpu_to_le16(key);
+ param_hdr->len = cpu_to_le16(payload_size);
+ memcpy(param + sizeof(struct iwm_umac_cmd_set_param_var),
+ payload, payload_size);
+
+ ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, param,
+ sizeof(struct iwm_umac_cmd_set_param_var) +
+ payload_size);
+ kfree(param);
+
+ return ret;
+}
+
+int iwm_send_umac_config(struct iwm_priv *iwm,
+ __le32 reset_flags)
+{
+ int ret;
+
+ /* Use UMAC default values */
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+ CFG_POWER_INDEX, iwm->conf.power_index);
+ if (ret < 0)
+ return ret;
+
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
+ CFG_FRAG_THRESHOLD,
+ iwm->conf.frag_threshold);
+ if (ret < 0)
+ return ret;
+
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+ CFG_RTS_THRESHOLD,
+ iwm->conf.rts_threshold);
+ if (ret < 0)
+ return ret;
+
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+ CFG_CTS_TO_SELF, iwm->conf.cts_to_self);
+ if (ret < 0)
+ return ret;
+
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+ CFG_COEX_MODE, iwm->conf.coexist_mode);
+ if (ret < 0)
+ return ret;
+
+ /*
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+ CFG_ASSOCIATION_TIMEOUT,
+ iwm->conf.assoc_timeout);
+ if (ret < 0)
+ return ret;
+
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+ CFG_ROAM_TIMEOUT,
+ iwm->conf.roam_timeout);
+ if (ret < 0)
+ return ret;
+
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+ CFG_WIRELESS_MODE,
+ WIRELESS_MODE_11A | WIRELESS_MODE_11G);
+ if (ret < 0)
+ return ret;
+ */
+
+ ret = iwm_umac_set_config_var(iwm, CFG_NET_ADDR,
+ iwm_to_ndev(iwm)->dev_addr, ETH_ALEN);
+ if (ret < 0)
+ return ret;
+
+ /* UMAC PM static configurations */
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+ CFG_PM_LEGACY_RX_TIMEOUT, 0x12C);
+ if (ret < 0)
+ return ret;
+
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+ CFG_PM_LEGACY_TX_TIMEOUT, 0x15E);
+ if (ret < 0)
+ return ret;
+
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+ CFG_PM_CTRL_FLAGS, 0x30001);
+ if (ret < 0)
+ return ret;
+
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+ CFG_PM_KEEP_ALIVE_IN_BEACONS, 0x80);
+ if (ret < 0)
+ return ret;
+
+ /* reset UMAC */
+ ret = iwm_send_umac_reset(iwm, reset_flags, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_RESET, IWM_SRC_UMAC,
+ WAIT_NOTIF_TIMEOUT);
+ if (ret) {
+ IWM_ERR(iwm, "Wait for UMAC RESET timeout\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id)
+{
+ struct iwm_udma_wifi_cmd udma_cmd;
+ struct iwm_umac_cmd umac_cmd;
+ struct iwm_tx_info *tx_info = skb_to_tx_info(skb);
+
+ udma_cmd.eop = 1; /* always set eop for non-concatenated Tx */
+ udma_cmd.credit_group = pool_id;
+ udma_cmd.ra_tid = tx_info->sta << 4 | tx_info->tid;
+ udma_cmd.lmac_offset = 0;
+
+ umac_cmd.id = REPLY_TX;
+ umac_cmd.color = tx_info->color;
+ umac_cmd.resp = 0;
+
+ return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd,
+ skb->data, skb->len);
+}
+
+static int iwm_target_read(struct iwm_priv *iwm, __le32 address,
+ u8 *response, u32 resp_size)
+{
+ struct iwm_udma_nonwifi_cmd target_cmd;
+ struct iwm_nonwifi_cmd *cmd;
+ u16 seq_num;
+ int ret = 0;
+
+ target_cmd.opcode = UMAC_HDI_OUT_OPCODE_READ;
+ target_cmd.addr = address;
+ target_cmd.op1_sz = cpu_to_le32(resp_size);
+ target_cmd.op2 = 0;
+ target_cmd.handle_by_hw = 0;
+ target_cmd.resp = 1;
+ target_cmd.eop = 1;
+
+ ret = iwm_hal_send_target_cmd(iwm, &target_cmd, NULL);
+ if (ret < 0)
+ IWM_ERR(iwm, "Couldn't send READ command\n");
+
+ /* When succeding, the send_target routine returns the seq number */
+ seq_num = ret;
+
+ ret = wait_event_interruptible_timeout(iwm->nonwifi_queue,
+ (cmd = iwm_get_pending_nonwifi_cmd(iwm, seq_num,
+ UMAC_HDI_OUT_OPCODE_READ)) != NULL,
+ 2 * HZ);
+
+ if (!ret) {
+ IWM_ERR(iwm, "Didn't receive a target READ answer\n");
+ return ret;
+ }
+
+ memcpy(response, cmd->buf.hdr + sizeof(struct iwm_udma_in_hdr),
+ resp_size);
+
+ kfree(cmd);
+
+ return ret;
+}
+
+int iwm_read_mac(struct iwm_priv *iwm, u8 *mac)
+{
+ int ret;
+ u8 mac_align[ALIGN(ETH_ALEN, 8)];
+
+ ret = iwm_target_read(iwm, cpu_to_le32(WICO_MAC_ADDRESS_ADDR),
+ mac_align, sizeof(mac_align));
+ if (ret < 0)
+ return ret;
+
+ if (is_valid_ether_addr(mac_align))
+ memcpy(mac, mac_align, ETH_ALEN);
+ else {
+ IWM_ERR(iwm, "Invalid EEPROM MAC\n");
+ memcpy(mac, iwm->conf.mac_addr, ETH_ALEN);
+ get_random_bytes(&mac[3], 3);
+ }
+
+ return 0;
+}
+
+int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx)
+{
+ struct iwm_umac_tx_key_id tx_key_id;
+
+ if (!iwm->default_key || !iwm->default_key->in_use)
+ return -EINVAL;
+
+ tx_key_id.hdr.oid = UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID;
+ tx_key_id.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_tx_key_id) -
+ sizeof(struct iwm_umac_wifi_if));
+
+ tx_key_id.key_idx = key_idx;
+
+ return iwm_send_wifi_if_cmd(iwm, &tx_key_id, sizeof(tx_key_id), 1);
+}
+
+static int iwm_check_profile(struct iwm_priv *iwm)
+{
+ if (!iwm->umac_profile_active)
+ return -EAGAIN;
+
+ if (iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_WEP_40 &&
+ iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_WEP_104 &&
+ iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_TKIP &&
+ iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_CCMP) {
+ IWM_ERR(iwm, "Wrong unicast cipher: 0x%x\n",
+ iwm->umac_profile->sec.ucast_cipher);
+ return -EAGAIN;
+ }
+
+ if (iwm->umac_profile->sec.mcast_cipher != UMAC_CIPHER_TYPE_WEP_40 &&
+ iwm->umac_profile->sec.mcast_cipher != UMAC_CIPHER_TYPE_WEP_104 &&
+ iwm->umac_profile->sec.mcast_cipher != UMAC_CIPHER_TYPE_TKIP &&
+ iwm->umac_profile->sec.mcast_cipher != UMAC_CIPHER_TYPE_CCMP) {
+ IWM_ERR(iwm, "Wrong multicast cipher: 0x%x\n",
+ iwm->umac_profile->sec.mcast_cipher);
+ return -EAGAIN;
+ }
+
+ if ((iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_40 ||
+ iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_104) &&
+ (iwm->umac_profile->sec.ucast_cipher !=
+ iwm->umac_profile->sec.mcast_cipher)) {
+ IWM_ERR(iwm, "Unicast and multicast ciphers differ for WEP\n");
+ }
+
+ return 0;
+}
+
+int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
+ struct iwm_key *key)
+{
+ int ret;
+ u8 cmd[64], *sta_addr, *key_data, key_len;
+ s8 key_idx;
+ u16 cmd_size = 0;
+ struct iwm_umac_key_hdr *key_hdr = &key->hdr;
+ struct iwm_umac_key_wep40 *wep40 = (struct iwm_umac_key_wep40 *)cmd;
+ struct iwm_umac_key_wep104 *wep104 = (struct iwm_umac_key_wep104 *)cmd;
+ struct iwm_umac_key_tkip *tkip = (struct iwm_umac_key_tkip *)cmd;
+ struct iwm_umac_key_ccmp *ccmp = (struct iwm_umac_key_ccmp *)cmd;
+
+ if (set_tx_key)
+ iwm->default_key = key;
+
+ /*
+ * We check if our current profile is valid.
+ * If not, we dont push the key, we just cache them,
+ * so that with the next siwsessid call, the keys
+ * will be actually pushed.
+ */
+ if (!remove) {
+ ret = iwm_check_profile(iwm);
+ if (ret < 0)
+ return ret;
+ }
+
+ sta_addr = key->hdr.mac;
+ key_data = key->key;
+ key_len = key->key_len;
+ key_idx = key->hdr.key_idx;
+
+ if (!remove) {
+ IWM_DBG_WEXT(iwm, DBG, "key_idx:%d set tx key:%d\n",
+ key_idx, set_tx_key);
+ IWM_DBG_WEXT(iwm, DBG, "key_len:%d\n", key_len);
+ IWM_DBG_WEXT(iwm, DBG, "MAC:%pM, idx:%d, multicast:%d\n",
+ key_hdr->mac, key_hdr->key_idx, key_hdr->multicast);
+
+ IWM_DBG_WEXT(iwm, DBG, "profile: mcast:0x%x, ucast:0x%x\n",
+ iwm->umac_profile->sec.mcast_cipher,
+ iwm->umac_profile->sec.ucast_cipher);
+ IWM_DBG_WEXT(iwm, DBG, "profile: auth_type:0x%x, flags:0x%x\n",
+ iwm->umac_profile->sec.auth_type,
+ iwm->umac_profile->sec.flags);
+
+ switch (key->alg) {
+ case UMAC_CIPHER_TYPE_WEP_40:
+ wep40->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP40_KEY;
+ wep40->hdr.buf_size =
+ cpu_to_le16(sizeof(struct iwm_umac_key_wep40) -
+ sizeof(struct iwm_umac_wifi_if));
+
+ memcpy(&wep40->key_hdr, key_hdr,
+ sizeof(struct iwm_umac_key_hdr));
+ memcpy(wep40->key, key_data, key_len);
+ wep40->static_key = 1;
+
+ cmd_size = sizeof(struct iwm_umac_key_wep40);
+ break;
+
+ case UMAC_CIPHER_TYPE_WEP_104:
+ wep104->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP104_KEY;
+ wep104->hdr.buf_size =
+ cpu_to_le16(sizeof(struct iwm_umac_key_wep104) -
+ sizeof(struct iwm_umac_wifi_if));
+
+ memcpy(&wep104->key_hdr, key_hdr,
+ sizeof(struct iwm_umac_key_hdr));
+ memcpy(wep104->key, key_data, key_len);
+ wep104->static_key = 1;
+
+ cmd_size = sizeof(struct iwm_umac_key_wep104);
+ break;
+
+ case UMAC_CIPHER_TYPE_CCMP:
+ key_hdr->key_idx++;
+ ccmp->hdr.oid = UMAC_WIFI_IF_CMD_ADD_CCMP_KEY;
+ ccmp->hdr.buf_size =
+ cpu_to_le16(sizeof(struct iwm_umac_key_ccmp) -
+ sizeof(struct iwm_umac_wifi_if));
+
+ memcpy(&ccmp->key_hdr, key_hdr,
+ sizeof(struct iwm_umac_key_hdr));
+
+ memcpy(ccmp->key, key_data, key_len);
+
+ if (key->flags & IW_ENCODE_EXT_RX_SEQ_VALID)
+ memcpy(ccmp->iv_count, key->rx_seq, 6);
+
+ cmd_size = sizeof(struct iwm_umac_key_ccmp);
+ break;
+
+ case UMAC_CIPHER_TYPE_TKIP:
+ key_hdr->key_idx++;
+ tkip->hdr.oid = UMAC_WIFI_IF_CMD_ADD_TKIP_KEY;
+ tkip->hdr.buf_size =
+ cpu_to_le16(sizeof(struct iwm_umac_key_tkip) -
+ sizeof(struct iwm_umac_wifi_if));
+
+ memcpy(&tkip->key_hdr, key_hdr,
+ sizeof(struct iwm_umac_key_hdr));
+
+ memcpy(tkip->tkip_key, key_data, IWM_TKIP_KEY_SIZE);
+ memcpy(tkip->mic_tx_key, key_data + IWM_TKIP_KEY_SIZE,
+ IWM_TKIP_MIC_SIZE);
+ memcpy(tkip->mic_rx_key,
+ key_data + IWM_TKIP_KEY_SIZE + IWM_TKIP_MIC_SIZE,
+ IWM_TKIP_MIC_SIZE);
+
+ if (key->flags & IW_ENCODE_EXT_RX_SEQ_VALID)
+ memcpy(ccmp->iv_count, key->rx_seq, 6);
+
+ cmd_size = sizeof(struct iwm_umac_key_tkip);
+ break;
+
+ default:
+ return -ENOTSUPP;
+ }
+
+ if ((key->alg == UMAC_CIPHER_TYPE_CCMP) ||
+ (key->alg == UMAC_CIPHER_TYPE_TKIP))
+ /*
+ * UGLY_UGLY_UGLY
+ * Copied HACK from the MWG driver.
+ * Without it, the key is set before the second
+ * EAPOL frame is sent, and the latter is thus
+ * encrypted.
+ */
+ schedule_timeout_interruptible(usecs_to_jiffies(300));
+
+ ret = iwm_send_wifi_if_cmd(iwm, cmd, cmd_size, 1);
+ if (ret < 0)
+ goto err;
+
+ /*
+ * We need a default key only if it is set and
+ * if we're doing WEP.
+ */
+ if (iwm->default_key == key &&
+ ((key->alg == UMAC_CIPHER_TYPE_WEP_40) ||
+ (key->alg == UMAC_CIPHER_TYPE_WEP_104))) {
+ ret = iwm_set_tx_key(iwm, key_idx);
+ if (ret < 0)
+ goto err;
+ }
+ } else {
+ struct iwm_umac_key_remove key_remove;
+
+ key_remove.hdr.oid = UMAC_WIFI_IF_CMD_REMOVE_KEY;
+ key_remove.hdr.buf_size =
+ cpu_to_le16(sizeof(struct iwm_umac_key_remove) -
+ sizeof(struct iwm_umac_wifi_if));
+ memcpy(&key_remove.key_hdr, key_hdr,
+ sizeof(struct iwm_umac_key_hdr));
+
+ ret = iwm_send_wifi_if_cmd(iwm, &key_remove,
+ sizeof(struct iwm_umac_key_remove),
+ 1);
+ if (ret < 0)
+ return ret;
+
+ iwm->keys[key_idx].in_use = 0;
+ }
+
+ return 0;
+
+ err:
+ kfree(key);
+ return ret;
+}
+
+
+int iwm_send_mlme_profile(struct iwm_priv *iwm)
+{
+ int ret, i;
+ struct iwm_umac_profile profile;
+
+ memcpy(&profile, iwm->umac_profile, sizeof(profile));
+
+ profile.hdr.oid = UMAC_WIFI_IF_CMD_SET_PROFILE;
+ profile.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_profile) -
+ sizeof(struct iwm_umac_wifi_if));
+
+ ret = iwm_send_wifi_if_cmd(iwm, &profile, sizeof(profile), 1);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Send profile command failed\n");
+ return ret;
+ }
+
+ /* Wait for the profile to be active */
+ ret = wait_event_interruptible_timeout(iwm->mlme_queue,
+ iwm->umac_profile_active == 1,
+ 3 * HZ);
+ if (!ret)
+ return -EBUSY;
+
+
+ for (i = 0; i < IWM_NUM_KEYS; i++)
+ if (iwm->keys[i].in_use) {
+ int default_key = 0;
+ struct iwm_key *key = &iwm->keys[i];
+
+ if (key == iwm->default_key)
+ default_key = 1;
+
+ /* Wait for the profile before sending the keys */
+ wait_event_interruptible_timeout(iwm->mlme_queue,
+ (test_bit(IWM_STATUS_ASSOCIATING, &iwm->status) ||
+ test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)),
+ 3 * HZ);
+
+ ret = iwm_set_key(iwm, 0, default_key, key);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
+{
+ int ret;
+ struct iwm_umac_invalidate_profile invalid;
+
+ invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE;
+ invalid.hdr.buf_size =
+ cpu_to_le16(sizeof(struct iwm_umac_invalidate_profile) -
+ sizeof(struct iwm_umac_wifi_if));
+
+ invalid.reason = WLAN_REASON_UNSPECIFIED;
+
+ ret = iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1);
+ if (ret < 0)
+ return ret;
+
+ ret = wait_event_interruptible_timeout(iwm->mlme_queue,
+ (iwm->umac_profile_active == 0),
+ 2 * HZ);
+ if (!ret)
+ return -EBUSY;
+
+ return 0;
+}
+
+int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags)
+{
+ struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
+ struct iwm_umac_cmd umac_cmd;
+ struct iwm_umac_cmd_stats_req stats_req;
+
+ stats_req.flags = cpu_to_le32(flags);
+
+ umac_cmd.id = UMAC_CMD_OPCODE_STATISTIC_REQUEST;
+ umac_cmd.resp = 0;
+
+ return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, &stats_req,
+ sizeof(struct iwm_umac_cmd_stats_req));
+}
+
+int iwm_send_umac_channel_list(struct iwm_priv *iwm)
+{
+ struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
+ struct iwm_umac_cmd umac_cmd;
+ struct iwm_umac_cmd_get_channel_list *ch_list;
+ int size = sizeof(struct iwm_umac_cmd_get_channel_list) +
+ sizeof(struct iwm_umac_channel_info) * 4;
+ int ret;
+
+ ch_list = kzalloc(size, GFP_KERNEL);
+ if (!ch_list) {
+ IWM_ERR(iwm, "Couldn't allocate channel list cmd\n");
+ return -ENOMEM;
+ }
+
+ ch_list->ch[0].band = UMAC_BAND_2GHZ;
+ ch_list->ch[0].type = UMAC_CHANNEL_WIDTH_20MHZ;
+ ch_list->ch[0].flags = UMAC_CHANNEL_FLAG_VALID;
+
+ ch_list->ch[1].band = UMAC_BAND_5GHZ;
+ ch_list->ch[1].type = UMAC_CHANNEL_WIDTH_20MHZ;
+ ch_list->ch[1].flags = UMAC_CHANNEL_FLAG_VALID;
+
+ ch_list->ch[2].band = UMAC_BAND_2GHZ;
+ ch_list->ch[2].type = UMAC_CHANNEL_WIDTH_20MHZ;
+ ch_list->ch[2].flags = UMAC_CHANNEL_FLAG_VALID | UMAC_CHANNEL_FLAG_IBSS;
+
+ ch_list->ch[3].band = UMAC_BAND_5GHZ;
+ ch_list->ch[3].type = UMAC_CHANNEL_WIDTH_20MHZ;
+ ch_list->ch[3].flags = UMAC_CHANNEL_FLAG_VALID | UMAC_CHANNEL_FLAG_IBSS;
+
+ ch_list->count = cpu_to_le16(4);
+
+ umac_cmd.id = UMAC_CMD_OPCODE_GET_CHAN_INFO_LIST;
+ umac_cmd.resp = 1;
+
+ ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, ch_list, size);
+
+ kfree(ch_list);
+
+ return ret;
+}
+
+int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids,
+ int ssid_num)
+{
+ struct iwm_umac_cmd_scan_request req;
+ int i, ret;
+
+ memset(&req, 0, sizeof(struct iwm_umac_cmd_scan_request));
+
+ req.hdr.oid = UMAC_WIFI_IF_CMD_SCAN_REQUEST;
+ req.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_cmd_scan_request)
+ - sizeof(struct iwm_umac_wifi_if));
+ req.type = UMAC_WIFI_IF_SCAN_TYPE_USER;
+ req.timeout = 2;
+ req.seq_num = iwm->scan_id;
+ req.ssid_num = min(ssid_num, UMAC_WIFI_IF_PROBE_OPTION_MAX);
+
+ for (i = 0; i < req.ssid_num; i++) {
+ memcpy(req.ssids[i].ssid, ssids[i].ssid, ssids[i].ssid_len);
+ req.ssids[i].ssid_len = ssids[i].ssid_len;
+ }
+
+ ret = iwm_send_wifi_if_cmd(iwm, &req, sizeof(req), 0);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Couldn't send scan request\n");
+ return ret;
+ }
+
+ iwm->scan_id = iwm->scan_id++ % IWM_SCAN_ID_MAX;
+
+ return 0;
+}
+
+int iwm_scan_one_ssid(struct iwm_priv *iwm, u8 *ssid, int ssid_len)
+{
+ struct cfg80211_ssid one_ssid;
+
+ if (test_and_set_bit(IWM_STATUS_SCANNING, &iwm->status))
+ return 0;
+
+ one_ssid.ssid_len = min(ssid_len, IEEE80211_MAX_SSID_LEN);
+ memcpy(&one_ssid.ssid, ssid, one_ssid.ssid_len);
+
+ return iwm_scan_ssids(iwm, &one_ssid, 1);
+}
+
+int iwm_target_reset(struct iwm_priv *iwm)
+{
+ struct iwm_udma_nonwifi_cmd target_cmd;
+
+ target_cmd.opcode = UMAC_HDI_OUT_OPCODE_REBOOT;
+ target_cmd.addr = 0;
+ target_cmd.op1_sz = 0;
+ target_cmd.op2 = 0;
+ target_cmd.handle_by_hw = 0;
+ target_cmd.resp = 0;
+ target_cmd.eop = 1;
+
+ return iwm_hal_send_target_cmd(iwm, &target_cmd, NULL);
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h
new file mode 100644
index 00000000000..36b13a13059
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/commands.h
@@ -0,0 +1,419 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_COMMANDS_H__
+#define __IWM_COMMANDS_H__
+
+#include <linux/ieee80211.h>
+
+#define IWM_BARKER_REBOOT_NOTIFICATION 0xF
+#define IWM_ACK_BARKER_NOTIFICATION 0x10
+
+/* UMAC commands */
+#define UMAC_RST_CTRL_FLG_LARC_CLK_EN 0x0001
+#define UMAC_RST_CTRL_FLG_LARC_RESET 0x0002
+#define UMAC_RST_CTRL_FLG_FUNC_RESET 0x0004
+#define UMAC_RST_CTRL_FLG_DEV_RESET 0x0008
+#define UMAC_RST_CTRL_FLG_WIFI_CORE_EN 0x0010
+#define UMAC_RST_CTRL_FLG_WIFI_LINK_EN 0x0040
+#define UMAC_RST_CTRL_FLG_WIFI_MLME_EN 0x0080
+#define UMAC_RST_CTRL_FLG_NVM_RELOAD 0x0100
+
+struct iwm_umac_cmd_reset {
+ __le32 flags;
+} __attribute__ ((packed));
+
+#define UMAC_PARAM_TBL_ORD_FIX 0x0
+#define UMAC_PARAM_TBL_ORD_VAR 0x1
+#define UMAC_PARAM_TBL_CFG_FIX 0x2
+#define UMAC_PARAM_TBL_CFG_VAR 0x3
+#define UMAC_PARAM_TBL_BSS_TRK 0x4
+#define UMAC_PARAM_TBL_FA_CFG_FIX 0x5
+#define UMAC_PARAM_TBL_STA 0x6
+#define UMAC_PARAM_TBL_CHN 0x7
+#define UMAC_PARAM_TBL_STATISTICS 0x8
+
+/* fast access table */
+enum {
+ CFG_FRAG_THRESHOLD = 0,
+ CFG_FRAME_RETRY_LIMIT,
+ CFG_OS_QUEUE_UTIL_TH,
+ CFG_RX_FILTER,
+ /* <-- LAST --> */
+ FAST_ACCESS_CFG_TBL_FIX_LAST
+};
+
+/* fixed size table */
+enum {
+ CFG_POWER_INDEX = 0,
+ CFG_PM_LEGACY_RX_TIMEOUT,
+ CFG_PM_LEGACY_TX_TIMEOUT,
+ CFG_PM_CTRL_FLAGS,
+ CFG_PM_KEEP_ALIVE_IN_BEACONS,
+ CFG_BT_ON_THRESHOLD,
+ CFG_RTS_THRESHOLD,
+ CFG_CTS_TO_SELF,
+ CFG_COEX_MODE,
+ CFG_WIRELESS_MODE,
+ CFG_ASSOCIATION_TIMEOUT,
+ CFG_ROAM_TIMEOUT,
+ CFG_CAPABILITY_SUPPORTED_RATES,
+ CFG_SCAN_ALLOWED_UNASSOC_FLAGS,
+ CFG_SCAN_ALLOWED_MAIN_ASSOC_FLAGS,
+ CFG_SCAN_ALLOWED_PAN_ASSOC_FLAGS,
+ CFG_SCAN_INTERNAL_PERIODIC_ENABLED,
+ CFG_SCAN_IMM_INTERNAL_PERIODIC_SCAN_ON_INIT,
+ CFG_SCAN_DEFAULT_PERIODIC_FREQ_SEC,
+ CFG_SCAN_NUM_PASSIVE_CHAN_PER_PARTIAL_SCAN,
+ CFG_TLC_SUPPORTED_TX_HT_RATES,
+ CFG_TLC_SUPPORTED_TX_RATES,
+ CFG_TLC_VALID_ANTENNA,
+ CFG_TLC_SPATIAL_STREAM_SUPPORTED,
+ CFG_TLC_RETRY_PER_RATE,
+ CFG_TLC_RETRY_PER_HT_RATE,
+ CFG_TLC_FIXED_RATE,
+ CFG_TLC_FIXED_RATE_FLAGS,
+ CFG_TLC_CONTROL_FLAGS,
+ CFG_TLC_SR_MIN_FAIL,
+ CFG_TLC_SR_MIN_PASS,
+ CFG_TLC_HT_STAY_IN_COL_PASS_THRESH,
+ CFG_TLC_HT_STAY_IN_COL_FAIL_THRESH,
+ CFG_TLC_LEGACY_STAY_IN_COL_PASS_THRESH,
+ CFG_TLC_LEGACY_STAY_IN_COL_FAIL_THRESH,
+ CFG_TLC_HT_FLUSH_STATS_PACKETS,
+ CFG_TLC_LEGACY_FLUSH_STATS_PACKETS,
+ CFG_TLC_LEGACY_FLUSH_STATS_MS,
+ CFG_TLC_HT_FLUSH_STATS_MS,
+ CFG_TLC_STAY_IN_COL_TIME_OUT,
+ CFG_TLC_AGG_SHORT_LIM,
+ CFG_TLC_AGG_LONG_LIM,
+ CFG_TLC_HT_SR_NO_DECREASE,
+ CFG_TLC_LEGACY_SR_NO_DECREASE,
+ CFG_TLC_SR_FORCE_DECREASE,
+ CFG_TLC_SR_ALLOW_INCREASE,
+ CFG_TLC_AGG_SET_LONG,
+ CFG_TLC_AUTO_AGGREGATION,
+ CFG_TLC_AGG_THRESHOLD,
+ CFG_TLC_TID_LOAD_THRESHOLD,
+ CFG_TLC_BLOCK_ACK_TIMEOUT,
+ CFG_TLC_NO_BA_COUNTED_AS_ONE,
+ CFG_TLC_NUM_BA_STREAMS_ALLOWED,
+ CFG_TLC_NUM_BA_STREAMS_PRESENT,
+ CFG_TLC_RENEW_ADDBA_DELAY,
+ CFG_TLC_NUM_OF_MULTISEC_TO_COUN_LOAD,
+ CFG_TLC_IS_STABLE_IN_HT,
+ CFG_RLC_CHAIN_CTRL,
+ CFG_TRK_TABLE_OP_MODE,
+ CFG_TRK_TABLE_RSSI_THRESHOLD,
+ CFG_TX_PWR_TARGET, /* Used By xVT */
+ CFG_TX_PWR_LIMIT_USR,
+ CFG_TX_PWR_LIMIT_BSS, /* 11d limit */
+ CFG_TX_PWR_LIMIT_BSS_CONSTRAINT, /* 11h constraint */
+ CFG_TX_PWR_MODE,
+ CFG_MLME_DBG_NOTIF_BLOCK,
+ CFG_BT_OFF_BECONS_INTERVALS,
+ CFG_BT_FRAG_DURATION,
+
+ /* <-- LAST --> */
+ CFG_TBL_FIX_LAST
+};
+
+/* variable size table */
+enum {
+ CFG_NET_ADDR = 0,
+ CFG_PROFILE,
+ /* <-- LAST --> */
+ CFG_TBL_VAR_LAST
+};
+
+struct iwm_umac_cmd_set_param_fix {
+ __le16 tbl;
+ __le16 key;
+ __le32 value;
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_set_param_var {
+ __le16 tbl;
+ __le16 key;
+ __le16 len;
+ __le16 reserved;
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_get_param {
+ __le16 tbl;
+ __le16 key;
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_get_param_resp {
+ __le16 tbl;
+ __le16 key;
+ __le16 len;
+ __le16 reserved;
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_eeprom_proxy_hdr {
+ __le32 type;
+ __le32 offset;
+ __le32 len;
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_eeprom_proxy {
+ struct iwm_umac_cmd_eeprom_proxy_hdr hdr;
+ u8 buf[0];
+} __attribute__ ((packed));
+
+#define IWM_UMAC_CMD_EEPROM_TYPE_READ 0x1
+#define IWM_UMAC_CMD_EEPROM_TYPE_WRITE 0x2
+
+#define UMAC_CHANNEL_FLAG_VALID BIT(0)
+#define UMAC_CHANNEL_FLAG_IBSS BIT(1)
+#define UMAC_CHANNEL_FLAG_ACTIVE BIT(3)
+#define UMAC_CHANNEL_FLAG_RADAR BIT(4)
+#define UMAC_CHANNEL_FLAG_DFS BIT(7)
+
+struct iwm_umac_channel_info {
+ u8 band;
+ u8 type;
+ u8 reserved;
+ u8 flags;
+ __le32 channels_mask;
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_get_channel_list {
+ __le16 count;
+ __le16 reserved;
+ struct iwm_umac_channel_info ch[0];
+} __attribute__ ((packed));
+
+
+/* UMAC WiFi interface commands */
+
+/* Coexistence mode */
+#define COEX_MODE_SA 0x1
+#define COEX_MODE_XOR 0x2
+#define COEX_MODE_CM 0x3
+#define COEX_MODE_MAX 0x4
+
+/* Wireless mode */
+#define WIRELESS_MODE_11A 0x1
+#define WIRELESS_MODE_11G 0x2
+
+#define UMAC_PROFILE_EX_IE_REQUIRED 0x1
+#define UMAC_PROFILE_QOS_ALLOWED 0x2
+
+/* Scanning */
+#define UMAC_WIFI_IF_PROBE_OPTION_MAX 10
+
+#define UMAC_WIFI_IF_SCAN_TYPE_USER 0x0
+#define UMAC_WIFI_IF_SCAN_TYPE_UMAC_RESERVED 0x1
+#define UMAC_WIFI_IF_SCAN_TYPE_HOST_PERIODIC 0x2
+#define UMAC_WIFI_IF_SCAN_TYPE_MAX 0x3
+
+struct iwm_umac_ssid {
+ u8 ssid_len;
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+ u8 reserved[3];
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_scan_request {
+ struct iwm_umac_wifi_if hdr;
+ __le32 type; /* UMAC_WIFI_IF_SCAN_TYPE_* */
+ u8 ssid_num;
+ u8 seq_num;
+ u8 timeout; /* In seconds */
+ u8 reserved;
+ struct iwm_umac_ssid ssids[UMAC_WIFI_IF_PROBE_OPTION_MAX];
+} __attribute__ ((packed));
+
+#define UMAC_CIPHER_TYPE_NONE 0xFF
+#define UMAC_CIPHER_TYPE_USE_GROUPCAST 0x00
+#define UMAC_CIPHER_TYPE_WEP_40 0x01
+#define UMAC_CIPHER_TYPE_WEP_104 0x02
+#define UMAC_CIPHER_TYPE_TKIP 0x04
+#define UMAC_CIPHER_TYPE_CCMP 0x08
+
+/* Supported authentication types - bitmap */
+#define UMAC_AUTH_TYPE_OPEN 0x00
+#define UMAC_AUTH_TYPE_LEGACY_PSK 0x01
+#define UMAC_AUTH_TYPE_8021X 0x02
+#define UMAC_AUTH_TYPE_RSNA_PSK 0x04
+
+/* iwm_umac_security.flag is WPA supported -- bits[0:0] */
+#define UMAC_SEC_FLG_WPA_ON_POS 0
+#define UMAC_SEC_FLG_WPA_ON_SEED 1
+#define UMAC_SEC_FLG_WPA_ON_MSK (UMAC_SEC_FLG_WPA_ON_SEED << \
+ UMAC_SEC_FLG_WPA_ON_POS)
+
+/* iwm_umac_security.flag is WPA2 supported -- bits [1:1] */
+#define UMAC_SEC_FLG_RSNA_ON_POS 1
+#define UMAC_SEC_FLG_RSNA_ON_SEED 1
+#define UMAC_SEC_FLG_RSNA_ON_MSK (UMAC_SEC_FLG_RSNA_ON_SEED << \
+ UMAC_SEC_FLG_RSNA_ON_POS)
+
+/* iwm_umac_security.flag is WSC mode on -- bits [2:2] */
+#define UMAC_SEC_FLG_WSC_ON_POS 2
+#define UMAC_SEC_FLG_WSC_ON_SEED 1
+
+/* Legacy profile can use only WEP40 and WEP104 for encryption and
+ * OPEN or PSK for authentication */
+#define UMAC_SEC_FLG_LEGACY_PROFILE 0
+
+struct iwm_umac_security {
+ u8 auth_type;
+ u8 ucast_cipher;
+ u8 mcast_cipher;
+ u8 flags;
+} __attribute__ ((packed));
+
+struct iwm_umac_ibss {
+ u8 beacon_interval; /* in millisecond */
+ u8 atim; /* in millisecond */
+ s8 join_only;
+ u8 band;
+ u8 channel;
+ u8 reserved[3];
+} __attribute__ ((packed));
+
+#define UMAC_MODE_BSS 0
+#define UMAC_MODE_IBSS 1
+
+#define UMAC_BSSID_MAX 4
+
+struct iwm_umac_profile {
+ struct iwm_umac_wifi_if hdr;
+ __le32 mode;
+ struct iwm_umac_ssid ssid;
+ u8 bssid[UMAC_BSSID_MAX][ETH_ALEN];
+ struct iwm_umac_security sec;
+ struct iwm_umac_ibss ibss;
+ __le32 channel_2ghz;
+ __le32 channel_5ghz;
+ __le16 flags;
+ u8 wireless_mode;
+ u8 bss_num;
+} __attribute__ ((packed));
+
+struct iwm_umac_invalidate_profile {
+ struct iwm_umac_wifi_if hdr;
+ u8 reason;
+ u8 reserved[3];
+} __attribute__ ((packed));
+
+/* Encryption key commands */
+struct iwm_umac_key_wep40 {
+ struct iwm_umac_wifi_if hdr;
+ struct iwm_umac_key_hdr key_hdr;
+ u8 key[WLAN_KEY_LEN_WEP40];
+ u8 static_key;
+ u8 reserved[2];
+} __attribute__ ((packed));
+
+struct iwm_umac_key_wep104 {
+ struct iwm_umac_wifi_if hdr;
+ struct iwm_umac_key_hdr key_hdr;
+ u8 key[WLAN_KEY_LEN_WEP104];
+ u8 static_key;
+ u8 reserved[2];
+} __attribute__ ((packed));
+
+#define IWM_TKIP_KEY_SIZE 16
+#define IWM_TKIP_MIC_SIZE 8
+struct iwm_umac_key_tkip {
+ struct iwm_umac_wifi_if hdr;
+ struct iwm_umac_key_hdr key_hdr;
+ u8 iv_count[6];
+ u8 reserved[2];
+ u8 tkip_key[IWM_TKIP_KEY_SIZE];
+ u8 mic_rx_key[IWM_TKIP_MIC_SIZE];
+ u8 mic_tx_key[IWM_TKIP_MIC_SIZE];
+} __attribute__ ((packed));
+
+struct iwm_umac_key_ccmp {
+ struct iwm_umac_wifi_if hdr;
+ struct iwm_umac_key_hdr key_hdr;
+ u8 iv_count[6];
+ u8 reserved[2];
+ u8 key[WLAN_KEY_LEN_CCMP];
+} __attribute__ ((packed));
+
+struct iwm_umac_key_remove {
+ struct iwm_umac_wifi_if hdr;
+ struct iwm_umac_key_hdr key_hdr;
+} __attribute__ ((packed));
+
+struct iwm_umac_tx_key_id {
+ struct iwm_umac_wifi_if hdr;
+ u8 key_idx;
+ u8 reserved[3];
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_stats_req {
+ __le32 flags;
+} __attribute__ ((packed));
+
+/* LMAC commands */
+int iwm_read_mac(struct iwm_priv *iwm, u8 *mac);
+int iwm_send_prio_table(struct iwm_priv *iwm);
+int iwm_send_init_calib_cfg(struct iwm_priv *iwm, u8 calib_requested);
+int iwm_send_periodic_calib_cfg(struct iwm_priv *iwm, u8 calib_requested);
+int iwm_send_calib_results(struct iwm_priv *iwm);
+int iwm_store_rxiq_calib_result(struct iwm_priv *iwm);
+
+/* UMAC commands */
+int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size,
+ bool resp);
+int iwm_send_umac_reset(struct iwm_priv *iwm, __le32 reset_flags, bool resp);
+int iwm_umac_set_config_fix(struct iwm_priv *iwm, u16 tbl, u16 key, u32 value);
+int iwm_umac_set_config_var(struct iwm_priv *iwm, u16 key,
+ void *payload, u16 payload_size);
+int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags);
+int iwm_send_mlme_profile(struct iwm_priv *iwm);
+int iwm_invalidate_mlme_profile(struct iwm_priv *iwm);
+int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id);
+int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx);
+int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
+ struct iwm_key *key);
+int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags);
+int iwm_send_umac_channel_list(struct iwm_priv *iwm);
+int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids,
+ int ssid_num);
+int iwm_scan_one_ssid(struct iwm_priv *iwm, u8 *ssid, int ssid_len);
+
+/* UDMA commands */
+int iwm_target_reset(struct iwm_priv *iwm);
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/debug.h b/drivers/net/wireless/iwmc3200wifi/debug.h
new file mode 100644
index 00000000000..8fbb42d9c21
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/debug.h
@@ -0,0 +1,124 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef __IWM_DEBUG_H__
+#define __IWM_DEBUG_H__
+
+#define IWM_ERR(p, f, a...) dev_err(iwm_to_dev(p), f, ## a)
+#define IWM_WARN(p, f, a...) dev_warn(iwm_to_dev(p), f, ## a)
+#define IWM_INFO(p, f, a...) dev_info(iwm_to_dev(p), f, ## a)
+#define IWM_CRIT(p, f, a...) dev_crit(iwm_to_dev(p), f, ## a)
+
+#ifdef CONFIG_IWM_DEBUG
+
+#define IWM_DEBUG_MODULE(i, level, module, f, a...) \
+do { \
+ if (unlikely(i->dbg.dbg_module[IWM_DM_##module] >= (IWM_DL_##level)))\
+ dev_printk(KERN_INFO, (iwm_to_dev(i)), \
+ "%s " f, __func__ , ## a); \
+} while (0)
+
+#define IWM_HEXDUMP(i, level, module, pref, buf, len) \
+do { \
+ if (unlikely(i->dbg.dbg_module[IWM_DM_##module] >= (IWM_DL_##level)))\
+ print_hex_dump(KERN_INFO, pref, DUMP_PREFIX_OFFSET, \
+ 16, 1, buf, len, 1); \
+} while (0)
+
+#else
+
+#define IWM_DEBUG_MODULE(i, level, module, f, a...)
+#define IWM_HEXDUMP(i, level, module, pref, buf, len)
+
+#endif /* CONFIG_IWM_DEBUG */
+
+/* Debug modules */
+enum iwm_debug_module_id {
+ IWM_DM_BOOT = 0,
+ IWM_DM_FW,
+ IWM_DM_SDIO,
+ IWM_DM_NTF,
+ IWM_DM_RX,
+ IWM_DM_TX,
+ IWM_DM_MLME,
+ IWM_DM_CMD,
+ IWM_DM_WEXT,
+ __IWM_DM_NR,
+};
+#define IWM_DM_DEFAULT 0
+
+#define IWM_DBG_BOOT(i, l, f, a...) IWM_DEBUG_MODULE(i, l, BOOT, f, ## a)
+#define IWM_DBG_FW(i, l, f, a...) IWM_DEBUG_MODULE(i, l, FW, f, ## a)
+#define IWM_DBG_SDIO(i, l, f, a...) IWM_DEBUG_MODULE(i, l, SDIO, f, ## a)
+#define IWM_DBG_NTF(i, l, f, a...) IWM_DEBUG_MODULE(i, l, NTF, f, ## a)
+#define IWM_DBG_RX(i, l, f, a...) IWM_DEBUG_MODULE(i, l, RX, f, ## a)
+#define IWM_DBG_TX(i, l, f, a...) IWM_DEBUG_MODULE(i, l, TX, f, ## a)
+#define IWM_DBG_MLME(i, l, f, a...) IWM_DEBUG_MODULE(i, l, MLME, f, ## a)
+#define IWM_DBG_CMD(i, l, f, a...) IWM_DEBUG_MODULE(i, l, CMD, f, ## a)
+#define IWM_DBG_WEXT(i, l, f, a...) IWM_DEBUG_MODULE(i, l, WEXT, f, ## a)
+
+/* Debug levels */
+enum iwm_debug_level {
+ IWM_DL_NONE = 0,
+ IWM_DL_ERR,
+ IWM_DL_WARN,
+ IWM_DL_INFO,
+ IWM_DL_DBG,
+};
+#define IWM_DL_DEFAULT IWM_DL_ERR
+
+struct iwm_debugfs {
+ struct iwm_priv *iwm;
+ struct dentry *rootdir;
+ struct dentry *devdir;
+ struct dentry *dbgdir;
+ struct dentry *txdir;
+ struct dentry *rxdir;
+ struct dentry *busdir;
+
+ u32 dbg_level;
+ struct dentry *dbg_level_dentry;
+
+ unsigned long dbg_modules;
+ struct dentry *dbg_modules_dentry;
+
+ u8 dbg_module[__IWM_DM_NR];
+ struct dentry *dbg_module_dentries[__IWM_DM_NR];
+
+ struct dentry *txq_dentry;
+ struct dentry *tx_credit_dentry;
+ struct dentry *rx_ticket_dentry;
+};
+
+#ifdef CONFIG_IWM_DEBUG
+int iwm_debugfs_init(struct iwm_priv *iwm);
+void iwm_debugfs_exit(struct iwm_priv *iwm);
+#else
+static inline int iwm_debugfs_init(struct iwm_priv *iwm)
+{
+ return 0;
+}
+static inline void iwm_debugfs_exit(struct iwm_priv *iwm) {}
+#endif
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c
new file mode 100644
index 00000000000..0fa7b9150d5
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c
@@ -0,0 +1,453 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/debugfs.h>
+
+#include "iwm.h"
+#include "bus.h"
+#include "rx.h"
+#include "debug.h"
+
+static struct {
+ u8 id;
+ char *name;
+} iwm_debug_module[__IWM_DM_NR] = {
+ {IWM_DM_BOOT, "boot"},
+ {IWM_DM_FW, "fw"},
+ {IWM_DM_SDIO, "sdio"},
+ {IWM_DM_NTF, "ntf"},
+ {IWM_DM_RX, "rx"},
+ {IWM_DM_TX, "tx"},
+ {IWM_DM_MLME, "mlme"},
+ {IWM_DM_CMD, "cmd"},
+ {IWM_DM_WEXT, "wext"},
+};
+
+#define add_dbg_module(dbg, name, id, initlevel) \
+do { \
+ struct dentry *d; \
+ dbg.dbg_module[id] = (initlevel); \
+ d = debugfs_create_x8(name, 0600, dbg.dbgdir, \
+ &(dbg.dbg_module[id])); \
+ if (!IS_ERR(d)) \
+ dbg.dbg_module_dentries[id] = d; \
+} while (0)
+
+static int iwm_debugfs_u32_read(void *data, u64 *val)
+{
+ struct iwm_priv *iwm = data;
+
+ *val = iwm->dbg.dbg_level;
+ return 0;
+}
+
+static int iwm_debugfs_dbg_level_write(void *data, u64 val)
+{
+ struct iwm_priv *iwm = data;
+ int i;
+
+ iwm->dbg.dbg_level = val;
+
+ for (i = 0; i < __IWM_DM_NR; i++)
+ iwm->dbg.dbg_module[i] = val;
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_iwm_dbg_level,
+ iwm_debugfs_u32_read, iwm_debugfs_dbg_level_write,
+ "%llu\n");
+
+static int iwm_debugfs_dbg_modules_write(void *data, u64 val)
+{
+ struct iwm_priv *iwm = data;
+ int i, bit;
+
+ iwm->dbg.dbg_modules = val;
+
+ for (i = 0; i < __IWM_DM_NR; i++)
+ iwm->dbg.dbg_module[i] = 0;
+
+ for_each_bit(bit, &iwm->dbg.dbg_modules, __IWM_DM_NR)
+ iwm->dbg.dbg_module[bit] = iwm->dbg.dbg_level;
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_iwm_dbg_modules,
+ iwm_debugfs_u32_read, iwm_debugfs_dbg_modules_write,
+ "%llu\n");
+
+static int iwm_txrx_open(struct inode *inode, struct file *filp)
+{
+ filp->private_data = inode->i_private;
+ return 0;
+}
+
+
+static ssize_t iwm_debugfs_txq_read(struct file *filp, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct iwm_priv *iwm = filp->private_data;
+ char *buf;
+ int i, buf_len = 4096;
+ size_t len = 0;
+ ssize_t ret;
+
+ if (*ppos != 0)
+ return 0;
+ if (count < sizeof(buf))
+ return -ENOSPC;
+
+ buf = kzalloc(buf_len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ for (i = 0; i < IWM_TX_QUEUES; i++) {
+ struct iwm_tx_queue *txq = &iwm->txq[i];
+ struct sk_buff *skb;
+ int j;
+ unsigned long flags;
+
+ spin_lock_irqsave(&txq->queue.lock, flags);
+
+ skb = (struct sk_buff *)&txq->queue;
+
+ len += snprintf(buf + len, buf_len - len, "TXQ #%d\n", i);
+ len += snprintf(buf + len, buf_len - len, "\tStopped: %d\n",
+ __netif_subqueue_stopped(iwm_to_ndev(iwm),
+ txq->id));
+ len += snprintf(buf + len, buf_len - len, "\tConcat count:%d\n",
+ txq->concat_count);
+ len += snprintf(buf + len, buf_len - len, "\tQueue len: %d\n",
+ skb_queue_len(&txq->queue));
+ for (j = 0; j < skb_queue_len(&txq->queue); j++) {
+ struct iwm_tx_info *tx_info;
+
+ skb = skb->next;
+ tx_info = skb_to_tx_info(skb);
+
+ len += snprintf(buf + len, buf_len - len,
+ "\tSKB #%d\n", j);
+ len += snprintf(buf + len, buf_len - len,
+ "\t\tsta: %d\n", tx_info->sta);
+ len += snprintf(buf + len, buf_len - len,
+ "\t\tcolor: %d\n", tx_info->color);
+ len += snprintf(buf + len, buf_len - len,
+ "\t\ttid: %d\n", tx_info->tid);
+ }
+
+ spin_unlock_irqrestore(&txq->queue.lock, flags);
+ }
+
+ ret = simple_read_from_buffer(buffer, len, ppos, buf, buf_len);
+ kfree(buf);
+
+ return ret;
+}
+
+static ssize_t iwm_debugfs_tx_credit_read(struct file *filp,
+ char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct iwm_priv *iwm = filp->private_data;
+ struct iwm_tx_credit *credit = &iwm->tx_credit;
+ char *buf;
+ int i, buf_len = 4096;
+ size_t len = 0;
+ ssize_t ret;
+
+ if (*ppos != 0)
+ return 0;
+ if (count < sizeof(buf))
+ return -ENOSPC;
+
+ buf = kzalloc(buf_len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ len += snprintf(buf + len, buf_len - len,
+ "NR pools: %d\n", credit->pool_nr);
+ len += snprintf(buf + len, buf_len - len,
+ "pools map: 0x%lx\n", credit->full_pools_map);
+
+ len += snprintf(buf + len, buf_len - len, "\n### POOLS ###\n");
+ for (i = 0; i < IWM_MACS_OUT_GROUPS; i++) {
+ len += snprintf(buf + len, buf_len - len,
+ "pools entry #%d\n", i);
+ len += snprintf(buf + len, buf_len - len,
+ "\tid: %d\n",
+ credit->pools[i].id);
+ len += snprintf(buf + len, buf_len - len,
+ "\tsid: %d\n",
+ credit->pools[i].sid);
+ len += snprintf(buf + len, buf_len - len,
+ "\tmin_pages: %d\n",
+ credit->pools[i].min_pages);
+ len += snprintf(buf + len, buf_len - len,
+ "\tmax_pages: %d\n",
+ credit->pools[i].max_pages);
+ len += snprintf(buf + len, buf_len - len,
+ "\talloc_pages: %d\n",
+ credit->pools[i].alloc_pages);
+ len += snprintf(buf + len, buf_len - len,
+ "\tfreed_pages: %d\n",
+ credit->pools[i].total_freed_pages);
+ }
+
+ len += snprintf(buf + len, buf_len - len, "\n### SPOOLS ###\n");
+ for (i = 0; i < IWM_MACS_OUT_SGROUPS; i++) {
+ len += snprintf(buf + len, buf_len - len,
+ "spools entry #%d\n", i);
+ len += snprintf(buf + len, buf_len - len,
+ "\tid: %d\n",
+ credit->spools[i].id);
+ len += snprintf(buf + len, buf_len - len,
+ "\tmax_pages: %d\n",
+ credit->spools[i].max_pages);
+ len += snprintf(buf + len, buf_len - len,
+ "\talloc_pages: %d\n",
+ credit->spools[i].alloc_pages);
+
+ }
+
+ ret = simple_read_from_buffer(buffer, len, ppos, buf, buf_len);
+ kfree(buf);
+
+ return ret;
+}
+
+static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp,
+ char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct iwm_priv *iwm = filp->private_data;
+ struct iwm_rx_ticket_node *ticket, *next;
+ char *buf;
+ int buf_len = 4096, i;
+ size_t len = 0;
+ ssize_t ret;
+
+ if (*ppos != 0)
+ return 0;
+ if (count < sizeof(buf))
+ return -ENOSPC;
+
+ buf = kzalloc(buf_len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) {
+ len += snprintf(buf + len, buf_len - len, "Ticket #%d\n",
+ ticket->ticket->id);
+ len += snprintf(buf + len, buf_len - len, "\taction: 0x%x\n",
+ ticket->ticket->action);
+ len += snprintf(buf + len, buf_len - len, "\tflags: 0x%x\n",
+ ticket->ticket->flags);
+ }
+
+ for (i = 0; i < IWM_RX_ID_HASH; i++) {
+ struct iwm_rx_packet *packet, *nxt;
+ struct list_head *pkt_list = &iwm->rx_packets[i];
+ if (!list_empty(pkt_list)) {
+ len += snprintf(buf + len, buf_len - len,
+ "Packet hash #%d\n", i);
+ list_for_each_entry_safe(packet, nxt, pkt_list, node) {
+ len += snprintf(buf + len, buf_len - len,
+ "\tPacket id: %d\n",
+ packet->id);
+ len += snprintf(buf + len, buf_len - len,
+ "\tPacket length: %lu\n",
+ packet->pkt_size);
+ }
+ }
+ }
+
+ ret = simple_read_from_buffer(buffer, len, ppos, buf, buf_len);
+ kfree(buf);
+
+ return ret;
+}
+
+
+static const struct file_operations iwm_debugfs_txq_fops = {
+ .owner = THIS_MODULE,
+ .open = iwm_txrx_open,
+ .read = iwm_debugfs_txq_read,
+};
+
+static const struct file_operations iwm_debugfs_tx_credit_fops = {
+ .owner = THIS_MODULE,
+ .open = iwm_txrx_open,
+ .read = iwm_debugfs_tx_credit_read,
+};
+
+static const struct file_operations iwm_debugfs_rx_ticket_fops = {
+ .owner = THIS_MODULE,
+ .open = iwm_txrx_open,
+ .read = iwm_debugfs_rx_ticket_read,
+};
+
+int iwm_debugfs_init(struct iwm_priv *iwm)
+{
+ int i, result;
+ char devdir[16];
+
+ iwm->dbg.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+ result = PTR_ERR(iwm->dbg.rootdir);
+ if (!result || IS_ERR(iwm->dbg.rootdir)) {
+ if (result == -ENODEV) {
+ IWM_ERR(iwm, "DebugFS (CONFIG_DEBUG_FS) not "
+ "enabled in kernel config\n");
+ result = 0; /* No debugfs support */
+ }
+ IWM_ERR(iwm, "Couldn't create rootdir: %d\n", result);
+ goto error;
+ }
+
+ snprintf(devdir, sizeof(devdir), "%s", wiphy_name(iwm_to_wiphy(iwm)));
+
+ iwm->dbg.devdir = debugfs_create_dir(devdir, iwm->dbg.rootdir);
+ result = PTR_ERR(iwm->dbg.devdir);
+ if (IS_ERR(iwm->dbg.devdir) && (result != -ENODEV)) {
+ IWM_ERR(iwm, "Couldn't create devdir: %d\n", result);
+ goto error;
+ }
+
+ iwm->dbg.dbgdir = debugfs_create_dir("debug", iwm->dbg.devdir);
+ result = PTR_ERR(iwm->dbg.dbgdir);
+ if (IS_ERR(iwm->dbg.dbgdir) && (result != -ENODEV)) {
+ IWM_ERR(iwm, "Couldn't create dbgdir: %d\n", result);
+ goto error;
+ }
+
+ iwm->dbg.rxdir = debugfs_create_dir("rx", iwm->dbg.devdir);
+ result = PTR_ERR(iwm->dbg.rxdir);
+ if (IS_ERR(iwm->dbg.rxdir) && (result != -ENODEV)) {
+ IWM_ERR(iwm, "Couldn't create rx dir: %d\n", result);
+ goto error;
+ }
+
+ iwm->dbg.txdir = debugfs_create_dir("tx", iwm->dbg.devdir);
+ result = PTR_ERR(iwm->dbg.txdir);
+ if (IS_ERR(iwm->dbg.txdir) && (result != -ENODEV)) {
+ IWM_ERR(iwm, "Couldn't create tx dir: %d\n", result);
+ goto error;
+ }
+
+ iwm->dbg.busdir = debugfs_create_dir("bus", iwm->dbg.devdir);
+ result = PTR_ERR(iwm->dbg.busdir);
+ if (IS_ERR(iwm->dbg.busdir) && (result != -ENODEV)) {
+ IWM_ERR(iwm, "Couldn't create bus dir: %d\n", result);
+ goto error;
+ }
+
+ if (iwm->bus_ops->debugfs_init) {
+ result = iwm->bus_ops->debugfs_init(iwm, iwm->dbg.busdir);
+ if (result < 0) {
+ IWM_ERR(iwm, "Couldn't create bus entry: %d\n", result);
+ goto error;
+ }
+ }
+
+
+ iwm->dbg.dbg_level = IWM_DL_NONE;
+ iwm->dbg.dbg_level_dentry =
+ debugfs_create_file("level", 0200, iwm->dbg.dbgdir, iwm,
+ &fops_iwm_dbg_level);
+ result = PTR_ERR(iwm->dbg.dbg_level_dentry);
+ if (IS_ERR(iwm->dbg.dbg_level_dentry) && (result != -ENODEV)) {
+ IWM_ERR(iwm, "Couldn't create dbg_level: %d\n", result);
+ goto error;
+ }
+
+
+ iwm->dbg.dbg_modules = IWM_DM_DEFAULT;
+ iwm->dbg.dbg_modules_dentry =
+ debugfs_create_file("modules", 0200, iwm->dbg.dbgdir, iwm,
+ &fops_iwm_dbg_modules);
+ result = PTR_ERR(iwm->dbg.dbg_modules_dentry);
+ if (IS_ERR(iwm->dbg.dbg_modules_dentry) && (result != -ENODEV)) {
+ IWM_ERR(iwm, "Couldn't create dbg_modules: %d\n", result);
+ goto error;
+ }
+
+ for (i = 0; i < __IWM_DM_NR; i++)
+ add_dbg_module(iwm->dbg, iwm_debug_module[i].name,
+ iwm_debug_module[i].id, IWM_DL_DEFAULT);
+
+ iwm->dbg.txq_dentry = debugfs_create_file("queues", 0200,
+ iwm->dbg.txdir, iwm,
+ &iwm_debugfs_txq_fops);
+ result = PTR_ERR(iwm->dbg.txq_dentry);
+ if (IS_ERR(iwm->dbg.txq_dentry) && (result != -ENODEV)) {
+ IWM_ERR(iwm, "Couldn't create tx queue: %d\n", result);
+ goto error;
+ }
+
+ iwm->dbg.tx_credit_dentry = debugfs_create_file("credits", 0200,
+ iwm->dbg.txdir, iwm,
+ &iwm_debugfs_tx_credit_fops);
+ result = PTR_ERR(iwm->dbg.tx_credit_dentry);
+ if (IS_ERR(iwm->dbg.tx_credit_dentry) && (result != -ENODEV)) {
+ IWM_ERR(iwm, "Couldn't create tx credit: %d\n", result);
+ goto error;
+ }
+
+ iwm->dbg.rx_ticket_dentry = debugfs_create_file("tickets", 0200,
+ iwm->dbg.rxdir, iwm,
+ &iwm_debugfs_rx_ticket_fops);
+ result = PTR_ERR(iwm->dbg.rx_ticket_dentry);
+ if (IS_ERR(iwm->dbg.rx_ticket_dentry) && (result != -ENODEV)) {
+ IWM_ERR(iwm, "Couldn't create rx ticket: %d\n", result);
+ goto error;
+ }
+
+ return 0;
+
+ error:
+ return result;
+}
+
+void iwm_debugfs_exit(struct iwm_priv *iwm)
+{
+ int i;
+
+ for (i = 0; i < __IWM_DM_NR; i++)
+ debugfs_remove(iwm->dbg.dbg_module_dentries[i]);
+
+ debugfs_remove(iwm->dbg.dbg_modules_dentry);
+ debugfs_remove(iwm->dbg.dbg_level_dentry);
+ debugfs_remove(iwm->dbg.txq_dentry);
+ debugfs_remove(iwm->dbg.tx_credit_dentry);
+ debugfs_remove(iwm->dbg.rx_ticket_dentry);
+ if (iwm->bus_ops->debugfs_exit)
+ iwm->bus_ops->debugfs_exit(iwm);
+
+ debugfs_remove(iwm->dbg.busdir);
+ debugfs_remove(iwm->dbg.dbgdir);
+ debugfs_remove(iwm->dbg.txdir);
+ debugfs_remove(iwm->dbg.rxdir);
+ debugfs_remove(iwm->dbg.devdir);
+ debugfs_remove(iwm->dbg.rootdir);
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/eeprom.c b/drivers/net/wireless/iwmc3200wifi/eeprom.c
new file mode 100644
index 00000000000..0f34b84fd2e
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/eeprom.c
@@ -0,0 +1,187 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#include <linux/kernel.h>
+
+#include "iwm.h"
+#include "umac.h"
+#include "commands.h"
+#include "eeprom.h"
+
+static struct iwm_eeprom_entry eeprom_map[] = {
+ [IWM_EEPROM_SIG] =
+ {"Signature", IWM_EEPROM_SIG_OFF, IWM_EEPROM_SIG_LEN},
+
+ [IWM_EEPROM_VERSION] =
+ {"Version", IWM_EEPROM_VERSION_OFF, IWM_EEPROM_VERSION_LEN},
+
+ [IWM_EEPROM_OEM_HW_VERSION] =
+ {"OEM HW version", IWM_EEPROM_OEM_HW_VERSION_OFF,
+ IWM_EEPROM_OEM_HW_VERSION_LEN},
+
+ [IWM_EEPROM_MAC_VERSION] =
+ {"MAC version", IWM_EEPROM_MAC_VERSION_OFF, IWM_EEPROM_MAC_VERSION_LEN},
+
+ [IWM_EEPROM_CARD_ID] =
+ {"Card ID", IWM_EEPROM_CARD_ID_OFF, IWM_EEPROM_CARD_ID_LEN},
+
+ [IWM_EEPROM_RADIO_CONF] =
+ {"Radio config", IWM_EEPROM_RADIO_CONF_OFF, IWM_EEPROM_RADIO_CONF_LEN},
+
+ [IWM_EEPROM_SKU_CAP] =
+ {"SKU capabilities", IWM_EEPROM_SKU_CAP_OFF, IWM_EEPROM_SKU_CAP_LEN},
+
+ [IWM_EEPROM_CALIB_RXIQ_OFFSET] =
+ {"RX IQ offset", IWM_EEPROM_CALIB_RXIQ_OFF, IWM_EEPROM_INDIRECT_LEN},
+
+ [IWM_EEPROM_CALIB_RXIQ] =
+ {"Calib RX IQ", 0, IWM_EEPROM_CALIB_RXIQ_LEN},
+};
+
+
+static int iwm_eeprom_read(struct iwm_priv *iwm, u8 eeprom_id)
+{
+ int ret;
+ u32 entry_size, chunk_size, data_offset = 0, addr_offset = 0;
+ u32 addr;
+ struct iwm_udma_wifi_cmd udma_cmd;
+ struct iwm_umac_cmd umac_cmd;
+ struct iwm_umac_cmd_eeprom_proxy eeprom_cmd;
+
+ if (eeprom_id > (IWM_EEPROM_LAST - 1))
+ return -EINVAL;
+
+ entry_size = eeprom_map[eeprom_id].length;
+
+ if (eeprom_id >= IWM_EEPROM_INDIRECT_DATA) {
+ /* indirect data */
+ u32 off_id = eeprom_id - IWM_EEPROM_INDIRECT_DATA +
+ IWM_EEPROM_INDIRECT_OFFSET;
+
+ eeprom_map[eeprom_id].offset =
+ *(u16 *)(iwm->eeprom + eeprom_map[off_id].offset) << 1;
+ }
+
+ addr = eeprom_map[eeprom_id].offset;
+
+ udma_cmd.eop = 1;
+ udma_cmd.credit_group = 0x4;
+ udma_cmd.ra_tid = UMAC_HDI_ACT_TBL_IDX_HOST_CMD;
+ udma_cmd.lmac_offset = 0;
+
+ umac_cmd.id = UMAC_CMD_OPCODE_EEPROM_PROXY;
+ umac_cmd.resp = 1;
+
+ while (entry_size > 0) {
+ chunk_size = min_t(u32, entry_size, IWM_MAX_EEPROM_DATA_LEN);
+
+ eeprom_cmd.hdr.type =
+ cpu_to_le32(IWM_UMAC_CMD_EEPROM_TYPE_READ);
+ eeprom_cmd.hdr.offset = cpu_to_le32(addr + addr_offset);
+ eeprom_cmd.hdr.len = cpu_to_le32(chunk_size);
+
+ ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd,
+ &umac_cmd, &eeprom_cmd,
+ sizeof(struct iwm_umac_cmd_eeprom_proxy));
+ if (ret < 0) {
+ IWM_ERR(iwm, "Couldn't read eeprom\n");
+ return ret;
+ }
+
+ ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_EEPROM_PROXY,
+ IWM_SRC_UMAC, 2*HZ);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Did not get any eeprom answer\n");
+ return ret;
+ }
+
+ data_offset += chunk_size;
+ addr_offset += chunk_size;
+ entry_size -= chunk_size;
+ }
+
+ return 0;
+}
+
+u8 *iwm_eeprom_access(struct iwm_priv *iwm, u8 eeprom_id)
+{
+ if (!iwm->eeprom)
+ return ERR_PTR(-ENODEV);
+
+ return iwm->eeprom + eeprom_map[eeprom_id].offset;
+}
+
+int iwm_eeprom_init(struct iwm_priv *iwm)
+{
+ int i, ret = 0;
+ char name[32];
+
+ iwm->eeprom = kzalloc(IWM_EEPROM_LEN, GFP_KERNEL);
+ if (!iwm->eeprom)
+ return -ENOMEM;
+
+ for (i = IWM_EEPROM_FIRST; i < IWM_EEPROM_LAST; i++) {
+#ifdef CONFIG_IWM_B0_HW_SUPPORT
+ if (iwm->conf.hw_b0 && (i >= IWM_EEPROM_INDIRECT_OFFSET))
+ break;
+#endif
+ ret = iwm_eeprom_read(iwm, i);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Couldn't read eeprom entry #%d: %s\n",
+ i, eeprom_map[i].name);
+ break;
+ }
+ }
+
+ IWM_DBG_BOOT(iwm, DBG, "EEPROM dump:\n");
+ for (i = IWM_EEPROM_FIRST; i < IWM_EEPROM_LAST; i++) {
+ memset(name, 0, 32);
+ sprintf(name, "%s: ", eeprom_map[i].name);
+
+ IWM_HEXDUMP(iwm, DBG, BOOT, name,
+ iwm->eeprom + eeprom_map[i].offset,
+ eeprom_map[i].length);
+ }
+
+ return ret;
+}
+
+void iwm_eeprom_exit(struct iwm_priv *iwm)
+{
+ kfree(iwm->eeprom);
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/eeprom.h b/drivers/net/wireless/iwmc3200wifi/eeprom.h
new file mode 100644
index 00000000000..cdb31a6a1f5
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/eeprom.h
@@ -0,0 +1,114 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_EEPROM_H__
+#define __IWM_EEPROM_H__
+
+enum {
+ IWM_EEPROM_SIG = 0,
+ IWM_EEPROM_FIRST = IWM_EEPROM_SIG,
+ IWM_EEPROM_VERSION,
+ IWM_EEPROM_OEM_HW_VERSION,
+ IWM_EEPROM_MAC_VERSION,
+ IWM_EEPROM_CARD_ID,
+ IWM_EEPROM_RADIO_CONF,
+ IWM_EEPROM_SKU_CAP,
+
+ IWM_EEPROM_INDIRECT_OFFSET,
+ IWM_EEPROM_CALIB_RXIQ_OFFSET = IWM_EEPROM_INDIRECT_OFFSET,
+
+ IWM_EEPROM_INDIRECT_DATA,
+ IWM_EEPROM_CALIB_RXIQ = IWM_EEPROM_INDIRECT_DATA,
+
+ IWM_EEPROM_LAST,
+};
+
+#define IWM_EEPROM_SIG_OFF 0x00
+#define IWM_EEPROM_VERSION_OFF (0x54 << 1)
+#define IWM_EEPROM_OEM_HW_VERSION_OFF (0x56 << 1)
+#define IWM_EEPROM_MAC_VERSION_OFF (0x30 << 1)
+#define IWM_EEPROM_CARD_ID_OFF (0x5d << 1)
+#define IWM_EEPROM_RADIO_CONF_OFF (0x58 << 1)
+#define IWM_EEPROM_SKU_CAP_OFF (0x55 << 1)
+#define IWM_EEPROM_CALIB_CONFIG_OFF (0x7c << 1)
+
+#define IWM_EEPROM_SIG_LEN 4
+#define IWM_EEPROM_VERSION_LEN 2
+#define IWM_EEPROM_OEM_HW_VERSION_LEN 2
+#define IWM_EEPROM_MAC_VERSION_LEN 1
+#define IWM_EEPROM_CARD_ID_LEN 2
+#define IWM_EEPROM_RADIO_CONF_LEN 2
+#define IWM_EEPROM_SKU_CAP_LEN 2
+#define IWM_EEPROM_INDIRECT_LEN 2
+
+#define IWM_MAX_EEPROM_DATA_LEN 240
+#define IWM_EEPROM_LEN 0x800
+
+#define IWM_EEPROM_MIN_ALLOWED_VERSION 0x0610
+#define IWM_EEPROM_MAX_ALLOWED_VERSION 0x0700
+#define IWM_EEPROM_CURRENT_VERSION 0x0612
+
+#define IWM_EEPROM_SKU_CAP_BAND_24GHZ (1 << 4)
+#define IWM_EEPROM_SKU_CAP_BAND_52GHZ (1 << 5)
+#define IWM_EEPROM_SKU_CAP_11N_ENABLE (1 << 6)
+
+enum {
+ IWM_EEPROM_CALIB_CAL_HDR,
+ IWM_EEPROM_CALIB_TX_POWER,
+ IWM_EEPROM_CALIB_XTAL,
+ IWM_EEPROM_CALIB_TEMPERATURE,
+ IWM_EEPROM_CALIB_RX_BB_FILTER,
+ IWM_EEPROM_CALIB_RX_IQ,
+ IWM_EEPROM_CALIB_MAX,
+};
+
+#define IWM_EEPROM_CALIB_RXIQ_OFF (IWM_EEPROM_CALIB_CONFIG_OFF + \
+ (IWM_EEPROM_CALIB_RX_IQ << 1))
+#define IWM_EEPROM_CALIB_RXIQ_LEN sizeof(struct iwm_lmac_calib_rxiq)
+
+struct iwm_eeprom_entry {
+ char *name;
+ u32 offset;
+ u32 length;
+};
+
+int iwm_eeprom_init(struct iwm_priv *iwm);
+void iwm_eeprom_exit(struct iwm_priv *iwm);
+u8 *iwm_eeprom_access(struct iwm_priv *iwm, u8 eeprom_id);
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/fw.c b/drivers/net/wireless/iwmc3200wifi/fw.c
new file mode 100644
index 00000000000..ec1a15a5a0e
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/fw.c
@@ -0,0 +1,388 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/firmware.h>
+
+#include "iwm.h"
+#include "bus.h"
+#include "hal.h"
+#include "umac.h"
+#include "debug.h"
+#include "fw.h"
+#include "commands.h"
+
+static const char fw_barker[] = "*WESTOPFORNOONE*";
+
+/*
+ * @op_code: Op code we're looking for.
+ * @index: There can be several instances of the same opcode within
+ * the firmware. Index specifies which one we're looking for.
+ */
+static int iwm_fw_op_offset(struct iwm_priv *iwm, const struct firmware *fw,
+ u16 op_code, u32 index)
+{
+ int offset = -EINVAL, fw_offset;
+ u32 op_index = 0;
+ const u8 *fw_ptr;
+ struct iwm_fw_hdr_rec *rec;
+
+ fw_offset = 0;
+ fw_ptr = fw->data;
+
+ /* We first need to look for the firmware barker */
+ if (memcmp(fw_ptr, fw_barker, IWM_HDR_BARKER_LEN)) {
+ IWM_ERR(iwm, "No barker string in this FW\n");
+ return -EINVAL;
+ }
+
+ if (fw->size < IWM_HDR_LEN) {
+ IWM_ERR(iwm, "FW is too small (%zu)\n", fw->size);
+ return -EINVAL;
+ }
+
+ fw_offset += IWM_HDR_BARKER_LEN;
+
+ while (fw_offset < fw->size) {
+ rec = (struct iwm_fw_hdr_rec *)(fw_ptr + fw_offset);
+
+ IWM_DBG_FW(iwm, DBG, "FW: op_code: 0x%x, len: %d @ 0x%x\n",
+ rec->op_code, rec->len, fw_offset);
+
+ if (rec->op_code == IWM_HDR_REC_OP_INVALID) {
+ IWM_DBG_FW(iwm, DBG, "Reached INVALID op code\n");
+ break;
+ }
+
+ if (rec->op_code == op_code) {
+ if (op_index == index) {
+ fw_offset += sizeof(struct iwm_fw_hdr_rec);
+ offset = fw_offset;
+ goto out;
+ }
+ op_index++;
+ }
+
+ fw_offset += sizeof(struct iwm_fw_hdr_rec) + rec->len;
+ }
+
+ out:
+ return offset;
+}
+
+static int iwm_load_firmware_chunk(struct iwm_priv *iwm,
+ const struct firmware *fw,
+ struct iwm_fw_img_desc *img_desc)
+{
+ struct iwm_udma_nonwifi_cmd target_cmd;
+ u32 chunk_size;
+ const u8 *chunk_ptr;
+ int ret = 0;
+
+ IWM_DBG_FW(iwm, INFO, "Loading FW chunk: %d bytes @ 0x%x\n",
+ img_desc->length, img_desc->address);
+
+ target_cmd.opcode = UMAC_HDI_OUT_OPCODE_WRITE;
+ target_cmd.handle_by_hw = 1;
+ target_cmd.op2 = 0;
+ target_cmd.resp = 0;
+ target_cmd.eop = 1;
+
+ chunk_size = img_desc->length;
+ chunk_ptr = fw->data + img_desc->offset;
+
+ while (chunk_size > 0) {
+ u32 tmp_chunk_size;
+
+ tmp_chunk_size = min_t(u32, chunk_size,
+ IWM_MAX_NONWIFI_CMD_BUFF_SIZE);
+
+ target_cmd.addr = cpu_to_le32(img_desc->address +
+ (chunk_ptr - fw->data - img_desc->offset));
+ target_cmd.op1_sz = cpu_to_le32(tmp_chunk_size);
+
+ IWM_DBG_FW(iwm, DBG, "\t%d bytes @ 0x%x\n",
+ tmp_chunk_size, target_cmd.addr);
+
+ ret = iwm_hal_send_target_cmd(iwm, &target_cmd, chunk_ptr);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Couldn't load FW chunk\n");
+ break;
+ }
+
+ chunk_size -= tmp_chunk_size;
+ chunk_ptr += tmp_chunk_size;
+ }
+
+ return ret;
+}
+/*
+ * To load a fw image to the target, we basically go through the
+ * fw, looking for OP_MEM_DESC records. Once we found one, we
+ * pass it to iwm_load_firmware_chunk().
+ * The OP_MEM_DESC records contain the actuall memory chunk to be
+ * sent, but also the destination address.
+ */
+static int iwm_load_img(struct iwm_priv *iwm, const char *img_name)
+{
+ const struct firmware *fw;
+ struct iwm_fw_img_desc *img_desc;
+ struct iwm_fw_img_ver *ver;
+ int ret = 0, fw_offset;
+ u32 opcode_idx = 0, build_date;
+ char *build_tag;
+
+ ret = request_firmware(&fw, img_name, iwm_to_dev(iwm));
+ if (ret) {
+ IWM_ERR(iwm, "Request firmware failed");
+ return ret;
+ }
+
+ IWM_DBG_FW(iwm, INFO, "Start to load FW %s\n", img_name);
+
+ while (1) {
+ fw_offset = iwm_fw_op_offset(iwm, fw,
+ IWM_HDR_REC_OP_MEM_DESC,
+ opcode_idx);
+ if (fw_offset < 0)
+ break;
+
+ img_desc = (struct iwm_fw_img_desc *)(fw->data + fw_offset);
+ ret = iwm_load_firmware_chunk(iwm, fw, img_desc);
+ if (ret < 0)
+ goto err_release_fw;
+ opcode_idx++;
+ };
+
+ /* Read firmware version */
+ fw_offset = iwm_fw_op_offset(iwm, fw, IWM_HDR_REC_OP_SW_VER, 0);
+ if (fw_offset < 0)
+ goto err_release_fw;
+
+ ver = (struct iwm_fw_img_ver *)(fw->data + fw_offset);
+
+ /* Read build tag */
+ fw_offset = iwm_fw_op_offset(iwm, fw, IWM_HDR_REC_OP_BUILD_TAG, 0);
+ if (fw_offset < 0)
+ goto err_release_fw;
+
+ build_tag = (char *)(fw->data + fw_offset);
+
+ /* Read build date */
+ fw_offset = iwm_fw_op_offset(iwm, fw, IWM_HDR_REC_OP_BUILD_DATE, 0);
+ if (fw_offset < 0)
+ goto err_release_fw;
+
+ build_date = *(u32 *)(fw->data + fw_offset);
+
+ IWM_INFO(iwm, "%s:\n", img_name);
+ IWM_INFO(iwm, "\tVersion: %02X.%02X\n", ver->major, ver->minor);
+ IWM_INFO(iwm, "\tBuild tag: %s\n", build_tag);
+ IWM_INFO(iwm, "\tBuild date: %x-%x-%x\n",
+ IWM_BUILD_YEAR(build_date), IWM_BUILD_MONTH(build_date),
+ IWM_BUILD_DAY(build_date));
+
+
+ err_release_fw:
+ release_firmware(fw);
+
+ return ret;
+}
+
+static int iwm_load_umac(struct iwm_priv *iwm)
+{
+ struct iwm_udma_nonwifi_cmd target_cmd;
+ int ret;
+
+ ret = iwm_load_img(iwm, iwm->bus_ops->umac_name);
+ if (ret < 0)
+ return ret;
+
+ /* We've loaded the UMAC, we can tell the target to jump there */
+ target_cmd.opcode = UMAC_HDI_OUT_OPCODE_JUMP;
+ target_cmd.addr = cpu_to_le32(UMAC_MU_FW_INST_DATA_12_ADDR);
+ target_cmd.op1_sz = 0;
+ target_cmd.op2 = 0;
+ target_cmd.handle_by_hw = 0;
+ target_cmd.resp = 1 ;
+ target_cmd.eop = 1;
+
+ ret = iwm_hal_send_target_cmd(iwm, &target_cmd, NULL);
+ if (ret < 0)
+ IWM_ERR(iwm, "Couldn't send JMP command\n");
+
+ return ret;
+}
+
+static int iwm_load_lmac(struct iwm_priv *iwm, const char *img_name)
+{
+ int ret;
+
+ ret = iwm_load_img(iwm, img_name);
+ if (ret < 0)
+ return ret;
+
+ return iwm_send_umac_reset(iwm,
+ cpu_to_le32(UMAC_RST_CTRL_FLG_LARC_CLK_EN), 0);
+}
+
+/*
+ * We currently have to load 3 FWs:
+ * 1) The UMAC (Upper MAC).
+ * 2) The calibration LMAC (Lower MAC).
+ * We then send the calibration init command, so that the device can
+ * run a first calibration round.
+ * 3) The operational LMAC, which replaces the calibration one when it's
+ * done with the first calibration round.
+ *
+ * Once those 3 FWs have been loaded, we send the periodic calibration
+ * command, and then the device is available for regular 802.11 operations.
+ */
+int iwm_load_fw(struct iwm_priv *iwm)
+{
+ int ret;
+
+ /* We first start downloading the UMAC */
+ ret = iwm_load_umac(iwm);
+ if (ret < 0) {
+ IWM_ERR(iwm, "UMAC loading failed\n");
+ return ret;
+ }
+
+ /* Handle UMAC_ALIVE notification */
+ ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_ALIVE, IWM_SRC_UMAC,
+ WAIT_NOTIF_TIMEOUT);
+ if (ret) {
+ IWM_ERR(iwm, "Handle UMAC_ALIVE failed: %d\n", ret);
+ return ret;
+ }
+
+ /* UMAC is alive, we can download the calibration LMAC */
+ ret = iwm_load_lmac(iwm, iwm->bus_ops->calib_lmac_name);
+ if (ret) {
+ IWM_ERR(iwm, "Calibration LMAC loading failed\n");
+ return ret;
+ }
+
+ /* Handle UMAC_INIT_COMPLETE notification */
+ ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_INIT_COMPLETE,
+ IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
+ if (ret) {
+ IWM_ERR(iwm, "Handle INIT_COMPLETE failed for calibration "
+ "LMAC: %d\n", ret);
+ return ret;
+ }
+
+ /* Read EEPROM data */
+ ret = iwm_eeprom_init(iwm);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Couldn't init eeprom array\n");
+ return ret;
+ }
+
+#ifdef CONFIG_IWM_B0_HW_SUPPORT
+ if (iwm->conf.hw_b0) {
+ clear_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->conf.init_calib_map);
+ clear_bit(PHY_CALIBRATE_RX_IQ_CMD,
+ &iwm->conf.periodic_calib_map);
+ }
+#endif
+ /* Read RX IQ calibration result from EEPROM */
+ if (test_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->conf.init_calib_map)) {
+ iwm_store_rxiq_calib_result(iwm);
+ set_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->calib_done_map);
+ }
+
+ iwm_send_prio_table(iwm);
+ iwm_send_init_calib_cfg(iwm, iwm->conf.init_calib_map);
+
+ while (iwm->calib_done_map != iwm->conf.init_calib_map) {
+ ret = iwm_notif_handle(iwm, CALIBRATION_RES_NOTIFICATION,
+ IWM_SRC_LMAC, WAIT_NOTIF_TIMEOUT);
+ if (ret) {
+ IWM_ERR(iwm, "Wait for calibration result timeout\n");
+ goto out;
+ }
+ IWM_DBG_FW(iwm, DBG, "Got calibration result. calib_done_map: "
+ "0x%lx, requested calibrations: 0x%lx\n",
+ iwm->calib_done_map, iwm->conf.init_calib_map);
+ }
+
+ /* Handle LMAC CALIBRATION_COMPLETE notification */
+ ret = iwm_notif_handle(iwm, CALIBRATION_COMPLETE_NOTIFICATION,
+ IWM_SRC_LMAC, WAIT_NOTIF_TIMEOUT);
+ if (ret) {
+ IWM_ERR(iwm, "Wait for CALIBRATION_COMPLETE timeout\n");
+ goto out;
+ }
+
+ IWM_INFO(iwm, "LMAC calibration done: 0x%lx\n", iwm->calib_done_map);
+
+ iwm_send_umac_reset(iwm, cpu_to_le32(UMAC_RST_CTRL_FLG_LARC_RESET), 1);
+
+ ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_RESET, IWM_SRC_UMAC,
+ WAIT_NOTIF_TIMEOUT);
+ if (ret) {
+ IWM_ERR(iwm, "Wait for UMAC RESET timeout\n");
+ goto out;
+ }
+
+ /* Download the operational LMAC */
+ ret = iwm_load_lmac(iwm, iwm->bus_ops->lmac_name);
+ if (ret) {
+ IWM_ERR(iwm, "LMAC loading failed\n");
+ goto out;
+ }
+
+ ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_INIT_COMPLETE,
+ IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
+ if (ret) {
+ IWM_ERR(iwm, "Handle INIT_COMPLETE failed for LMAC: %d\n", ret);
+ goto out;
+ }
+
+ iwm_send_prio_table(iwm);
+ iwm_send_calib_results(iwm);
+ iwm_send_periodic_calib_cfg(iwm, iwm->conf.periodic_calib_map);
+
+ return 0;
+
+ out:
+ iwm_eeprom_exit(iwm);
+ return ret;
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/fw.h b/drivers/net/wireless/iwmc3200wifi/fw.h
new file mode 100644
index 00000000000..c70a3b40dad
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/fw.h
@@ -0,0 +1,100 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_FW_H__
+#define __IWM_FW_H__
+
+/**
+ * struct iwm_fw_hdr_rec - An iwm firmware image is a
+ * concatenation of various records. Each of them is
+ * defined by an ID (aka op code), a length, and the
+ * actual data.
+ * @op_code: The record ID, see IWM_HDR_REC_OP_*
+ *
+ * @len: The record payload length
+ *
+ * @buf: The record payload
+ */
+struct iwm_fw_hdr_rec {
+ u16 op_code;
+ u16 len;
+ u8 buf[0];
+};
+
+/* Header's definitions */
+#define IWM_HDR_LEN (512)
+#define IWM_HDR_BARKER_LEN (16)
+
+/* Header's opcodes */
+#define IWM_HDR_REC_OP_INVALID (0x00)
+#define IWM_HDR_REC_OP_BUILD_DATE (0x01)
+#define IWM_HDR_REC_OP_BUILD_TAG (0x02)
+#define IWM_HDR_REC_OP_SW_VER (0x03)
+#define IWM_HDR_REC_OP_HW_SKU (0x04)
+#define IWM_HDR_REC_OP_BUILD_OPT (0x05)
+#define IWM_HDR_REC_OP_MEM_DESC (0x06)
+#define IWM_HDR_REC_USERDEFS (0x07)
+
+/* Header's records length (in bytes) */
+#define IWM_HDR_REC_LEN_BUILD_DATE (4)
+#define IWM_HDR_REC_LEN_BUILD_TAG (64)
+#define IWM_HDR_REC_LEN_SW_VER (4)
+#define IWM_HDR_REC_LEN_HW_SKU (4)
+#define IWM_HDR_REC_LEN_BUILD_OPT (4)
+#define IWM_HDR_REC_LEN_MEM_DESC (12)
+#define IWM_HDR_REC_LEN_USERDEF (64)
+
+#define IWM_BUILD_YEAR(date) ((date >> 16) & 0xffff)
+#define IWM_BUILD_MONTH(date) ((date >> 8) & 0xff)
+#define IWM_BUILD_DAY(date) (date & 0xff)
+
+struct iwm_fw_img_desc {
+ u32 offset;
+ u32 address;
+ u32 length;
+};
+
+struct iwm_fw_img_ver {
+ u8 minor;
+ u8 major;
+ u16 reserved;
+};
+
+int iwm_load_fw(struct iwm_priv *iwm);
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c
new file mode 100644
index 00000000000..ee127fe4f43
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/hal.c
@@ -0,0 +1,464 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+/*
+ * Hardware Abstraction Layer for iwm.
+ *
+ * This file mostly defines an abstraction API for
+ * sending various commands to the target.
+ *
+ * We have 2 types of commands: wifi and non-wifi ones.
+ *
+ * - wifi commands:
+ * They are used for sending LMAC and UMAC commands,
+ * and thus are the most commonly used ones.
+ * There are 2 different wifi command types, the regular
+ * one and the LMAC one. The former is used to send
+ * UMAC commands (see UMAC_CMD_OPCODE_* from umac.h)
+ * while the latter is used for sending commands to the
+ * LMAC. If you look at LMAC commands you'll se that they
+ * are actually regular iwlwifi target commands encapsulated
+ * into a special UMAC command called UMAC passthrough.
+ * This is due to the fact the the host talks exclusively
+ * to the UMAC and so there needs to be a special UMAC
+ * command for talking to the LMAC.
+ * This is how a wifi command is layed out:
+ * ------------------------
+ * | iwm_udma_out_wifi_hdr |
+ * ------------------------
+ * | SW meta_data (32 bits) |
+ * ------------------------
+ * | iwm_dev_cmd_hdr |
+ * ------------------------
+ * | payload |
+ * | .... |
+ *
+ * - non-wifi, or general commands:
+ * Those commands are handled by the device's bootrom,
+ * and are typically sent when the UMAC and the LMAC
+ * are not yet available.
+ * * This is how a non-wifi command is layed out:
+ * ---------------------------
+ * | iwm_udma_out_nonwifi_hdr |
+ * ---------------------------
+ * | payload |
+ * | .... |
+
+ *
+ * All the commands start with a UDMA header, which is
+ * basically a 32 bits field. The 4 LSB there define
+ * an opcode that allows the target to differentiate
+ * between wifi (opcode is 0xf) and non-wifi commands
+ * (opcode is [0..0xe]).
+ *
+ * When a command (wifi or non-wifi) is supposed to receive
+ * an answer, we queue the command buffer. When we do receive
+ * a command response from the UMAC, we go through the list
+ * of pending command, and pass both the command and the answer
+ * to the rx handler. Each command is sent with a unique
+ * sequence id, and the answer is sent with the same one. This
+ * is how we're supposed to match an answer with its command.
+ * See rx.c:iwm_rx_handle_[non]wifi() and iwm_get_pending_[non]wifi()
+ * for the implementation details.
+ */
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+
+#include "iwm.h"
+#include "bus.h"
+#include "hal.h"
+#include "umac.h"
+#include "debug.h"
+
+static void iwm_nonwifi_cmd_init(struct iwm_priv *iwm,
+ struct iwm_nonwifi_cmd *cmd,
+ struct iwm_udma_nonwifi_cmd *udma_cmd)
+{
+ INIT_LIST_HEAD(&cmd->pending);
+
+ spin_lock(&iwm->cmd_lock);
+
+ cmd->resp_received = 0;
+
+ cmd->seq_num = iwm->nonwifi_seq_num;
+ udma_cmd->seq_num = cpu_to_le16(cmd->seq_num);
+
+ cmd->seq_num = iwm->nonwifi_seq_num++;
+ iwm->nonwifi_seq_num %= UMAC_NONWIFI_SEQ_NUM_MAX;
+
+ if (udma_cmd->resp)
+ list_add_tail(&cmd->pending, &iwm->nonwifi_pending_cmd);
+
+ spin_unlock(&iwm->cmd_lock);
+
+ cmd->buf.start = cmd->buf.payload;
+ cmd->buf.len = 0;
+
+ memcpy(&cmd->udma_cmd, udma_cmd, sizeof(*udma_cmd));
+}
+
+u16 iwm_alloc_wifi_cmd_seq(struct iwm_priv *iwm)
+{
+ u16 seq_num = iwm->wifi_seq_num;
+
+ iwm->wifi_seq_num++;
+ iwm->wifi_seq_num %= UMAC_WIFI_SEQ_NUM_MAX;
+
+ return seq_num;
+}
+
+static void iwm_wifi_cmd_init(struct iwm_priv *iwm,
+ struct iwm_wifi_cmd *cmd,
+ struct iwm_udma_wifi_cmd *udma_cmd,
+ struct iwm_umac_cmd *umac_cmd,
+ struct iwm_lmac_cmd *lmac_cmd,
+ u16 payload_size)
+{
+ INIT_LIST_HEAD(&cmd->pending);
+
+ spin_lock(&iwm->cmd_lock);
+
+ cmd->seq_num = iwm_alloc_wifi_cmd_seq(iwm);
+ umac_cmd->seq_num = cpu_to_le16(cmd->seq_num);
+
+ if (umac_cmd->resp)
+ list_add_tail(&cmd->pending, &iwm->wifi_pending_cmd);
+
+ spin_unlock(&iwm->cmd_lock);
+
+ cmd->buf.start = cmd->buf.payload;
+ cmd->buf.len = 0;
+
+ if (lmac_cmd) {
+ cmd->buf.start -= sizeof(struct iwm_lmac_hdr);
+
+ lmac_cmd->seq_num = cpu_to_le16(cmd->seq_num);
+ lmac_cmd->count = cpu_to_le16(payload_size);
+
+ memcpy(&cmd->lmac_cmd, lmac_cmd, sizeof(*lmac_cmd));
+
+ umac_cmd->count = cpu_to_le16(sizeof(struct iwm_lmac_hdr));
+ } else
+ umac_cmd->count = 0;
+
+ umac_cmd->count = cpu_to_le16(payload_size +
+ le16_to_cpu(umac_cmd->count));
+ udma_cmd->count = cpu_to_le16(sizeof(struct iwm_umac_fw_cmd_hdr) +
+ le16_to_cpu(umac_cmd->count));
+
+ memcpy(&cmd->udma_cmd, udma_cmd, sizeof(*udma_cmd));
+ memcpy(&cmd->umac_cmd, umac_cmd, sizeof(*umac_cmd));
+}
+
+void iwm_cmd_flush(struct iwm_priv *iwm)
+{
+ struct iwm_wifi_cmd *wcmd, *wnext;
+ struct iwm_nonwifi_cmd *nwcmd, *nwnext;
+
+ list_for_each_entry_safe(wcmd, wnext, &iwm->wifi_pending_cmd, pending) {
+ list_del(&wcmd->pending);
+ kfree(wcmd);
+ }
+
+ list_for_each_entry_safe(nwcmd, nwnext, &iwm->nonwifi_pending_cmd,
+ pending) {
+ list_del(&nwcmd->pending);
+ kfree(nwcmd);
+ }
+}
+
+struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num)
+{
+ struct iwm_wifi_cmd *cmd, *next;
+
+ list_for_each_entry_safe(cmd, next, &iwm->wifi_pending_cmd, pending)
+ if (cmd->seq_num == seq_num) {
+ list_del(&cmd->pending);
+ return cmd;
+ }
+
+ return NULL;
+}
+
+struct iwm_nonwifi_cmd *
+iwm_get_pending_nonwifi_cmd(struct iwm_priv *iwm, u8 seq_num, u8 cmd_opcode)
+{
+ struct iwm_nonwifi_cmd *cmd, *next;
+
+ list_for_each_entry_safe(cmd, next, &iwm->nonwifi_pending_cmd, pending)
+ if ((cmd->seq_num == seq_num) &&
+ (cmd->udma_cmd.opcode == cmd_opcode) &&
+ (cmd->resp_received)) {
+ list_del(&cmd->pending);
+ return cmd;
+ }
+
+ return NULL;
+}
+
+static void iwm_build_udma_nonwifi_hdr(struct iwm_priv *iwm,
+ struct iwm_udma_out_nonwifi_hdr *hdr,
+ struct iwm_udma_nonwifi_cmd *cmd)
+{
+ memset(hdr, 0, sizeof(*hdr));
+
+ SET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_OPCODE, cmd->opcode);
+ SET_VAL32(hdr->cmd, UDMA_HDI_OUT_NW_CMD_RESP, cmd->resp);
+ SET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_EOT, 1);
+ SET_VAL32(hdr->cmd, UDMA_HDI_OUT_NW_CMD_HANDLE_BY_HW,
+ cmd->handle_by_hw);
+ SET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_SIGNATURE, UMAC_HDI_OUT_SIGNATURE);
+ SET_VAL32(hdr->cmd, UDMA_HDI_OUT_CMD_NON_WIFI_HW_SEQ_NUM,
+ le16_to_cpu(cmd->seq_num));
+
+ hdr->addr = cmd->addr;
+ hdr->op1_sz = cmd->op1_sz;
+ hdr->op2 = cmd->op2;
+}
+
+static int iwm_send_udma_nonwifi_cmd(struct iwm_priv *iwm,
+ struct iwm_nonwifi_cmd *cmd)
+{
+ struct iwm_udma_out_nonwifi_hdr *udma_hdr;
+ struct iwm_nonwifi_cmd_buff *buf;
+ struct iwm_udma_nonwifi_cmd *udma_cmd = &cmd->udma_cmd;
+
+ buf = &cmd->buf;
+
+ buf->start -= sizeof(struct iwm_umac_nonwifi_out_hdr);
+ buf->len += sizeof(struct iwm_umac_nonwifi_out_hdr);
+
+ udma_hdr = (struct iwm_udma_out_nonwifi_hdr *)(buf->start);
+
+ iwm_build_udma_nonwifi_hdr(iwm, udma_hdr, udma_cmd);
+
+ IWM_DBG_CMD(iwm, DBG,
+ "Send UDMA nonwifi cmd: opcode = 0x%x, resp = 0x%x, "
+ "hw = 0x%x, seqnum = %d, addr = 0x%x, op1_sz = 0x%x, "
+ "op2 = 0x%x\n", udma_cmd->opcode, udma_cmd->resp,
+ udma_cmd->handle_by_hw, cmd->seq_num, udma_cmd->addr,
+ udma_cmd->op1_sz, udma_cmd->op2);
+
+ return iwm_bus_send_chunk(iwm, buf->start, buf->len);
+}
+
+void iwm_udma_wifi_hdr_set_eop(struct iwm_priv *iwm, u8 *buf, u8 eop)
+{
+ struct iwm_udma_out_wifi_hdr *hdr = (struct iwm_udma_out_wifi_hdr *)buf;
+
+ SET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_EOT, eop);
+}
+
+void iwm_build_udma_wifi_hdr(struct iwm_priv *iwm,
+ struct iwm_udma_out_wifi_hdr *hdr,
+ struct iwm_udma_wifi_cmd *cmd)
+{
+ memset(hdr, 0, sizeof(*hdr));
+
+ SET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_OPCODE, UMAC_HDI_OUT_OPCODE_WIFI);
+ SET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_EOT, cmd->eop);
+ SET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_SIGNATURE, UMAC_HDI_OUT_SIGNATURE);
+
+ SET_VAL32(hdr->meta_data, UMAC_HDI_OUT_BYTE_COUNT,
+ le16_to_cpu(cmd->count));
+ SET_VAL32(hdr->meta_data, UMAC_HDI_OUT_CREDIT_GRP, cmd->credit_group);
+ SET_VAL32(hdr->meta_data, UMAC_HDI_OUT_RATID, cmd->ra_tid);
+ SET_VAL32(hdr->meta_data, UMAC_HDI_OUT_LMAC_OFFSET, cmd->lmac_offset);
+}
+
+void iwm_build_umac_hdr(struct iwm_priv *iwm,
+ struct iwm_umac_fw_cmd_hdr *hdr,
+ struct iwm_umac_cmd *cmd)
+{
+ memset(hdr, 0, sizeof(*hdr));
+
+ SET_VAL32(hdr->meta_data, UMAC_FW_CMD_BYTE_COUNT,
+ le16_to_cpu(cmd->count));
+ SET_VAL32(hdr->meta_data, UMAC_FW_CMD_TX_STA_COLOR, cmd->color);
+ SET_VAL8(hdr->cmd.flags, UMAC_DEV_CMD_FLAGS_RESP_REQ, cmd->resp);
+
+ hdr->cmd.cmd = cmd->id;
+ hdr->cmd.seq_num = cmd->seq_num;
+}
+
+static int iwm_send_udma_wifi_cmd(struct iwm_priv *iwm,
+ struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_wifi_out_hdr *umac_hdr;
+ struct iwm_wifi_cmd_buff *buf;
+ struct iwm_udma_wifi_cmd *udma_cmd = &cmd->udma_cmd;
+ struct iwm_umac_cmd *umac_cmd = &cmd->umac_cmd;
+ int ret;
+
+ buf = &cmd->buf;
+
+ buf->start -= sizeof(struct iwm_umac_wifi_out_hdr);
+ buf->len += sizeof(struct iwm_umac_wifi_out_hdr);
+
+ umac_hdr = (struct iwm_umac_wifi_out_hdr *)(buf->start);
+
+ iwm_build_udma_wifi_hdr(iwm, &umac_hdr->hw_hdr, udma_cmd);
+ iwm_build_umac_hdr(iwm, &umac_hdr->sw_hdr, umac_cmd);
+
+ IWM_DBG_CMD(iwm, DBG,
+ "Send UDMA wifi cmd: opcode = 0x%x, UMAC opcode = 0x%x, "
+ "eop = 0x%x, count = 0x%x, credit_group = 0x%x, "
+ "ra_tid = 0x%x, lmac_offset = 0x%x, seqnum = %d\n",
+ UMAC_HDI_OUT_OPCODE_WIFI, umac_cmd->id,
+ udma_cmd->eop, udma_cmd->count, udma_cmd->credit_group,
+ udma_cmd->ra_tid, udma_cmd->lmac_offset, cmd->seq_num);
+
+ if (umac_cmd->id == UMAC_CMD_OPCODE_WIFI_PASS_THROUGH)
+ IWM_DBG_CMD(iwm, DBG, "\tLMAC opcode: 0x%x\n",
+ cmd->lmac_cmd.id);
+
+ ret = iwm_tx_credit_alloc(iwm, udma_cmd->credit_group, buf->len);
+
+ /* We keep sending UMAC reset regardless of the command credits.
+ * The UMAC is supposed to be reset anyway and the Tx credits are
+ * reinitialized afterwards. If we are lucky, the reset could
+ * still be done even though we have run out of credits for the
+ * command pool at this moment.*/
+ if (ret && (umac_cmd->id != UMAC_CMD_OPCODE_RESET)) {
+ IWM_DBG_TX(iwm, DBG, "Failed to alloc tx credit for cmd %d\n",
+ umac_cmd->id);
+ return ret;
+ }
+
+ return iwm_bus_send_chunk(iwm, buf->start, buf->len);
+}
+
+/* target_cmd a.k.a udma_nonwifi_cmd can be sent when UMAC is not available */
+int iwm_hal_send_target_cmd(struct iwm_priv *iwm,
+ struct iwm_udma_nonwifi_cmd *udma_cmd,
+ const void *payload)
+{
+ struct iwm_nonwifi_cmd *cmd;
+ int ret;
+
+ cmd = kzalloc(sizeof(struct iwm_nonwifi_cmd), GFP_KERNEL);
+ if (!cmd) {
+ IWM_ERR(iwm, "Couldn't alloc memory for hal cmd\n");
+ return -ENOMEM;
+ }
+
+ iwm_nonwifi_cmd_init(iwm, cmd, udma_cmd);
+
+ if (cmd->udma_cmd.opcode == UMAC_HDI_OUT_OPCODE_WRITE ||
+ cmd->udma_cmd.opcode == UMAC_HDI_OUT_OPCODE_WRITE_PERSISTENT) {
+ cmd->buf.len = le32_to_cpu(cmd->udma_cmd.op1_sz);
+ memcpy(&cmd->buf.payload, payload, cmd->buf.len);
+ }
+
+ ret = iwm_send_udma_nonwifi_cmd(iwm, cmd);
+
+ if (!udma_cmd->resp)
+ kfree(cmd);
+
+ if (ret < 0)
+ return ret;
+
+ return cmd->seq_num;
+}
+
+static void iwm_build_lmac_hdr(struct iwm_priv *iwm, struct iwm_lmac_hdr *hdr,
+ struct iwm_lmac_cmd *cmd)
+{
+ memset(hdr, 0, sizeof(*hdr));
+
+ hdr->id = cmd->id;
+ hdr->flags = 0; /* Is this ever used? */
+ hdr->seq_num = cmd->seq_num;
+}
+
+/*
+ * iwm_hal_send_host_cmd(): sends commands to the UMAC or the LMAC.
+ * Sending command to the LMAC is equivalent to sending a
+ * regular UMAC command with the LMAC passtrough or the LMAC
+ * wrapper UMAC command IDs.
+ */
+int iwm_hal_send_host_cmd(struct iwm_priv *iwm,
+ struct iwm_udma_wifi_cmd *udma_cmd,
+ struct iwm_umac_cmd *umac_cmd,
+ struct iwm_lmac_cmd *lmac_cmd,
+ const void *payload, u16 payload_size)
+{
+ struct iwm_wifi_cmd *cmd;
+ struct iwm_lmac_hdr *hdr;
+ int lmac_hdr_len = 0;
+ int ret;
+
+ cmd = kzalloc(sizeof(struct iwm_wifi_cmd), GFP_KERNEL);
+ if (!cmd) {
+ IWM_ERR(iwm, "Couldn't alloc memory for wifi hal cmd\n");
+ return -ENOMEM;
+ }
+
+ iwm_wifi_cmd_init(iwm, cmd, udma_cmd, umac_cmd, lmac_cmd, payload_size);
+
+ if (lmac_cmd) {
+ hdr = (struct iwm_lmac_hdr *)(cmd->buf.start);
+
+ iwm_build_lmac_hdr(iwm, hdr, &cmd->lmac_cmd);
+ lmac_hdr_len = sizeof(struct iwm_lmac_hdr);
+ }
+
+ memcpy(cmd->buf.payload, payload, payload_size);
+ cmd->buf.len = le16_to_cpu(umac_cmd->count);
+
+ ret = iwm_send_udma_wifi_cmd(iwm, cmd);
+
+ /* We free the cmd if we're not expecting any response */
+ if (!umac_cmd->resp)
+ kfree(cmd);
+ return ret;
+}
+
+/*
+ * iwm_hal_send_umac_cmd(): This is a special case for
+ * iwm_hal_send_host_cmd() to send direct UMAC cmd (without
+ * LMAC involved).
+ */
+int iwm_hal_send_umac_cmd(struct iwm_priv *iwm,
+ struct iwm_udma_wifi_cmd *udma_cmd,
+ struct iwm_umac_cmd *umac_cmd,
+ const void *payload, u16 payload_size)
+{
+ return iwm_hal_send_host_cmd(iwm, udma_cmd, umac_cmd, NULL,
+ payload, payload_size);
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.h b/drivers/net/wireless/iwmc3200wifi/hal.h
new file mode 100644
index 00000000000..0adfdc85765
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/hal.h
@@ -0,0 +1,236 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef _IWM_HAL_H_
+#define _IWM_HAL_H_
+
+#include "umac.h"
+
+#define GET_VAL8(s, name) ((s >> name##_POS) & name##_SEED)
+#define GET_VAL16(s, name) ((le16_to_cpu(s) >> name##_POS) & name##_SEED)
+#define GET_VAL32(s, name) ((le32_to_cpu(s) >> name##_POS) & name##_SEED)
+
+#define SET_VAL8(s, name, val) \
+do { \
+ s = (s & ~(name##_SEED << name##_POS)) | \
+ ((val & name##_SEED) << name##_POS); \
+} while (0)
+
+#define SET_VAL16(s, name, val) \
+do { \
+ s = cpu_to_le16((le16_to_cpu(s) & ~(name##_SEED << name##_POS)) | \
+ ((val & name##_SEED) << name##_POS)); \
+} while (0)
+
+#define SET_VAL32(s, name, val) \
+do { \
+ s = cpu_to_le32((le32_to_cpu(s) & ~(name##_SEED << name##_POS)) | \
+ ((val & name##_SEED) << name##_POS)); \
+} while (0)
+
+
+#define UDMA_UMAC_INIT { .eop = 1, \
+ .credit_group = 0x4, \
+ .ra_tid = UMAC_HDI_ACT_TBL_IDX_HOST_CMD, \
+ .lmac_offset = 0 }
+#define UDMA_LMAC_INIT { .eop = 1, \
+ .credit_group = 0x4, \
+ .ra_tid = UMAC_HDI_ACT_TBL_IDX_HOST_CMD, \
+ .lmac_offset = 4 }
+
+
+/* UDMA IN OP CODE -- cmd bits [3:0] */
+#define UDMA_IN_OPCODE_MASK 0xF
+
+#define UDMA_IN_OPCODE_GENERAL_RESP 0x0
+#define UDMA_IN_OPCODE_READ_RESP 0x1
+#define UDMA_IN_OPCODE_WRITE_RESP 0x2
+#define UDMA_IN_OPCODE_PERS_WRITE_RESP 0x5
+#define UDMA_IN_OPCODE_PERS_READ_RESP 0x6
+#define UDMA_IN_OPCODE_RD_MDFY_WR_RESP 0x7
+#define UDMA_IN_OPCODE_EP_MNGMT_MSG 0x8
+#define UDMA_IN_OPCODE_CRDT_CHNG_MSG 0x9
+#define UDMA_IN_OPCODE_CNTRL_DATABASE_MSG 0xA
+#define UDMA_IN_OPCODE_SW_MSG 0xB
+#define UDMA_IN_OPCODE_WIFI 0xF
+#define UDMA_IN_OPCODE_WIFI_LMAC 0x1F
+#define UDMA_IN_OPCODE_WIFI_UMAC 0x2F
+
+/* HW API: udma_hdi_nonwifi API (OUT and IN) */
+
+/* iwm_udma_nonwifi_cmd request response -- bits [9:9] */
+#define UDMA_HDI_OUT_NW_CMD_RESP_POS 9
+#define UDMA_HDI_OUT_NW_CMD_RESP_SEED 0x1
+
+/* iwm_udma_nonwifi_cmd handle by HW -- bits [11:11] */
+#define UDMA_HDI_OUT_NW_CMD_HANDLE_BY_HW_POS 11
+#define UDMA_HDI_OUT_NW_CMD_HANDLE_BY_HW_SEED 0x1
+
+/* iwm_udma_nonwifi_cmd sequence-number -- bits [12:15] */
+#define UDMA_HDI_OUT_NW_CMD_SEQ_NUM_POS 12
+#define UDMA_HDI_OUT_NW_CMD_SEQ_NUM_SEED 0xF
+
+/* UDMA IN Non-WIFI HW sequence number -- bits [12:15] */
+#define UDMA_IN_NW_HW_SEQ_NUM_POS 12
+#define UDMA_IN_NW_HW_SEQ_NUM_SEED 0xF
+
+/* UDMA IN Non-WIFI HW signature -- bits [16:31] */
+#define UDMA_IN_NW_HW_SIG_POS 16
+#define UDMA_IN_NW_HW_SIG_SEED 0xFFFF
+
+/* fixed signature */
+#define UDMA_IN_NW_HW_SIG 0xCBBC
+
+/* UDMA IN Non-WIFI HW block length -- bits [32:35] */
+#define UDMA_IN_NW_HW_LENGTH_SEED 0xF
+#define UDMA_IN_NW_HW_LENGTH_POS 32
+
+/* End of HW API: udma_hdi_nonwifi API (OUT and IN) */
+
+#define IWM_SDIO_FW_MAX_CHUNK_SIZE 2032
+#define IWM_MAX_WIFI_HEADERS_SIZE 32
+#define IWM_MAX_NONWIFI_HEADERS_SIZE 16
+#define IWM_MAX_NONWIFI_CMD_BUFF_SIZE (IWM_SDIO_FW_MAX_CHUNK_SIZE - \
+ IWM_MAX_NONWIFI_HEADERS_SIZE)
+#define IWM_MAX_WIFI_CMD_BUFF_SIZE (IWM_SDIO_FW_MAX_CHUNK_SIZE - \
+ IWM_MAX_WIFI_HEADERS_SIZE)
+
+#define IWM_HAL_CONCATENATE_BUF_SIZE 8192
+
+struct iwm_wifi_cmd_buff {
+ u16 len;
+ u8 *start;
+ u8 hdr[IWM_MAX_WIFI_HEADERS_SIZE];
+ u8 payload[IWM_MAX_WIFI_CMD_BUFF_SIZE];
+};
+
+struct iwm_nonwifi_cmd_buff {
+ u16 len;
+ u8 *start;
+ u8 hdr[IWM_MAX_NONWIFI_HEADERS_SIZE];
+ u8 payload[IWM_MAX_NONWIFI_CMD_BUFF_SIZE];
+};
+
+struct iwm_udma_nonwifi_cmd {
+ u8 opcode;
+ u8 eop;
+ u8 resp;
+ u8 handle_by_hw;
+ __le32 addr;
+ __le32 op1_sz;
+ __le32 op2;
+ __le16 seq_num;
+};
+
+struct iwm_udma_wifi_cmd {
+ __le16 count;
+ u8 eop;
+ u8 credit_group;
+ u8 ra_tid;
+ u8 lmac_offset;
+};
+
+struct iwm_umac_cmd {
+ u8 id;
+ __le16 count;
+ u8 resp;
+ __le16 seq_num;
+ u8 color;
+};
+
+struct iwm_lmac_cmd {
+ u8 id;
+ __le16 count;
+ u8 resp;
+ __le16 seq_num;
+};
+
+struct iwm_nonwifi_cmd {
+ u16 seq_num;
+ bool resp_received;
+ struct list_head pending;
+ struct iwm_udma_nonwifi_cmd udma_cmd;
+ struct iwm_umac_cmd umac_cmd;
+ struct iwm_lmac_cmd lmac_cmd;
+ struct iwm_nonwifi_cmd_buff buf;
+ u32 flags;
+};
+
+struct iwm_wifi_cmd {
+ u16 seq_num;
+ struct list_head pending;
+ struct iwm_udma_wifi_cmd udma_cmd;
+ struct iwm_umac_cmd umac_cmd;
+ struct iwm_lmac_cmd lmac_cmd;
+ struct iwm_wifi_cmd_buff buf;
+ u32 flags;
+};
+
+void iwm_cmd_flush(struct iwm_priv *iwm);
+
+struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm,
+ u16 seq_num);
+struct iwm_nonwifi_cmd *iwm_get_pending_nonwifi_cmd(struct iwm_priv *iwm,
+ u8 seq_num, u8 cmd_opcode);
+
+
+int iwm_hal_send_target_cmd(struct iwm_priv *iwm,
+ struct iwm_udma_nonwifi_cmd *ucmd,
+ const void *payload);
+
+int iwm_hal_send_host_cmd(struct iwm_priv *iwm,
+ struct iwm_udma_wifi_cmd *udma_cmd,
+ struct iwm_umac_cmd *umac_cmd,
+ struct iwm_lmac_cmd *lmac_cmd,
+ const void *payload, u16 payload_size);
+
+int iwm_hal_send_umac_cmd(struct iwm_priv *iwm,
+ struct iwm_udma_wifi_cmd *udma_cmd,
+ struct iwm_umac_cmd *umac_cmd,
+ const void *payload, u16 payload_size);
+
+u16 iwm_alloc_wifi_cmd_seq(struct iwm_priv *iwm);
+
+void iwm_udma_wifi_hdr_set_eop(struct iwm_priv *iwm, u8 *buf, u8 eop);
+void iwm_build_udma_wifi_hdr(struct iwm_priv *iwm,
+ struct iwm_udma_out_wifi_hdr *hdr,
+ struct iwm_udma_wifi_cmd *cmd);
+void iwm_build_umac_hdr(struct iwm_priv *iwm,
+ struct iwm_umac_fw_cmd_hdr *hdr,
+ struct iwm_umac_cmd *cmd);
+#endif /* _IWM_HAL_H_ */
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
new file mode 100644
index 00000000000..635c16ee618
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -0,0 +1,346 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_H__
+#define __IWM_H__
+
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <net/cfg80211.h>
+
+#include "debug.h"
+#include "hal.h"
+#include "umac.h"
+#include "lmac.h"
+#include "eeprom.h"
+
+#define IWM_COPYRIGHT "Copyright(c) 2009 Intel Corporation"
+#define IWM_AUTHOR "<ilw@linux.intel.com>"
+
+#define CONFIG_IWM_B0_HW_SUPPORT 1
+
+#define IWM_SRC_LMAC UMAC_HDI_IN_SOURCE_FHRX
+#define IWM_SRC_UDMA UMAC_HDI_IN_SOURCE_UDMA
+#define IWM_SRC_UMAC UMAC_HDI_IN_SOURCE_FW
+#define IWM_SRC_NUM 3
+
+#define IWM_POWER_INDEX_MIN 0
+#define IWM_POWER_INDEX_MAX 5
+#define IWM_POWER_INDEX_DEFAULT 3
+
+struct iwm_conf {
+ u32 sdio_ior_timeout;
+ unsigned long init_calib_map;
+ unsigned long periodic_calib_map;
+ bool reset_on_fatal_err;
+ bool auto_connect;
+ bool wimax_not_present;
+ bool enable_qos;
+ u32 mode;
+
+ u32 power_index;
+ u32 frag_threshold;
+ u32 rts_threshold;
+ bool cts_to_self;
+
+ u32 assoc_timeout;
+ u32 roam_timeout;
+ u32 wireless_mode;
+ u32 coexist_mode;
+
+ u8 ibss_band;
+ u8 ibss_channel;
+
+ u8 mac_addr[ETH_ALEN];
+#ifdef CONFIG_IWM_B0_HW_SUPPORT
+ bool hw_b0;
+#endif
+};
+
+enum {
+ COEX_MODE_SA = 1,
+ COEX_MODE_XOR,
+ COEX_MODE_CM,
+ COEX_MODE_MAX,
+};
+
+struct iwm_if_ops;
+struct iwm_wifi_cmd;
+
+struct pool_entry {
+ int id; /* group id */
+ int sid; /* super group id */
+ int min_pages; /* min capacity in pages */
+ int max_pages; /* max capacity in pages */
+ int alloc_pages; /* allocated # of pages. incresed by driver */
+ int total_freed_pages; /* total freed # of pages. incresed by UMAC */
+};
+
+struct spool_entry {
+ int id;
+ int max_pages;
+ int alloc_pages;
+};
+
+struct iwm_tx_credit {
+ spinlock_t lock;
+ int pool_nr;
+ unsigned long full_pools_map; /* bitmap for # of filled tx pools */
+ struct pool_entry pools[IWM_MACS_OUT_GROUPS];
+ struct spool_entry spools[IWM_MACS_OUT_SGROUPS];
+};
+
+struct iwm_notif {
+ struct list_head pending;
+ u32 cmd_id;
+ void *cmd;
+ u8 src;
+ void *buf;
+ unsigned long buf_size;
+};
+
+struct iwm_sta_info {
+ u8 addr[ETH_ALEN];
+ bool valid;
+ bool qos;
+ u8 color;
+};
+
+struct iwm_tx_info {
+ u8 sta;
+ u8 color;
+ u8 tid;
+};
+
+struct iwm_rx_info {
+ unsigned long rx_size;
+ unsigned long rx_buf_size;
+};
+
+#define IWM_NUM_KEYS 4
+
+struct iwm_umac_key_hdr {
+ u8 mac[ETH_ALEN];
+ u8 key_idx;
+ u8 multicast; /* BCast encrypt & BCast decrypt of frames FROM mac */
+} __attribute__ ((packed));
+
+struct iwm_key {
+ struct iwm_umac_key_hdr hdr;
+ u8 in_use;
+ u8 alg;
+ u32 flags;
+ u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE];
+ u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE];
+ u8 key_len;
+ u8 key[32];
+};
+
+#define IWM_RX_ID_HASH 0xff
+#define IWM_RX_ID_GET_HASH(id) ((id) % IWM_RX_ID_HASH)
+
+#define IWM_STA_TABLE_NUM 16
+#define IWM_TX_LIST_SIZE 64
+#define IWM_RX_LIST_SIZE 256
+
+#define IWM_SCAN_ID_MAX 0xff
+
+#define IWM_STATUS_READY 0
+#define IWM_STATUS_SCANNING 1
+#define IWM_STATUS_SCAN_ABORTING 2
+#define IWM_STATUS_ASSOCIATING 3
+#define IWM_STATUS_ASSOCIATED 4
+
+#define IWM_RADIO_RFKILL_OFF 0
+#define IWM_RADIO_RFKILL_HW 1
+#define IWM_RADIO_RFKILL_SW 2
+
+struct iwm_tx_queue {
+ int id;
+ struct sk_buff_head queue;
+ struct workqueue_struct *wq;
+ struct work_struct worker;
+ u8 concat_buf[IWM_HAL_CONCATENATE_BUF_SIZE];
+ int concat_count;
+ u8 *concat_ptr;
+};
+
+/* Queues 0 ~ 3 for AC data, 5 for iPAN */
+#define IWM_TX_QUEUES 5
+#define IWM_TX_DATA_QUEUES 4
+#define IWM_TX_CMD_QUEUE 4
+
+struct iwm_bss_info {
+ struct list_head node;
+ struct cfg80211_bss *cfg_bss;
+ struct iwm_umac_notif_bss_info *bss;
+};
+
+typedef int (*iwm_handler)(struct iwm_priv *priv, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd);
+
+#define IWM_WATCHDOG_PERIOD (6 * HZ)
+
+struct iwm_priv {
+ struct wireless_dev *wdev;
+ struct iwm_if_ops *bus_ops;
+
+ struct iwm_conf conf;
+
+ unsigned long status;
+ unsigned long radio;
+
+ struct list_head pending_notif;
+ wait_queue_head_t notif_queue;
+
+ wait_queue_head_t nonwifi_queue;
+
+ unsigned long calib_done_map;
+ struct {
+ u8 *buf;
+ u32 size;
+ } calib_res[CALIBRATION_CMD_NUM];
+
+ struct iwm_umac_profile *umac_profile;
+ bool umac_profile_active;
+
+ u8 bssid[ETH_ALEN];
+ u8 channel;
+ u16 rate;
+
+ struct iwm_sta_info sta_table[IWM_STA_TABLE_NUM];
+ struct list_head bss_list;
+
+ void (*nonwifi_rx_handlers[UMAC_HDI_IN_OPCODE_NONWIFI_MAX])
+ (struct iwm_priv *priv, u8 *buf, unsigned long buf_size);
+
+ const iwm_handler *umac_handlers;
+ const iwm_handler *lmac_handlers;
+ DECLARE_BITMAP(lmac_handler_map, LMAC_COMMAND_ID_NUM);
+ DECLARE_BITMAP(umac_handler_map, LMAC_COMMAND_ID_NUM);
+ DECLARE_BITMAP(udma_handler_map, LMAC_COMMAND_ID_NUM);
+
+ struct list_head wifi_pending_cmd;
+ struct list_head nonwifi_pending_cmd;
+ u16 wifi_seq_num;
+ u8 nonwifi_seq_num;
+ spinlock_t cmd_lock;
+
+ u32 core_enabled;
+
+ u8 scan_id;
+ struct cfg80211_scan_request *scan_request;
+
+ struct sk_buff_head rx_list;
+ struct list_head rx_tickets;
+ struct list_head rx_packets[IWM_RX_ID_HASH];
+ struct workqueue_struct *rx_wq;
+ struct work_struct rx_worker;
+
+ struct iwm_tx_credit tx_credit;
+ struct iwm_tx_queue txq[IWM_TX_QUEUES];
+
+ struct iwm_key keys[IWM_NUM_KEYS];
+ struct iwm_key *default_key;
+
+ wait_queue_head_t mlme_queue;
+
+ struct iw_statistics wstats;
+ struct delayed_work stats_request;
+
+ struct iwm_debugfs dbg;
+
+ u8 *eeprom;
+ struct timer_list watchdog;
+ struct work_struct reset_worker;
+ struct rfkill *rfkill;
+
+ char private[0] __attribute__((__aligned__(NETDEV_ALIGN)));
+};
+
+static inline void *iwm_private(struct iwm_priv *iwm)
+{
+ BUG_ON(!iwm);
+ return &iwm->private;
+}
+
+#define hw_to_iwm(h) (h->iwm)
+#define iwm_to_dev(i) (wiphy_dev(i->wdev->wiphy))
+#define iwm_to_wiphy(i) (i->wdev->wiphy)
+#define wiphy_to_iwm(w) (struct iwm_priv *)(wiphy_priv(w))
+#define iwm_to_wdev(i) (i->wdev)
+#define wdev_to_iwm(w) (struct iwm_priv *)(wdev_priv(w))
+#define iwm_to_ndev(i) (i->wdev->netdev)
+#define ndev_to_iwm(n) (wdev_to_iwm(n->ieee80211_ptr))
+#define skb_to_rx_info(s) ((struct iwm_rx_info *)(s->cb))
+#define skb_to_tx_info(s) ((struct iwm_tx_info *)s->cb)
+
+extern const struct iw_handler_def iwm_iw_handler_def;
+
+void *iwm_if_alloc(int sizeof_bus, struct device *dev,
+ struct iwm_if_ops *if_ops);
+void iwm_if_free(struct iwm_priv *iwm);
+int iwm_mode_to_nl80211_iftype(int mode);
+int iwm_priv_init(struct iwm_priv *iwm);
+void iwm_reset(struct iwm_priv *iwm);
+void iwm_tx_credit_init_pools(struct iwm_priv *iwm,
+ struct iwm_umac_notif_alive *alive);
+int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb);
+int iwm_notif_send(struct iwm_priv *iwm, struct iwm_wifi_cmd *cmd,
+ u8 cmd_id, u8 source, u8 *buf, unsigned long buf_size);
+int iwm_notif_handle(struct iwm_priv *iwm, u32 cmd, u8 source, long timeout);
+void iwm_init_default_profile(struct iwm_priv *iwm,
+ struct iwm_umac_profile *profile);
+void iwm_link_on(struct iwm_priv *iwm);
+void iwm_link_off(struct iwm_priv *iwm);
+int iwm_up(struct iwm_priv *iwm);
+int iwm_down(struct iwm_priv *iwm);
+
+/* TX API */
+void iwm_tx_credit_inc(struct iwm_priv *iwm, int id, int total_freed_pages);
+void iwm_tx_worker(struct work_struct *work);
+int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
+
+/* RX API */
+void iwm_rx_setup_handlers(struct iwm_priv *iwm);
+int iwm_rx_handle(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size);
+int iwm_rx_handle_resp(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd);
+void iwm_rx_free(struct iwm_priv *iwm);
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/lmac.h b/drivers/net/wireless/iwmc3200wifi/lmac.h
new file mode 100644
index 00000000000..db2e5eea189
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/lmac.h
@@ -0,0 +1,457 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_LMAC_H__
+#define __IWM_LMAC_H__
+
+struct iwm_lmac_hdr {
+ u8 id;
+ u8 flags;
+ __le16 seq_num;
+} __attribute__ ((packed));
+
+/* LMAC commands */
+#define CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_AFTER_MSK 0x1
+
+struct iwm_lmac_cal_cfg_elt {
+ __le32 enable; /* 1 means LMAC needs to do something */
+ __le32 start; /* 1 to start calibration, 0 to stop */
+ __le32 send_res; /* 1 for sending back results */
+ __le32 apply_res; /* 1 for applying calibration results to HW */
+ __le32 reserved;
+} __attribute__ ((packed));
+
+struct iwm_lmac_cal_cfg_status {
+ struct iwm_lmac_cal_cfg_elt init;
+ struct iwm_lmac_cal_cfg_elt periodic;
+ __le32 flags; /* CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_AFTER_MSK */
+} __attribute__ ((packed));
+
+struct iwm_lmac_cal_cfg_cmd {
+ struct iwm_lmac_cal_cfg_status ucode_cfg;
+ struct iwm_lmac_cal_cfg_status driver_cfg;
+ __le32 reserved;
+} __attribute__ ((packed));
+
+struct iwm_lmac_cal_cfg_resp {
+ __le32 status;
+} __attribute__ ((packed));
+
+#define IWM_CARD_STATE_SW_HW_ENABLED 0x00
+#define IWM_CARD_STATE_HW_DISABLED 0x01
+#define IWM_CARD_STATE_SW_DISABLED 0x02
+#define IWM_CARD_STATE_CTKILL_DISABLED 0x04
+#define IWM_CARD_STATE_IS_RXON 0x10
+
+struct iwm_lmac_card_state {
+ __le32 flags;
+} __attribute__ ((packed));
+
+/**
+ * COEX_PRIORITY_TABLE_CMD
+ *
+ * Priority entry for each state
+ * Will keep two tables, for STA and WIPAN
+ */
+enum {
+ /* UN-ASSOCIATION PART */
+ COEX_UNASSOC_IDLE = 0,
+ COEX_UNASSOC_MANUAL_SCAN,
+ COEX_UNASSOC_AUTO_SCAN,
+
+ /* CALIBRATION */
+ COEX_CALIBRATION,
+ COEX_PERIODIC_CALIBRATION,
+
+ /* CONNECTION */
+ COEX_CONNECTION_ESTAB,
+
+ /* ASSOCIATION PART */
+ COEX_ASSOCIATED_IDLE,
+ COEX_ASSOC_MANUAL_SCAN,
+ COEX_ASSOC_AUTO_SCAN,
+ COEX_ASSOC_ACTIVE_LEVEL,
+
+ /* RF ON/OFF */
+ COEX_RF_ON,
+ COEX_RF_OFF,
+ COEX_STAND_ALONE_DEBUG,
+
+ /* IPNN */
+ COEX_IPAN_ASSOC_LEVEL,
+
+ /* RESERVED */
+ COEX_RSRVD1,
+ COEX_RSRVD2,
+
+ COEX_EVENTS_NUM
+};
+
+#define COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK 0x1
+#define COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK 0x2
+#define COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_MSK 0x4
+
+struct coex_event {
+ u8 req_prio;
+ u8 win_med_prio;
+ u8 reserved;
+ u8 flags;
+} __attribute__ ((packed));
+
+#define COEX_FLAGS_STA_TABLE_VALID_MSK 0x1
+#define COEX_FLAGS_UNASSOC_WAKEUP_UMASK_MSK 0x4
+#define COEX_FLAGS_ASSOC_WAKEUP_UMASK_MSK 0x8
+#define COEX_FLAGS_COEX_ENABLE_MSK 0x80
+
+struct iwm_coex_prio_table_cmd {
+ u8 flags;
+ u8 reserved[3];
+ struct coex_event sta_prio[COEX_EVENTS_NUM];
+} __attribute__ ((packed));
+
+/* Coexistence definitions
+ *
+ * Constants to fill in the Priorities' Tables
+ * RP - Requested Priority
+ * WP - Win Medium Priority: priority assigned when the contention has been won
+ * FLAGS - Combination of COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK and
+ * COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK
+ */
+
+#define COEX_UNASSOC_IDLE_FLAGS 0
+#define COEX_UNASSOC_MANUAL_SCAN_FLAGS (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+ COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK)
+#define COEX_UNASSOC_AUTO_SCAN_FLAGS (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+ COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK)
+#define COEX_CALIBRATION_FLAGS (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+ COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK)
+#define COEX_PERIODIC_CALIBRATION_FLAGS 0
+/* COEX_CONNECTION_ESTAB: we need DELAY_MEDIUM_FREE_NTFY to let WiMAX
+ * disconnect from network. */
+#define COEX_CONNECTION_ESTAB_FLAGS (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+ COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK | \
+ COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_MSK)
+#define COEX_ASSOCIATED_IDLE_FLAGS 0
+#define COEX_ASSOC_MANUAL_SCAN_FLAGS (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+ COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK)
+#define COEX_ASSOC_AUTO_SCAN_FLAGS (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+ COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK)
+#define COEX_ASSOC_ACTIVE_LEVEL_FLAGS 0
+#define COEX_RF_ON_FLAGS 0
+#define COEX_RF_OFF_FLAGS 0
+#define COEX_STAND_ALONE_DEBUG_FLAGS (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+ COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK)
+#define COEX_IPAN_ASSOC_LEVEL_FLAGS (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+ COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK | \
+ COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_MSK)
+#define COEX_RSRVD1_FLAGS 0
+#define COEX_RSRVD2_FLAGS 0
+/* XOR_RF_ON is the event wrapping all radio ownership. We need
+ * DELAY_MEDIUM_FREE_NTFY to let WiMAX disconnect from network. */
+#define COEX_XOR_RF_ON_FLAGS (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+ COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK | \
+ COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_MSK)
+
+/* LMAC OP CODES */
+#define REPLY_PAD 0x0
+#define REPLY_ALIVE 0x1
+#define REPLY_ERROR 0x2
+#define REPLY_ECHO 0x3
+#define REPLY_HALT 0x6
+
+/* RXON state commands */
+#define REPLY_RX_ON 0x10
+#define REPLY_RX_ON_ASSOC 0x11
+#define REPLY_RX_OFF 0x12
+#define REPLY_QOS_PARAM 0x13
+#define REPLY_RX_ON_TIMING 0x14
+#define REPLY_INTERNAL_QOS_PARAM 0x15
+#define REPLY_RX_INT_TIMEOUT_CNFG 0x16
+#define REPLY_NULL 0x17
+
+/* Multi-Station support */
+#define REPLY_ADD_STA 0x18
+#define REPLY_REMOVE_STA 0x19
+#define REPLY_RESET_ALL_STA 0x1a
+
+/* RX, TX */
+#define REPLY_ALM_RX 0x1b
+#define REPLY_TX 0x1c
+#define REPLY_TXFIFO_FLUSH 0x1e
+
+/* MISC commands */
+#define REPLY_MGMT_MCAST_KEY 0x1f
+#define REPLY_WEPKEY 0x20
+#define REPLY_INIT_IV 0x21
+#define REPLY_WRITE_MIB 0x22
+#define REPLY_READ_MIB 0x23
+#define REPLY_RADIO_FE 0x24
+#define REPLY_TXFIFO_CFG 0x25
+#define REPLY_WRITE_READ 0x26
+#define REPLY_INSTALL_SEC_KEY 0x27
+
+
+#define REPLY_RATE_SCALE 0x47
+#define REPLY_LEDS_CMD 0x48
+#define REPLY_TX_LINK_QUALITY_CMD 0x4e
+#define REPLY_ANA_MIB_OVERRIDE_CMD 0x4f
+#define REPLY_WRITE2REG_CMD 0x50
+
+/* winfi-wifi coexistence */
+#define COEX_PRIORITY_TABLE_CMD 0x5a
+#define COEX_MEDIUM_NOTIFICATION 0x5b
+#define COEX_EVENT_CMD 0x5c
+
+/* more Protocol and Protocol-test commands */
+#define REPLY_MAX_SLEEP_TIME_CMD 0x61
+#define CALIBRATION_CFG_CMD 0x65
+#define CALIBRATION_RES_NOTIFICATION 0x66
+#define CALIBRATION_COMPLETE_NOTIFICATION 0x67
+
+/* Measurements */
+#define REPLY_QUIET_CMD 0x71
+#define REPLY_CHANNEL_SWITCH 0x72
+#define CHANNEL_SWITCH_NOTIFICATION 0x73
+
+#define REPLY_SPECTRUM_MEASUREMENT_CMD 0x74
+#define SPECTRUM_MEASURE_NOTIFICATION 0x75
+#define REPLY_MEASUREMENT_ABORT_CMD 0x76
+
+/* Power Management */
+#define POWER_TABLE_CMD 0x77
+#define SAVE_RESTORE_ADRESS_CMD 0x78
+#define REPLY_WATERMARK_CMD 0x79
+#define PM_DEBUG_STATISTIC_NOTIFIC 0x7B
+#define PD_FLUSH_N_NOTIFICATION 0x7C
+
+/* Scan commands and notifications */
+#define REPLY_SCAN_REQUEST_CMD 0x80
+#define REPLY_SCAN_ABORT_CMD 0x81
+#define SCAN_START_NOTIFICATION 0x82
+#define SCAN_RESULTS_NOTIFICATION 0x83
+#define SCAN_COMPLETE_NOTIFICATION 0x84
+
+/* Continuous TX commands */
+#define REPLY_CONT_TX_CMD 0x85
+#define END_OF_CONT_TX_NOTIFICATION 0x86
+
+/* Timer/Eeprom commands */
+#define TIMER_CMD 0x87
+#define EEPROM_WRITE_CMD 0x88
+
+/* PAPD commands */
+#define FEEDBACK_REQUEST_NOTIFICATION 0x8b
+#define REPLY_CW_CMD 0x8c
+
+/* IBSS/AP commands Continue */
+#define BEACON_NOTIFICATION 0x90
+#define REPLY_TX_BEACON 0x91
+#define REPLY_REQUEST_ATIM 0x93
+#define WHO_IS_AWAKE_NOTIFICATION 0x94
+#define TX_PWR_DBM_LIMIT_CMD 0x95
+#define QUIET_NOTIFICATION 0x96
+#define TX_PWR_TABLE_CMD 0x97
+#define TX_ANT_CONFIGURATION_CMD 0x98
+#define MEASURE_ABORT_NOTIFICATION 0x99
+#define REPLY_CALIBRATION_TUNE 0x9a
+
+/* bt config command */
+#define REPLY_BT_CONFIG 0x9b
+#define REPLY_STATISTICS_CMD 0x9c
+#define STATISTICS_NOTIFICATION 0x9d
+
+/* RF-KILL commands and notifications */
+#define REPLY_CARD_STATE_CMD 0xa0
+#define CARD_STATE_NOTIFICATION 0xa1
+
+/* Missed beacons notification */
+#define MISSED_BEACONS_NOTIFICATION 0xa2
+#define MISSED_BEACONS_NOTIFICATION_TH_CMD 0xa3
+
+#define REPLY_CT_KILL_CONFIG_CMD 0xa4
+
+/* HD commands and notifications */
+#define REPLY_HD_PARAMS_CMD 0xa6
+#define HD_PARAMS_NOTIFICATION 0xa7
+#define SENSITIVITY_CMD 0xa8
+#define U_APSD_PARAMS_CMD 0xa9
+#define NOISY_PLATFORM_CMD 0xaa
+#define ILLEGAL_CMD 0xac
+#define REPLY_PHY_CALIBRATION_CMD 0xb0
+#define REPLAY_RX_GAIN_CALIB_CMD 0xb1
+
+/* WiPAN commands */
+#define REPLY_WIPAN_PARAMS_CMD 0xb2
+#define REPLY_WIPAN_RX_ON_CMD 0xb3
+#define REPLY_WIPAN_RX_ON_TIMING 0xb4
+#define REPLY_WIPAN_TX_PWR_TABLE_CMD 0xb5
+#define REPLY_WIPAN_RXON_ASSOC_CMD 0xb6
+#define REPLY_WIPAN_QOS_PARAM 0xb7
+#define WIPAN_REPLY_WEPKEY 0xb8
+
+/* BeamForming commands */
+#define BEAMFORMER_CFG_CMD 0xba
+#define BEAMFORMEE_NOTIFICATION 0xbb
+
+/* TGn new Commands */
+#define REPLY_RX_PHY_CMD 0xc0
+#define REPLY_RX_MPDU_CMD 0xc1
+#define REPLY_MULTICAST_HASH 0xc2
+#define REPLY_KDR_RX 0xc3
+#define REPLY_RX_DSP_EXT_INFO 0xc4
+#define REPLY_COMPRESSED_BA 0xc5
+
+/* PNC commands */
+#define PNC_CONFIG_CMD 0xc8
+#define PNC_UPDATE_TABLE_CMD 0xc9
+#define XVT_GENERAL_CTRL_CMD 0xca
+#define REPLY_LEGACY_RADIO_FE 0xdd
+
+/* WoWLAN commands */
+#define WOWLAN_PATTERNS 0xe0
+#define WOWLAN_WAKEUP_FILTER 0xe1
+#define WOWLAN_TSC_RSC_PARAM 0xe2
+#define WOWLAN_TKIP_PARAM 0xe3
+#define WOWLAN_KEK_KCK_MATERIAL 0xe4
+#define WOWLAN_GET_STATUSES 0xe5
+#define WOWLAN_TX_POWER_PER_DB 0xe6
+#define REPLY_WOWLAN_GET_STATUSES WOWLAN_GET_STATUSES
+
+#define REPLY_DEBUG_CMD 0xf0
+#define REPLY_DSP_DEBUG_CMD 0xf1
+#define REPLY_DEBUG_MONITOR_CMD 0xf2
+#define REPLY_DEBUG_XVT_CMD 0xf3
+#define REPLY_DEBUG_DC_CALIB 0xf4
+#define REPLY_DYNAMIC_BP 0xf5
+
+/* General purpose Commands */
+#define REPLY_GP1_CMD 0xfa
+#define REPLY_GP2_CMD 0xfb
+#define REPLY_GP3_CMD 0xfc
+#define REPLY_GP4_CMD 0xfd
+#define REPLY_REPLAY_WRAPPER 0xfe
+#define REPLY_FRAME_DURATION_CALC_CMD 0xff
+
+#define LMAC_COMMAND_ID_MAX 0xff
+#define LMAC_COMMAND_ID_NUM (LMAC_COMMAND_ID_MAX + 1)
+
+
+/* Calibration */
+
+enum {
+ PHY_CALIBRATE_DC_CMD = 0,
+ PHY_CALIBRATE_LO_CMD = 1,
+ PHY_CALIBRATE_RX_BB_CMD = 2,
+ PHY_CALIBRATE_TX_IQ_CMD = 3,
+ PHY_CALIBRATE_RX_IQ_CMD = 4,
+ PHY_CALIBRATION_NOISE_CMD = 5,
+ PHY_CALIBRATE_AGC_TABLE_CMD = 6,
+ PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 7,
+ PHY_CALIBRATE_OPCODES_NUM,
+ SHILOH_PHY_CALIBRATE_DC_CMD = 8,
+ SHILOH_PHY_CALIBRATE_LO_CMD = 9,
+ SHILOH_PHY_CALIBRATE_RX_BB_CMD = 10,
+ SHILOH_PHY_CALIBRATE_TX_IQ_CMD = 11,
+ SHILOH_PHY_CALIBRATE_RX_IQ_CMD = 12,
+ SHILOH_PHY_CALIBRATION_NOISE_CMD = 13,
+ SHILOH_PHY_CALIBRATE_AGC_TABLE_CMD = 14,
+ SHILOH_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15,
+ SHILOH_PHY_CALIBRATE_BASE_BAND_CMD = 16,
+ SHILOH_PHY_CALIBRATE_TXIQ_PERIODIC_CMD = 17,
+ CALIBRATION_CMD_NUM,
+};
+
+struct iwm_lmac_calib_hdr {
+ u8 opcode;
+ u8 first_grp;
+ u8 grp_num;
+ u8 all_data_valid;
+} __attribute__ ((packed));
+
+#define IWM_LMAC_CALIB_FREQ_GROUPS_NR 7
+#define IWM_CALIB_FREQ_GROUPS_NR 5
+#define IWM_CALIB_DC_MODES_NR 12
+
+struct iwm_calib_rxiq_entry {
+ u16 ptam_postdist_ars;
+ u16 ptam_postdist_arc;
+} __attribute__ ((packed));
+
+struct iwm_calib_rxiq_group {
+ struct iwm_calib_rxiq_entry mode[IWM_CALIB_DC_MODES_NR];
+} __attribute__ ((packed));
+
+struct iwm_lmac_calib_rxiq {
+ struct iwm_calib_rxiq_group group[IWM_LMAC_CALIB_FREQ_GROUPS_NR];
+} __attribute__ ((packed));
+
+struct iwm_calib_rxiq {
+ struct iwm_lmac_calib_hdr hdr;
+ struct iwm_calib_rxiq_group group[IWM_CALIB_FREQ_GROUPS_NR];
+} __attribute__ ((packed));
+
+#define LMAC_STA_ID_SEED 0x0f
+#define LMAC_STA_ID_POS 0
+
+#define LMAC_STA_COLOR_SEED 0x7
+#define LMAC_STA_COLOR_POS 4
+
+struct iwm_lmac_power_report {
+ u8 pa_status;
+ u8 pa_integ_res_A[3];
+ u8 pa_integ_res_B[3];
+ u8 pa_integ_res_C[3];
+} __attribute__ ((packed));
+
+struct iwm_lmac_tx_resp {
+ u8 frame_cnt; /* 1-no aggregation, greater then 1 - aggregation */
+ u8 bt_kill_cnt;
+ __le16 retry_cnt;
+ __le32 initial_tx_rate;
+ __le16 wireless_media_time;
+ struct iwm_lmac_power_report power_report;
+ __le32 tfd_info;
+ __le16 seq_ctl;
+ __le16 byte_cnt;
+ u8 tlc_rate_info;
+ u8 ra_tid;
+ __le16 frame_ctl;
+ __le32 status;
+} __attribute__ ((packed));
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
new file mode 100644
index 00000000000..6a2640f16b6
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -0,0 +1,680 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/ieee80211.h>
+#include <linux/wireless.h>
+
+#include "iwm.h"
+#include "debug.h"
+#include "bus.h"
+#include "umac.h"
+#include "commands.h"
+#include "hal.h"
+#include "fw.h"
+#include "rx.h"
+
+static struct iwm_conf def_iwm_conf = {
+
+ .sdio_ior_timeout = 5000,
+ .init_calib_map = BIT(PHY_CALIBRATE_DC_CMD) |
+ BIT(PHY_CALIBRATE_LO_CMD) |
+ BIT(PHY_CALIBRATE_TX_IQ_CMD) |
+ BIT(PHY_CALIBRATE_RX_IQ_CMD),
+ .periodic_calib_map = BIT(PHY_CALIBRATE_DC_CMD) |
+ BIT(PHY_CALIBRATE_LO_CMD) |
+ BIT(PHY_CALIBRATE_TX_IQ_CMD) |
+ BIT(PHY_CALIBRATE_RX_IQ_CMD) |
+ BIT(SHILOH_PHY_CALIBRATE_BASE_BAND_CMD),
+ .reset_on_fatal_err = 1,
+ .auto_connect = 1,
+ .wimax_not_present = 0,
+ .enable_qos = 1,
+ .mode = UMAC_MODE_BSS,
+
+ /* UMAC configuration */
+ .power_index = 0,
+ .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
+ .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD,
+ .cts_to_self = 0,
+
+ .assoc_timeout = 2,
+ .roam_timeout = 10,
+ .wireless_mode = WIRELESS_MODE_11A | WIRELESS_MODE_11G,
+ .coexist_mode = COEX_MODE_CM,
+
+ /* IBSS */
+ .ibss_band = UMAC_BAND_2GHZ,
+ .ibss_channel = 1,
+
+ .mac_addr = {0x00, 0x02, 0xb3, 0x01, 0x02, 0x03},
+};
+
+static int modparam_reset;
+module_param_named(reset, modparam_reset, bool, 0644);
+MODULE_PARM_DESC(reset, "reset on firmware errors (default 0 [not reset])");
+
+int iwm_mode_to_nl80211_iftype(int mode)
+{
+ switch (mode) {
+ case UMAC_MODE_BSS:
+ return NL80211_IFTYPE_STATION;
+ case UMAC_MODE_IBSS:
+ return NL80211_IFTYPE_ADHOC;
+ default:
+ return NL80211_IFTYPE_UNSPECIFIED;
+ }
+
+ return 0;
+}
+
+static void iwm_statistics_request(struct work_struct *work)
+{
+ struct iwm_priv *iwm =
+ container_of(work, struct iwm_priv, stats_request.work);
+
+ iwm_send_umac_stats_req(iwm, 0);
+}
+
+static void iwm_reset_worker(struct work_struct *work)
+{
+ struct iwm_priv *iwm;
+ struct iwm_umac_profile *profile = NULL;
+ int uninitialized_var(ret), retry = 0;
+
+ iwm = container_of(work, struct iwm_priv, reset_worker);
+
+ if (iwm->umac_profile_active) {
+ profile = kmalloc(sizeof(struct iwm_umac_profile), GFP_KERNEL);
+ if (profile)
+ memcpy(profile, iwm->umac_profile, sizeof(*profile));
+ else
+ IWM_ERR(iwm, "Couldn't alloc memory for profile\n");
+ }
+
+ iwm_down(iwm);
+
+ while (retry++ < 3) {
+ ret = iwm_up(iwm);
+ if (!ret)
+ break;
+
+ schedule_timeout_uninterruptible(10 * HZ);
+ }
+
+ if (ret) {
+ IWM_WARN(iwm, "iwm_up() failed: %d\n", ret);
+
+ kfree(profile);
+ return;
+ }
+
+ if (profile) {
+ IWM_DBG_MLME(iwm, DBG, "Resend UMAC profile\n");
+ memcpy(iwm->umac_profile, profile, sizeof(*profile));
+ iwm_send_mlme_profile(iwm);
+ kfree(profile);
+ }
+}
+
+static void iwm_watchdog(unsigned long data)
+{
+ struct iwm_priv *iwm = (struct iwm_priv *)data;
+
+ IWM_WARN(iwm, "Watchdog expired: UMAC stalls!\n");
+
+ if (modparam_reset)
+ schedule_work(&iwm->reset_worker);
+}
+
+int iwm_priv_init(struct iwm_priv *iwm)
+{
+ int i;
+ char name[32];
+
+ iwm->status = 0;
+ INIT_LIST_HEAD(&iwm->pending_notif);
+ init_waitqueue_head(&iwm->notif_queue);
+ init_waitqueue_head(&iwm->nonwifi_queue);
+ init_waitqueue_head(&iwm->mlme_queue);
+ memcpy(&iwm->conf, &def_iwm_conf, sizeof(struct iwm_conf));
+ spin_lock_init(&iwm->tx_credit.lock);
+ INIT_LIST_HEAD(&iwm->wifi_pending_cmd);
+ INIT_LIST_HEAD(&iwm->nonwifi_pending_cmd);
+ iwm->wifi_seq_num = UMAC_WIFI_SEQ_NUM_BASE;
+ iwm->nonwifi_seq_num = UMAC_NONWIFI_SEQ_NUM_BASE;
+ spin_lock_init(&iwm->cmd_lock);
+ iwm->scan_id = 1;
+ INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request);
+ INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
+ INIT_LIST_HEAD(&iwm->bss_list);
+
+ skb_queue_head_init(&iwm->rx_list);
+ INIT_LIST_HEAD(&iwm->rx_tickets);
+ for (i = 0; i < IWM_RX_ID_HASH; i++)
+ INIT_LIST_HEAD(&iwm->rx_packets[i]);
+
+ INIT_WORK(&iwm->rx_worker, iwm_rx_worker);
+
+ iwm->rx_wq = create_singlethread_workqueue(KBUILD_MODNAME "_rx");
+ if (!iwm->rx_wq)
+ return -EAGAIN;
+
+ for (i = 0; i < IWM_TX_QUEUES; i++) {
+ INIT_WORK(&iwm->txq[i].worker, iwm_tx_worker);
+ snprintf(name, 32, KBUILD_MODNAME "_tx_%d", i);
+ iwm->txq[i].id = i;
+ iwm->txq[i].wq = create_singlethread_workqueue(name);
+ if (!iwm->txq[i].wq)
+ return -EAGAIN;
+
+ skb_queue_head_init(&iwm->txq[i].queue);
+ }
+
+ for (i = 0; i < IWM_NUM_KEYS; i++)
+ memset(&iwm->keys[i], 0, sizeof(struct iwm_key));
+
+ iwm->default_key = NULL;
+
+ init_timer(&iwm->watchdog);
+ iwm->watchdog.function = iwm_watchdog;
+ iwm->watchdog.data = (unsigned long)iwm;
+
+ return 0;
+}
+
+/*
+ * We reset all the structures, and we reset the UMAC.
+ * After calling this routine, you're expected to reload
+ * the firmware.
+ */
+void iwm_reset(struct iwm_priv *iwm)
+{
+ struct iwm_notif *notif, *next;
+
+ if (test_bit(IWM_STATUS_READY, &iwm->status))
+ iwm_target_reset(iwm);
+
+ iwm->status = 0;
+ iwm->scan_id = 1;
+
+ list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) {
+ list_del(&notif->pending);
+ kfree(notif->buf);
+ kfree(notif);
+ }
+
+ iwm_cmd_flush(iwm);
+
+ flush_workqueue(iwm->rx_wq);
+
+ iwm_link_off(iwm);
+}
+
+/*
+ * Notification code:
+ *
+ * We're faced with the following issue: Any host command can
+ * have an answer or not, and if there's an answer to expect,
+ * it can be treated synchronously or asynchronously.
+ * To work around the synchronous answer case, we implemented
+ * our notification mechanism.
+ * When a code path needs to wait for a command response
+ * synchronously, it calls notif_handle(), which waits for the
+ * right notification to show up, and then process it. Before
+ * starting to wait, it registered as a waiter for this specific
+ * answer (by toggling a bit in on of the handler_map), so that
+ * the rx code knows that it needs to send a notification to the
+ * waiting processes. It does so by calling iwm_notif_send(),
+ * which adds the notification to the pending notifications list,
+ * and then wakes the waiting processes up.
+ */
+int iwm_notif_send(struct iwm_priv *iwm, struct iwm_wifi_cmd *cmd,
+ u8 cmd_id, u8 source, u8 *buf, unsigned long buf_size)
+{
+ struct iwm_notif *notif;
+
+ notif = kzalloc(sizeof(struct iwm_notif), GFP_KERNEL);
+ if (!notif) {
+ IWM_ERR(iwm, "Couldn't alloc memory for notification\n");
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD(&notif->pending);
+ notif->cmd = cmd;
+ notif->cmd_id = cmd_id;
+ notif->src = source;
+ notif->buf = kzalloc(buf_size, GFP_KERNEL);
+ if (!notif->buf) {
+ IWM_ERR(iwm, "Couldn't alloc notification buffer\n");
+ kfree(notif);
+ return -ENOMEM;
+ }
+ notif->buf_size = buf_size;
+ memcpy(notif->buf, buf, buf_size);
+ list_add_tail(&notif->pending, &iwm->pending_notif);
+
+ wake_up_interruptible(&iwm->notif_queue);
+
+ return 0;
+}
+
+static struct iwm_notif *iwm_notif_find(struct iwm_priv *iwm, u32 cmd,
+ u8 source)
+{
+ struct iwm_notif *notif, *next;
+
+ list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) {
+ if ((notif->cmd_id == cmd) && (notif->src == source)) {
+ list_del(&notif->pending);
+ return notif;
+ }
+ }
+
+ return NULL;
+}
+
+static struct iwm_notif *iwm_notif_wait(struct iwm_priv *iwm, u32 cmd,
+ u8 source, long timeout)
+{
+ int ret;
+ struct iwm_notif *notif;
+ unsigned long *map = NULL;
+
+ switch (source) {
+ case IWM_SRC_LMAC:
+ map = &iwm->lmac_handler_map[0];
+ break;
+ case IWM_SRC_UMAC:
+ map = &iwm->umac_handler_map[0];
+ break;
+ case IWM_SRC_UDMA:
+ map = &iwm->udma_handler_map[0];
+ break;
+ }
+
+ set_bit(cmd, map);
+
+ ret = wait_event_interruptible_timeout(iwm->notif_queue,
+ ((notif = iwm_notif_find(iwm, cmd, source)) != NULL),
+ timeout);
+ clear_bit(cmd, map);
+
+ if (!ret)
+ return NULL;
+
+ return notif;
+}
+
+int iwm_notif_handle(struct iwm_priv *iwm, u32 cmd, u8 source, long timeout)
+{
+ int ret;
+ struct iwm_notif *notif;
+
+ notif = iwm_notif_wait(iwm, cmd, source, timeout);
+ if (!notif)
+ return -ETIME;
+
+ ret = iwm_rx_handle_resp(iwm, notif->buf, notif->buf_size, notif->cmd);
+ kfree(notif->buf);
+ kfree(notif);
+
+ return ret;
+}
+
+static int iwm_config_boot_params(struct iwm_priv *iwm)
+{
+ struct iwm_udma_nonwifi_cmd target_cmd;
+ int ret;
+
+ /* check Wimax is off and config debug monitor */
+ if (iwm->conf.wimax_not_present) {
+ u32 data1 = 0x1f;
+ u32 addr1 = 0x606BE258;
+
+ u32 data2_set = 0x0;
+ u32 data2_clr = 0x1;
+ u32 addr2 = 0x606BE100;
+
+ u32 data3 = 0x1;
+ u32 addr3 = 0x606BEC00;
+
+ target_cmd.resp = 0;
+ target_cmd.handle_by_hw = 0;
+ target_cmd.eop = 1;
+
+ target_cmd.opcode = UMAC_HDI_OUT_OPCODE_WRITE;
+ target_cmd.addr = cpu_to_le32(addr1);
+ target_cmd.op1_sz = cpu_to_le32(sizeof(u32));
+ target_cmd.op2 = 0;
+
+ ret = iwm_hal_send_target_cmd(iwm, &target_cmd, &data1);
+ if (ret < 0) {
+ IWM_ERR(iwm, "iwm_hal_send_target_cmd failed\n");
+ return ret;
+ }
+
+ target_cmd.opcode = UMAC_HDI_OUT_OPCODE_READ_MODIFY_WRITE;
+ target_cmd.addr = cpu_to_le32(addr2);
+ target_cmd.op1_sz = cpu_to_le32(data2_set);
+ target_cmd.op2 = cpu_to_le32(data2_clr);
+
+ ret = iwm_hal_send_target_cmd(iwm, &target_cmd, &data1);
+ if (ret < 0) {
+ IWM_ERR(iwm, "iwm_hal_send_target_cmd failed\n");
+ return ret;
+ }
+
+ target_cmd.opcode = UMAC_HDI_OUT_OPCODE_WRITE;
+ target_cmd.addr = cpu_to_le32(addr3);
+ target_cmd.op1_sz = cpu_to_le32(sizeof(u32));
+ target_cmd.op2 = 0;
+
+ ret = iwm_hal_send_target_cmd(iwm, &target_cmd, &data3);
+ if (ret < 0) {
+ IWM_ERR(iwm, "iwm_hal_send_target_cmd failed\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+void iwm_init_default_profile(struct iwm_priv *iwm,
+ struct iwm_umac_profile *profile)
+{
+ memset(profile, 0, sizeof(struct iwm_umac_profile));
+
+ profile->sec.auth_type = UMAC_AUTH_TYPE_OPEN;
+ profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
+ profile->sec.ucast_cipher = UMAC_CIPHER_TYPE_NONE;
+ profile->sec.mcast_cipher = UMAC_CIPHER_TYPE_NONE;
+
+ if (iwm->conf.enable_qos)
+ profile->flags |= cpu_to_le16(UMAC_PROFILE_QOS_ALLOWED);
+
+ profile->wireless_mode = iwm->conf.wireless_mode;
+ profile->mode = cpu_to_le32(iwm->conf.mode);
+
+ profile->ibss.atim = 0;
+ profile->ibss.beacon_interval = 100;
+ profile->ibss.join_only = 0;
+ profile->ibss.band = iwm->conf.ibss_band;
+ profile->ibss.channel = iwm->conf.ibss_channel;
+}
+
+void iwm_link_on(struct iwm_priv *iwm)
+{
+ netif_carrier_on(iwm_to_ndev(iwm));
+ netif_tx_wake_all_queues(iwm_to_ndev(iwm));
+
+ iwm_send_umac_stats_req(iwm, 0);
+}
+
+void iwm_link_off(struct iwm_priv *iwm)
+{
+ struct iw_statistics *wstats = &iwm->wstats;
+ int i;
+
+ netif_tx_stop_all_queues(iwm_to_ndev(iwm));
+ netif_carrier_off(iwm_to_ndev(iwm));
+
+ for (i = 0; i < IWM_TX_QUEUES; i++) {
+ skb_queue_purge(&iwm->txq[i].queue);
+
+ iwm->txq[i].concat_count = 0;
+ iwm->txq[i].concat_ptr = iwm->txq[i].concat_buf;
+
+ flush_workqueue(iwm->txq[i].wq);
+ }
+
+ iwm_rx_free(iwm);
+
+ cancel_delayed_work(&iwm->stats_request);
+ memset(wstats, 0, sizeof(struct iw_statistics));
+ wstats->qual.updated = IW_QUAL_ALL_INVALID;
+
+ del_timer_sync(&iwm->watchdog);
+}
+
+static void iwm_bss_list_clean(struct iwm_priv *iwm)
+{
+ struct iwm_bss_info *bss, *next;
+
+ list_for_each_entry_safe(bss, next, &iwm->bss_list, node) {
+ list_del(&bss->node);
+ kfree(bss->bss);
+ kfree(bss);
+ }
+}
+
+static int iwm_channels_init(struct iwm_priv *iwm)
+{
+ int ret;
+
+#ifdef CONFIG_IWM_B0_HW_SUPPORT
+ if (iwm->conf.hw_b0) {
+ IWM_INFO(iwm, "Workaround EEPROM channels for B0 hardware\n");
+ return 0;
+ }
+#endif
+
+ ret = iwm_send_umac_channel_list(iwm);
+ if (ret) {
+ IWM_ERR(iwm, "Send channel list failed\n");
+ return ret;
+ }
+
+ ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_GET_CHAN_INFO_LIST,
+ IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
+ if (ret) {
+ IWM_ERR(iwm, "Didn't get a channel list notification\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+int iwm_up(struct iwm_priv *iwm)
+{
+ int ret;
+ struct iwm_notif *notif_reboot, *notif_ack = NULL;
+
+ ret = iwm_bus_enable(iwm);
+ if (ret) {
+ IWM_ERR(iwm, "Couldn't enable function\n");
+ return ret;
+ }
+
+ iwm_rx_setup_handlers(iwm);
+
+ /* Wait for initial BARKER_REBOOT from hardware */
+ notif_reboot = iwm_notif_wait(iwm, IWM_BARKER_REBOOT_NOTIFICATION,
+ IWM_SRC_UDMA, 2 * HZ);
+ if (!notif_reboot) {
+ IWM_ERR(iwm, "Wait for REBOOT_BARKER timeout\n");
+ goto err_disable;
+ }
+
+ /* We send the barker back */
+ ret = iwm_bus_send_chunk(iwm, notif_reboot->buf, 16);
+ if (ret) {
+ IWM_ERR(iwm, "REBOOT barker response failed\n");
+ kfree(notif_reboot);
+ goto err_disable;
+ }
+
+ kfree(notif_reboot->buf);
+ kfree(notif_reboot);
+
+ /* Wait for ACK_BARKER from hardware */
+ notif_ack = iwm_notif_wait(iwm, IWM_ACK_BARKER_NOTIFICATION,
+ IWM_SRC_UDMA, 2 * HZ);
+ if (!notif_ack) {
+ IWM_ERR(iwm, "Wait for ACK_BARKER timeout\n");
+ goto err_disable;
+ }
+
+ kfree(notif_ack->buf);
+ kfree(notif_ack);
+
+ /* We start to config static boot parameters */
+ ret = iwm_config_boot_params(iwm);
+ if (ret) {
+ IWM_ERR(iwm, "Config boot parameters failed\n");
+ goto err_disable;
+ }
+
+ ret = iwm_read_mac(iwm, iwm_to_ndev(iwm)->dev_addr);
+ if (ret) {
+ IWM_ERR(iwm, "MAC reading failed\n");
+ goto err_disable;
+ }
+
+ /* We can load the FWs */
+ ret = iwm_load_fw(iwm);
+ if (ret) {
+ IWM_ERR(iwm, "FW loading failed\n");
+ goto err_disable;
+ }
+
+ /* We configure the UMAC and enable the wifi module */
+ ret = iwm_send_umac_config(iwm,
+ cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_CORE_EN) |
+ cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_LINK_EN) |
+ cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_MLME_EN));
+ if (ret) {
+ IWM_ERR(iwm, "UMAC config failed\n");
+ goto err_fw;
+ }
+
+ ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_WIFI_CORE_STATUS,
+ IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
+ if (ret) {
+ IWM_ERR(iwm, "Didn't get a wifi core status notification\n");
+ goto err_fw;
+ }
+
+ if (iwm->core_enabled != (UMAC_NTFY_WIFI_CORE_STATUS_LINK_EN |
+ UMAC_NTFY_WIFI_CORE_STATUS_MLME_EN)) {
+ IWM_DBG_BOOT(iwm, DBG, "Not all cores enabled:0x%x\n",
+ iwm->core_enabled);
+ ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_WIFI_CORE_STATUS,
+ IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
+ if (ret) {
+ IWM_ERR(iwm, "Didn't get a core status notification\n");
+ goto err_fw;
+ }
+
+ if (iwm->core_enabled != (UMAC_NTFY_WIFI_CORE_STATUS_LINK_EN |
+ UMAC_NTFY_WIFI_CORE_STATUS_MLME_EN)) {
+ IWM_ERR(iwm, "Not all cores enabled: 0x%x\n",
+ iwm->core_enabled);
+ goto err_fw;
+ } else {
+ IWM_INFO(iwm, "All cores enabled\n");
+ }
+ }
+
+ iwm->umac_profile = kmalloc(sizeof(struct iwm_umac_profile),
+ GFP_KERNEL);
+ if (!iwm->umac_profile) {
+ IWM_ERR(iwm, "Couldn't alloc memory for profile\n");
+ goto err_fw;
+ }
+
+ iwm_init_default_profile(iwm, iwm->umac_profile);
+
+ ret = iwm_channels_init(iwm);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Couldn't init channels\n");
+ goto err_profile;
+ }
+
+ /* Set the READY bit to indicate interface is brought up successfully */
+ set_bit(IWM_STATUS_READY, &iwm->status);
+
+ return 0;
+
+ err_profile:
+ kfree(iwm->umac_profile);
+ iwm->umac_profile = NULL;
+
+ err_fw:
+ iwm_eeprom_exit(iwm);
+
+ err_disable:
+ ret = iwm_bus_disable(iwm);
+ if (ret < 0)
+ IWM_ERR(iwm, "Couldn't disable function\n");
+
+ return -EIO;
+}
+
+int iwm_down(struct iwm_priv *iwm)
+{
+ int ret;
+
+ /* The interface is already down */
+ if (!test_bit(IWM_STATUS_READY, &iwm->status))
+ return 0;
+
+ if (iwm->scan_request) {
+ cfg80211_scan_done(iwm->scan_request, true);
+ iwm->scan_request = NULL;
+ }
+
+ clear_bit(IWM_STATUS_READY, &iwm->status);
+
+ iwm_eeprom_exit(iwm);
+ kfree(iwm->umac_profile);
+ iwm->umac_profile = NULL;
+ iwm_bss_list_clean(iwm);
+
+ iwm->default_key = NULL;
+ iwm->core_enabled = 0;
+
+ ret = iwm_bus_disable(iwm);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Couldn't disable function\n");
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c
new file mode 100644
index 00000000000..68e2c3b6c7a
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/netdev.c
@@ -0,0 +1,162 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+/*
+ * This is the netdev related hooks for iwm.
+ *
+ * Some interesting code paths:
+ *
+ * iwm_open() (Called at netdev interface bringup time)
+ * -> iwm_up() (main.c)
+ * -> iwm_bus_enable()
+ * -> if_sdio_enable() (In case of an SDIO bus)
+ * -> sdio_enable_func()
+ * -> iwm_notif_wait(BARKER_REBOOT) (wait for reboot barker)
+ * -> iwm_notif_wait(ACK_BARKER) (wait for ACK barker)
+ * -> iwm_load_fw() (fw.c)
+ * -> iwm_load_umac()
+ * -> iwm_load_lmac() (Calibration LMAC)
+ * -> iwm_load_lmac() (Operational LMAC)
+ * -> iwm_send_umac_config()
+ *
+ * iwm_stop() (Called at netdev interface bringdown time)
+ * -> iwm_down()
+ * -> iwm_bus_disable()
+ * -> if_sdio_disable() (In case of an SDIO bus)
+ * -> sdio_disable_func()
+ */
+#include <linux/netdevice.h>
+
+#include "iwm.h"
+#include "cfg80211.h"
+#include "debug.h"
+
+static int iwm_open(struct net_device *ndev)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(ndev);
+ int ret = 0;
+
+ if (!test_bit(IWM_RADIO_RFKILL_SW, &iwm->radio))
+ ret = iwm_up(iwm);
+
+ return ret;
+}
+
+static int iwm_stop(struct net_device *ndev)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(ndev);
+ int ret = 0;
+
+ if (!test_bit(IWM_RADIO_RFKILL_SW, &iwm->radio))
+ ret = iwm_down(iwm);
+
+ return ret;
+}
+
+/*
+ * iwm AC to queue mapping
+ *
+ * AC_VO -> queue 3
+ * AC_VI -> queue 2
+ * AC_BE -> queue 1
+ * AC_BK -> queue 0
+ */
+static const u16 iwm_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
+
+static u16 iwm_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+ skb->priority = cfg80211_classify8021d(skb);
+
+ return iwm_1d_to_queue[skb->priority];
+}
+
+static const struct net_device_ops iwm_netdev_ops = {
+ .ndo_open = iwm_open,
+ .ndo_stop = iwm_stop,
+ .ndo_start_xmit = iwm_xmit_frame,
+ .ndo_select_queue = iwm_select_queue,
+};
+
+void *iwm_if_alloc(int sizeof_bus, struct device *dev,
+ struct iwm_if_ops *if_ops)
+{
+ struct net_device *ndev;
+ struct wireless_dev *wdev;
+ struct iwm_priv *iwm;
+ int ret = 0;
+
+ wdev = iwm_wdev_alloc(sizeof_bus, dev);
+ if (!wdev) {
+ dev_err(dev, "no memory for wireless device instance\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ iwm = wdev_to_iwm(wdev);
+ iwm->bus_ops = if_ops;
+ iwm->wdev = wdev;
+ iwm_priv_init(iwm);
+ wdev->iftype = iwm_mode_to_nl80211_iftype(iwm->conf.mode);
+
+ ndev = alloc_netdev_mq(0, "wlan%d", ether_setup,
+ IWM_TX_QUEUES);
+ if (!ndev) {
+ dev_err(dev, "no memory for network device instance\n");
+ goto out_wdev;
+ }
+
+ ndev->netdev_ops = &iwm_netdev_ops;
+ ndev->wireless_handlers = &iwm_iw_handler_def;
+ ndev->ieee80211_ptr = wdev;
+ SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
+ ret = register_netdev(ndev);
+ if (ret < 0) {
+ dev_err(dev, "Failed to register netdev: %d\n", ret);
+ goto out_ndev;
+ }
+
+ wdev->netdev = ndev;
+
+ return iwm;
+
+ out_ndev:
+ free_netdev(ndev);
+
+ out_wdev:
+ iwm_wdev_free(iwm);
+ return ERR_PTR(ret);
+}
+
+void iwm_if_free(struct iwm_priv *iwm)
+{
+ int i;
+
+ if (!iwm_to_ndev(iwm))
+ return;
+
+ unregister_netdev(iwm_to_ndev(iwm));
+ free_netdev(iwm_to_ndev(iwm));
+ iwm_wdev_free(iwm);
+ destroy_workqueue(iwm->rx_wq);
+ for (i = 0; i < IWM_TX_QUEUES; i++)
+ destroy_workqueue(iwm->txq[i].wq);
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
new file mode 100644
index 00000000000..d73cf96c6dc
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -0,0 +1,1431 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <linux/if_arp.h>
+#include <linux/list.h>
+#include <net/iw_handler.h>
+
+#include "iwm.h"
+#include "debug.h"
+#include "hal.h"
+#include "umac.h"
+#include "lmac.h"
+#include "commands.h"
+#include "rx.h"
+#include "cfg80211.h"
+#include "eeprom.h"
+
+static int iwm_rx_check_udma_hdr(struct iwm_udma_in_hdr *hdr)
+{
+ if ((le32_to_cpu(hdr->cmd) == UMAC_PAD_TERMINAL) ||
+ (le32_to_cpu(hdr->size) == UMAC_PAD_TERMINAL))
+ return -EINVAL;
+
+ return 0;
+}
+
+static inline int iwm_rx_resp_size(struct iwm_udma_in_hdr *hdr)
+{
+ return ALIGN(le32_to_cpu(hdr->size) + sizeof(struct iwm_udma_in_hdr),
+ 16);
+}
+
+/*
+ * Notification handlers:
+ *
+ * For every possible notification we can receive from the
+ * target, we have a handler.
+ * When we get a target notification, and there is no one
+ * waiting for it, it's just processed through the rx code
+ * path:
+ *
+ * iwm_rx_handle()
+ * -> iwm_rx_handle_umac()
+ * -> iwm_rx_handle_wifi()
+ * -> iwm_rx_handle_resp()
+ * -> iwm_ntf_*()
+ *
+ * OR
+ *
+ * -> iwm_rx_handle_non_wifi()
+ *
+ * If there are processes waiting for this notification, then
+ * iwm_rx_handle_wifi() just wakes those processes up and they
+ * grab the pending notification.
+ */
+static int iwm_ntf_error(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_notif_error *error;
+ struct iwm_fw_error_hdr *fw_err;
+
+ error = (struct iwm_umac_notif_error *)buf;
+ fw_err = &error->err;
+
+
+ IWM_ERR(iwm, "%cMAC FW ERROR:\n",
+ (le32_to_cpu(fw_err->category) == UMAC_SYS_ERR_CAT_LMAC) ? 'L' : 'U');
+ IWM_ERR(iwm, "\tCategory: %d\n", le32_to_cpu(fw_err->category));
+ IWM_ERR(iwm, "\tStatus: 0x%x\n", le32_to_cpu(fw_err->status));
+ IWM_ERR(iwm, "\tPC: 0x%x\n", le32_to_cpu(fw_err->pc));
+ IWM_ERR(iwm, "\tblink1: %d\n", le32_to_cpu(fw_err->blink1));
+ IWM_ERR(iwm, "\tblink2: %d\n", le32_to_cpu(fw_err->blink2));
+ IWM_ERR(iwm, "\tilink1: %d\n", le32_to_cpu(fw_err->ilink1));
+ IWM_ERR(iwm, "\tilink2: %d\n", le32_to_cpu(fw_err->ilink2));
+ IWM_ERR(iwm, "\tData1: 0x%x\n", le32_to_cpu(fw_err->data1));
+ IWM_ERR(iwm, "\tData2: 0x%x\n", le32_to_cpu(fw_err->data2));
+ IWM_ERR(iwm, "\tLine number: %d\n", le32_to_cpu(fw_err->line_num));
+ IWM_ERR(iwm, "\tUMAC status: 0x%x\n", le32_to_cpu(fw_err->umac_status));
+ IWM_ERR(iwm, "\tLMAC status: 0x%x\n", le32_to_cpu(fw_err->lmac_status));
+ IWM_ERR(iwm, "\tSDIO status: 0x%x\n", le32_to_cpu(fw_err->sdio_status));
+
+ return 0;
+}
+
+static int iwm_ntf_umac_alive(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_notif_alive *alive_resp =
+ (struct iwm_umac_notif_alive *)(buf);
+ u16 status = le16_to_cpu(alive_resp->status);
+
+ if (status == UMAC_NTFY_ALIVE_STATUS_ERR) {
+ IWM_ERR(iwm, "Receive error UMAC_ALIVE\n");
+ return -EIO;
+ }
+
+ iwm_tx_credit_init_pools(iwm, alive_resp);
+
+ return 0;
+}
+
+static int iwm_ntf_init_complete(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_notif_init_complete *init_complete =
+ (struct iwm_umac_notif_init_complete *)(buf);
+ u16 status = le16_to_cpu(init_complete->status);
+
+ if (status == UMAC_NTFY_INIT_COMPLETE_STATUS_ERR) {
+ IWM_DBG_NTF(iwm, DBG, "Hardware rf kill is on (radio off)\n");
+ set_bit(IWM_RADIO_RFKILL_HW, &iwm->radio);
+ } else {
+ IWM_DBG_NTF(iwm, DBG, "Hardware rf kill is off (radio on)\n");
+ clear_bit(IWM_RADIO_RFKILL_HW, &iwm->radio);
+ }
+
+ return 0;
+}
+
+static int iwm_ntf_tx_credit_update(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ int pool_nr, total_freed_pages;
+ unsigned long pool_map;
+ int i, id;
+ struct iwm_umac_notif_page_dealloc *dealloc =
+ (struct iwm_umac_notif_page_dealloc *)buf;
+
+ pool_nr = GET_VAL32(dealloc->changes, UMAC_DEALLOC_NTFY_CHANGES_CNT);
+ pool_map = GET_VAL32(dealloc->changes, UMAC_DEALLOC_NTFY_CHANGES_MSK);
+
+ IWM_DBG_TX(iwm, DBG, "UMAC dealloc notification: pool nr %d, "
+ "update map 0x%lx\n", pool_nr, pool_map);
+
+ spin_lock(&iwm->tx_credit.lock);
+
+ for (i = 0; i < pool_nr; i++) {
+ id = GET_VAL32(dealloc->grp_info[i],
+ UMAC_DEALLOC_NTFY_GROUP_NUM);
+ if (test_bit(id, &pool_map)) {
+ total_freed_pages = GET_VAL32(dealloc->grp_info[i],
+ UMAC_DEALLOC_NTFY_PAGE_CNT);
+ iwm_tx_credit_inc(iwm, id, total_freed_pages);
+ }
+ }
+
+ spin_unlock(&iwm->tx_credit.lock);
+
+ return 0;
+}
+
+static int iwm_ntf_umac_reset(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+ IWM_DBG_NTF(iwm, DBG, "UMAC RESET done\n");
+
+ return 0;
+}
+
+static int iwm_ntf_lmac_version(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ IWM_DBG_NTF(iwm, INFO, "LMAC Version: %x.%x\n", buf[9], buf[8]);
+
+ return 0;
+}
+
+static int iwm_ntf_tx(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_lmac_tx_resp *tx_resp;
+ struct iwm_umac_wifi_in_hdr *hdr;
+
+ tx_resp = (struct iwm_lmac_tx_resp *)
+ (buf + sizeof(struct iwm_umac_wifi_in_hdr));
+ hdr = (struct iwm_umac_wifi_in_hdr *)buf;
+
+ IWM_DBG_NTF(iwm, DBG, "REPLY_TX, buf size: %lu\n", buf_size);
+
+ IWM_DBG_NTF(iwm, DBG, "Seqnum: %d\n",
+ le16_to_cpu(hdr->sw_hdr.cmd.seq_num));
+ IWM_DBG_NTF(iwm, DBG, "\tFrame cnt: %d\n", tx_resp->frame_cnt);
+ IWM_DBG_NTF(iwm, DBG, "\tRetry cnt: %d\n",
+ le16_to_cpu(tx_resp->retry_cnt));
+ IWM_DBG_NTF(iwm, DBG, "\tSeq ctl: %d\n", le16_to_cpu(tx_resp->seq_ctl));
+ IWM_DBG_NTF(iwm, DBG, "\tByte cnt: %d\n",
+ le16_to_cpu(tx_resp->byte_cnt));
+ IWM_DBG_NTF(iwm, DBG, "\tStatus: 0x%x\n", le32_to_cpu(tx_resp->status));
+
+ return 0;
+}
+
+
+static int iwm_ntf_calib_res(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+ u8 opcode;
+ u8 *calib_buf;
+ struct iwm_lmac_calib_hdr *hdr = (struct iwm_lmac_calib_hdr *)
+ (buf + sizeof(struct iwm_umac_wifi_in_hdr));
+
+ opcode = hdr->opcode;
+
+ BUG_ON(opcode >= CALIBRATION_CMD_NUM ||
+ opcode < PHY_CALIBRATE_OPCODES_NUM);
+
+ IWM_DBG_NTF(iwm, DBG, "Store calibration result for opcode: %d\n",
+ opcode);
+
+ buf_size -= sizeof(struct iwm_umac_wifi_in_hdr);
+ calib_buf = iwm->calib_res[opcode].buf;
+
+ if (!calib_buf || (iwm->calib_res[opcode].size < buf_size)) {
+ kfree(calib_buf);
+ calib_buf = kzalloc(buf_size, GFP_KERNEL);
+ if (!calib_buf) {
+ IWM_ERR(iwm, "Memory allocation failed: calib_res\n");
+ return -ENOMEM;
+ }
+ iwm->calib_res[opcode].buf = calib_buf;
+ iwm->calib_res[opcode].size = buf_size;
+ }
+
+ memcpy(calib_buf, hdr, buf_size);
+ set_bit(opcode - PHY_CALIBRATE_OPCODES_NUM, &iwm->calib_done_map);
+
+ return 0;
+}
+
+static int iwm_ntf_calib_complete(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ IWM_DBG_NTF(iwm, DBG, "Calibration completed\n");
+
+ return 0;
+}
+
+static int iwm_ntf_calib_cfg(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_lmac_cal_cfg_resp *cal_resp;
+
+ cal_resp = (struct iwm_lmac_cal_cfg_resp *)
+ (buf + sizeof(struct iwm_umac_wifi_in_hdr));
+
+ IWM_DBG_NTF(iwm, DBG, "Calibration CFG command status: %d\n",
+ le32_to_cpu(cal_resp->status));
+
+ return 0;
+}
+
+static int iwm_ntf_wifi_status(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_notif_wifi_status *status =
+ (struct iwm_umac_notif_wifi_status *)buf;
+
+ iwm->core_enabled |= le16_to_cpu(status->status);
+
+ return 0;
+}
+
+static struct iwm_rx_ticket_node *
+iwm_rx_ticket_node_alloc(struct iwm_priv *iwm, struct iwm_rx_ticket *ticket)
+{
+ struct iwm_rx_ticket_node *ticket_node;
+
+ ticket_node = kzalloc(sizeof(struct iwm_rx_ticket_node), GFP_KERNEL);
+ if (!ticket_node) {
+ IWM_ERR(iwm, "Couldn't allocate ticket node\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ ticket_node->ticket = kzalloc(sizeof(struct iwm_rx_ticket), GFP_KERNEL);
+ if (!ticket_node->ticket) {
+ IWM_ERR(iwm, "Couldn't allocate RX ticket\n");
+ kfree(ticket_node);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ memcpy(ticket_node->ticket, ticket, sizeof(struct iwm_rx_ticket));
+ INIT_LIST_HEAD(&ticket_node->node);
+
+ return ticket_node;
+}
+
+static void iwm_rx_ticket_node_free(struct iwm_rx_ticket_node *ticket_node)
+{
+ kfree(ticket_node->ticket);
+ kfree(ticket_node);
+}
+
+static struct iwm_rx_packet *iwm_rx_packet_get(struct iwm_priv *iwm, u16 id)
+{
+ u8 id_hash = IWM_RX_ID_GET_HASH(id);
+ struct list_head *packet_list;
+ struct iwm_rx_packet *packet, *next;
+
+ packet_list = &iwm->rx_packets[id_hash];
+
+ list_for_each_entry_safe(packet, next, packet_list, node)
+ if (packet->id == id)
+ return packet;
+
+ return NULL;
+}
+
+static struct iwm_rx_packet *iwm_rx_packet_alloc(struct iwm_priv *iwm, u8 *buf,
+ u32 size, u16 id)
+{
+ struct iwm_rx_packet *packet;
+
+ packet = kzalloc(sizeof(struct iwm_rx_packet), GFP_KERNEL);
+ if (!packet) {
+ IWM_ERR(iwm, "Couldn't allocate packet\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ packet->skb = dev_alloc_skb(size);
+ if (!packet->skb) {
+ IWM_ERR(iwm, "Couldn't allocate packet SKB\n");
+ kfree(packet);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ packet->pkt_size = size;
+
+ skb_put(packet->skb, size);
+ memcpy(packet->skb->data, buf, size);
+ INIT_LIST_HEAD(&packet->node);
+ packet->id = id;
+
+ return packet;
+}
+
+void iwm_rx_free(struct iwm_priv *iwm)
+{
+ struct iwm_rx_ticket_node *ticket, *nt;
+ struct iwm_rx_packet *packet, *np;
+ int i;
+
+ list_for_each_entry_safe(ticket, nt, &iwm->rx_tickets, node) {
+ list_del(&ticket->node);
+ iwm_rx_ticket_node_free(ticket);
+ }
+
+ for (i = 0; i < IWM_RX_ID_HASH; i++) {
+ list_for_each_entry_safe(packet, np, &iwm->rx_packets[i],
+ node) {
+ list_del(&packet->node);
+ kfree_skb(packet->skb);
+ kfree(packet);
+ }
+ }
+}
+
+static int iwm_ntf_rx_ticket(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_notif_rx_ticket *ntf_rx_ticket =
+ (struct iwm_umac_notif_rx_ticket *)buf;
+ struct iwm_rx_ticket *ticket =
+ (struct iwm_rx_ticket *)ntf_rx_ticket->tickets;
+ int i, schedule_rx = 0;
+
+ for (i = 0; i < ntf_rx_ticket->num_tickets; i++) {
+ struct iwm_rx_ticket_node *ticket_node;
+
+ switch (le16_to_cpu(ticket->action)) {
+ case IWM_RX_TICKET_RELEASE:
+ case IWM_RX_TICKET_DROP:
+ /* We can push the packet to the stack */
+ ticket_node = iwm_rx_ticket_node_alloc(iwm, ticket);
+ if (IS_ERR(ticket_node))
+ return PTR_ERR(ticket_node);
+
+ IWM_DBG_NTF(iwm, DBG, "TICKET RELEASE(%d)\n",
+ ticket->id);
+ list_add_tail(&ticket_node->node, &iwm->rx_tickets);
+
+ /*
+ * We received an Rx ticket, most likely there's
+ * a packet pending for it, it's not worth going
+ * through the packet hash list to double check.
+ * Let's just fire the rx worker..
+ */
+ schedule_rx = 1;
+
+ break;
+
+ default:
+ IWM_ERR(iwm, "Invalid RX ticket action: 0x%x\n",
+ ticket->action);
+ }
+
+ ticket++;
+ }
+
+ if (schedule_rx)
+ queue_work(iwm->rx_wq, &iwm->rx_worker);
+
+ return 0;
+}
+
+static int iwm_ntf_rx_packet(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_wifi_in_hdr *wifi_hdr;
+ struct iwm_rx_packet *packet;
+ u16 id, buf_offset;
+ u32 packet_size;
+
+ IWM_DBG_NTF(iwm, DBG, "\n");
+
+ wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf;
+ id = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num);
+ buf_offset = sizeof(struct iwm_umac_wifi_in_hdr);
+ packet_size = buf_size - sizeof(struct iwm_umac_wifi_in_hdr);
+
+ IWM_DBG_NTF(iwm, DBG, "CMD:0x%x, seqnum: %d, packet size: %d\n",
+ wifi_hdr->sw_hdr.cmd.cmd, id, packet_size);
+ IWM_DBG_RX(iwm, DBG, "Packet id: %d\n", id);
+ IWM_HEXDUMP(iwm, DBG, RX, "PACKET: ", buf + buf_offset, packet_size);
+
+ packet = iwm_rx_packet_alloc(iwm, buf + buf_offset, packet_size, id);
+ if (IS_ERR(packet))
+ return PTR_ERR(packet);
+
+ list_add_tail(&packet->node, &iwm->rx_packets[IWM_RX_ID_GET_HASH(id)]);
+
+ /* We might (unlikely) have received the packet _after_ the ticket */
+ queue_work(iwm->rx_wq, &iwm->rx_worker);
+
+ return 0;
+}
+
+/* MLME handlers */
+static int iwm_mlme_assoc_start(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_notif_assoc_start *start;
+
+ start = (struct iwm_umac_notif_assoc_start *)buf;
+
+ set_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
+
+ IWM_DBG_MLME(iwm, INFO, "Association with %pM Started, reason: %d\n",
+ start->bssid, le32_to_cpu(start->roam_reason));
+
+ wake_up_interruptible(&iwm->mlme_queue);
+
+ return 0;
+}
+
+static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_notif_assoc_complete *complete =
+ (struct iwm_umac_notif_assoc_complete *)buf;
+ union iwreq_data wrqu;
+
+ IWM_DBG_MLME(iwm, INFO, "Association with %pM completed, status: %d\n",
+ complete->bssid, complete->status);
+
+ memset(&wrqu, 0, sizeof(wrqu));
+
+ clear_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
+
+ switch (le32_to_cpu(complete->status)) {
+ case UMAC_ASSOC_COMPLETE_SUCCESS:
+ set_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
+ memcpy(iwm->bssid, complete->bssid, ETH_ALEN);
+ iwm->channel = complete->channel;
+
+ iwm_link_on(iwm);
+
+ memcpy(wrqu.ap_addr.sa_data, complete->bssid, ETH_ALEN);
+ break;
+ case UMAC_ASSOC_COMPLETE_FAILURE:
+ clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
+ memset(iwm->bssid, 0, ETH_ALEN);
+ iwm->channel = 0;
+
+ iwm_link_off(iwm);
+ default:
+ break;
+ }
+
+ if (iwm->conf.mode == UMAC_MODE_IBSS) {
+ cfg80211_ibss_joined(iwm_to_ndev(iwm), iwm->bssid, GFP_KERNEL);
+ return 0;
+ }
+
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(iwm_to_ndev(iwm), SIOCGIWAP, &wrqu, NULL);
+
+ return 0;
+}
+
+static int iwm_mlme_profile_invalidate(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_notif_profile_invalidate *invalid;
+
+ invalid = (struct iwm_umac_notif_profile_invalidate *)buf;
+
+ IWM_DBG_MLME(iwm, INFO, "Profile Invalidated. Reason: %d\n",
+ le32_to_cpu(invalid->reason));
+
+ clear_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
+ clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
+
+ iwm->umac_profile_active = 0;
+ memset(iwm->bssid, 0, ETH_ALEN);
+ iwm->channel = 0;
+
+ iwm_link_off(iwm);
+
+ wake_up_interruptible(&iwm->mlme_queue);
+
+ return 0;
+}
+
+static int iwm_mlme_scan_complete(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ int ret;
+ struct iwm_umac_notif_scan_complete *scan_complete =
+ (struct iwm_umac_notif_scan_complete *)buf;
+ u32 result = le32_to_cpu(scan_complete->result);
+
+ IWM_DBG_MLME(iwm, INFO, "type:0x%x result:0x%x seq:%d\n",
+ le32_to_cpu(scan_complete->type),
+ le32_to_cpu(scan_complete->result),
+ scan_complete->seq_num);
+
+ if (!test_and_clear_bit(IWM_STATUS_SCANNING, &iwm->status)) {
+ IWM_ERR(iwm, "Scan complete while device not scanning\n");
+ return -EIO;
+ }
+ if (!iwm->scan_request)
+ return 0;
+
+ ret = iwm_cfg80211_inform_bss(iwm);
+
+ cfg80211_scan_done(iwm->scan_request,
+ (result & UMAC_SCAN_RESULT_ABORTED) ? 1 : !!ret);
+ iwm->scan_request = NULL;
+
+ return ret;
+}
+
+static int iwm_mlme_update_sta_table(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_notif_sta_info *umac_sta =
+ (struct iwm_umac_notif_sta_info *)buf;
+ struct iwm_sta_info *sta;
+ int i;
+
+ switch (le32_to_cpu(umac_sta->opcode)) {
+ case UMAC_OPCODE_ADD_MODIFY:
+ sta = &iwm->sta_table[GET_VAL8(umac_sta->sta_id, LMAC_STA_ID)];
+
+ IWM_DBG_MLME(iwm, INFO, "%s STA: ID = %d, Color = %d, "
+ "addr = %pM, qos = %d\n",
+ sta->valid ? "Modify" : "Add",
+ GET_VAL8(umac_sta->sta_id, LMAC_STA_ID),
+ GET_VAL8(umac_sta->sta_id, LMAC_STA_COLOR),
+ umac_sta->mac_addr,
+ umac_sta->flags & UMAC_STA_FLAG_QOS);
+
+ sta->valid = 1;
+ sta->qos = umac_sta->flags & UMAC_STA_FLAG_QOS;
+ sta->color = GET_VAL8(umac_sta->sta_id, LMAC_STA_COLOR);
+ memcpy(sta->addr, umac_sta->mac_addr, ETH_ALEN);
+ break;
+ case UMAC_OPCODE_REMOVE:
+ IWM_DBG_MLME(iwm, INFO, "Remove STA: ID = %d, Color = %d, "
+ "addr = %pM\n",
+ GET_VAL8(umac_sta->sta_id, LMAC_STA_ID),
+ GET_VAL8(umac_sta->sta_id, LMAC_STA_COLOR),
+ umac_sta->mac_addr);
+
+ sta = &iwm->sta_table[GET_VAL8(umac_sta->sta_id, LMAC_STA_ID)];
+
+ if (!memcmp(sta->addr, umac_sta->mac_addr, ETH_ALEN))
+ sta->valid = 0;
+
+ break;
+ case UMAC_OPCODE_CLEAR_ALL:
+ for (i = 0; i < IWM_STA_TABLE_NUM; i++)
+ iwm->sta_table[i].valid = 0;
+
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ struct wiphy *wiphy = iwm_to_wiphy(iwm);
+ struct ieee80211_mgmt *mgmt;
+ struct iwm_umac_notif_bss_info *umac_bss =
+ (struct iwm_umac_notif_bss_info *)buf;
+ struct ieee80211_channel *channel;
+ struct ieee80211_supported_band *band;
+ struct iwm_bss_info *bss, *next;
+ s32 signal;
+ int freq;
+ u16 frame_len = le16_to_cpu(umac_bss->frame_len);
+ size_t bss_len = sizeof(struct iwm_umac_notif_bss_info) + frame_len;
+
+ mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
+
+ IWM_DBG_MLME(iwm, DBG, "New BSS info entry: %pM\n", mgmt->bssid);
+ IWM_DBG_MLME(iwm, DBG, "\tType: 0x%x\n", le32_to_cpu(umac_bss->type));
+ IWM_DBG_MLME(iwm, DBG, "\tTimestamp: %d\n",
+ le32_to_cpu(umac_bss->timestamp));
+ IWM_DBG_MLME(iwm, DBG, "\tTable Index: %d\n",
+ le16_to_cpu(umac_bss->table_idx));
+ IWM_DBG_MLME(iwm, DBG, "\tBand: %d\n", umac_bss->band);
+ IWM_DBG_MLME(iwm, DBG, "\tChannel: %d\n", umac_bss->channel);
+ IWM_DBG_MLME(iwm, DBG, "\tRSSI: %d\n", umac_bss->rssi);
+ IWM_DBG_MLME(iwm, DBG, "\tFrame Length: %d\n", frame_len);
+
+ list_for_each_entry_safe(bss, next, &iwm->bss_list, node)
+ if (bss->bss->table_idx == umac_bss->table_idx)
+ break;
+
+ if (&bss->node != &iwm->bss_list) {
+ /* Remove the old BSS entry, we will add it back later. */
+ list_del(&bss->node);
+ kfree(bss->bss);
+ } else {
+ /* New BSS entry */
+
+ bss = kzalloc(sizeof(struct iwm_bss_info), GFP_KERNEL);
+ if (!bss) {
+ IWM_ERR(iwm, "Couldn't allocate bss_info\n");
+ return -ENOMEM;
+ }
+ }
+
+ bss->bss = kzalloc(bss_len, GFP_KERNEL);
+ if (!bss) {
+ kfree(bss);
+ IWM_ERR(iwm, "Couldn't allocate bss\n");
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD(&bss->node);
+ memcpy(bss->bss, umac_bss, bss_len);
+
+ if (umac_bss->band == UMAC_BAND_2GHZ)
+ band = wiphy->bands[IEEE80211_BAND_2GHZ];
+ else if (umac_bss->band == UMAC_BAND_5GHZ)
+ band = wiphy->bands[IEEE80211_BAND_5GHZ];
+ else {
+ IWM_ERR(iwm, "Invalid band: %d\n", umac_bss->band);
+ goto err;
+ }
+
+ freq = ieee80211_channel_to_frequency(umac_bss->channel);
+ channel = ieee80211_get_channel(wiphy, freq);
+ signal = umac_bss->rssi * 100;
+
+ bss->cfg_bss = cfg80211_inform_bss_frame(wiphy, channel,
+ mgmt, frame_len,
+ signal, GFP_KERNEL);
+ if (!bss->cfg_bss)
+ goto err;
+
+ list_add_tail(&bss->node, &iwm->bss_list);
+
+ return 0;
+ err:
+ kfree(bss->bss);
+ kfree(bss);
+
+ return -EINVAL;
+}
+
+static int iwm_mlme_remove_bss(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_notif_bss_removed *bss_rm =
+ (struct iwm_umac_notif_bss_removed *)buf;
+ struct iwm_bss_info *bss, *next;
+ u16 table_idx;
+ int i;
+
+ for (i = 0; i < le32_to_cpu(bss_rm->count); i++) {
+ table_idx = (le16_to_cpu(bss_rm->entries[i])
+ & IWM_BSS_REMOVE_INDEX_MSK);
+ list_for_each_entry_safe(bss, next, &iwm->bss_list, node)
+ if (bss->bss->table_idx == cpu_to_le16(table_idx)) {
+ struct ieee80211_mgmt *mgmt;
+
+ mgmt = (struct ieee80211_mgmt *)
+ (bss->bss->frame_buf);
+ IWM_DBG_MLME(iwm, ERR,
+ "BSS removed: %pM\n",
+ mgmt->bssid);
+ list_del(&bss->node);
+ kfree(bss->bss);
+ kfree(bss);
+ }
+ }
+
+ return 0;
+}
+
+static int iwm_mlme_mgt_frame(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_notif_mgt_frame *mgt_frame =
+ (struct iwm_umac_notif_mgt_frame *)buf;
+ struct ieee80211_mgmt *mgt = (struct ieee80211_mgmt *)mgt_frame->frame;
+ u8 *ie;
+ unsigned int event;
+ union iwreq_data wrqu;
+
+ IWM_HEXDUMP(iwm, DBG, MLME, "MGT: ", mgt_frame->frame,
+ le16_to_cpu(mgt_frame->len));
+
+ if (ieee80211_is_assoc_req(mgt->frame_control)) {
+ ie = mgt->u.assoc_req.variable;;
+ event = IWEVASSOCREQIE;
+ } else if (ieee80211_is_reassoc_req(mgt->frame_control)) {
+ ie = mgt->u.reassoc_req.variable;;
+ event = IWEVASSOCREQIE;
+ } else if (ieee80211_is_assoc_resp(mgt->frame_control)) {
+ ie = mgt->u.assoc_resp.variable;;
+ event = IWEVASSOCRESPIE;
+ } else if (ieee80211_is_reassoc_resp(mgt->frame_control)) {
+ ie = mgt->u.reassoc_resp.variable;;
+ event = IWEVASSOCRESPIE;
+ } else {
+ IWM_ERR(iwm, "Unsupported management frame");
+ return 0;
+ }
+
+ wrqu.data.length = le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
+
+ IWM_HEXDUMP(iwm, DBG, MLME, "EVT: ", ie, wrqu.data.length);
+ wireless_send_event(iwm_to_ndev(iwm), event, &wrqu, ie);
+
+ return 0;
+}
+
+static int iwm_ntf_mlme(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_notif_wifi_if *notif =
+ (struct iwm_umac_notif_wifi_if *)buf;
+
+ switch (notif->status) {
+ case WIFI_IF_NTFY_ASSOC_START:
+ return iwm_mlme_assoc_start(iwm, buf, buf_size, cmd);
+ case WIFI_IF_NTFY_ASSOC_COMPLETE:
+ return iwm_mlme_assoc_complete(iwm, buf, buf_size, cmd);
+ case WIFI_IF_NTFY_PROFILE_INVALIDATE_COMPLETE:
+ return iwm_mlme_profile_invalidate(iwm, buf, buf_size, cmd);
+ case WIFI_IF_NTFY_CONNECTION_TERMINATED:
+ IWM_DBG_MLME(iwm, DBG, "Connection terminated\n");
+ break;
+ case WIFI_IF_NTFY_SCAN_COMPLETE:
+ return iwm_mlme_scan_complete(iwm, buf, buf_size, cmd);
+ case WIFI_IF_NTFY_STA_TABLE_CHANGE:
+ return iwm_mlme_update_sta_table(iwm, buf, buf_size, cmd);
+ case WIFI_IF_NTFY_EXTENDED_IE_REQUIRED:
+ IWM_DBG_MLME(iwm, DBG, "Extended IE required\n");
+ break;
+ case WIFI_IF_NTFY_BSS_TRK_TABLE_CHANGED:
+ return iwm_mlme_update_bss_table(iwm, buf, buf_size, cmd);
+ case WIFI_IF_NTFY_BSS_TRK_ENTRIES_REMOVED:
+ return iwm_mlme_remove_bss(iwm, buf, buf_size, cmd);
+ break;
+ case WIFI_IF_NTFY_MGMT_FRAME:
+ return iwm_mlme_mgt_frame(iwm, buf, buf_size, cmd);
+ case WIFI_DBG_IF_NTFY_SCAN_SUPER_JOB_START:
+ case WIFI_DBG_IF_NTFY_SCAN_SUPER_JOB_COMPLETE:
+ case WIFI_DBG_IF_NTFY_SCAN_CHANNEL_START:
+ case WIFI_DBG_IF_NTFY_SCAN_CHANNEL_RESULT:
+ case WIFI_DBG_IF_NTFY_SCAN_MINI_JOB_START:
+ case WIFI_DBG_IF_NTFY_SCAN_MINI_JOB_COMPLETE:
+ case WIFI_DBG_IF_NTFY_CNCT_ATC_START:
+ case WIFI_DBG_IF_NTFY_COEX_NOTIFICATION:
+ case WIFI_DBG_IF_NTFY_COEX_HANDLE_ENVELOP:
+ case WIFI_DBG_IF_NTFY_COEX_HANDLE_RELEASE_ENVELOP:
+ IWM_DBG_MLME(iwm, DBG, "MLME debug notification: 0x%x\n",
+ notif->status);
+ break;
+ default:
+ IWM_ERR(iwm, "Unhandled notification: 0x%x\n", notif->status);
+ break;
+ }
+
+ return 0;
+}
+
+#define IWM_STATS_UPDATE_INTERVAL (2 * HZ)
+
+static int iwm_ntf_statistics(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_notif_stats *stats = (struct iwm_umac_notif_stats *)buf;
+ struct iw_statistics *wstats = &iwm->wstats;
+ u16 max_rate = 0;
+ int i;
+
+ IWM_DBG_MLME(iwm, DBG, "Statistics notification received\n");
+
+ if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
+ for (i = 0; i < UMAC_NTF_RATE_SAMPLE_NR; i++) {
+ max_rate = max_t(u16, max_rate,
+ max(le16_to_cpu(stats->tx_rate[i]),
+ le16_to_cpu(stats->rx_rate[i])));
+ }
+ /* UMAC passes rate info multiplies by 2 */
+ iwm->rate = max_rate >> 1;
+ }
+
+ wstats->status = 0;
+
+ wstats->discard.nwid = le32_to_cpu(stats->rx_drop_other_bssid);
+ wstats->discard.code = le32_to_cpu(stats->rx_drop_decode);
+ wstats->discard.fragment = le32_to_cpu(stats->rx_drop_reassembly);
+ wstats->discard.retries = le32_to_cpu(stats->tx_drop_max_retry);
+
+ wstats->miss.beacon = le32_to_cpu(stats->missed_beacons);
+
+ /* according to cfg80211 */
+ if (stats->rssi_dbm < -110)
+ wstats->qual.qual = 0;
+ else if (stats->rssi_dbm > -40)
+ wstats->qual.qual = 70;
+ else
+ wstats->qual.qual = stats->rssi_dbm + 110;
+
+ wstats->qual.level = stats->rssi_dbm;
+ wstats->qual.noise = stats->noise_dbm;
+ wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+
+ schedule_delayed_work(&iwm->stats_request, IWM_STATS_UPDATE_INTERVAL);
+
+ mod_timer(&iwm->watchdog, round_jiffies(jiffies + IWM_WATCHDOG_PERIOD));
+
+ return 0;
+}
+
+static int iwm_ntf_eeprom_proxy(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_cmd_eeprom_proxy *eeprom_proxy =
+ (struct iwm_umac_cmd_eeprom_proxy *)
+ (buf + sizeof(struct iwm_umac_wifi_in_hdr));
+ struct iwm_umac_cmd_eeprom_proxy_hdr *hdr = &eeprom_proxy->hdr;
+ u32 hdr_offset = le32_to_cpu(hdr->offset);
+ u32 hdr_len = le32_to_cpu(hdr->len);
+ u32 hdr_type = le32_to_cpu(hdr->type);
+
+ IWM_DBG_NTF(iwm, DBG, "type: 0x%x, len: %d, offset: 0x%x\n",
+ hdr_type, hdr_len, hdr_offset);
+
+ if ((hdr_offset + hdr_len) > IWM_EEPROM_LEN)
+ return -EINVAL;
+
+#ifdef CONFIG_IWM_B0_HW_SUPPORT
+ if (hdr_offset == IWM_EEPROM_SKU_CAP_OFF) {
+ if (eeprom_proxy->buf[0] == 0xff)
+ iwm->conf.hw_b0 = 1;
+ }
+#endif
+
+ switch (hdr_type) {
+ case IWM_UMAC_CMD_EEPROM_TYPE_READ:
+ memcpy(iwm->eeprom + hdr_offset, eeprom_proxy->buf, hdr_len);
+ break;
+ case IWM_UMAC_CMD_EEPROM_TYPE_WRITE:
+ default:
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static int iwm_ntf_channel_info_list(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_cmd_get_channel_list *ch_list =
+ (struct iwm_umac_cmd_get_channel_list *)
+ (buf + sizeof(struct iwm_umac_wifi_in_hdr));
+ struct wiphy *wiphy = iwm_to_wiphy(iwm);
+ struct ieee80211_supported_band *band;
+ int i;
+
+ band = wiphy->bands[IEEE80211_BAND_2GHZ];
+
+ for (i = 0; i < band->n_channels; i++) {
+ unsigned long ch_mask_0 =
+ le32_to_cpu(ch_list->ch[0].channels_mask);
+ unsigned long ch_mask_2 =
+ le32_to_cpu(ch_list->ch[2].channels_mask);
+
+ if (!test_bit(i, &ch_mask_0))
+ band->channels[i].flags |= IEEE80211_CHAN_DISABLED;
+
+ if (!test_bit(i, &ch_mask_2))
+ band->channels[i].flags |= IEEE80211_CHAN_NO_IBSS;
+ }
+
+ band = wiphy->bands[IEEE80211_BAND_5GHZ];
+
+ for (i = 0; i < min(band->n_channels, 32); i++) {
+ unsigned long ch_mask_1 =
+ le32_to_cpu(ch_list->ch[1].channels_mask);
+ unsigned long ch_mask_3 =
+ le32_to_cpu(ch_list->ch[3].channels_mask);
+
+ if (!test_bit(i, &ch_mask_1))
+ band->channels[i].flags |= IEEE80211_CHAN_DISABLED;
+
+ if (!test_bit(i, &ch_mask_3))
+ band->channels[i].flags |= IEEE80211_CHAN_NO_IBSS;
+ }
+
+ return 0;
+}
+
+static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_umac_wifi_if *hdr =
+ (struct iwm_umac_wifi_if *)cmd->buf.payload;
+
+ IWM_DBG_NTF(iwm, DBG, "WIFI_IF_WRAPPER cmd is delivered to UMAC: "
+ "oid is %d\n", hdr->oid);
+
+ switch (hdr->oid) {
+ case UMAC_WIFI_IF_CMD_SET_PROFILE:
+ iwm->umac_profile_active = 1;
+ wake_up_interruptible(&iwm->mlme_queue);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int iwm_ntf_card_state(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+ struct iwm_lmac_card_state *state = (struct iwm_lmac_card_state *)
+ (buf + sizeof(struct iwm_umac_wifi_in_hdr));
+ u32 flags = le32_to_cpu(state->flags);
+
+ IWM_INFO(iwm, "HW RF Kill %s, CT Kill %s\n",
+ flags & IWM_CARD_STATE_HW_DISABLED ? "ON" : "OFF",
+ flags & IWM_CARD_STATE_CTKILL_DISABLED ? "ON" : "OFF");
+
+ if (flags & IWM_CARD_STATE_HW_DISABLED)
+ set_bit(IWM_RADIO_RFKILL_HW, &iwm->radio);
+ else
+ clear_bit(IWM_RADIO_RFKILL_HW, &iwm->radio);
+
+ return 0;
+}
+
+static int iwm_rx_handle_wifi(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size)
+{
+ struct iwm_umac_wifi_in_hdr *wifi_hdr;
+ struct iwm_wifi_cmd *cmd;
+ u8 source, cmd_id;
+ u16 seq_num;
+ u32 count;
+ u8 resp;
+
+ wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf;
+ cmd_id = wifi_hdr->sw_hdr.cmd.cmd;
+
+ source = GET_VAL32(wifi_hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE);
+ if (source >= IWM_SRC_NUM) {
+ IWM_CRIT(iwm, "invalid source %d\n", source);
+ return -EINVAL;
+ }
+
+ count = (GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_BYTE_COUNT));
+ count += sizeof(struct iwm_umac_wifi_in_hdr) -
+ sizeof(struct iwm_dev_cmd_hdr);
+ if (count > buf_size) {
+ IWM_CRIT(iwm, "count %d, buf size:%ld\n", count, buf_size);
+ return -EINVAL;
+ }
+
+ resp = GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_STATUS);
+
+ seq_num = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num);
+
+ IWM_DBG_RX(iwm, DBG, "CMD:0x%x, source: 0x%x, seqnum: %d\n",
+ cmd_id, source, seq_num);
+
+ /*
+ * If this is a response to a previously sent command, there must
+ * be a pending command for this sequence number.
+ */
+ cmd = iwm_get_pending_wifi_cmd(iwm, seq_num);
+
+ /* Notify the caller only for sync commands. */
+ switch (source) {
+ case UMAC_HDI_IN_SOURCE_FHRX:
+ if (iwm->lmac_handlers[cmd_id] &&
+ test_bit(cmd_id, &iwm->lmac_handler_map[0]))
+ return iwm_notif_send(iwm, cmd, cmd_id, source,
+ buf, count);
+ break;
+ case UMAC_HDI_IN_SOURCE_FW:
+ if (iwm->umac_handlers[cmd_id] &&
+ test_bit(cmd_id, &iwm->umac_handler_map[0]))
+ return iwm_notif_send(iwm, cmd, cmd_id, source,
+ buf, count);
+ break;
+ case UMAC_HDI_IN_SOURCE_UDMA:
+ break;
+ }
+
+ return iwm_rx_handle_resp(iwm, buf, count, cmd);
+}
+
+int iwm_rx_handle_resp(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ u8 source, cmd_id;
+ struct iwm_umac_wifi_in_hdr *wifi_hdr;
+ int ret = 0;
+
+ wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf;
+ cmd_id = wifi_hdr->sw_hdr.cmd.cmd;
+
+ source = GET_VAL32(wifi_hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE);
+
+ IWM_DBG_RX(iwm, DBG, "CMD:0x%x, source: 0x%x\n", cmd_id, source);
+
+ switch (source) {
+ case UMAC_HDI_IN_SOURCE_FHRX:
+ if (iwm->lmac_handlers[cmd_id])
+ ret = iwm->lmac_handlers[cmd_id]
+ (iwm, buf, buf_size, cmd);
+ break;
+ case UMAC_HDI_IN_SOURCE_FW:
+ if (iwm->umac_handlers[cmd_id])
+ ret = iwm->umac_handlers[cmd_id]
+ (iwm, buf, buf_size, cmd);
+ break;
+ case UMAC_HDI_IN_SOURCE_UDMA:
+ ret = -EINVAL;
+ break;
+ }
+
+ kfree(cmd);
+
+ return ret;
+}
+
+static int iwm_rx_handle_nonwifi(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size)
+{
+ u8 seq_num;
+ struct iwm_udma_in_hdr *hdr = (struct iwm_udma_in_hdr *)buf;
+ struct iwm_nonwifi_cmd *cmd, *next;
+
+ seq_num = GET_VAL32(hdr->cmd, UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM);
+
+ /*
+ * We received a non wifi answer.
+ * Let's check if there's a pending command for it, and if so
+ * replace the command payload with the buffer, and then wake the
+ * callers up.
+ * That means we only support synchronised non wifi command response
+ * schemes.
+ */
+ list_for_each_entry_safe(cmd, next, &iwm->nonwifi_pending_cmd, pending)
+ if (cmd->seq_num == seq_num) {
+ cmd->resp_received = 1;
+ cmd->buf.len = buf_size;
+ memcpy(cmd->buf.hdr, buf, buf_size);
+ wake_up_interruptible(&iwm->nonwifi_queue);
+ }
+
+ return 0;
+}
+
+static int iwm_rx_handle_umac(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size)
+{
+ int ret = 0;
+ u8 op_code;
+ unsigned long buf_offset = 0;
+ struct iwm_udma_in_hdr *hdr;
+
+ /*
+ * To allow for a more efficient bus usage, UMAC
+ * messages are encapsulated into UDMA ones. This
+ * way we can have several UMAC messages in one bus
+ * transfer.
+ * A UDMA frame size is always aligned on 16 bytes,
+ * and a UDMA frame must not start with a UMAC_PAD_TERMINAL
+ * word. This is how we parse a bus frame into several
+ * UDMA ones.
+ */
+ while (buf_offset < buf_size) {
+
+ hdr = (struct iwm_udma_in_hdr *)(buf + buf_offset);
+
+ if (iwm_rx_check_udma_hdr(hdr) < 0) {
+ IWM_DBG_RX(iwm, DBG, "End of frame\n");
+ break;
+ }
+
+ op_code = GET_VAL32(hdr->cmd, UMAC_HDI_IN_CMD_OPCODE);
+
+ IWM_DBG_RX(iwm, DBG, "Op code: 0x%x\n", op_code);
+
+ if (op_code == UMAC_HDI_IN_OPCODE_WIFI) {
+ ret |= iwm_rx_handle_wifi(iwm, buf + buf_offset,
+ buf_size - buf_offset);
+ } else if (op_code < UMAC_HDI_IN_OPCODE_NONWIFI_MAX) {
+ if (GET_VAL32(hdr->cmd,
+ UDMA_HDI_IN_CMD_NON_WIFI_HW_SIG) !=
+ UDMA_HDI_IN_CMD_NON_WIFI_HW_SIG) {
+ IWM_ERR(iwm, "Incorrect hw signature\n");
+ return -EINVAL;
+ }
+ ret |= iwm_rx_handle_nonwifi(iwm, buf + buf_offset,
+ buf_size - buf_offset);
+ } else {
+ IWM_ERR(iwm, "Invalid RX opcode: 0x%x\n", op_code);
+ ret |= -EINVAL;
+ }
+
+ buf_offset += iwm_rx_resp_size(hdr);
+ }
+
+ return ret;
+}
+
+int iwm_rx_handle(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size)
+{
+ struct iwm_udma_in_hdr *hdr;
+
+ hdr = (struct iwm_udma_in_hdr *)buf;
+
+ switch (le32_to_cpu(hdr->cmd)) {
+ case UMAC_REBOOT_BARKER:
+ return iwm_notif_send(iwm, NULL, IWM_BARKER_REBOOT_NOTIFICATION,
+ IWM_SRC_UDMA, buf, buf_size);
+ case UMAC_ACK_BARKER:
+ return iwm_notif_send(iwm, NULL, IWM_ACK_BARKER_NOTIFICATION,
+ IWM_SRC_UDMA, NULL, 0);
+ default:
+ IWM_DBG_RX(iwm, DBG, "Received cmd: 0x%x\n", hdr->cmd);
+ return iwm_rx_handle_umac(iwm, buf, buf_size);
+ }
+
+ return 0;
+}
+
+static const iwm_handler iwm_umac_handlers[] =
+{
+ [UMAC_NOTIFY_OPCODE_ERROR] = iwm_ntf_error,
+ [UMAC_NOTIFY_OPCODE_ALIVE] = iwm_ntf_umac_alive,
+ [UMAC_NOTIFY_OPCODE_INIT_COMPLETE] = iwm_ntf_init_complete,
+ [UMAC_NOTIFY_OPCODE_WIFI_CORE_STATUS] = iwm_ntf_wifi_status,
+ [UMAC_NOTIFY_OPCODE_WIFI_IF_WRAPPER] = iwm_ntf_mlme,
+ [UMAC_NOTIFY_OPCODE_PAGE_DEALLOC] = iwm_ntf_tx_credit_update,
+ [UMAC_NOTIFY_OPCODE_RX_TICKET] = iwm_ntf_rx_ticket,
+ [UMAC_CMD_OPCODE_RESET] = iwm_ntf_umac_reset,
+ [UMAC_NOTIFY_OPCODE_STATS] = iwm_ntf_statistics,
+ [UMAC_CMD_OPCODE_EEPROM_PROXY] = iwm_ntf_eeprom_proxy,
+ [UMAC_CMD_OPCODE_GET_CHAN_INFO_LIST] = iwm_ntf_channel_info_list,
+ [REPLY_RX_MPDU_CMD] = iwm_ntf_rx_packet,
+ [UMAC_CMD_OPCODE_WIFI_IF_WRAPPER] = iwm_ntf_wifi_if_wrapper,
+};
+
+static const iwm_handler iwm_lmac_handlers[] =
+{
+ [REPLY_TX] = iwm_ntf_tx,
+ [REPLY_ALIVE] = iwm_ntf_lmac_version,
+ [CALIBRATION_RES_NOTIFICATION] = iwm_ntf_calib_res,
+ [CALIBRATION_COMPLETE_NOTIFICATION] = iwm_ntf_calib_complete,
+ [CALIBRATION_CFG_CMD] = iwm_ntf_calib_cfg,
+ [REPLY_RX_MPDU_CMD] = iwm_ntf_rx_packet,
+ [CARD_STATE_NOTIFICATION] = iwm_ntf_card_state,
+};
+
+void iwm_rx_setup_handlers(struct iwm_priv *iwm)
+{
+ iwm->umac_handlers = (iwm_handler *) iwm_umac_handlers;
+ iwm->lmac_handlers = (iwm_handler *) iwm_lmac_handlers;
+}
+
+static void iwm_remove_iv(struct sk_buff *skb, u32 hdr_total_len)
+{
+ struct ieee80211_hdr *hdr;
+ unsigned int hdr_len;
+
+ hdr = (struct ieee80211_hdr *)skb->data;
+
+ if (!ieee80211_has_protected(hdr->frame_control))
+ return;
+
+ hdr_len = ieee80211_hdrlen(hdr->frame_control);
+ if (hdr_total_len <= hdr_len)
+ return;
+
+ memmove(skb->data + (hdr_total_len - hdr_len), skb->data, hdr_len);
+ skb_pull(skb, (hdr_total_len - hdr_len));
+}
+
+static void iwm_rx_adjust_packet(struct iwm_priv *iwm,
+ struct iwm_rx_packet *packet,
+ struct iwm_rx_ticket_node *ticket_node)
+{
+ u32 payload_offset = 0, payload_len;
+ struct iwm_rx_ticket *ticket = ticket_node->ticket;
+ struct iwm_rx_mpdu_hdr *mpdu_hdr;
+ struct ieee80211_hdr *hdr;
+
+ mpdu_hdr = (struct iwm_rx_mpdu_hdr *)packet->skb->data;
+ payload_offset += sizeof(struct iwm_rx_mpdu_hdr);
+ /* Padding is 0 or 2 bytes */
+ payload_len = le16_to_cpu(mpdu_hdr->len) +
+ (le16_to_cpu(ticket->flags) & IWM_RX_TICKET_PAD_SIZE_MSK);
+ payload_len -= ticket->tail_len;
+
+ IWM_DBG_RX(iwm, DBG, "Packet adjusted, len:%d, offset:%d, "
+ "ticket offset:%d ticket tail len:%d\n",
+ payload_len, payload_offset, ticket->payload_offset,
+ ticket->tail_len);
+
+ IWM_HEXDUMP(iwm, DBG, RX, "RAW: ", packet->skb->data, packet->skb->len);
+
+ skb_pull(packet->skb, payload_offset);
+ skb_trim(packet->skb, payload_len);
+
+ iwm_remove_iv(packet->skb, ticket->payload_offset);
+
+ hdr = (struct ieee80211_hdr *) packet->skb->data;
+ if (ieee80211_is_data_qos(hdr->frame_control)) {
+ /* UMAC handed QOS_DATA frame with 2 padding bytes appended
+ * to the qos_ctl field in IEEE 802.11 headers. */
+ memmove(packet->skb->data + IEEE80211_QOS_CTL_LEN + 2,
+ packet->skb->data,
+ ieee80211_hdrlen(hdr->frame_control) -
+ IEEE80211_QOS_CTL_LEN);
+ hdr = (struct ieee80211_hdr *) skb_pull(packet->skb,
+ IEEE80211_QOS_CTL_LEN + 2);
+ hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
+ }
+
+ IWM_HEXDUMP(iwm, DBG, RX, "ADJUSTED: ",
+ packet->skb->data, packet->skb->len);
+}
+
+static void classify8023(struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+
+ if (ieee80211_is_data_qos(hdr->frame_control)) {
+ u8 *qc = ieee80211_get_qos_ctl(hdr);
+ /* frame has qos control */
+ skb->priority = *qc & IEEE80211_QOS_CTL_TID_MASK;
+ } else {
+ skb->priority = 0;
+ }
+}
+
+static void iwm_rx_process_packet(struct iwm_priv *iwm,
+ struct iwm_rx_packet *packet,
+ struct iwm_rx_ticket_node *ticket_node)
+{
+ int ret;
+ struct sk_buff *skb = packet->skb;
+ struct wireless_dev *wdev = iwm_to_wdev(iwm);
+ struct net_device *ndev = iwm_to_ndev(iwm);
+
+ IWM_DBG_RX(iwm, DBG, "Processing packet ID %d\n", packet->id);
+
+ switch (le16_to_cpu(ticket_node->ticket->action)) {
+ case IWM_RX_TICKET_RELEASE:
+ IWM_DBG_RX(iwm, DBG, "RELEASE packet\n");
+ classify8023(skb);
+ iwm_rx_adjust_packet(iwm, packet, ticket_node);
+ ret = ieee80211_data_to_8023(skb, ndev->dev_addr, wdev->iftype);
+ if (ret < 0) {
+ IWM_DBG_RX(iwm, DBG, "Couldn't convert 802.11 header - "
+ "%d\n", ret);
+ break;
+ }
+
+ IWM_HEXDUMP(iwm, DBG, RX, "802.3: ", skb->data, skb->len);
+
+ skb->dev = iwm_to_ndev(iwm);
+ skb->protocol = eth_type_trans(skb, ndev);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ memset(skb->cb, 0, sizeof(skb->cb));
+
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += skb->len;
+
+ if (netif_rx(skb) == NET_RX_DROP) {
+ IWM_ERR(iwm, "Packet dropped\n");
+ ndev->stats.rx_dropped++;
+ }
+ break;
+ case IWM_RX_TICKET_DROP:
+ IWM_DBG_RX(iwm, DBG, "DROP packet\n");
+ kfree_skb(packet->skb);
+ break;
+ default:
+ IWM_ERR(iwm, "Unknow ticket action: %d\n",
+ le16_to_cpu(ticket_node->ticket->action));
+ kfree_skb(packet->skb);
+ }
+
+ kfree(packet);
+ iwm_rx_ticket_node_free(ticket_node);
+}
+
+/*
+ * Rx data processing:
+ *
+ * We're receiving Rx packet from the LMAC, and Rx ticket from
+ * the UMAC.
+ * To forward a target data packet upstream (i.e. to the
+ * kernel network stack), we must have received an Rx ticket
+ * that tells us we're allowed to release this packet (ticket
+ * action is IWM_RX_TICKET_RELEASE). The Rx ticket also indicates,
+ * among other things, where valid data actually starts in the Rx
+ * packet.
+ */
+void iwm_rx_worker(struct work_struct *work)
+{
+ struct iwm_priv *iwm;
+ struct iwm_rx_ticket_node *ticket, *next;
+
+ iwm = container_of(work, struct iwm_priv, rx_worker);
+
+ /*
+ * We go through the tickets list and if there is a pending
+ * packet for it, we push it upstream.
+ * We stop whenever a ticket is missing its packet, as we're
+ * supposed to send the packets in order.
+ */
+ list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) {
+ struct iwm_rx_packet *packet =
+ iwm_rx_packet_get(iwm, le16_to_cpu(ticket->ticket->id));
+
+ if (!packet) {
+ IWM_DBG_RX(iwm, DBG, "Skip rx_work: Wait for ticket %d "
+ "to be handled first\n",
+ le16_to_cpu(ticket->ticket->id));
+ return;
+ }
+
+ list_del(&ticket->node);
+ list_del(&packet->node);
+ iwm_rx_process_packet(iwm, packet, ticket);
+ }
+}
+
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.h b/drivers/net/wireless/iwmc3200wifi/rx.h
new file mode 100644
index 00000000000..da0db91cee5
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/rx.h
@@ -0,0 +1,60 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_RX_H__
+#define __IWM_RX_H__
+
+#include <linux/skbuff.h>
+
+#include "umac.h"
+
+struct iwm_rx_ticket_node {
+ struct list_head node;
+ struct iwm_rx_ticket *ticket;
+};
+
+struct iwm_rx_packet {
+ struct list_head node;
+ u16 id;
+ struct sk_buff *skb;
+ unsigned long pkt_size;
+};
+
+void iwm_rx_worker(struct work_struct *work);
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c
new file mode 100644
index 00000000000..b54da677b37
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/sdio.c
@@ -0,0 +1,516 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+/*
+ * This is the SDIO bus specific hooks for iwm.
+ * It also is the module's entry point.
+ *
+ * Interesting code paths:
+ * iwm_sdio_probe() (Called by an SDIO bus scan)
+ * -> iwm_if_alloc() (netdev.c)
+ * -> iwm_wdev_alloc() (cfg80211.c, allocates and register our wiphy)
+ * -> wiphy_new()
+ * -> wiphy_register()
+ * -> alloc_netdev_mq()
+ * -> register_netdev()
+ *
+ * iwm_sdio_remove()
+ * -> iwm_if_free() (netdev.c)
+ * -> unregister_netdev()
+ * -> iwm_wdev_free() (cfg80211.c)
+ * -> wiphy_unregister()
+ * -> wiphy_free()
+ *
+ * iwm_sdio_isr() (called in process context from the SDIO core code)
+ * -> queue_work(.., isr_worker)
+ * -- [async] --> iwm_sdio_isr_worker()
+ * -> iwm_rx_handle()
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/debugfs.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "iwm.h"
+#include "debug.h"
+#include "bus.h"
+#include "sdio.h"
+
+static void iwm_sdio_isr_worker(struct work_struct *work)
+{
+ struct iwm_sdio_priv *hw;
+ struct iwm_priv *iwm;
+ struct iwm_rx_info *rx_info;
+ struct sk_buff *skb;
+ u8 *rx_buf;
+ unsigned long rx_size;
+
+ hw = container_of(work, struct iwm_sdio_priv, isr_worker);
+ iwm = hw_to_iwm(hw);
+
+ while (!skb_queue_empty(&iwm->rx_list)) {
+ skb = skb_dequeue(&iwm->rx_list);
+ rx_info = skb_to_rx_info(skb);
+ rx_size = rx_info->rx_size;
+ rx_buf = skb->data;
+
+ IWM_HEXDUMP(iwm, DBG, SDIO, "RX: ", rx_buf, rx_size);
+ if (iwm_rx_handle(iwm, rx_buf, rx_size) < 0)
+ IWM_WARN(iwm, "RX error\n");
+
+ kfree_skb(skb);
+ }
+}
+
+static void iwm_sdio_isr(struct sdio_func *func)
+{
+ struct iwm_priv *iwm;
+ struct iwm_sdio_priv *hw;
+ struct iwm_rx_info *rx_info;
+ struct sk_buff *skb;
+ unsigned long buf_size, read_size;
+ int ret;
+ u8 val;
+
+ hw = sdio_get_drvdata(func);
+ iwm = hw_to_iwm(hw);
+
+ buf_size = hw->blk_size;
+
+ /* We're checking the status */
+ val = sdio_readb(func, IWM_SDIO_INTR_STATUS_ADDR, &ret);
+ if (val == 0 || ret < 0) {
+ IWM_ERR(iwm, "Wrong INTR_STATUS\n");
+ return;
+ }
+
+ /* See if we have free buffers */
+ if (skb_queue_len(&iwm->rx_list) > IWM_RX_LIST_SIZE) {
+ IWM_ERR(iwm, "No buffer for more Rx frames\n");
+ return;
+ }
+
+ /* We first read the transaction size */
+ read_size = sdio_readb(func, IWM_SDIO_INTR_GET_SIZE_ADDR + 1, &ret);
+ read_size = read_size << 8;
+
+ if (ret < 0) {
+ IWM_ERR(iwm, "Couldn't read the xfer size\n");
+ return;
+ }
+
+ /* We need to clear the INT register */
+ sdio_writeb(func, 1, IWM_SDIO_INTR_CLEAR_ADDR, &ret);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Couldn't clear the INT register\n");
+ return;
+ }
+
+ while (buf_size < read_size)
+ buf_size <<= 1;
+
+ skb = dev_alloc_skb(buf_size);
+ if (!skb) {
+ IWM_ERR(iwm, "Couldn't alloc RX skb\n");
+ return;
+ }
+ rx_info = skb_to_rx_info(skb);
+ rx_info->rx_size = read_size;
+ rx_info->rx_buf_size = buf_size;
+
+ /* Now we can read the actual buffer */
+ ret = sdio_memcpy_fromio(func, skb_put(skb, read_size),
+ IWM_SDIO_DATA_ADDR, read_size);
+
+ /* The skb is put on a driver's specific Rx SKB list */
+ skb_queue_tail(&iwm->rx_list, skb);
+
+ /* We can now schedule the actual worker */
+ queue_work(hw->isr_wq, &hw->isr_worker);
+}
+
+static void iwm_sdio_rx_free(struct iwm_sdio_priv *hw)
+{
+ struct iwm_priv *iwm = hw_to_iwm(hw);
+
+ flush_workqueue(hw->isr_wq);
+
+ skb_queue_purge(&iwm->rx_list);
+}
+
+/* Bus ops */
+static int if_sdio_enable(struct iwm_priv *iwm)
+{
+ struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
+ int ret;
+
+ sdio_claim_host(hw->func);
+
+ ret = sdio_enable_func(hw->func);
+ if (ret) {
+ IWM_ERR(iwm, "Couldn't enable the device: is TOP driver "
+ "loaded and functional?\n");
+ goto release_host;
+ }
+
+ iwm_reset(iwm);
+
+ ret = sdio_claim_irq(hw->func, iwm_sdio_isr);
+ if (ret) {
+ IWM_ERR(iwm, "Failed to claim irq: %d\n", ret);
+ goto release_host;
+ }
+
+ sdio_writeb(hw->func, 1, IWM_SDIO_INTR_ENABLE_ADDR, &ret);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Couldn't enable INTR: %d\n", ret);
+ goto release_irq;
+ }
+
+ sdio_release_host(hw->func);
+
+ IWM_DBG_SDIO(iwm, INFO, "IWM SDIO enable\n");
+
+ return 0;
+
+ release_irq:
+ sdio_release_irq(hw->func);
+ release_host:
+ sdio_release_host(hw->func);
+
+ return ret;
+}
+
+static int if_sdio_disable(struct iwm_priv *iwm)
+{
+ struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
+ int ret;
+
+ iwm_reset(iwm);
+
+ sdio_claim_host(hw->func);
+ sdio_writeb(hw->func, 0, IWM_SDIO_INTR_ENABLE_ADDR, &ret);
+ if (ret < 0)
+ IWM_WARN(iwm, "Couldn't disable INTR: %d\n", ret);
+
+ sdio_release_irq(hw->func);
+ sdio_disable_func(hw->func);
+ sdio_release_host(hw->func);
+
+ iwm_sdio_rx_free(hw);
+
+ IWM_DBG_SDIO(iwm, INFO, "IWM SDIO disable\n");
+
+ return 0;
+}
+
+static int if_sdio_send_chunk(struct iwm_priv *iwm, u8 *buf, int count)
+{
+ struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
+ int aligned_count = ALIGN(count, hw->blk_size);
+ int ret;
+
+ if ((unsigned long)buf & 0x3) {
+ IWM_ERR(iwm, "buf <%p> is not dword aligned\n", buf);
+ /* TODO: Is this a hardware limitation? use get_unligned */
+ return -EINVAL;
+ }
+
+ sdio_claim_host(hw->func);
+ ret = sdio_memcpy_toio(hw->func, IWM_SDIO_DATA_ADDR, buf,
+ aligned_count);
+ sdio_release_host(hw->func);
+
+ return ret;
+}
+
+/* debugfs hooks */
+static int iwm_debugfs_sdio_open(struct inode *inode, struct file *filp)
+{
+ filp->private_data = inode->i_private;
+ return 0;
+}
+
+static ssize_t iwm_debugfs_sdio_read(struct file *filp, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct iwm_priv *iwm = filp->private_data;
+ struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
+ char *buf;
+ u8 cccr;
+ int buf_len = 4096, ret;
+ size_t len = 0;
+
+ if (*ppos != 0)
+ return 0;
+ if (count < sizeof(buf))
+ return -ENOSPC;
+
+ buf = kzalloc(buf_len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ sdio_claim_host(hw->func);
+
+ cccr = sdio_f0_readb(hw->func, SDIO_CCCR_IOEx, &ret);
+ if (ret) {
+ IWM_ERR(iwm, "Could not read SDIO_CCCR_IOEx\n");
+ goto err;
+ }
+ len += snprintf(buf + len, buf_len - len, "CCCR_IOEx: 0x%x\n", cccr);
+
+ cccr = sdio_f0_readb(hw->func, SDIO_CCCR_IORx, &ret);
+ if (ret) {
+ IWM_ERR(iwm, "Could not read SDIO_CCCR_IORx\n");
+ goto err;
+ }
+ len += snprintf(buf + len, buf_len - len, "CCCR_IORx: 0x%x\n", cccr);
+
+
+ cccr = sdio_f0_readb(hw->func, SDIO_CCCR_IENx, &ret);
+ if (ret) {
+ IWM_ERR(iwm, "Could not read SDIO_CCCR_IENx\n");
+ goto err;
+ }
+ len += snprintf(buf + len, buf_len - len, "CCCR_IENx: 0x%x\n", cccr);
+
+
+ cccr = sdio_f0_readb(hw->func, SDIO_CCCR_INTx, &ret);
+ if (ret) {
+ IWM_ERR(iwm, "Could not read SDIO_CCCR_INTx\n");
+ goto err;
+ }
+ len += snprintf(buf + len, buf_len - len, "CCCR_INTx: 0x%x\n", cccr);
+
+
+ cccr = sdio_f0_readb(hw->func, SDIO_CCCR_ABORT, &ret);
+ if (ret) {
+ IWM_ERR(iwm, "Could not read SDIO_CCCR_ABORTx\n");
+ goto err;
+ }
+ len += snprintf(buf + len, buf_len - len, "CCCR_ABORT: 0x%x\n", cccr);
+
+ cccr = sdio_f0_readb(hw->func, SDIO_CCCR_IF, &ret);
+ if (ret) {
+ IWM_ERR(iwm, "Could not read SDIO_CCCR_IF\n");
+ goto err;
+ }
+ len += snprintf(buf + len, buf_len - len, "CCCR_IF: 0x%x\n", cccr);
+
+
+ cccr = sdio_f0_readb(hw->func, SDIO_CCCR_CAPS, &ret);
+ if (ret) {
+ IWM_ERR(iwm, "Could not read SDIO_CCCR_CAPS\n");
+ goto err;
+ }
+ len += snprintf(buf + len, buf_len - len, "CCCR_CAPS: 0x%x\n", cccr);
+
+ cccr = sdio_f0_readb(hw->func, SDIO_CCCR_CIS, &ret);
+ if (ret) {
+ IWM_ERR(iwm, "Could not read SDIO_CCCR_CIS\n");
+ goto err;
+ }
+ len += snprintf(buf + len, buf_len - len, "CCCR_CIS: 0x%x\n", cccr);
+
+ ret = simple_read_from_buffer(buffer, len, ppos, buf, buf_len);
+err:
+ sdio_release_host(hw->func);
+
+ kfree(buf);
+
+ return ret;
+}
+
+static const struct file_operations iwm_debugfs_sdio_fops = {
+ .owner = THIS_MODULE,
+ .open = iwm_debugfs_sdio_open,
+ .read = iwm_debugfs_sdio_read,
+};
+
+static int if_sdio_debugfs_init(struct iwm_priv *iwm, struct dentry *parent_dir)
+{
+ int result;
+ struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
+
+ hw->cccr_dentry = debugfs_create_file("cccr", 0200,
+ parent_dir, iwm,
+ &iwm_debugfs_sdio_fops);
+ result = PTR_ERR(hw->cccr_dentry);
+ if (IS_ERR(hw->cccr_dentry) && (result != -ENODEV)) {
+ IWM_ERR(iwm, "Couldn't create CCCR entry: %d\n", result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void if_sdio_debugfs_exit(struct iwm_priv *iwm)
+{
+ struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
+
+ debugfs_remove(hw->cccr_dentry);
+}
+
+static struct iwm_if_ops if_sdio_ops = {
+ .enable = if_sdio_enable,
+ .disable = if_sdio_disable,
+ .send_chunk = if_sdio_send_chunk,
+ .debugfs_init = if_sdio_debugfs_init,
+ .debugfs_exit = if_sdio_debugfs_exit,
+ .umac_name = "iwmc3200wifi-umac-sdio.bin",
+ .calib_lmac_name = "iwmc3200wifi-calib-sdio.bin",
+ .lmac_name = "iwmc3200wifi-lmac-sdio.bin",
+};
+
+static int iwm_sdio_probe(struct sdio_func *func,
+ const struct sdio_device_id *id)
+{
+ struct iwm_priv *iwm;
+ struct iwm_sdio_priv *hw;
+ struct device *dev = &func->dev;
+ int ret;
+
+ /* check if TOP has already initialized the card */
+ sdio_claim_host(func);
+ ret = sdio_enable_func(func);
+ if (ret) {
+ dev_err(dev, "wait for TOP to enable the device\n");
+ sdio_release_host(func);
+ return ret;
+ }
+
+ ret = sdio_set_block_size(func, IWM_SDIO_BLK_SIZE);
+
+ sdio_disable_func(func);
+ sdio_release_host(func);
+
+ if (ret < 0) {
+ dev_err(dev, "Failed to set block size: %d\n", ret);
+ return ret;
+ }
+
+ iwm = iwm_if_alloc(sizeof(struct iwm_sdio_priv), dev, &if_sdio_ops);
+ if (IS_ERR(iwm)) {
+ dev_err(dev, "allocate SDIO interface failed\n");
+ return PTR_ERR(iwm);
+ }
+
+ hw = iwm_private(iwm);
+ hw->iwm = iwm;
+
+ ret = iwm_debugfs_init(iwm);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Debugfs registration failed\n");
+ goto if_free;
+ }
+
+ sdio_set_drvdata(func, hw);
+
+ hw->func = func;
+ hw->blk_size = IWM_SDIO_BLK_SIZE;
+
+ hw->isr_wq = create_singlethread_workqueue(KBUILD_MODNAME "_sdio");
+ if (!hw->isr_wq) {
+ ret = -ENOMEM;
+ goto debugfs_exit;
+ }
+
+ INIT_WORK(&hw->isr_worker, iwm_sdio_isr_worker);
+
+ dev_info(dev, "IWM SDIO probe\n");
+
+ return 0;
+
+ debugfs_exit:
+ iwm_debugfs_exit(iwm);
+ if_free:
+ iwm_if_free(iwm);
+ return ret;
+}
+
+static void iwm_sdio_remove(struct sdio_func *func)
+{
+ struct iwm_sdio_priv *hw = sdio_get_drvdata(func);
+ struct iwm_priv *iwm = hw_to_iwm(hw);
+ struct device *dev = &func->dev;
+
+ iwm_debugfs_exit(iwm);
+ iwm_if_free(iwm);
+ destroy_workqueue(hw->isr_wq);
+
+ sdio_set_drvdata(func, NULL);
+
+ dev_info(dev, "IWM SDIO remove\n");
+
+ return;
+}
+
+static const struct sdio_device_id iwm_sdio_ids[] = {
+ { SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, SDIO_DEVICE_ID_IWM) },
+ { /* end: all zeroes */ },
+};
+MODULE_DEVICE_TABLE(sdio, iwm_sdio_ids);
+
+static struct sdio_driver iwm_sdio_driver = {
+ .name = "iwm_sdio",
+ .id_table = iwm_sdio_ids,
+ .probe = iwm_sdio_probe,
+ .remove = iwm_sdio_remove,
+};
+
+static int __init iwm_sdio_init_module(void)
+{
+ int ret;
+
+ ret = sdio_register_driver(&iwm_sdio_driver);
+
+ return ret;
+}
+
+static void __exit iwm_sdio_exit_module(void)
+{
+ sdio_unregister_driver(&iwm_sdio_driver);
+}
+
+module_init(iwm_sdio_init_module);
+module_exit(iwm_sdio_exit_module);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR(IWM_COPYRIGHT " " IWM_AUTHOR);
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.h b/drivers/net/wireless/iwmc3200wifi/sdio.h
new file mode 100644
index 00000000000..b3c156b08dd
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/sdio.h
@@ -0,0 +1,67 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_SDIO_H__
+#define __IWM_SDIO_H__
+
+#define SDIO_VENDOR_ID_INTEL 0x89
+#define SDIO_DEVICE_ID_IWM 0x1403
+
+#define IWM_SDIO_DATA_ADDR 0x0
+#define IWM_SDIO_INTR_ENABLE_ADDR 0x14
+#define IWM_SDIO_INTR_STATUS_ADDR 0x13
+#define IWM_SDIO_INTR_CLEAR_ADDR 0x13
+#define IWM_SDIO_INTR_GET_SIZE_ADDR 0x2C
+
+#define IWM_SDIO_BLK_SIZE 256
+
+#define iwm_to_if_sdio(i) (struct iwm_sdio_priv *)(iwm->private)
+
+struct iwm_sdio_priv {
+ struct sdio_func *func;
+ struct iwm_priv *iwm;
+
+ struct workqueue_struct *isr_wq;
+ struct work_struct isr_worker;
+
+ struct dentry *cccr_dentry;
+
+ unsigned int blk_size;
+};
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/tx.c b/drivers/net/wireless/iwmc3200wifi/tx.c
new file mode 100644
index 00000000000..e3b4f7902da
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/tx.c
@@ -0,0 +1,492 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+/*
+ * iwm Tx theory of operation:
+ *
+ * 1) We receive a 802.3 frame from the stack
+ * 2) We convert it to a 802.11 frame [iwm_xmit_frame]
+ * 3) We queue it to its corresponding tx queue [iwm_xmit_frame]
+ * 4) We schedule the tx worker. There is one worker per tx
+ * queue. [iwm_xmit_frame]
+ * 5) The tx worker is scheduled
+ * 6) We go through every queued skb on the tx queue, and for each
+ * and every one of them: [iwm_tx_worker]
+ * a) We check if we have enough Tx credits (see below for a Tx
+ * credits description) for the frame length. [iwm_tx_worker]
+ * b) If we do, we aggregate the Tx frame into a UDMA one, by
+ * concatenating one REPLY_TX command per Tx frame. [iwm_tx_worker]
+ * c) When we run out of credits, or when we reach the maximum
+ * concatenation size, we actually send the concatenated UDMA
+ * frame. [iwm_tx_worker]
+ *
+ * When we run out of Tx credits, the skbs are filling the tx queue,
+ * and eventually we will stop the netdev queue. [iwm_tx_worker]
+ * The tx queue is emptied as we're getting new tx credits, by
+ * scheduling the tx_worker. [iwm_tx_credit_inc]
+ * The netdev queue is started again when we have enough tx credits,
+ * and when our tx queue has some reasonable amout of space available
+ * (i.e. half of the max size). [iwm_tx_worker]
+ */
+
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/ieee80211.h>
+
+#include "iwm.h"
+#include "debug.h"
+#include "commands.h"
+#include "hal.h"
+#include "umac.h"
+#include "bus.h"
+
+#define IWM_UMAC_PAGE_ALLOC_WRAP 0xffff
+
+#define BYTES_TO_PAGES(n) (1 + ((n) >> ilog2(IWM_UMAC_PAGE_SIZE)) - \
+ (((n) & (IWM_UMAC_PAGE_SIZE - 1)) == 0))
+
+#define pool_id_to_queue(id) ((id < IWM_TX_CMD_QUEUE) ? id : id - 1)
+#define queue_to_pool_id(q) ((q < IWM_TX_CMD_QUEUE) ? q : q + 1)
+
+/* require to hold tx_credit lock */
+static int iwm_tx_credit_get(struct iwm_tx_credit *tx_credit, int id)
+{
+ struct pool_entry *pool = &tx_credit->pools[id];
+ struct spool_entry *spool = &tx_credit->spools[pool->sid];
+ int spool_pages;
+
+ /* number of pages can be taken from spool by this pool */
+ spool_pages = spool->max_pages - spool->alloc_pages +
+ max(pool->min_pages - pool->alloc_pages, 0);
+
+ return min(pool->max_pages - pool->alloc_pages, spool_pages);
+}
+
+static bool iwm_tx_credit_ok(struct iwm_priv *iwm, int id, int nb)
+{
+ u32 npages = BYTES_TO_PAGES(nb);
+
+ if (npages <= iwm_tx_credit_get(&iwm->tx_credit, id))
+ return 1;
+
+ set_bit(id, &iwm->tx_credit.full_pools_map);
+
+ IWM_DBG_TX(iwm, DBG, "LINK: stop txq[%d], available credit: %d\n",
+ pool_id_to_queue(id),
+ iwm_tx_credit_get(&iwm->tx_credit, id));
+
+ return 0;
+}
+
+void iwm_tx_credit_inc(struct iwm_priv *iwm, int id, int total_freed_pages)
+{
+ struct pool_entry *pool;
+ struct spool_entry *spool;
+ int freed_pages;
+ int queue;
+
+ BUG_ON(id >= IWM_MACS_OUT_GROUPS);
+
+ pool = &iwm->tx_credit.pools[id];
+ spool = &iwm->tx_credit.spools[pool->sid];
+
+ freed_pages = total_freed_pages - pool->total_freed_pages;
+ IWM_DBG_TX(iwm, DBG, "Free %d pages for pool[%d]\n", freed_pages, id);
+
+ if (!freed_pages) {
+ IWM_DBG_TX(iwm, DBG, "No pages are freed by UMAC\n");
+ return;
+ } else if (freed_pages < 0)
+ freed_pages += IWM_UMAC_PAGE_ALLOC_WRAP + 1;
+
+ if (pool->alloc_pages > pool->min_pages) {
+ int spool_pages = pool->alloc_pages - pool->min_pages;
+ spool_pages = min(spool_pages, freed_pages);
+ spool->alloc_pages -= spool_pages;
+ }
+
+ pool->alloc_pages -= freed_pages;
+ pool->total_freed_pages = total_freed_pages;
+
+ IWM_DBG_TX(iwm, DBG, "Pool[%d] pages alloc: %d, total_freed: %d, "
+ "Spool[%d] pages alloc: %d\n", id, pool->alloc_pages,
+ pool->total_freed_pages, pool->sid, spool->alloc_pages);
+
+ if (test_bit(id, &iwm->tx_credit.full_pools_map) &&
+ (pool->alloc_pages < pool->max_pages / 2)) {
+ clear_bit(id, &iwm->tx_credit.full_pools_map);
+
+ queue = pool_id_to_queue(id);
+
+ IWM_DBG_TX(iwm, DBG, "LINK: start txq[%d], available "
+ "credit: %d\n", queue,
+ iwm_tx_credit_get(&iwm->tx_credit, id));
+ queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker);
+ }
+}
+
+static void iwm_tx_credit_dec(struct iwm_priv *iwm, int id, int alloc_pages)
+{
+ struct pool_entry *pool;
+ struct spool_entry *spool;
+ int spool_pages;
+
+ IWM_DBG_TX(iwm, DBG, "Allocate %d pages for pool[%d]\n",
+ alloc_pages, id);
+
+ BUG_ON(id >= IWM_MACS_OUT_GROUPS);
+
+ pool = &iwm->tx_credit.pools[id];
+ spool = &iwm->tx_credit.spools[pool->sid];
+
+ spool_pages = pool->alloc_pages + alloc_pages - pool->min_pages;
+
+ if (pool->alloc_pages >= pool->min_pages)
+ spool->alloc_pages += alloc_pages;
+ else if (spool_pages > 0)
+ spool->alloc_pages += spool_pages;
+
+ pool->alloc_pages += alloc_pages;
+
+ IWM_DBG_TX(iwm, DBG, "Pool[%d] pages alloc: %d, total_freed: %d, "
+ "Spool[%d] pages alloc: %d\n", id, pool->alloc_pages,
+ pool->total_freed_pages, pool->sid, spool->alloc_pages);
+}
+
+int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb)
+{
+ u32 npages = BYTES_TO_PAGES(nb);
+ int ret = 0;
+
+ spin_lock(&iwm->tx_credit.lock);
+
+ if (!iwm_tx_credit_ok(iwm, id, nb)) {
+ IWM_DBG_TX(iwm, DBG, "No credit avaliable for pool[%d]\n", id);
+ ret = -ENOSPC;
+ goto out;
+ }
+
+ iwm_tx_credit_dec(iwm, id, npages);
+
+ out:
+ spin_unlock(&iwm->tx_credit.lock);
+ return ret;
+}
+
+/*
+ * Since we're on an SDIO or USB bus, we are not sharing memory
+ * for storing to be transmitted frames. The host needs to push
+ * them upstream. As a consequence there needs to be a way for
+ * the target to let us know if it can actually take more TX frames
+ * or not. This is what Tx credits are for.
+ *
+ * For each Tx HW queue, we have a Tx pool, and then we have one
+ * unique super pool (spool), which is actually a global pool of
+ * all the UMAC pages.
+ * For each Tx pool we have a min_pages, a max_pages fields, and a
+ * alloc_pages fields. The alloc_pages tracks the number of pages
+ * currently allocated from the tx pool.
+ * Here are the rules to check if given a tx frame we have enough
+ * tx credits for it:
+ * 1) We translate the frame length into a number of UMAC pages.
+ * Let's call them n_pages.
+ * 2) For the corresponding tx pool, we check if n_pages +
+ * pool->alloc_pages is higher than pool->min_pages. min_pages
+ * represent a set of pre-allocated pages on the tx pool. If
+ * that's the case, then we need to allocate those pages from
+ * the spool. We can do so until we reach spool->max_pages.
+ * 3) Each tx pool is not allowed to allocate more than pool->max_pages
+ * from the spool, so once we're over min_pages, we can allocate
+ * pages from the spool, but not more than max_pages.
+ *
+ * When the tx code path needs to send a tx frame, it checks first
+ * if it has enough tx credits, following those rules. [iwm_tx_credit_get]
+ * If it does, it then updates the pool and spool counters and
+ * then send the frame. [iwm_tx_credit_alloc and iwm_tx_credit_dec]
+ * On the other side, when the UMAC is done transmitting frames, it
+ * will send a credit update notification to the host. This is when
+ * the pool and spool counters gets to be decreased. [iwm_tx_credit_inc,
+ * called from rx.c:iwm_ntf_tx_credit_update]
+ *
+ */
+void iwm_tx_credit_init_pools(struct iwm_priv *iwm,
+ struct iwm_umac_notif_alive *alive)
+{
+ int i, sid, pool_pages;
+
+ spin_lock(&iwm->tx_credit.lock);
+
+ iwm->tx_credit.pool_nr = le16_to_cpu(alive->page_grp_count);
+ iwm->tx_credit.full_pools_map = 0;
+ memset(&iwm->tx_credit.spools[0], 0, sizeof(struct spool_entry));
+
+ IWM_DBG_TX(iwm, DBG, "Pools number is %d\n", iwm->tx_credit.pool_nr);
+
+ for (i = 0; i < iwm->tx_credit.pool_nr; i++) {
+ __le32 page_grp_state = alive->page_grp_state[i];
+
+ iwm->tx_credit.pools[i].id = GET_VAL32(page_grp_state,
+ UMAC_ALIVE_PAGE_STS_GRP_NUM);
+ iwm->tx_credit.pools[i].sid = GET_VAL32(page_grp_state,
+ UMAC_ALIVE_PAGE_STS_SGRP_NUM);
+ iwm->tx_credit.pools[i].min_pages = GET_VAL32(page_grp_state,
+ UMAC_ALIVE_PAGE_STS_GRP_MIN_SIZE);
+ iwm->tx_credit.pools[i].max_pages = GET_VAL32(page_grp_state,
+ UMAC_ALIVE_PAGE_STS_GRP_MAX_SIZE);
+ iwm->tx_credit.pools[i].alloc_pages = 0;
+ iwm->tx_credit.pools[i].total_freed_pages = 0;
+
+ sid = iwm->tx_credit.pools[i].sid;
+ pool_pages = iwm->tx_credit.pools[i].min_pages;
+
+ if (iwm->tx_credit.spools[sid].max_pages == 0) {
+ iwm->tx_credit.spools[sid].id = sid;
+ iwm->tx_credit.spools[sid].max_pages =
+ GET_VAL32(page_grp_state,
+ UMAC_ALIVE_PAGE_STS_SGRP_MAX_SIZE);
+ iwm->tx_credit.spools[sid].alloc_pages = 0;
+ }
+
+ iwm->tx_credit.spools[sid].alloc_pages += pool_pages;
+
+ IWM_DBG_TX(iwm, DBG, "Pool idx: %d, id: %d, sid: %d, capacity "
+ "min: %d, max: %d, pool alloc: %d, total_free: %d, "
+ "super poll alloc: %d\n",
+ i, iwm->tx_credit.pools[i].id,
+ iwm->tx_credit.pools[i].sid,
+ iwm->tx_credit.pools[i].min_pages,
+ iwm->tx_credit.pools[i].max_pages,
+ iwm->tx_credit.pools[i].alloc_pages,
+ iwm->tx_credit.pools[i].total_freed_pages,
+ iwm->tx_credit.spools[sid].alloc_pages);
+ }
+
+ spin_unlock(&iwm->tx_credit.lock);
+}
+
+#define IWM_UDMA_HDR_LEN sizeof(struct iwm_umac_wifi_out_hdr)
+
+static int iwm_tx_build_packet(struct iwm_priv *iwm, struct sk_buff *skb,
+ int pool_id, u8 *buf)
+{
+ struct iwm_umac_wifi_out_hdr *hdr = (struct iwm_umac_wifi_out_hdr *)buf;
+ struct iwm_udma_wifi_cmd udma_cmd;
+ struct iwm_umac_cmd umac_cmd;
+ struct iwm_tx_info *tx_info = skb_to_tx_info(skb);
+
+ udma_cmd.count = cpu_to_le16(skb->len +
+ sizeof(struct iwm_umac_fw_cmd_hdr));
+ /* set EOP to 0 here. iwm_udma_wifi_hdr_set_eop() will be
+ * called later to set EOP for the last packet. */
+ udma_cmd.eop = 0;
+ udma_cmd.credit_group = pool_id;
+ udma_cmd.ra_tid = tx_info->sta << 4 | tx_info->tid;
+ udma_cmd.lmac_offset = 0;
+
+ umac_cmd.id = REPLY_TX;
+ umac_cmd.count = cpu_to_le16(skb->len);
+ umac_cmd.color = tx_info->color;
+ umac_cmd.resp = 0;
+ umac_cmd.seq_num = cpu_to_le16(iwm_alloc_wifi_cmd_seq(iwm));
+
+ iwm_build_udma_wifi_hdr(iwm, &hdr->hw_hdr, &udma_cmd);
+ iwm_build_umac_hdr(iwm, &hdr->sw_hdr, &umac_cmd);
+
+ memcpy(buf + sizeof(*hdr), skb->data, skb->len);
+
+ return 0;
+}
+
+static int iwm_tx_send_concat_packets(struct iwm_priv *iwm,
+ struct iwm_tx_queue *txq)
+{
+ int ret;
+
+ if (!txq->concat_count)
+ return 0;
+
+ IWM_DBG_TX(iwm, DBG, "Send concatenated Tx: queue %d, %d bytes\n",
+ txq->id, txq->concat_count);
+
+ /* mark EOP for the last packet */
+ iwm_udma_wifi_hdr_set_eop(iwm, txq->concat_ptr, 1);
+
+ ret = iwm_bus_send_chunk(iwm, txq->concat_buf, txq->concat_count);
+
+ txq->concat_count = 0;
+ txq->concat_ptr = txq->concat_buf;
+
+ return ret;
+}
+
+#define CONFIG_IWM_TX_CONCATENATED 1
+
+void iwm_tx_worker(struct work_struct *work)
+{
+ struct iwm_priv *iwm;
+ struct iwm_tx_info *tx_info = NULL;
+ struct sk_buff *skb;
+ int cmdlen, ret;
+ struct iwm_tx_queue *txq;
+ int pool_id;
+
+ txq = container_of(work, struct iwm_tx_queue, worker);
+ iwm = container_of(txq, struct iwm_priv, txq[txq->id]);
+
+ pool_id = queue_to_pool_id(txq->id);
+
+ while (!test_bit(pool_id, &iwm->tx_credit.full_pools_map) &&
+ !skb_queue_empty(&txq->queue)) {
+
+ skb = skb_dequeue(&txq->queue);
+ tx_info = skb_to_tx_info(skb);
+ cmdlen = IWM_UDMA_HDR_LEN + skb->len;
+
+ IWM_DBG_TX(iwm, DBG, "Tx frame on queue %d: skb: 0x%p, sta: "
+ "%d, color: %d\n", txq->id, skb, tx_info->sta,
+ tx_info->color);
+
+#if !CONFIG_IWM_TX_CONCATENATED
+ /* temporarily keep this to comparing the performance */
+ ret = iwm_send_packet(iwm, skb, pool_id);
+#else
+
+ if (txq->concat_count + cmdlen > IWM_HAL_CONCATENATE_BUF_SIZE)
+ iwm_tx_send_concat_packets(iwm, txq);
+
+ ret = iwm_tx_credit_alloc(iwm, pool_id, cmdlen);
+ if (ret) {
+ IWM_DBG_TX(iwm, DBG, "not enough tx_credit for queue "
+ "%d, Tx worker stopped\n", txq->id);
+ skb_queue_head(&txq->queue, skb);
+ break;
+ }
+
+ txq->concat_ptr = txq->concat_buf + txq->concat_count;
+ iwm_tx_build_packet(iwm, skb, pool_id, txq->concat_ptr);
+ txq->concat_count += ALIGN(cmdlen, 16);
+#endif
+ kfree_skb(skb);
+ }
+
+ iwm_tx_send_concat_packets(iwm, txq);
+
+ if (__netif_subqueue_stopped(iwm_to_ndev(iwm), txq->id) &&
+ !test_bit(pool_id, &iwm->tx_credit.full_pools_map) &&
+ (skb_queue_len(&txq->queue) < IWM_TX_LIST_SIZE / 2)) {
+ IWM_DBG_TX(iwm, DBG, "LINK: start netif_subqueue[%d]", txq->id);
+ netif_wake_subqueue(iwm_to_ndev(iwm), txq->id);
+ }
+}
+
+int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(netdev);
+ struct net_device *ndev = iwm_to_ndev(iwm);
+ struct wireless_dev *wdev = iwm_to_wdev(iwm);
+ u8 *dst_addr;
+ struct iwm_tx_info *tx_info;
+ struct iwm_tx_queue *txq;
+ struct iwm_sta_info *sta_info;
+ u8 sta_id;
+ u16 queue;
+ int ret;
+
+ if (!test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
+ IWM_DBG_TX(iwm, DBG, "LINK: stop netif_all_queues: "
+ "not associated\n");
+ netif_tx_stop_all_queues(netdev);
+ goto drop;
+ }
+
+ queue = skb_get_queue_mapping(skb);
+ BUG_ON(queue >= IWM_TX_DATA_QUEUES); /* no iPAN yet */
+
+ txq = &iwm->txq[queue];
+
+ /* No free space for Tx, tx_worker is too slow */
+ if (skb_queue_len(&txq->queue) > IWM_TX_LIST_SIZE) {
+ IWM_DBG_TX(iwm, DBG, "LINK: stop netif_subqueue[%d]\n", queue);
+ netif_stop_subqueue(netdev, queue);
+ return NETDEV_TX_BUSY;
+ }
+
+ ret = ieee80211_data_from_8023(skb, netdev->dev_addr, wdev->iftype,
+ iwm->bssid, 0);
+ if (ret) {
+ IWM_ERR(iwm, "build wifi header failed\n");
+ goto drop;
+ }
+
+ dst_addr = ((struct ieee80211_hdr *)(skb->data))->addr1;
+
+ for (sta_id = 0; sta_id < IWM_STA_TABLE_NUM; sta_id++) {
+ sta_info = &iwm->sta_table[sta_id];
+ if (sta_info->valid &&
+ !memcmp(dst_addr, sta_info->addr, ETH_ALEN))
+ break;
+ }
+
+ if (sta_id == IWM_STA_TABLE_NUM) {
+ IWM_ERR(iwm, "STA %pM not found in sta_table, Tx ignored\n",
+ dst_addr);
+ goto drop;
+ }
+
+ tx_info = skb_to_tx_info(skb);
+ tx_info->sta = sta_id;
+ tx_info->color = sta_info->color;
+ /* UMAC uses TID 8 (vs. 0) for non QoS packets */
+ if (sta_info->qos)
+ tx_info->tid = skb->priority;
+ else
+ tx_info->tid = IWM_UMAC_MGMT_TID;
+
+ skb_queue_tail(&iwm->txq[queue].queue, skb);
+
+ queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker);
+
+ ndev->stats.tx_packets++;
+ ndev->stats.tx_bytes += skb->len;
+ return NETDEV_TX_OK;
+
+ drop:
+ ndev->stats.tx_dropped++;
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/umac.h b/drivers/net/wireless/iwmc3200wifi/umac.h
new file mode 100644
index 00000000000..4a95cce1f0a
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/umac.h
@@ -0,0 +1,744 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_UMAC_H__
+#define __IWM_UMAC_H__
+
+struct iwm_udma_in_hdr {
+ __le32 cmd;
+ __le32 size;
+} __attribute__ ((packed));
+
+struct iwm_udma_out_nonwifi_hdr {
+ __le32 cmd;
+ __le32 addr;
+ __le32 op1_sz;
+ __le32 op2;
+} __attribute__ ((packed));
+
+struct iwm_udma_out_wifi_hdr {
+ __le32 cmd;
+ __le32 meta_data;
+} __attribute__ ((packed));
+
+/* Sequence numbering */
+#define UMAC_WIFI_SEQ_NUM_BASE 1
+#define UMAC_WIFI_SEQ_NUM_MAX 0x4000
+#define UMAC_NONWIFI_SEQ_NUM_BASE 1
+#define UMAC_NONWIFI_SEQ_NUM_MAX 0x10
+
+/* MAC address address */
+#define WICO_MAC_ADDRESS_ADDR 0x604008F8
+
+/* RA / TID */
+#define UMAC_HDI_ACT_TBL_IDX_TID_POS 0
+#define UMAC_HDI_ACT_TBL_IDX_TID_SEED 0xF
+
+#define UMAC_HDI_ACT_TBL_IDX_RA_POS 4
+#define UMAC_HDI_ACT_TBL_IDX_RA_SEED 0xF
+
+#define UMAC_HDI_ACT_TBL_IDX_RA_UMAC 0xF
+#define UMAC_HDI_ACT_TBL_IDX_TID_UMAC 0x9
+#define UMAC_HDI_ACT_TBL_IDX_TID_LMAC 0xA
+
+#define UMAC_HDI_ACT_TBL_IDX_HOST_CMD \
+ ((UMAC_HDI_ACT_TBL_IDX_RA_UMAC << UMAC_HDI_ACT_TBL_IDX_RA_POS) |\
+ (UMAC_HDI_ACT_TBL_IDX_TID_UMAC << UMAC_HDI_ACT_TBL_IDX_TID_POS))
+#define UMAC_HDI_ACT_TBL_IDX_UMAC_CMD \
+ ((UMAC_HDI_ACT_TBL_IDX_RA_UMAC << UMAC_HDI_ACT_TBL_IDX_RA_POS) |\
+ (UMAC_HDI_ACT_TBL_IDX_TID_LMAC << UMAC_HDI_ACT_TBL_IDX_TID_POS))
+
+/* iwm_umac_notif_alive.page_grp_state Group number -- bits [3:0] */
+#define UMAC_ALIVE_PAGE_STS_GRP_NUM_POS 0
+#define UMAC_ALIVE_PAGE_STS_GRP_NUM_SEED 0xF
+
+/* iwm_umac_notif_alive.page_grp_state Super group number -- bits [7:4] */
+#define UMAC_ALIVE_PAGE_STS_SGRP_NUM_POS 4
+#define UMAC_ALIVE_PAGE_STS_SGRP_NUM_SEED 0xF
+
+/* iwm_umac_notif_alive.page_grp_state Group min size -- bits [15:8] */
+#define UMAC_ALIVE_PAGE_STS_GRP_MIN_SIZE_POS 8
+#define UMAC_ALIVE_PAGE_STS_GRP_MIN_SIZE_SEED 0xFF
+
+/* iwm_umac_notif_alive.page_grp_state Group max size -- bits [23:16] */
+#define UMAC_ALIVE_PAGE_STS_GRP_MAX_SIZE_POS 16
+#define UMAC_ALIVE_PAGE_STS_GRP_MAX_SIZE_SEED 0xFF
+
+/* iwm_umac_notif_alive.page_grp_state Super group max size -- bits [31:24] */
+#define UMAC_ALIVE_PAGE_STS_SGRP_MAX_SIZE_POS 24
+#define UMAC_ALIVE_PAGE_STS_SGRP_MAX_SIZE_SEED 0xFF
+
+/* Barkers */
+#define UMAC_REBOOT_BARKER 0xdeadbeef
+#define UMAC_ACK_BARKER 0xfeedbabe
+#define UMAC_PAD_TERMINAL 0xadadadad
+
+/* UMAC JMP address */
+#define UMAC_MU_FW_INST_DATA_12_ADDR 0xBF0000
+
+/* iwm_umac_hdi_out_hdr.cmd OP code -- bits [3:0] */
+#define UMAC_HDI_OUT_CMD_OPCODE_POS 0
+#define UMAC_HDI_OUT_CMD_OPCODE_SEED 0xF
+
+/* iwm_umac_hdi_out_hdr.cmd End-Of-Transfer -- bits [10:10] */
+#define UMAC_HDI_OUT_CMD_EOT_POS 10
+#define UMAC_HDI_OUT_CMD_EOT_SEED 0x1
+
+/* iwm_umac_hdi_out_hdr.cmd UTFD only usage -- bits [11:11] */
+#define UMAC_HDI_OUT_CMD_UTFD_ONLY_POS 11
+#define UMAC_HDI_OUT_CMD_UTFD_ONLY_SEED 0x1
+
+/* iwm_umac_hdi_out_hdr.cmd Non-WiFi HW sequence number -- bits [12:15] */
+#define UDMA_HDI_OUT_CMD_NON_WIFI_HW_SEQ_NUM_POS 12
+#define UDMA_HDI_OUT_CMD_NON_WIFI_HW_SEQ_NUM_SEED 0xF
+
+/* iwm_umac_hdi_out_hdr.cmd Signature -- bits [31:16] */
+#define UMAC_HDI_OUT_CMD_SIGNATURE_POS 16
+#define UMAC_HDI_OUT_CMD_SIGNATURE_SEED 0xFFFF
+
+/* iwm_umac_hdi_out_hdr.meta_data Byte count -- bits [11:0] */
+#define UMAC_HDI_OUT_BYTE_COUNT_POS 0
+#define UMAC_HDI_OUT_BYTE_COUNT_SEED 0xFFF
+
+/* iwm_umac_hdi_out_hdr.meta_data Credit group -- bits [15:12] */
+#define UMAC_HDI_OUT_CREDIT_GRP_POS 12
+#define UMAC_HDI_OUT_CREDIT_GRP_SEED 0xF
+
+/* iwm_umac_hdi_out_hdr.meta_data RA/TID -- bits [23:16] */
+#define UMAC_HDI_OUT_RATID_POS 16
+#define UMAC_HDI_OUT_RATID_SEED 0xFF
+
+/* iwm_umac_hdi_out_hdr.meta_data LMAC offset -- bits [31:24] */
+#define UMAC_HDI_OUT_LMAC_OFFSET_POS 24
+#define UMAC_HDI_OUT_LMAC_OFFSET_SEED 0xFF
+
+/* Signature */
+#define UMAC_HDI_OUT_SIGNATURE 0xCBBC
+
+/* buffer alignment */
+#define UMAC_HDI_BUF_ALIGN_MSK 0xF
+
+/* iwm_umac_hdi_in_hdr.cmd OP code -- bits [3:0] */
+#define UMAC_HDI_IN_CMD_OPCODE_POS 0
+#define UMAC_HDI_IN_CMD_OPCODE_SEED 0xF
+
+/* iwm_umac_hdi_in_hdr.cmd Non-WiFi API response -- bits [6:4] */
+#define UMAC_HDI_IN_CMD_NON_WIFI_RESP_POS 4
+#define UMAC_HDI_IN_CMD_NON_WIFI_RESP_SEED 0x7
+
+/* iwm_umac_hdi_in_hdr.cmd WiFi API source -- bits [5:4] */
+#define UMAC_HDI_IN_CMD_SOURCE_POS 4
+#define UMAC_HDI_IN_CMD_SOURCE_SEED 0x3
+
+/* iwm_umac_hdi_in_hdr.cmd WiFi API EOT -- bits [6:6] */
+#define UMAC_HDI_IN_CMD_EOT_POS 6
+#define UMAC_HDI_IN_CMD_EOT_SEED 0x1
+
+/* iwm_umac_hdi_in_hdr.cmd timestamp present -- bits [7:7] */
+#define UMAC_HDI_IN_CMD_TIME_STAMP_PRESENT_POS 7
+#define UMAC_HDI_IN_CMD_TIME_STAMP_PRESENT_SEED 0x1
+
+/* iwm_umac_hdi_in_hdr.cmd WiFi Non-last AMSDU -- bits [8:8] */
+#define UMAC_HDI_IN_CMD_NON_LAST_AMSDU_POS 8
+#define UMAC_HDI_IN_CMD_NON_LAST_AMSDU_SEED 0x1
+
+/* iwm_umac_hdi_in_hdr.cmd WiFi HW sequence number -- bits [31:9] */
+#define UMAC_HDI_IN_CMD_HW_SEQ_NUM_POS 9
+#define UMAC_HDI_IN_CMD_HW_SEQ_NUM_SEED 0x7FFFFF
+
+/* iwm_umac_hdi_in_hdr.cmd Non-WiFi HW sequence number -- bits [12:15] */
+#define UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM_POS 12
+#define UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM_SEED 0xF
+
+/* iwm_umac_hdi_in_hdr.cmd Non-WiFi HW signature -- bits [16:31] */
+#define UDMA_HDI_IN_CMD_NON_WIFI_HW_SIG_POS 16
+#define UDMA_HDI_IN_CMD_NON_WIFI_HW_SIG_SEED 0xFFFF
+
+/* Fixed Non-WiFi signature */
+#define UDMA_HDI_IN_CMD_NON_WIFI_HW_SIG 0xCBBC
+
+/* IN NTFY op-codes */
+#define UMAC_NOTIFY_OPCODE_ALIVE 0xA1
+#define UMAC_NOTIFY_OPCODE_INIT_COMPLETE 0xA2
+#define UMAC_NOTIFY_OPCODE_WIFI_CORE_STATUS 0xA3
+#define UMAC_NOTIFY_OPCODE_ERROR 0xA4
+#define UMAC_NOTIFY_OPCODE_DEBUG 0xA5
+#define UMAC_NOTIFY_OPCODE_WIFI_IF_WRAPPER 0xB0
+#define UMAC_NOTIFY_OPCODE_STATS 0xB1
+#define UMAC_NOTIFY_OPCODE_PAGE_DEALLOC 0xB3
+#define UMAC_NOTIFY_OPCODE_RX_TICKET 0xB4
+#define UMAC_NOTIFY_OPCODE_MAX (UMAC_NOTIFY_OPCODE_RX_TICKET -\
+ UMAC_NOTIFY_OPCODE_ALIVE + 1)
+#define UMAC_NOTIFY_OPCODE_FIRST (UMAC_NOTIFY_OPCODE_ALIVE)
+
+/* HDI OUT OP CODE */
+#define UMAC_HDI_OUT_OPCODE_PING 0x0
+#define UMAC_HDI_OUT_OPCODE_READ 0x1
+#define UMAC_HDI_OUT_OPCODE_WRITE 0x2
+#define UMAC_HDI_OUT_OPCODE_JUMP 0x3
+#define UMAC_HDI_OUT_OPCODE_REBOOT 0x4
+#define UMAC_HDI_OUT_OPCODE_WRITE_PERSISTENT 0x5
+#define UMAC_HDI_OUT_OPCODE_READ_PERSISTENT 0x6
+#define UMAC_HDI_OUT_OPCODE_READ_MODIFY_WRITE 0x7
+/* #define UMAC_HDI_OUT_OPCODE_RESERVED 0x8..0xA */
+#define UMAC_HDI_OUT_OPCODE_WRITE_AUX_REG 0xB
+#define UMAC_HDI_OUT_OPCODE_WIFI 0xF
+
+/* HDI IN OP CODE -- Non WiFi*/
+#define UMAC_HDI_IN_OPCODE_PING 0x0
+#define UMAC_HDI_IN_OPCODE_READ 0x1
+#define UMAC_HDI_IN_OPCODE_WRITE 0x2
+#define UMAC_HDI_IN_OPCODE_WRITE_PERSISTENT 0x5
+#define UMAC_HDI_IN_OPCODE_READ_PERSISTENT 0x6
+#define UMAC_HDI_IN_OPCODE_READ_MODIFY_WRITE 0x7
+#define UMAC_HDI_IN_OPCODE_EP_MGMT 0x8
+#define UMAC_HDI_IN_OPCODE_CREDIT_CHANGE 0x9
+#define UMAC_HDI_IN_OPCODE_CTRL_DATABASE 0xA
+#define UMAC_HDI_IN_OPCODE_WRITE_AUX_REG 0xB
+#define UMAC_HDI_IN_OPCODE_NONWIFI_MAX \
+ (UMAC_HDI_IN_OPCODE_WRITE_AUX_REG + 1)
+#define UMAC_HDI_IN_OPCODE_WIFI 0xF
+
+/* HDI IN SOURCE */
+#define UMAC_HDI_IN_SOURCE_FHRX 0x0
+#define UMAC_HDI_IN_SOURCE_UDMA 0x1
+#define UMAC_HDI_IN_SOURCE_FW 0x2
+#define UMAC_HDI_IN_SOURCE_RESERVED 0x3
+
+/* OUT CMD op-codes */
+#define UMAC_CMD_OPCODE_ECHO 0x01
+#define UMAC_CMD_OPCODE_HALT 0x02
+#define UMAC_CMD_OPCODE_RESET 0x03
+#define UMAC_CMD_OPCODE_BULK_EP_INACT_TIMEOUT 0x09
+#define UMAC_CMD_OPCODE_URB_CANCEL_ACK 0x0A
+#define UMAC_CMD_OPCODE_DCACHE_FLUSH 0x0B
+#define UMAC_CMD_OPCODE_EEPROM_PROXY 0x0C
+#define UMAC_CMD_OPCODE_TX_ECHO 0x0D
+#define UMAC_CMD_OPCODE_DBG_MON 0x0E
+#define UMAC_CMD_OPCODE_INTERNAL_TX 0x0F
+#define UMAC_CMD_OPCODE_SET_PARAM_FIX 0x10
+#define UMAC_CMD_OPCODE_SET_PARAM_VAR 0x11
+#define UMAC_CMD_OPCODE_GET_PARAM 0x12
+#define UMAC_CMD_OPCODE_DBG_EVENT_WRAPPER 0x13
+#define UMAC_CMD_OPCODE_TARGET 0x14
+#define UMAC_CMD_OPCODE_STATISTIC_REQUEST 0x15
+#define UMAC_CMD_OPCODE_GET_CHAN_INFO_LIST 0x16
+#define UMAC_CMD_OPCODE_SET_PARAM_LIST 0x17
+#define UMAC_CMD_OPCODE_GET_PARAM_LIST 0x18
+#define UMAC_CMD_OPCODE_BASE_WRAPPER 0xFA
+#define UMAC_CMD_OPCODE_LMAC_WRAPPER 0xFB
+#define UMAC_CMD_OPCODE_HW_TEST_WRAPPER 0xFC
+#define UMAC_CMD_OPCODE_WIFI_IF_WRAPPER 0xFD
+#define UMAC_CMD_OPCODE_WIFI_WRAPPER 0xFE
+#define UMAC_CMD_OPCODE_WIFI_PASS_THROUGH 0xFF
+
+/* UMAC WiFi interface op-codes */
+#define UMAC_WIFI_IF_CMD_SET_PROFILE 0x11
+#define UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE 0x12
+#define UMAC_WIFI_IF_CMD_SET_EXCLUDE_LIST 0x13
+#define UMAC_WIFI_IF_CMD_SCAN_REQUEST 0x14
+#define UMAC_WIFI_IF_CMD_SCAN_CONFIG 0x15
+#define UMAC_WIFI_IF_CMD_ADD_WEP40_KEY 0x16
+#define UMAC_WIFI_IF_CMD_ADD_WEP104_KEY 0x17
+#define UMAC_WIFI_IF_CMD_ADD_TKIP_KEY 0x18
+#define UMAC_WIFI_IF_CMD_ADD_CCMP_KEY 0x19
+#define UMAC_WIFI_IF_CMD_REMOVE_KEY 0x1A
+#define UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID 0x1B
+#define UMAC_WIFI_IF_CMD_SET_HOST_EXTENDED_IE 0x1C
+#define UMAC_WIFI_IF_CMD_GET_SUPPORTED_CHANNELS 0x1E
+#define UMAC_WIFI_IF_CMD_TX_PWR_TRIGGER 0x20
+
+/* UMAC WiFi interface ports */
+#define UMAC_WIFI_IF_FLG_PORT_DEF 0x00
+#define UMAC_WIFI_IF_FLG_PORT_PAN 0x01
+#define UMAC_WIFI_IF_FLG_PORT_PAN_INVALID WIFI_IF_FLG_PORT_DEF
+
+/* UMAC WiFi interface actions */
+#define UMAC_WIFI_IF_FLG_ACT_GET 0x10
+#define UMAC_WIFI_IF_FLG_ACT_SET 0x20
+
+/* iwm_umac_fw_cmd_hdr.meta_data byte count -- bits [11:0] */
+#define UMAC_FW_CMD_BYTE_COUNT_POS 0
+#define UMAC_FW_CMD_BYTE_COUNT_SEED 0xFFF
+
+/* iwm_umac_fw_cmd_hdr.meta_data status -- bits [15:12] */
+#define UMAC_FW_CMD_STATUS_POS 12
+#define UMAC_FW_CMD_STATUS_SEED 0xF
+
+/* iwm_umac_fw_cmd_hdr.meta_data full TX command by Driver -- bits [16:16] */
+#define UMAC_FW_CMD_TX_DRV_FULL_CMD_POS 16
+#define UMAC_FW_CMD_TX_DRV_FULL_CMD_SEED 0x1
+
+/* iwm_umac_fw_cmd_hdr.meta_data TX command by FW -- bits [17:17] */
+#define UMAC_FW_CMD_TX_FW_CMD_POS 17
+#define UMAC_FW_CMD_TX_FW_CMD_SEED 0x1
+
+/* iwm_umac_fw_cmd_hdr.meta_data TX plaintext mode -- bits [18:18] */
+#define UMAC_FW_CMD_TX_PLAINTEXT_POS 18
+#define UMAC_FW_CMD_TX_PLAINTEXT_SEED 0x1
+
+/* iwm_umac_fw_cmd_hdr.meta_data STA color -- bits [22:20] */
+#define UMAC_FW_CMD_TX_STA_COLOR_POS 20
+#define UMAC_FW_CMD_TX_STA_COLOR_SEED 0x7
+
+/* iwm_umac_fw_cmd_hdr.meta_data TX life time (TU) -- bits [31:24] */
+#define UMAC_FW_CMD_TX_LIFETIME_TU_POS 24
+#define UMAC_FW_CMD_TX_LIFETIME_TU_SEED 0xFF
+
+/* iwm_dev_cmd_hdr.flags Response required -- bits [5:5] */
+#define UMAC_DEV_CMD_FLAGS_RESP_REQ_POS 5
+#define UMAC_DEV_CMD_FLAGS_RESP_REQ_SEED 0x1
+
+/* iwm_dev_cmd_hdr.flags Aborted command -- bits [6:6] */
+#define UMAC_DEV_CMD_FLAGS_ABORT_POS 6
+#define UMAC_DEV_CMD_FLAGS_ABORT_SEED 0x1
+
+/* iwm_dev_cmd_hdr.flags Internal command -- bits [7:7] */
+#define DEV_CMD_FLAGS_FLD_INTERNAL_POS 7
+#define DEV_CMD_FLAGS_FLD_INTERNAL_SEED 0x1
+
+/* Rx */
+/* Rx actions */
+#define IWM_RX_TICKET_DROP 0x0
+#define IWM_RX_TICKET_RELEASE 0x1
+#define IWM_RX_TICKET_SNIFFER 0x2
+#define IWM_RX_TICKET_ENQUEUE 0x3
+
+/* Rx flags */
+#define IWM_RX_TICKET_PAD_SIZE_MSK 0x2
+#define IWM_RX_TICKET_SPECIAL_SNAP_MSK 0x4
+#define IWM_RX_TICKET_AMSDU_MSK 0x8
+#define IWM_RX_TICKET_DROP_REASON_POS 4
+#define IWM_RX_TICKET_DROP_REASON_MSK (0x1F << RX_TICKET_FLAGS_DROP_REASON_POS)
+
+#define IWM_RX_DROP_NO_DROP 0x0
+#define IWM_RX_DROP_BAD_CRC 0x1
+/* L2P no address match */
+#define IWM_RX_DROP_LMAC_ADDR_FILTER 0x2
+/* Multicast address not in list */
+#define IWM_RX_DROP_MCAST_ADDR_FILTER 0x3
+/* Control frames are not sent to the driver */
+#define IWM_RX_DROP_CTL_FRAME 0x4
+/* Our frame is back */
+#define IWM_RX_DROP_OUR_TX 0x5
+/* Association class filtering */
+#define IWM_RX_DROP_CLASS_FILTER 0x6
+/* Duplicated frame */
+#define IWM_RX_DROP_DUPLICATE_FILTER 0x7
+/* Decryption error */
+#define IWM_RX_DROP_SEC_ERR 0x8
+/* Unencrypted frame while encryption is on */
+#define IWM_RX_DROP_SEC_NO_ENCRYPTION 0x9
+/* Replay check failure */
+#define IWM_RX_DROP_SEC_REPLAY_ERR 0xa
+/* uCode and FW key color mismatch, check before replay */
+#define IWM_RX_DROP_SEC_KEY_COLOR_MISMATCH 0xb
+#define IWM_RX_DROP_SEC_TKIP_COUNTER_MEASURE 0xc
+/* No fragmentations Db is found */
+#define IWM_RX_DROP_FRAG_NO_RESOURCE 0xd
+/* Fragmention Db has seqCtl mismatch Vs. non-1st frag */
+#define IWM_RX_DROP_FRAG_ERR 0xe
+#define IWM_RX_DROP_FRAG_LOST 0xf
+#define IWM_RX_DROP_FRAG_COMPLETE 0x10
+/* Should be handled by UMAC */
+#define IWM_RX_DROP_MANAGEMENT 0x11
+/* STA not found by UMAC */
+#define IWM_RX_DROP_NO_STATION 0x12
+/* NULL or QoS NULL */
+#define IWM_RX_DROP_NULL_DATA 0x13
+#define IWM_RX_DROP_BA_REORDER_OLD_SEQCTL 0x14
+#define IWM_RX_DROP_BA_REORDER_DUPLICATE 0x15
+
+struct iwm_rx_ticket {
+ __le16 action;
+ __le16 id;
+ __le16 flags;
+ u8 payload_offset; /* includes: MAC header, pad, IV */
+ u8 tail_len; /* includes: MIC, ICV, CRC (w/o STATUS) */
+} __attribute__ ((packed));
+
+struct iwm_rx_mpdu_hdr {
+ __le16 len;
+ __le16 reserved;
+} __attribute__ ((packed));
+
+/* UMAC SW WIFI API */
+
+struct iwm_dev_cmd_hdr {
+ u8 cmd;
+ u8 flags;
+ __le16 seq_num;
+} __attribute__ ((packed));
+
+struct iwm_umac_fw_cmd_hdr {
+ __le32 meta_data;
+ struct iwm_dev_cmd_hdr cmd;
+} __attribute__ ((packed));
+
+struct iwm_umac_wifi_out_hdr {
+ struct iwm_udma_out_wifi_hdr hw_hdr;
+ struct iwm_umac_fw_cmd_hdr sw_hdr;
+} __attribute__ ((packed));
+
+struct iwm_umac_nonwifi_out_hdr {
+ struct iwm_udma_out_nonwifi_hdr hw_hdr;
+} __attribute__ ((packed));
+
+struct iwm_umac_wifi_in_hdr {
+ struct iwm_udma_in_hdr hw_hdr;
+ struct iwm_umac_fw_cmd_hdr sw_hdr;
+} __attribute__ ((packed));
+
+struct iwm_umac_nonwifi_in_hdr {
+ struct iwm_udma_in_hdr hw_hdr;
+ __le32 time_stamp;
+} __attribute__ ((packed));
+
+#define IWM_UMAC_PAGE_SIZE 0x200
+
+/* Notify structures */
+struct iwm_fw_version {
+ u8 minor;
+ u8 major;
+ __le16 id;
+};
+
+struct iwm_fw_build {
+ u8 type;
+ u8 subtype;
+ u8 platform;
+ u8 opt;
+};
+
+struct iwm_fw_alive_hdr {
+ struct iwm_fw_version ver;
+ struct iwm_fw_build build;
+ __le32 os_build;
+ __le32 log_hdr_addr;
+ __le32 log_buf_addr;
+ __le32 sys_timer_addr;
+};
+
+#define WAIT_NOTIF_TIMEOUT (2 * HZ)
+#define SCAN_COMPLETE_TIMEOUT (3 * HZ)
+
+#define UMAC_NTFY_ALIVE_STATUS_ERR 0xDEAD
+#define UMAC_NTFY_ALIVE_STATUS_OK 0xCAFE
+
+#define UMAC_NTFY_INIT_COMPLETE_STATUS_ERR 0xDEAD
+#define UMAC_NTFY_INIT_COMPLETE_STATUS_OK 0xCAFE
+
+#define UMAC_NTFY_WIFI_CORE_STATUS_LINK_EN 0x40
+#define UMAC_NTFY_WIFI_CORE_STATUS_MLME_EN 0x80
+
+#define IWM_MACS_OUT_GROUPS 6
+#define IWM_MACS_OUT_SGROUPS 1
+
+
+#define WIFI_IF_NTFY_ASSOC_START 0x80
+#define WIFI_IF_NTFY_ASSOC_COMPLETE 0x81
+#define WIFI_IF_NTFY_PROFILE_INVALIDATE_COMPLETE 0x82
+#define WIFI_IF_NTFY_CONNECTION_TERMINATED 0x83
+#define WIFI_IF_NTFY_SCAN_COMPLETE 0x84
+#define WIFI_IF_NTFY_STA_TABLE_CHANGE 0x85
+#define WIFI_IF_NTFY_EXTENDED_IE_REQUIRED 0x86
+#define WIFI_IF_NTFY_RADIO_PREEMPTION 0x87
+#define WIFI_IF_NTFY_BSS_TRK_TABLE_CHANGED 0x88
+#define WIFI_IF_NTFY_BSS_TRK_ENTRIES_REMOVED 0x89
+#define WIFI_IF_NTFY_LINK_QUALITY_STATISTICS 0x8A
+#define WIFI_IF_NTFY_MGMT_FRAME 0x8B
+
+/* DEBUG INDICATIONS */
+#define WIFI_DBG_IF_NTFY_SCAN_SUPER_JOB_START 0xE0
+#define WIFI_DBG_IF_NTFY_SCAN_SUPER_JOB_COMPLETE 0xE1
+#define WIFI_DBG_IF_NTFY_SCAN_CHANNEL_START 0xE2
+#define WIFI_DBG_IF_NTFY_SCAN_CHANNEL_RESULT 0xE3
+#define WIFI_DBG_IF_NTFY_SCAN_MINI_JOB_START 0xE4
+#define WIFI_DBG_IF_NTFY_SCAN_MINI_JOB_COMPLETE 0xE5
+#define WIFI_DBG_IF_NTFY_CNCT_ATC_START 0xE6
+#define WIFI_DBG_IF_NTFY_COEX_NOTIFICATION 0xE7
+#define WIFI_DBG_IF_NTFY_COEX_HANDLE_ENVELOP 0xE8
+#define WIFI_DBG_IF_NTFY_COEX_HANDLE_RELEASE_ENVELOP 0xE9
+
+/* Notification structures */
+struct iwm_umac_notif_wifi_if {
+ struct iwm_umac_wifi_in_hdr hdr;
+ u8 status;
+ u8 flags;
+ __le16 buf_size;
+} __attribute__ ((packed));
+
+#define UMAC_ROAM_REASON_FIRST_SELECTION 0x1
+#define UMAC_ROAM_REASON_AP_DEAUTH 0x2
+#define UMAC_ROAM_REASON_AP_CONNECT_LOST 0x3
+#define UMAC_ROAM_REASON_RSSI 0x4
+#define UMAC_ROAM_REASON_AP_ASSISTED_ROAM 0x5
+#define UMAC_ROAM_REASON_IBSS_COALESCING 0x6
+
+struct iwm_umac_notif_assoc_start {
+ struct iwm_umac_notif_wifi_if mlme_hdr;
+ __le32 roam_reason;
+ u8 bssid[ETH_ALEN];
+ u8 reserved[2];
+} __attribute__ ((packed));
+
+#define UMAC_ASSOC_COMPLETE_SUCCESS 0x0
+#define UMAC_ASSOC_COMPLETE_FAILURE 0x1
+
+struct iwm_umac_notif_assoc_complete {
+ struct iwm_umac_notif_wifi_if mlme_hdr;
+ __le32 status;
+ u8 bssid[ETH_ALEN];
+ u8 band;
+ u8 channel;
+} __attribute__ ((packed));
+
+#define UMAC_PROFILE_INVALID_ASSOC_TIMEOUT 0x0
+#define UMAC_PROFILE_INVALID_ROAM_TIMEOUT 0x1
+#define UMAC_PROFILE_INVALID_REQUEST 0x2
+#define UMAC_PROFILE_INVALID_RF_PREEMPTED 0x3
+
+struct iwm_umac_notif_profile_invalidate {
+ struct iwm_umac_notif_wifi_if mlme_hdr;
+ __le32 reason;
+} __attribute__ ((packed));
+
+#define UMAC_SCAN_RESULT_SUCCESS 0x0
+#define UMAC_SCAN_RESULT_ABORTED 0x1
+#define UMAC_SCAN_RESULT_REJECTED 0x2
+#define UMAC_SCAN_RESULT_FAILED 0x3
+
+struct iwm_umac_notif_scan_complete {
+ struct iwm_umac_notif_wifi_if mlme_hdr;
+ __le32 type;
+ __le32 result;
+ u8 seq_num;
+} __attribute__ ((packed));
+
+#define UMAC_OPCODE_ADD_MODIFY 0x0
+#define UMAC_OPCODE_REMOVE 0x1
+#define UMAC_OPCODE_CLEAR_ALL 0x2
+
+#define UMAC_STA_FLAG_QOS 0x1
+
+struct iwm_umac_notif_sta_info {
+ struct iwm_umac_notif_wifi_if mlme_hdr;
+ __le32 opcode;
+ u8 mac_addr[ETH_ALEN];
+ u8 sta_id; /* bits 0-3: station ID, bits 4-7: station color */
+ u8 flags;
+} __attribute__ ((packed));
+
+#define UMAC_BAND_2GHZ 0
+#define UMAC_BAND_5GHZ 1
+
+#define UMAC_CHANNEL_WIDTH_20MHZ 0
+#define UMAC_CHANNEL_WIDTH_40MHZ 1
+
+struct iwm_umac_notif_bss_info {
+ struct iwm_umac_notif_wifi_if mlme_hdr;
+ __le32 type;
+ __le32 timestamp;
+ __le16 table_idx;
+ __le16 frame_len;
+ u8 band;
+ u8 channel;
+ s8 rssi;
+ u8 reserved;
+ u8 frame_buf[1];
+} __attribute__ ((packed));
+
+#define IWM_BSS_REMOVE_INDEX_MSK 0x0fff
+#define IWM_BSS_REMOVE_FLAGS_MSK 0xfc00
+
+#define IWM_BSS_REMOVE_FLG_AGE 0x1000
+#define IWM_BSS_REMOVE_FLG_TIMEOUT 0x2000
+#define IWM_BSS_REMOVE_FLG_TABLE_FULL 0x4000
+
+struct iwm_umac_notif_bss_removed {
+ struct iwm_umac_notif_wifi_if mlme_hdr;
+ __le32 count;
+ __le16 entries[0];
+} __attribute__ ((packed));
+
+struct iwm_umac_notif_mgt_frame {
+ struct iwm_umac_notif_wifi_if mlme_hdr;
+ __le16 len;
+ u8 frame[1];
+} __attribute__ ((packed));
+
+struct iwm_umac_notif_alive {
+ struct iwm_umac_wifi_in_hdr hdr;
+ __le16 status;
+ __le16 reserved1;
+ struct iwm_fw_alive_hdr alive_data;
+ __le16 reserved2;
+ __le16 page_grp_count;
+ __le32 page_grp_state[IWM_MACS_OUT_GROUPS];
+} __attribute__ ((packed));
+
+struct iwm_umac_notif_init_complete {
+ __le16 status;
+ __le16 reserved;
+} __attribute__ ((packed));
+
+/* error categories */
+enum {
+ UMAC_SYS_ERR_CAT_NONE = 0,
+ UMAC_SYS_ERR_CAT_BOOT,
+ UMAC_SYS_ERR_CAT_UMAC,
+ UMAC_SYS_ERR_CAT_UAXM,
+ UMAC_SYS_ERR_CAT_LMAC,
+ UMAC_SYS_ERR_CAT_MAX
+};
+
+struct iwm_fw_error_hdr {
+ __le32 category;
+ __le32 status;
+ __le32 pc;
+ __le32 blink1;
+ __le32 blink2;
+ __le32 ilink1;
+ __le32 ilink2;
+ __le32 data1;
+ __le32 data2;
+ __le32 line_num;
+ __le32 umac_status;
+ __le32 lmac_status;
+ __le32 sdio_status;
+} __attribute__ ((packed));
+
+struct iwm_umac_notif_error {
+ struct iwm_umac_wifi_in_hdr hdr;
+ struct iwm_fw_error_hdr err;
+} __attribute__ ((packed));
+
+#define UMAC_DEALLOC_NTFY_CHANGES_CNT_POS 0
+#define UMAC_DEALLOC_NTFY_CHANGES_CNT_SEED 0xff
+#define UMAC_DEALLOC_NTFY_CHANGES_MSK_POS 8
+#define UMAC_DEALLOC_NTFY_CHANGES_MSK_SEED 0xffffff
+#define UMAC_DEALLOC_NTFY_PAGE_CNT_POS 0
+#define UMAC_DEALLOC_NTFY_PAGE_CNT_SEED 0xffffff
+#define UMAC_DEALLOC_NTFY_GROUP_NUM_POS 24
+#define UMAC_DEALLOC_NTFY_GROUP_NUM_SEED 0xf
+
+struct iwm_umac_notif_page_dealloc {
+ struct iwm_umac_wifi_in_hdr hdr;
+ __le32 changes;
+ __le32 grp_info[IWM_MACS_OUT_GROUPS];
+} __attribute__ ((packed));
+
+struct iwm_umac_notif_wifi_status {
+ struct iwm_umac_wifi_in_hdr hdr;
+ __le16 status;
+ __le16 reserved;
+} __attribute__ ((packed));
+
+struct iwm_umac_notif_rx_ticket {
+ struct iwm_umac_wifi_in_hdr hdr;
+ u8 num_tickets;
+ u8 reserved[3];
+ struct iwm_rx_ticket tickets[1];
+} __attribute__ ((packed));
+
+/* Tx/Rx rates window (number of max of last update window per second) */
+#define UMAC_NTF_RATE_SAMPLE_NR 4
+
+#define IWM_UMAC_MGMT_TID 8
+#define IWM_UMAC_TID_NR 8
+
+struct iwm_umac_notif_stats {
+ struct iwm_umac_wifi_in_hdr hdr;
+ __le32 flags;
+ __le32 timestamp;
+ __le16 tid_load[IWM_UMAC_TID_NR + 2]; /* 1 non-QoS + 1 dword align */
+ __le16 tx_rate[UMAC_NTF_RATE_SAMPLE_NR];
+ __le16 rx_rate[UMAC_NTF_RATE_SAMPLE_NR];
+ s32 rssi_dbm;
+ s32 noise_dbm;
+ __le32 supp_rates;
+ __le32 missed_beacons;
+ __le32 rx_beacons;
+ __le32 rx_dir_pkts;
+ __le32 rx_nondir_pkts;
+ __le32 rx_multicast;
+ __le32 rx_errors;
+ __le32 rx_drop_other_bssid;
+ __le32 rx_drop_decode;
+ __le32 rx_drop_reassembly;
+ __le32 rx_drop_bad_len;
+ __le32 rx_drop_overflow;
+ __le32 rx_drop_crc;
+ __le32 rx_drop_missed;
+ __le32 tx_dir_pkts;
+ __le32 tx_nondir_pkts;
+ __le32 tx_failure;
+ __le32 tx_errors;
+ __le32 tx_drop_max_retry;
+ __le32 tx_err_abort;
+ __le32 tx_err_carrier;
+ __le32 rx_bytes;
+ __le32 tx_bytes;
+ __le32 tx_power;
+ __le32 tx_max_power;
+ __le32 roam_threshold;
+ __le32 ap_assoc_nr;
+ __le32 scan_full;
+ __le32 scan_abort;
+ __le32 ap_nr;
+ __le32 roam_nr;
+ __le32 roam_missed_beacons;
+ __le32 roam_rssi;
+ __le32 roam_unassoc;
+ __le32 roam_deauth;
+ __le32 roam_ap_loadblance;
+} __attribute__ ((packed));
+
+/* WiFi interface wrapper header */
+struct iwm_umac_wifi_if {
+ u8 oid;
+ u8 flags;
+ __le16 buf_size;
+} __attribute__ ((packed));
+
+#define IWM_SEQ_NUM_HOST_MSK 0x0000
+#define IWM_SEQ_NUM_UMAC_MSK 0x4000
+#define IWM_SEQ_NUM_LMAC_MSK 0x8000
+#define IWM_SEQ_NUM_MSK 0xC000
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/wext.c b/drivers/net/wireless/iwmc3200wifi/wext.c
new file mode 100644
index 00000000000..584c94d0f39
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/wext.c
@@ -0,0 +1,723 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <net/cfg80211.h>
+#include <net/iw_handler.h>
+
+#include "iwm.h"
+#include "umac.h"
+#include "commands.h"
+#include "debug.h"
+
+static struct iw_statistics *iwm_get_wireless_stats(struct net_device *dev)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(dev);
+ struct iw_statistics *wstats = &iwm->wstats;
+
+ if (!test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
+ memset(wstats, 0, sizeof(struct iw_statistics));
+ wstats->qual.updated = IW_QUAL_ALL_INVALID;
+ }
+
+ return wstats;
+}
+
+static int iwm_wext_siwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(dev);
+
+ if (freq->flags == IW_FREQ_AUTO)
+ return 0;
+
+ /* frequency/channel can only be set in IBSS mode */
+ if (iwm->conf.mode != UMAC_MODE_IBSS)
+ return -EOPNOTSUPP;
+
+ return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
+}
+
+static int iwm_wext_giwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(dev);
+
+ if (iwm->conf.mode == UMAC_MODE_IBSS)
+ return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
+
+ freq->e = 0;
+ freq->m = iwm->channel;
+
+ return 0;
+}
+
+static int iwm_wext_siwap(struct net_device *dev, struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(dev);
+
+ if (iwm->conf.mode == UMAC_MODE_IBSS)
+ return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
+
+ if (!test_bit(IWM_STATUS_READY, &iwm->status))
+ return -EIO;
+
+ if (is_zero_ether_addr(ap_addr->sa_data) ||
+ is_broadcast_ether_addr(ap_addr->sa_data)) {
+ IWM_DBG_WEXT(iwm, DBG, "clear mandatory bssid %pM\n",
+ iwm->umac_profile->bssid[0]);
+ memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN);
+ iwm->umac_profile->bss_num = 0;
+ } else {
+ IWM_DBG_WEXT(iwm, DBG, "add mandatory bssid %pM\n",
+ ap_addr->sa_data);
+ memcpy(&iwm->umac_profile->bssid[0], ap_addr->sa_data,
+ ETH_ALEN);
+ iwm->umac_profile->bss_num = 1;
+ }
+
+ if (iwm->umac_profile_active) {
+ if (!memcmp(&iwm->umac_profile->bssid[0], iwm->bssid, ETH_ALEN))
+ return 0;
+
+ iwm_invalidate_mlme_profile(iwm);
+ }
+
+ if (iwm->umac_profile->ssid.ssid_len)
+ return iwm_send_mlme_profile(iwm);
+
+ return 0;
+}
+
+static int iwm_wext_giwap(struct net_device *dev, struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(dev);
+
+ switch (iwm->conf.mode) {
+ case UMAC_MODE_IBSS:
+ return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
+ case UMAC_MODE_BSS:
+ if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
+ ap_addr->sa_family = ARPHRD_ETHER;
+ memcpy(&ap_addr->sa_data, iwm->bssid, ETH_ALEN);
+ } else
+ memset(&ap_addr->sa_data, 0, ETH_ALEN);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int iwm_wext_siwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(dev);
+ size_t len = data->length;
+ int ret;
+
+ if (iwm->conf.mode == UMAC_MODE_IBSS)
+ return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
+
+ if (!test_bit(IWM_STATUS_READY, &iwm->status))
+ return -EIO;
+
+ if (len > 0 && ssid[len - 1] == '\0')
+ len--;
+
+ if (iwm->umac_profile_active) {
+ if (iwm->umac_profile->ssid.ssid_len == len &&
+ !memcmp(iwm->umac_profile->ssid.ssid, ssid, len))
+ return 0;
+
+ ret = iwm_invalidate_mlme_profile(iwm);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Couldn't invalidate profile\n");
+ return ret;
+ }
+ }
+
+ iwm->umac_profile->ssid.ssid_len = len;
+ memcpy(iwm->umac_profile->ssid.ssid, ssid, len);
+
+ return iwm_send_mlme_profile(iwm);
+}
+
+static int iwm_wext_giwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(dev);
+
+ if (iwm->conf.mode == UMAC_MODE_IBSS)
+ return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
+
+ if (!test_bit(IWM_STATUS_READY, &iwm->status))
+ return -EIO;
+
+ data->length = iwm->umac_profile->ssid.ssid_len;
+ if (data->length) {
+ memcpy(ssid, iwm->umac_profile->ssid.ssid, data->length);
+ data->flags = 1;
+ } else
+ data->flags = 0;
+
+ return 0;
+}
+
+static struct iwm_key *
+iwm_key_init(struct iwm_priv *iwm, u8 key_idx, bool in_use,
+ struct iw_encode_ext *ext, u8 alg)
+{
+ struct iwm_key *key = &iwm->keys[key_idx];
+
+ memset(key, 0, sizeof(struct iwm_key));
+ memcpy(key->hdr.mac, ext->addr.sa_data, ETH_ALEN);
+ key->hdr.key_idx = key_idx;
+ if (is_broadcast_ether_addr(ext->addr.sa_data))
+ key->hdr.multicast = 1;
+
+ key->in_use = in_use;
+ key->flags = ext->ext_flags;
+ key->alg = alg;
+ key->key_len = ext->key_len;
+ memcpy(key->key, ext->key, ext->key_len);
+
+ return key;
+}
+
+static int iwm_wext_giwrate(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rate, char *extra)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(dev);
+
+ rate->value = iwm->rate * 1000000;
+
+ return 0;
+}
+
+static int iwm_wext_siwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *key_buf)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(dev);
+ struct iwm_key *uninitialized_var(key);
+ int idx, i, uninitialized_var(alg), remove = 0, ret;
+
+ IWM_DBG_WEXT(iwm, DBG, "key len: %d\n", erq->length);
+ IWM_DBG_WEXT(iwm, DBG, "flags: 0x%x\n", erq->flags);
+
+ if (!iwm->umac_profile) {
+ IWM_ERR(iwm, "UMAC profile not allocated yet\n");
+ return -ENODEV;
+ }
+
+ if (erq->length == WLAN_KEY_LEN_WEP40) {
+ alg = UMAC_CIPHER_TYPE_WEP_40;
+ iwm->umac_profile->sec.ucast_cipher = UMAC_CIPHER_TYPE_WEP_40;
+ iwm->umac_profile->sec.mcast_cipher = UMAC_CIPHER_TYPE_WEP_40;
+ } else if (erq->length == WLAN_KEY_LEN_WEP104) {
+ alg = UMAC_CIPHER_TYPE_WEP_104;
+ iwm->umac_profile->sec.ucast_cipher = UMAC_CIPHER_TYPE_WEP_104;
+ iwm->umac_profile->sec.mcast_cipher = UMAC_CIPHER_TYPE_WEP_104;
+ }
+
+ if (erq->flags & IW_ENCODE_RESTRICTED)
+ iwm->umac_profile->sec.auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
+ else
+ iwm->umac_profile->sec.auth_type = UMAC_AUTH_TYPE_OPEN;
+
+ idx = erq->flags & IW_ENCODE_INDEX;
+ if (idx == 0) {
+ if (iwm->default_key)
+ for (i = 0; i < IWM_NUM_KEYS; i++) {
+ if (iwm->default_key == &iwm->keys[i]) {
+ idx = i;
+ break;
+ }
+ }
+ else
+ iwm->default_key = &iwm->keys[idx];
+ } else if (idx < 1 || idx > 4) {
+ return -EINVAL;
+ } else
+ idx--;
+
+ if (erq->flags & IW_ENCODE_DISABLED)
+ remove = 1;
+ else if (erq->length == 0) {
+ if (!iwm->keys[idx].in_use)
+ return -EINVAL;
+ iwm->default_key = &iwm->keys[idx];
+ }
+
+ if (erq->length) {
+ key = &iwm->keys[idx];
+ memset(key, 0, sizeof(struct iwm_key));
+ memset(key->hdr.mac, 0xff, ETH_ALEN);
+ key->hdr.key_idx = idx;
+ key->hdr.multicast = 1;
+ key->in_use = !remove;
+ key->alg = alg;
+ key->key_len = erq->length;
+ memcpy(key->key, key_buf, erq->length);
+
+ IWM_DBG_WEXT(iwm, DBG, "Setting key %d, default: %d\n",
+ idx, !!iwm->default_key);
+ }
+
+ if (remove) {
+ if ((erq->flags & IW_ENCODE_NOKEY) || (erq->length == 0)) {
+ int j;
+ for (j = 0; j < IWM_NUM_KEYS; j++)
+ if (iwm->keys[j].in_use) {
+ struct iwm_key *k = &iwm->keys[j];
+
+ k->in_use = 0;
+ ret = iwm_set_key(iwm, remove, 0, k);
+ if (ret < 0)
+ return ret;
+ }
+
+ iwm->umac_profile->sec.ucast_cipher =
+ UMAC_CIPHER_TYPE_NONE;
+ iwm->umac_profile->sec.mcast_cipher =
+ UMAC_CIPHER_TYPE_NONE;
+ iwm->umac_profile->sec.auth_type =
+ UMAC_AUTH_TYPE_OPEN;
+
+ return 0;
+ } else {
+ key->in_use = 0;
+ return iwm_set_key(iwm, remove, 0, key);
+ }
+ }
+
+ /*
+ * If we havent set a profile yet, we cant set keys.
+ * Keys will be pushed after we're associated.
+ */
+ if (!iwm->umac_profile_active)
+ return 0;
+
+ /*
+ * If there is a current active profile, but no
+ * default key, it's not worth trying to associate again.
+ */
+ if (!iwm->default_key)
+ return 0;
+
+ /*
+ * Here we have an active profile, but a key setting changed.
+ * We thus have to invalidate the current profile, and push the
+ * new one. Keys will be pushed when association takes place.
+ */
+ ret = iwm_invalidate_mlme_profile(iwm);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Couldn't invalidate profile\n");
+ return ret;
+ }
+
+ return iwm_send_mlme_profile(iwm);
+}
+
+static int iwm_wext_giwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *key)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(dev);
+ int idx, i;
+
+ idx = erq->flags & IW_ENCODE_INDEX;
+ if (idx < 1 || idx > 4) {
+ idx = -1;
+ if (!iwm->default_key) {
+ erq->length = 0;
+ erq->flags |= IW_ENCODE_NOKEY;
+ return 0;
+ } else
+ for (i = 0; i < IWM_NUM_KEYS; i++) {
+ if (iwm->default_key == &iwm->keys[i]) {
+ idx = i;
+ break;
+ }
+ }
+ if (idx < 0)
+ return -EINVAL;
+ } else
+ idx--;
+
+ erq->flags = idx + 1;
+
+ if (!iwm->keys[idx].in_use) {
+ erq->length = 0;
+ erq->flags |= IW_ENCODE_DISABLED;
+ return 0;
+ }
+
+ memcpy(key, iwm->keys[idx].key,
+ min_t(int, erq->length, iwm->keys[idx].key_len));
+ erq->length = iwm->keys[idx].key_len;
+ erq->flags |= IW_ENCODE_ENABLED;
+
+ if (iwm->umac_profile->mode == UMAC_MODE_BSS) {
+ switch (iwm->umac_profile->sec.auth_type) {
+ case UMAC_AUTH_TYPE_OPEN:
+ erq->flags |= IW_ENCODE_OPEN;
+ break;
+ default:
+ erq->flags |= IW_ENCODE_RESTRICTED;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int iwm_set_wpa_version(struct iwm_priv *iwm, u8 wpa_version)
+{
+ if (wpa_version & IW_AUTH_WPA_VERSION_WPA2)
+ iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
+ else if (wpa_version & IW_AUTH_WPA_VERSION_WPA)
+ iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK;
+ else
+ iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
+
+ return 0;
+}
+
+static int iwm_wext_siwpower(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *wrq, char *extra)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(dev);
+ u32 power_index;
+
+ if (wrq->disabled) {
+ power_index = IWM_POWER_INDEX_MIN;
+ goto set;
+ } else
+ power_index = IWM_POWER_INDEX_DEFAULT;
+
+ switch (wrq->flags & IW_POWER_MODE) {
+ case IW_POWER_ON:
+ case IW_POWER_MODE:
+ case IW_POWER_ALL_R:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ set:
+ if (power_index == iwm->conf.power_index)
+ return 0;
+
+ iwm->conf.power_index = power_index;
+
+ return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+ CFG_POWER_INDEX, iwm->conf.power_index);
+}
+
+static int iwm_wext_giwpower(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(dev);
+
+ wrqu->power.disabled = (iwm->conf.power_index == IWM_POWER_INDEX_MIN);
+
+ return 0;
+}
+
+static int iwm_set_key_mgt(struct iwm_priv *iwm, u8 key_mgt)
+{
+ u8 *auth_type = &iwm->umac_profile->sec.auth_type;
+
+ if (key_mgt == IW_AUTH_KEY_MGMT_802_1X)
+ *auth_type = UMAC_AUTH_TYPE_8021X;
+ else if (key_mgt == IW_AUTH_KEY_MGMT_PSK) {
+ if (iwm->umac_profile->sec.flags &
+ (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK))
+ *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
+ else
+ *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
+ } else {
+ IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int iwm_set_cipher(struct iwm_priv *iwm, u8 cipher, u8 ucast)
+{
+ u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
+ &iwm->umac_profile->sec.mcast_cipher;
+
+ switch (cipher) {
+ case IW_AUTH_CIPHER_NONE:
+ *profile_cipher = UMAC_CIPHER_TYPE_NONE;
+ break;
+ case IW_AUTH_CIPHER_WEP40:
+ *profile_cipher = UMAC_CIPHER_TYPE_WEP_40;
+ break;
+ case IW_AUTH_CIPHER_TKIP:
+ *profile_cipher = UMAC_CIPHER_TYPE_TKIP;
+ break;
+ case IW_AUTH_CIPHER_CCMP:
+ *profile_cipher = UMAC_CIPHER_TYPE_CCMP;
+ break;
+ case IW_AUTH_CIPHER_WEP104:
+ *profile_cipher = UMAC_CIPHER_TYPE_WEP_104;
+ break;
+ default:
+ IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher);
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static int iwm_set_auth_alg(struct iwm_priv *iwm, u8 auth_alg)
+{
+ u8 *auth_type = &iwm->umac_profile->sec.auth_type;
+
+ switch (auth_alg) {
+ case IW_AUTH_ALG_OPEN_SYSTEM:
+ *auth_type = UMAC_AUTH_TYPE_OPEN;
+ break;
+ case IW_AUTH_ALG_SHARED_KEY:
+ if (iwm->umac_profile->sec.flags &
+ (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) {
+ if (*auth_type == UMAC_AUTH_TYPE_8021X)
+ return -EINVAL;
+ *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
+ } else {
+ *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
+ }
+ break;
+ case IW_AUTH_ALG_LEAP:
+ default:
+ IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", auth_alg);
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static int iwm_wext_siwauth(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *data, char *extra)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(dev);
+ int ret;
+
+ if ((data->flags) &
+ (IW_AUTH_WPA_VERSION | IW_AUTH_KEY_MGMT |
+ IW_AUTH_WPA_ENABLED | IW_AUTH_80211_AUTH_ALG)) {
+ /* We need to invalidate the current profile */
+ if (iwm->umac_profile_active) {
+ ret = iwm_invalidate_mlme_profile(iwm);
+ if (ret < 0) {
+ IWM_ERR(iwm, "Couldn't invalidate profile\n");
+ return ret;
+ }
+ }
+ }
+
+ switch (data->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_WPA_VERSION:
+ return iwm_set_wpa_version(iwm, data->value);
+ break;
+ case IW_AUTH_CIPHER_PAIRWISE:
+ return iwm_set_cipher(iwm, data->value, 1);
+ break;
+ case IW_AUTH_CIPHER_GROUP:
+ return iwm_set_cipher(iwm, data->value, 0);
+ break;
+ case IW_AUTH_KEY_MGMT:
+ return iwm_set_key_mgt(iwm, data->value);
+ break;
+ case IW_AUTH_80211_AUTH_ALG:
+ return iwm_set_auth_alg(iwm, data->value);
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static int iwm_wext_giwauth(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *data, char *extra)
+{
+ return 0;
+}
+
+static int iwm_wext_siwencodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *extra)
+{
+ struct iwm_priv *iwm = ndev_to_iwm(dev);
+ struct iwm_key *key;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
+ int uninitialized_var(alg), idx, i, remove = 0;
+
+ IWM_DBG_WEXT(iwm, DBG, "alg: 0x%x\n", ext->alg);
+ IWM_DBG_WEXT(iwm, DBG, "key len: %d\n", ext->key_len);
+ IWM_DBG_WEXT(iwm, DBG, "ext_flags: 0x%x\n", ext->ext_flags);
+ IWM_DBG_WEXT(iwm, DBG, "flags: 0x%x\n", erq->flags);
+ IWM_DBG_WEXT(iwm, DBG, "length: 0x%x\n", erq->length);
+
+ switch (ext->alg) {
+ case IW_ENCODE_ALG_NONE:
+ remove = 1;
+ break;
+ case IW_ENCODE_ALG_WEP:
+ if (ext->key_len == WLAN_KEY_LEN_WEP40)
+ alg = UMAC_CIPHER_TYPE_WEP_40;
+ else if (ext->key_len == WLAN_KEY_LEN_WEP104)
+ alg = UMAC_CIPHER_TYPE_WEP_104;
+ else {
+ IWM_ERR(iwm, "Invalid key length: %d\n", ext->key_len);
+ return -EINVAL;
+ }
+
+ break;
+ case IW_ENCODE_ALG_TKIP:
+ alg = UMAC_CIPHER_TYPE_TKIP;
+ break;
+ case IW_ENCODE_ALG_CCMP:
+ alg = UMAC_CIPHER_TYPE_CCMP;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ idx = erq->flags & IW_ENCODE_INDEX;
+
+ if (idx == 0) {
+ if (iwm->default_key)
+ for (i = 0; i < IWM_NUM_KEYS; i++) {
+ if (iwm->default_key == &iwm->keys[i]) {
+ idx = i;
+ break;
+ }
+ }
+ } else if (idx < 1 || idx > 4) {
+ return -EINVAL;
+ } else
+ idx--;
+
+ if (erq->flags & IW_ENCODE_DISABLED)
+ remove = 1;
+ else if ((erq->length == 0) ||
+ (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) {
+ iwm->default_key = &iwm->keys[idx];
+ if (iwm->umac_profile_active && ext->alg == IW_ENCODE_ALG_WEP)
+ return iwm_set_tx_key(iwm, idx);
+ }
+
+ key = iwm_key_init(iwm, idx, !remove, ext, alg);
+
+ return iwm_set_key(iwm, remove, !iwm->default_key, key);
+}
+
+static const iw_handler iwm_handlers[] =
+{
+ (iw_handler) NULL, /* SIOCSIWCOMMIT */
+ (iw_handler) cfg80211_wext_giwname, /* SIOCGIWNAME */
+ (iw_handler) NULL, /* SIOCSIWNWID */
+ (iw_handler) NULL, /* SIOCGIWNWID */
+ (iw_handler) iwm_wext_siwfreq, /* SIOCSIWFREQ */
+ (iw_handler) iwm_wext_giwfreq, /* SIOCGIWFREQ */
+ (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */
+ (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */
+ (iw_handler) NULL, /* SIOCSIWSENS */
+ (iw_handler) NULL, /* SIOCGIWSENS */
+ (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
+ (iw_handler) cfg80211_wext_giwrange, /* SIOCGIWRANGE */
+ (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
+ (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
+ (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
+ (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */
+ (iw_handler) NULL, /* SIOCSIWSPY */
+ (iw_handler) NULL, /* SIOCGIWSPY */
+ (iw_handler) NULL, /* SIOCSIWTHRSPY */
+ (iw_handler) NULL, /* SIOCGIWTHRSPY */
+ (iw_handler) iwm_wext_siwap, /* SIOCSIWAP */
+ (iw_handler) iwm_wext_giwap, /* SIOCGIWAP */
+ (iw_handler) NULL, /* SIOCSIWMLME */
+ (iw_handler) NULL, /* SIOCGIWAPLIST */
+ (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */
+ (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */
+ (iw_handler) iwm_wext_siwessid, /* SIOCSIWESSID */
+ (iw_handler) iwm_wext_giwessid, /* SIOCGIWESSID */
+ (iw_handler) NULL, /* SIOCSIWNICKN */
+ (iw_handler) NULL, /* SIOCGIWNICKN */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* SIOCSIWRATE */
+ (iw_handler) iwm_wext_giwrate, /* SIOCGIWRATE */
+ (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */
+ (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */
+ (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */
+ (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */
+ (iw_handler) NULL, /* SIOCSIWTXPOW */
+ (iw_handler) NULL, /* SIOCGIWTXPOW */
+ (iw_handler) NULL, /* SIOCSIWRETRY */
+ (iw_handler) NULL, /* SIOCGIWRETRY */
+ (iw_handler) iwm_wext_siwencode, /* SIOCSIWENCODE */
+ (iw_handler) iwm_wext_giwencode, /* SIOCGIWENCODE */
+ (iw_handler) iwm_wext_siwpower, /* SIOCSIWPOWER */
+ (iw_handler) iwm_wext_giwpower, /* SIOCGIWPOWER */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* SIOCSIWGENIE */
+ (iw_handler) NULL, /* SIOCGIWGENIE */
+ (iw_handler) iwm_wext_siwauth, /* SIOCSIWAUTH */
+ (iw_handler) iwm_wext_giwauth, /* SIOCGIWAUTH */
+ (iw_handler) iwm_wext_siwencodeext, /* SIOCSIWENCODEEXT */
+ (iw_handler) NULL, /* SIOCGIWENCODEEXT */
+ (iw_handler) NULL, /* SIOCSIWPMKSA */
+ (iw_handler) NULL, /* -- hole -- */
+};
+
+const struct iw_handler_def iwm_iw_handler_def = {
+ .num_standard = ARRAY_SIZE(iwm_handlers),
+ .standard = (iw_handler *) iwm_handlers,
+ .get_wireless_stats = iwm_get_wireless_stats,
+};
+
diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c
index 4bc46a60ae2..9a5408e7d94 100644
--- a/drivers/net/wireless/libertas/11d.c
+++ b/drivers/net/wireless/libertas/11d.c
@@ -207,7 +207,7 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d
lbs_deb_11d("nr_subband=%x\n", domaininfo->nr_subband);
lbs_deb_hex(LBS_DEB_11D, "domaininfo", (char *)domaininfo,
COUNTRY_CODE_LEN + 1 +
- sizeof(struct ieeetypes_subbandset) * nr_subband);
+ sizeof(struct ieee_subbandset) * nr_subband);
return 0;
}
@@ -302,11 +302,9 @@ done:
* @param parsed_region_chan pointer to parsed_region_chan_11d
* @return 0
*/
-static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
- countryinfo,
+static int parse_domain_info_11d(struct ieee_ie_country_info_full_set *countryinfo,
u8 band,
- struct parsed_region_chan_11d *
- parsed_region_chan)
+ struct parsed_region_chan_11d *parsed_region_chan)
{
u8 nr_subband, nrchan;
u8 lastchan, firstchan;
@@ -331,7 +329,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
lbs_deb_hex(LBS_DEB_11D, "countryinfo", (u8 *) countryinfo, 30);
if ((*(countryinfo->countrycode)) == 0
- || (countryinfo->len <= COUNTRY_CODE_LEN)) {
+ || (countryinfo->header.len <= COUNTRY_CODE_LEN)) {
/* No region Info or Wrong region info: treat as No 11D info */
goto done;
}
@@ -349,8 +347,8 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
memcpy(parsed_region_chan->countrycode, countryinfo->countrycode,
COUNTRY_CODE_LEN);
- nr_subband = (countryinfo->len - COUNTRY_CODE_LEN) /
- sizeof(struct ieeetypes_subbandset);
+ nr_subband = (countryinfo->header.len - COUNTRY_CODE_LEN) /
+ sizeof(struct ieee_subbandset);
for (j = 0, lastchan = 0; j < nr_subband; j++) {
@@ -502,7 +500,7 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
{
struct cmd_ds_802_11d_domain_info *pdomaininfo =
&cmd->params.domaininfo;
- struct mrvlietypes_domainparamset *domain = &pdomaininfo->domain;
+ struct mrvl_ie_domain_param_set *domain = &pdomaininfo->domain;
u8 nr_subband = priv->domainreg.nr_subband;
lbs_deb_enter(LBS_DEB_11D);
@@ -524,16 +522,16 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
sizeof(domain->countrycode));
domain->header.len =
- cpu_to_le16(nr_subband * sizeof(struct ieeetypes_subbandset) +
+ cpu_to_le16(nr_subband * sizeof(struct ieee_subbandset) +
sizeof(domain->countrycode));
if (nr_subband) {
memcpy(domain->subband, priv->domainreg.subband,
- nr_subband * sizeof(struct ieeetypes_subbandset));
+ nr_subband * sizeof(struct ieee_subbandset));
cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
le16_to_cpu(domain->header.len) +
- sizeof(struct mrvlietypesheader) +
+ sizeof(struct mrvl_ie_header) +
S_DS_GEN);
} else {
cmd->size =
@@ -556,7 +554,7 @@ done:
int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp)
{
struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp;
- struct mrvlietypes_domainparamset *domain = &domaininfo->domain;
+ struct mrvl_ie_domain_param_set *domain = &domaininfo->domain;
u16 action = le16_to_cpu(domaininfo->action);
s16 ret = 0;
u8 nr_subband = 0;
@@ -567,7 +565,7 @@ int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp)
(int)le16_to_cpu(resp->size));
nr_subband = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) /
- sizeof(struct ieeetypes_subbandset);
+ sizeof(struct ieee_subbandset);
lbs_deb_11d("domain info resp: nr_subband %d\n", nr_subband);
diff --git a/drivers/net/wireless/libertas/11d.h b/drivers/net/wireless/libertas/11d.h
index 4f4f47f0f87..fb75d3e321a 100644
--- a/drivers/net/wireless/libertas/11d.h
+++ b/drivers/net/wireless/libertas/11d.h
@@ -20,35 +20,36 @@
struct cmd_ds_command;
/** Data structure for Country IE*/
-struct ieeetypes_subbandset {
+struct ieee_subbandset {
u8 firstchan;
u8 nrchan;
u8 maxtxpwr;
} __attribute__ ((packed));
-struct ieeetypes_countryinfoset {
- u8 element_id;
- u8 len;
+struct ieee_ie_country_info_set {
+ struct ieee_ie_header header;
+
u8 countrycode[COUNTRY_CODE_LEN];
- struct ieeetypes_subbandset subband[1];
+ struct ieee_subbandset subband[1];
};
-struct ieeetypes_countryinfofullset {
- u8 element_id;
- u8 len;
+struct ieee_ie_country_info_full_set {
+ struct ieee_ie_header header;
+
u8 countrycode[COUNTRY_CODE_LEN];
- struct ieeetypes_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
+ struct ieee_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
} __attribute__ ((packed));
-struct mrvlietypes_domainparamset {
- struct mrvlietypesheader header;
+struct mrvl_ie_domain_param_set {
+ struct mrvl_ie_header header;
+
u8 countrycode[COUNTRY_CODE_LEN];
- struct ieeetypes_subbandset subband[1];
+ struct ieee_subbandset subband[1];
} __attribute__ ((packed));
struct cmd_ds_802_11d_domain_info {
__le16 action;
- struct mrvlietypes_domainparamset domain;
+ struct mrvl_ie_domain_param_set domain;
} __attribute__ ((packed));
/** domain regulatory information */
@@ -57,7 +58,7 @@ struct lbs_802_11d_domain_reg {
u8 countrycode[COUNTRY_CODE_LEN];
/** No. of subband*/
u8 nr_subband;
- struct ieeetypes_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
+ struct ieee_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
};
struct chan_power_11d {
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index a0e440cd896..b9b37411903 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -12,15 +12,14 @@
#include "scan.h"
#include "cmd.h"
-static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp);
-
static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) =
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-/* The firmware needs certain bits masked out of the beacon-derviced capability
- * field when associating/joining to BSSs.
+/* The firmware needs the following bits masked out of the beacon-derived
+ * capability field when associating/joining to a BSS:
+ * 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused)
*/
#define CAPINFO_MASK (~(0xda00))
@@ -102,6 +101,295 @@ static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
}
+static u8 iw_auth_to_ieee_auth(u8 auth)
+{
+ if (auth == IW_AUTH_ALG_OPEN_SYSTEM)
+ return 0x00;
+ else if (auth == IW_AUTH_ALG_SHARED_KEY)
+ return 0x01;
+ else if (auth == IW_AUTH_ALG_LEAP)
+ return 0x80;
+
+ lbs_deb_join("%s: invalid auth alg 0x%X\n", __func__, auth);
+ return 0;
+}
+
+/**
+ * @brief This function prepares the authenticate command. AUTHENTICATE only
+ * sets the authentication suite for future associations, as the firmware
+ * handles authentication internally during the ASSOCIATE command.
+ *
+ * @param priv A pointer to struct lbs_private structure
+ * @param bssid The peer BSSID with which to authenticate
+ * @param auth The authentication mode to use (from wireless.h)
+ *
+ * @return 0 or -1
+ */
+static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth)
+{
+ struct cmd_ds_802_11_authenticate cmd;
+ int ret = -1;
+ DECLARE_MAC_BUF(mac);
+
+ lbs_deb_enter(LBS_DEB_JOIN);
+
+ cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+ memcpy(cmd.bssid, bssid, ETH_ALEN);
+
+ cmd.authtype = iw_auth_to_ieee_auth(auth);
+
+ lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
+ print_mac(mac, bssid), cmd.authtype);
+
+ ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd);
+
+ lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
+ return ret;
+}
+
+
+static int lbs_assoc_post(struct lbs_private *priv,
+ struct cmd_ds_802_11_associate_response *resp)
+{
+ int ret = 0;
+ union iwreq_data wrqu;
+ struct bss_descriptor *bss;
+ u16 status_code;
+
+ lbs_deb_enter(LBS_DEB_ASSOC);
+
+ if (!priv->in_progress_assoc_req) {
+ lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
+ ret = -1;
+ goto done;
+ }
+ bss = &priv->in_progress_assoc_req->bss;
+
+ /*
+ * Older FW versions map the IEEE 802.11 Status Code in the association
+ * response to the following values returned in resp->statuscode:
+ *
+ * IEEE Status Code Marvell Status Code
+ * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
+ * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * others -> 0x0003 ASSOC_RESULT_REFUSED
+ *
+ * Other response codes:
+ * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
+ * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
+ * association response from the AP)
+ */
+
+ status_code = le16_to_cpu(resp->statuscode);
+ if (priv->fwrelease < 0x09000000) {
+ switch (status_code) {
+ case 0x00:
+ break;
+ case 0x01:
+ lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
+ break;
+ case 0x02:
+ lbs_deb_assoc("ASSOC_RESP: internal timer "
+ "expired while waiting for the AP\n");
+ break;
+ case 0x03:
+ lbs_deb_assoc("ASSOC_RESP: association "
+ "refused by AP\n");
+ break;
+ case 0x04:
+ lbs_deb_assoc("ASSOC_RESP: authentication "
+ "refused by AP\n");
+ break;
+ default:
+ lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
+ " unknown\n", status_code);
+ break;
+ }
+ } else {
+ /* v9+ returns the AP's association response */
+ lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x\n", status_code);
+ }
+
+ if (status_code) {
+ lbs_mac_event_disconnected(priv);
+ ret = -1;
+ goto done;
+ }
+
+ lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP",
+ (void *) (resp + sizeof (resp->hdr)),
+ le16_to_cpu(resp->hdr.size) - sizeof (resp->hdr));
+
+ /* Send a Media Connected event, according to the Spec */
+ priv->connect_status = LBS_CONNECTED;
+
+ /* Update current SSID and BSSID */
+ memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
+ priv->curbssparams.ssid_len = bss->ssid_len;
+ memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
+
+ priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
+ priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
+
+ memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
+ memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
+ priv->nextSNRNF = 0;
+ priv->numSNRNF = 0;
+
+ netif_carrier_on(priv->dev);
+ if (!priv->tx_pending_len)
+ netif_wake_queue(priv->dev);
+
+ memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
+
+done:
+ lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
+ return ret;
+}
+
+/**
+ * @brief This function prepares an association-class command.
+ *
+ * @param priv A pointer to struct lbs_private structure
+ * @param assoc_req The association request describing the BSS to associate
+ * or reassociate with
+ * @param command The actual command, either CMD_802_11_ASSOCIATE or
+ * CMD_802_11_REASSOCIATE
+ *
+ * @return 0 or -1
+ */
+static int lbs_associate(struct lbs_private *priv,
+ struct assoc_request *assoc_req,
+ u16 command)
+{
+ struct cmd_ds_802_11_associate cmd;
+ int ret = 0;
+ struct bss_descriptor *bss = &assoc_req->bss;
+ u8 *pos = &(cmd.iebuf[0]);
+ u16 tmpcap, tmplen, tmpauth;
+ struct mrvl_ie_ssid_param_set *ssid;
+ struct mrvl_ie_ds_param_set *ds;
+ struct mrvl_ie_cf_param_set *cf;
+ struct mrvl_ie_rates_param_set *rates;
+ struct mrvl_ie_rsn_param_set *rsn;
+ struct mrvl_ie_auth_type *auth;
+
+ lbs_deb_enter(LBS_DEB_ASSOC);
+
+ BUG_ON((command != CMD_802_11_ASSOCIATE) &&
+ (command != CMD_802_11_REASSOCIATE));
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.hdr.command = cpu_to_le16(command);
+
+ /* Fill in static fields */
+ memcpy(cmd.bssid, bss->bssid, ETH_ALEN);
+ cmd.listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
+
+ /* Capability info */
+ tmpcap = (bss->capability & CAPINFO_MASK);
+ if (bss->mode == IW_MODE_INFRA)
+ tmpcap |= WLAN_CAPABILITY_ESS;
+ cmd.capability = cpu_to_le16(tmpcap);
+ lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
+
+ /* SSID */
+ ssid = (struct mrvl_ie_ssid_param_set *) pos;
+ ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
+ tmplen = bss->ssid_len;
+ ssid->header.len = cpu_to_le16(tmplen);
+ memcpy(ssid->ssid, bss->ssid, tmplen);
+ pos += sizeof(ssid->header) + tmplen;
+
+ ds = (struct mrvl_ie_ds_param_set *) pos;
+ ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
+ ds->header.len = cpu_to_le16(1);
+ ds->channel = bss->phy.ds.channel;
+ pos += sizeof(ds->header) + 1;
+
+ cf = (struct mrvl_ie_cf_param_set *) pos;
+ cf->header.type = cpu_to_le16(TLV_TYPE_CF);
+ tmplen = sizeof(*cf) - sizeof (cf->header);
+ cf->header.len = cpu_to_le16(tmplen);
+ /* IE payload should be zeroed, firmware fills it in for us */
+ pos += sizeof(*cf);
+
+ rates = (struct mrvl_ie_rates_param_set *) pos;
+ rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
+ memcpy(&rates->rates, &bss->rates, MAX_RATES);
+ tmplen = MAX_RATES;
+ if (get_common_rates(priv, rates->rates, &tmplen)) {
+ ret = -1;
+ goto done;
+ }
+ pos += sizeof(rates->header) + tmplen;
+ rates->header.len = cpu_to_le16(tmplen);
+ lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
+
+ /* Copy the infra. association rates into Current BSS state structure */
+ memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
+ memcpy(&priv->curbssparams.rates, &rates->rates, tmplen);
+
+ /* Set MSB on basic rates as the firmware requires, but _after_
+ * copying to current bss rates.
+ */
+ lbs_set_basic_rate_flags(rates->rates, tmplen);
+
+ /* Firmware v9+ indicate authentication suites as a TLV */
+ if (priv->fwrelease >= 0x09000000) {
+ DECLARE_MAC_BUF(mac);
+
+ auth = (struct mrvl_ie_auth_type *) pos;
+ auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
+ auth->header.len = cpu_to_le16(2);
+ tmpauth = iw_auth_to_ieee_auth(priv->secinfo.auth_mode);
+ auth->auth = cpu_to_le16(tmpauth);
+ pos += sizeof(auth->header) + 2;
+
+ lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
+ print_mac(mac, bss->bssid), priv->secinfo.auth_mode);
+ }
+
+ /* WPA/WPA2 IEs */
+ if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
+ rsn = (struct mrvl_ie_rsn_param_set *) pos;
+ /* WPA_IE or WPA2_IE */
+ rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
+ tmplen = (u16) assoc_req->wpa_ie[1];
+ rsn->header.len = cpu_to_le16(tmplen);
+ memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
+ lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: WPA/RSN IE", (u8 *) rsn,
+ sizeof(rsn->header) + tmplen);
+ pos += sizeof(rsn->header) + tmplen;
+ }
+
+ cmd.hdr.size = cpu_to_le16((sizeof(cmd) - sizeof(cmd.iebuf)) +
+ (u16)(pos - (u8 *) &cmd.iebuf));
+
+ /* update curbssparams */
+ priv->curbssparams.channel = bss->phy.ds.channel;
+
+ if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
+ ret = -1;
+ goto done;
+ }
+
+ ret = lbs_cmd_with_response(priv, command, &cmd);
+ if (ret == 0) {
+ ret = lbs_assoc_post(priv,
+ (struct cmd_ds_802_11_associate_response *) &cmd);
+ }
+
+done:
+ lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
+ return ret;
+}
+
/**
* @brief Associate to a specific BSS discovered in a scan
*
@@ -110,7 +398,7 @@ static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
*
* @return 0-success, otherwise fail
*/
-static int lbs_associate(struct lbs_private *priv,
+static int lbs_try_associate(struct lbs_private *priv,
struct assoc_request *assoc_req)
{
int ret;
@@ -118,11 +406,15 @@ static int lbs_associate(struct lbs_private *priv,
lbs_deb_enter(LBS_DEB_ASSOC);
- ret = lbs_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE,
- 0, CMD_OPTION_WAITFORRSP,
- 0, assoc_req->bss.bssid);
- if (ret)
- goto out;
+ /* FW v9 and higher indicate authentication suites as a TLV in the
+ * association command, not as a separate authentication command.
+ */
+ if (priv->fwrelease < 0x09000000) {
+ ret = lbs_set_authentication(priv, assoc_req->bss.bssid,
+ priv->secinfo.auth_mode);
+ if (ret)
+ goto out;
+ }
/* Use short preamble only when both the BSS and firmware support it */
if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
@@ -133,14 +425,78 @@ static int lbs_associate(struct lbs_private *priv,
if (ret)
goto out;
- ret = lbs_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE,
- 0, CMD_OPTION_WAITFORRSP, 0, assoc_req);
+ ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE);
out:
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
+static int lbs_adhoc_post(struct lbs_private *priv,
+ struct cmd_ds_802_11_ad_hoc_result *resp)
+{
+ int ret = 0;
+ u16 command = le16_to_cpu(resp->hdr.command);
+ u16 result = le16_to_cpu(resp->hdr.result);
+ union iwreq_data wrqu;
+ struct bss_descriptor *bss;
+ DECLARE_SSID_BUF(ssid);
+
+ lbs_deb_enter(LBS_DEB_JOIN);
+
+ if (!priv->in_progress_assoc_req) {
+ lbs_deb_join("ADHOC_RESP: no in-progress association "
+ "request\n");
+ ret = -1;
+ goto done;
+ }
+ bss = &priv->in_progress_assoc_req->bss;
+
+ /*
+ * Join result code 0 --> SUCCESS
+ */
+ if (result) {
+ lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result);
+ if (priv->connect_status == LBS_CONNECTED)
+ lbs_mac_event_disconnected(priv);
+ ret = -1;
+ goto done;
+ }
+
+ /* Send a Media Connected event, according to the Spec */
+ priv->connect_status = LBS_CONNECTED;
+
+ if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
+ /* Update the created network descriptor with the new BSSID */
+ memcpy(bss->bssid, resp->bssid, ETH_ALEN);
+ }
+
+ /* Set the BSSID from the joined/started descriptor */
+ memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
+
+ /* Set the new SSID to current SSID */
+ memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
+ priv->curbssparams.ssid_len = bss->ssid_len;
+
+ netif_carrier_on(priv->dev);
+ if (!priv->tx_pending_len)
+ netif_wake_queue(priv->dev);
+
+ memset(&wrqu, 0, sizeof(wrqu));
+ memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
+
+ lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n",
+ print_ssid(ssid, bss->ssid, bss->ssid_len),
+ priv->curbssparams.bssid,
+ priv->curbssparams.channel);
+
+done:
+ lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
+ return ret;
+}
+
/**
* @brief Join an adhoc network found in a previous scan
*
@@ -219,11 +575,10 @@ static int lbs_adhoc_join(struct lbs_private *priv,
memcpy(&cmd.bss.bssid, &bss->bssid, ETH_ALEN);
memcpy(&cmd.bss.ssid, &bss->ssid, bss->ssid_len);
- memcpy(&cmd.bss.phyparamset, &bss->phyparamset,
- sizeof(union ieeetypes_phyparamset));
+ memcpy(&cmd.bss.ds, &bss->phy.ds, sizeof(struct ieee_ie_ds_param_set));
- memcpy(&cmd.bss.ssparamset, &bss->ssparamset,
- sizeof(union IEEEtypes_ssparamset));
+ memcpy(&cmd.bss.ibss, &bss->ss.ibss,
+ sizeof(struct ieee_ie_ibss_param_set));
cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
@@ -260,7 +615,7 @@ static int lbs_adhoc_join(struct lbs_private *priv,
*/
lbs_set_basic_rate_flags(cmd.bss.rates, ratesize);
- cmd.bss.ssparamset.ibssparamset.atimwindow = cpu_to_le16(bss->atimwindow);
+ cmd.bss.ibss.atimwindow = bss->atimwindow;
if (assoc_req->secinfo.wep_enabled) {
u16 tmp = le16_to_cpu(cmd.bss.capability);
@@ -287,8 +642,10 @@ static int lbs_adhoc_join(struct lbs_private *priv,
}
ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd);
- if (ret == 0)
- ret = lbs_adhoc_post(priv, (struct cmd_header *) &cmd);
+ if (ret == 0) {
+ ret = lbs_adhoc_post(priv,
+ (struct cmd_ds_802_11_ad_hoc_result *)&cmd);
+ }
out:
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -343,22 +700,24 @@ static int lbs_adhoc_start(struct lbs_private *priv,
WARN_ON(!assoc_req->channel);
/* set Physical parameter set */
- cmd.phyparamset.dsparamset.elementid = WLAN_EID_DS_PARAMS;
- cmd.phyparamset.dsparamset.len = 1;
- cmd.phyparamset.dsparamset.currentchan = assoc_req->channel;
+ cmd.ds.header.id = WLAN_EID_DS_PARAMS;
+ cmd.ds.header.len = 1;
+ cmd.ds.channel = assoc_req->channel;
/* set IBSS parameter set */
- cmd.ssparamset.ibssparamset.elementid = WLAN_EID_IBSS_PARAMS;
- cmd.ssparamset.ibssparamset.len = 2;
- cmd.ssparamset.ibssparamset.atimwindow = 0;
+ cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS;
+ cmd.ibss.header.len = 2;
+ cmd.ibss.atimwindow = cpu_to_le16(0);
/* set capability info */
tmpcap = WLAN_CAPABILITY_IBSS;
- if (assoc_req->secinfo.wep_enabled) {
- lbs_deb_join("ADHOC_START: WEP enabled, setting privacy on\n");
+ if (assoc_req->secinfo.wep_enabled ||
+ assoc_req->secinfo.WPAenabled ||
+ assoc_req->secinfo.WPA2enabled) {
+ lbs_deb_join("ADHOC_START: WEP/WPA enabled, privacy on\n");
tmpcap |= WLAN_CAPABILITY_PRIVACY;
} else
- lbs_deb_join("ADHOC_START: WEP disabled, setting privacy off\n");
+ lbs_deb_join("ADHOC_START: WEP disabled, privacy off\n");
cmd.capability = cpu_to_le16(tmpcap);
@@ -395,7 +754,8 @@ static int lbs_adhoc_start(struct lbs_private *priv,
ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd);
if (ret == 0)
- ret = lbs_adhoc_post(priv, (struct cmd_header *) &cmd);
+ ret = lbs_adhoc_post(priv,
+ (struct cmd_ds_802_11_ad_hoc_result *)&cmd);
out:
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -720,7 +1080,7 @@ static int assoc_helper_essid(struct lbs_private *priv,
assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel);
if (bss != NULL) {
memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
- ret = lbs_associate(priv, assoc_req);
+ ret = lbs_try_associate(priv, assoc_req);
} else {
lbs_deb_assoc("SSID not found; cannot associate\n");
}
@@ -772,8 +1132,9 @@ static int assoc_helper_bssid(struct lbs_private *priv,
memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
if (assoc_req->mode == IW_MODE_INFRA) {
- ret = lbs_associate(priv, assoc_req);
- lbs_deb_assoc("ASSOC: lbs_associate(bssid) returned %d\n", ret);
+ ret = lbs_try_associate(priv, assoc_req);
+ lbs_deb_assoc("ASSOC: lbs_try_associate(bssid) returned %d\n",
+ ret);
} else if (assoc_req->mode == IW_MODE_ADHOC) {
lbs_adhoc_join(priv, assoc_req);
}
@@ -1467,57 +1828,6 @@ struct assoc_request *lbs_get_association_request(struct lbs_private *priv)
/**
- * @brief This function prepares command of authenticate.
- *
- * @param priv A pointer to struct lbs_private structure
- * @param cmd A pointer to cmd_ds_command structure
- * @param pdata_buf Void cast of pointer to a BSSID to authenticate with
- *
- * @return 0 or -1
- */
-int lbs_cmd_80211_authenticate(struct lbs_private *priv,
- struct cmd_ds_command *cmd,
- void *pdata_buf)
-{
- struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth;
- int ret = -1;
- u8 *bssid = pdata_buf;
-
- lbs_deb_enter(LBS_DEB_JOIN);
-
- cmd->command = cpu_to_le16(CMD_802_11_AUTHENTICATE);
- cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
- + S_DS_GEN);
-
- /* translate auth mode to 802.11 defined wire value */
- switch (priv->secinfo.auth_mode) {
- case IW_AUTH_ALG_OPEN_SYSTEM:
- pauthenticate->authtype = 0x00;
- break;
- case IW_AUTH_ALG_SHARED_KEY:
- pauthenticate->authtype = 0x01;
- break;
- case IW_AUTH_ALG_LEAP:
- pauthenticate->authtype = 0x80;
- break;
- default:
- lbs_deb_join("AUTH_CMD: invalid auth alg 0x%X\n",
- priv->secinfo.auth_mode);
- goto out;
- }
-
- memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
-
- lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n",
- bssid, pauthenticate->authtype);
- ret = 0;
-
-out:
- lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
- return ret;
-}
-
-/**
* @brief Deauthenticate from a specific BSS
*
* @param priv A pointer to struct lbs_private structure
@@ -1550,285 +1860,3 @@ int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, u8 bssid[ETH_ALEN],
return ret;
}
-int lbs_cmd_80211_associate(struct lbs_private *priv,
- struct cmd_ds_command *cmd, void *pdata_buf)
-{
- struct cmd_ds_802_11_associate *passo = &cmd->params.associate;
- int ret = 0;
- struct assoc_request *assoc_req = pdata_buf;
- struct bss_descriptor *bss = &assoc_req->bss;
- u8 *pos;
- u16 tmpcap, tmplen;
- struct mrvlietypes_ssidparamset *ssid;
- struct mrvlietypes_phyparamset *phy;
- struct mrvlietypes_ssparamset *ss;
- struct mrvlietypes_ratesparamset *rates;
- struct mrvlietypes_rsnparamset *rsn;
-
- lbs_deb_enter(LBS_DEB_ASSOC);
-
- pos = (u8 *) passo;
-
- if (!priv) {
- ret = -1;
- goto done;
- }
-
- cmd->command = cpu_to_le16(CMD_802_11_ASSOCIATE);
-
- memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr));
- pos += sizeof(passo->peerstaaddr);
-
- /* set the listen interval */
- passo->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
-
- pos += sizeof(passo->capability);
- pos += sizeof(passo->listeninterval);
- pos += sizeof(passo->bcnperiod);
- pos += sizeof(passo->dtimperiod);
-
- ssid = (struct mrvlietypes_ssidparamset *) pos;
- ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
- tmplen = bss->ssid_len;
- ssid->header.len = cpu_to_le16(tmplen);
- memcpy(ssid->ssid, bss->ssid, tmplen);
- pos += sizeof(ssid->header) + tmplen;
-
- phy = (struct mrvlietypes_phyparamset *) pos;
- phy->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
- tmplen = sizeof(phy->fh_ds.dsparamset);
- phy->header.len = cpu_to_le16(tmplen);
- memcpy(&phy->fh_ds.dsparamset,
- &bss->phyparamset.dsparamset.currentchan,
- tmplen);
- pos += sizeof(phy->header) + tmplen;
-
- ss = (struct mrvlietypes_ssparamset *) pos;
- ss->header.type = cpu_to_le16(TLV_TYPE_CF);
- tmplen = sizeof(ss->cf_ibss.cfparamset);
- ss->header.len = cpu_to_le16(tmplen);
- pos += sizeof(ss->header) + tmplen;
-
- rates = (struct mrvlietypes_ratesparamset *) pos;
- rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
- memcpy(&rates->rates, &bss->rates, MAX_RATES);
- tmplen = MAX_RATES;
- if (get_common_rates(priv, rates->rates, &tmplen)) {
- ret = -1;
- goto done;
- }
- pos += sizeof(rates->header) + tmplen;
- rates->header.len = cpu_to_le16(tmplen);
- lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
-
- /* Copy the infra. association rates into Current BSS state structure */
- memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
- memcpy(&priv->curbssparams.rates, &rates->rates, tmplen);
-
- /* Set MSB on basic rates as the firmware requires, but _after_
- * copying to current bss rates.
- */
- lbs_set_basic_rate_flags(rates->rates, tmplen);
-
- if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
- rsn = (struct mrvlietypes_rsnparamset *) pos;
- /* WPA_IE or WPA2_IE */
- rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
- tmplen = (u16) assoc_req->wpa_ie[1];
- rsn->header.len = cpu_to_le16(tmplen);
- memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
- lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: RSN IE", (u8 *) rsn,
- sizeof(rsn->header) + tmplen);
- pos += sizeof(rsn->header) + tmplen;
- }
-
- /* update curbssparams */
- priv->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
-
- if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
- ret = -1;
- goto done;
- }
-
- cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN);
-
- /* set the capability info */
- tmpcap = (bss->capability & CAPINFO_MASK);
- if (bss->mode == IW_MODE_INFRA)
- tmpcap |= WLAN_CAPABILITY_ESS;
- passo->capability = cpu_to_le16(tmpcap);
- lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
-
-done:
- lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
- return ret;
-}
-
-int lbs_ret_80211_associate(struct lbs_private *priv,
- struct cmd_ds_command *resp)
-{
- int ret = 0;
- union iwreq_data wrqu;
- struct ieeetypes_assocrsp *passocrsp;
- struct bss_descriptor *bss;
- u16 status_code;
-
- lbs_deb_enter(LBS_DEB_ASSOC);
-
- if (!priv->in_progress_assoc_req) {
- lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
- ret = -1;
- goto done;
- }
- bss = &priv->in_progress_assoc_req->bss;
-
- passocrsp = (struct ieeetypes_assocrsp *) &resp->params;
-
- /*
- * Older FW versions map the IEEE 802.11 Status Code in the association
- * response to the following values returned in passocrsp->statuscode:
- *
- * IEEE Status Code Marvell Status Code
- * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
- * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
- * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
- * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
- * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
- * others -> 0x0003 ASSOC_RESULT_REFUSED
- *
- * Other response codes:
- * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
- * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
- * association response from the AP)
- */
-
- status_code = le16_to_cpu(passocrsp->statuscode);
- switch (status_code) {
- case 0x00:
- break;
- case 0x01:
- lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
- break;
- case 0x02:
- lbs_deb_assoc("ASSOC_RESP: internal timer "
- "expired while waiting for the AP\n");
- break;
- case 0x03:
- lbs_deb_assoc("ASSOC_RESP: association "
- "refused by AP\n");
- break;
- case 0x04:
- lbs_deb_assoc("ASSOC_RESP: authentication "
- "refused by AP\n");
- break;
- default:
- lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
- " unknown\n", status_code);
- break;
- }
-
- if (status_code) {
- lbs_mac_event_disconnected(priv);
- ret = -1;
- goto done;
- }
-
- lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP", (void *)&resp->params,
- le16_to_cpu(resp->size) - S_DS_GEN);
-
- /* Send a Media Connected event, according to the Spec */
- priv->connect_status = LBS_CONNECTED;
-
- /* Update current SSID and BSSID */
- memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
- priv->curbssparams.ssid_len = bss->ssid_len;
- memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
-
- priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
- priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
-
- memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
- memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
- priv->nextSNRNF = 0;
- priv->numSNRNF = 0;
-
- netif_carrier_on(priv->dev);
- if (!priv->tx_pending_len)
- netif_wake_queue(priv->dev);
-
- memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
-
-done:
- lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
- return ret;
-}
-
-static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp)
-{
- int ret = 0;
- u16 command = le16_to_cpu(resp->command);
- u16 result = le16_to_cpu(resp->result);
- struct cmd_ds_802_11_ad_hoc_result *adhoc_resp;
- union iwreq_data wrqu;
- struct bss_descriptor *bss;
- DECLARE_SSID_BUF(ssid);
-
- lbs_deb_enter(LBS_DEB_JOIN);
-
- adhoc_resp = (struct cmd_ds_802_11_ad_hoc_result *) resp;
-
- if (!priv->in_progress_assoc_req) {
- lbs_deb_join("ADHOC_RESP: no in-progress association "
- "request\n");
- ret = -1;
- goto done;
- }
- bss = &priv->in_progress_assoc_req->bss;
-
- /*
- * Join result code 0 --> SUCCESS
- */
- if (result) {
- lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result);
- if (priv->connect_status == LBS_CONNECTED)
- lbs_mac_event_disconnected(priv);
- ret = -1;
- goto done;
- }
-
- /* Send a Media Connected event, according to the Spec */
- priv->connect_status = LBS_CONNECTED;
-
- if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
- /* Update the created network descriptor with the new BSSID */
- memcpy(bss->bssid, adhoc_resp->bssid, ETH_ALEN);
- }
-
- /* Set the BSSID from the joined/started descriptor */
- memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
-
- /* Set the new SSID to current SSID */
- memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
- priv->curbssparams.ssid_len = bss->ssid_len;
-
- netif_carrier_on(priv->dev);
- if (!priv->tx_pending_len)
- netif_wake_queue(priv->dev);
-
- memset(&wrqu, 0, sizeof(wrqu));
- memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
-
- lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n",
- print_ssid(ssid, bss->ssid, bss->ssid_len),
- priv->curbssparams.bssid,
- priv->curbssparams.channel);
-
-done:
- lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
- return ret;
-}
-
diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h
index 8b7336dd02a..6e765e9f91a 100644
--- a/drivers/net/wireless/libertas/assoc.h
+++ b/drivers/net/wireless/libertas/assoc.h
@@ -8,22 +8,9 @@
void lbs_association_worker(struct work_struct *work);
struct assoc_request *lbs_get_association_request(struct lbs_private *priv);
-struct cmd_ds_command;
-int lbs_cmd_80211_authenticate(struct lbs_private *priv,
- struct cmd_ds_command *cmd,
- void *pdata_buf);
-
int lbs_adhoc_stop(struct lbs_private *priv);
int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
u8 bssid[ETH_ALEN], u16 reason);
-int lbs_cmd_80211_associate(struct lbs_private *priv,
- struct cmd_ds_command *cmd,
- void *pdata_buf);
-
-int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
- struct cmd_ds_command *resp);
-int lbs_ret_80211_associate(struct lbs_private *priv,
- struct cmd_ds_command *resp);
#endif /* _LBS_ASSOC_H */
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 8c3605cdc64..01db705a38e 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -119,6 +119,19 @@ int lbs_update_hw_spec(struct lbs_private *priv)
lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
cmd.hwifversion, cmd.version);
+ /* Determine mesh_fw_ver from fwrelease and fwcapinfo */
+ /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */
+ /* 5.110.22 have mesh command with 0xa3 command id */
+ /* 10.0.0.p0 FW brings in mesh config command with different id */
+ /* Check FW version MSB and initialize mesh_fw_ver */
+ if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5)
+ priv->mesh_fw_ver = MESH_FW_OLD;
+ else if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
+ (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK))
+ priv->mesh_fw_ver = MESH_FW_NEW;
+ else
+ priv->mesh_fw_ver = MESH_NONE;
+
/* Clamp region code to 8-bit since FW spec indicates that it should
* only ever be 8-bit, even though the field size is 16-bit. Some firmware
* returns non-zero high 8 bits here.
@@ -1036,17 +1049,26 @@ static int __lbs_mesh_config_send(struct lbs_private *priv,
uint16_t action, uint16_t type)
{
int ret;
+ u16 command = CMD_MESH_CONFIG_OLD;
lbs_deb_enter(LBS_DEB_CMD);
- cmd->hdr.command = cpu_to_le16(CMD_MESH_CONFIG);
+ /*
+ * Command id is 0xac for v10 FW along with mesh interface
+ * id in bits 14-13-12.
+ */
+ if (priv->mesh_fw_ver == MESH_FW_NEW)
+ command = CMD_MESH_CONFIG |
+ (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
+
+ cmd->hdr.command = cpu_to_le16(command);
cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
cmd->hdr.result = 0;
cmd->type = cpu_to_le16(type);
cmd->action = cpu_to_le16(action);
- ret = lbs_cmd_with_response(priv, CMD_MESH_CONFIG, cmd);
+ ret = lbs_cmd_with_response(priv, command, cmd);
lbs_deb_leave(LBS_DEB_CMD);
return ret;
@@ -1198,8 +1220,7 @@ static void lbs_submit_command(struct lbs_private *priv,
command = le16_to_cpu(cmd->command);
/* These commands take longer */
- if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE ||
- command == CMD_802_11_AUTHENTICATE)
+ if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE)
timeo = 5 * HZ;
lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n",
@@ -1393,15 +1414,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action);
break;
- case CMD_802_11_ASSOCIATE:
- case CMD_802_11_REASSOCIATE:
- ret = lbs_cmd_80211_associate(priv, cmdptr, pdata_buf);
- break;
-
- case CMD_802_11_AUTHENTICATE:
- ret = lbs_cmd_80211_authenticate(priv, cmdptr, pdata_buf);
- break;
-
case CMD_MAC_REG_ACCESS:
case CMD_BBP_REG_ACCESS:
case CMD_RF_REG_ACCESS:
@@ -1448,8 +1460,8 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
break;
case CMD_802_11_LED_GPIO_CTRL:
{
- struct mrvlietypes_ledgpio *gpio =
- (struct mrvlietypes_ledgpio*)
+ struct mrvl_ie_ledgpio *gpio =
+ (struct mrvl_ie_ledgpio*)
cmdptr->params.ledgpio.data;
memmove(&cmdptr->params.ledgpio,
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index bcf2a9756fb..c42d3faa266 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -5,7 +5,7 @@
#include <linux/delay.h>
#include <linux/if_arp.h>
#include <linux/netdevice.h>
-
+#include <asm/unaligned.h>
#include <net/iw_handler.h>
#include "host.h"
@@ -154,11 +154,11 @@ static int lbs_ret_802_11_rssi(struct lbs_private *priv,
lbs_deb_enter(LBS_DEB_CMD);
/* store the non average value */
- priv->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
- priv->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);
+ priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR);
+ priv->NF[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->noisefloor);
- priv->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
- priv->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);
+ priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR);
+ priv->NF[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgnoisefloor);
priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
@@ -210,12 +210,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
ret = lbs_ret_reg_access(priv, respcmd, resp);
break;
- case CMD_RET_802_11_ASSOCIATE:
- case CMD_RET(CMD_802_11_ASSOCIATE):
- case CMD_RET(CMD_802_11_REASSOCIATE):
- ret = lbs_ret_80211_associate(priv, resp);
- break;
-
case CMD_RET(CMD_802_11_SET_AFC):
case CMD_RET(CMD_802_11_GET_AFC):
spin_lock_irqsave(&priv->driver_lock, flags);
@@ -225,7 +219,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
break;
- case CMD_RET(CMD_802_11_AUTHENTICATE):
case CMD_RET(CMD_802_11_BEACON_STOP):
break;
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 50e28a0cdfe..811ffc3ef41 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -183,12 +183,12 @@ out_unlock:
*/
static void *lbs_tlv_find(uint16_t tlv_type, const uint8_t *tlv, uint16_t size)
{
- struct mrvlietypesheader *tlv_h;
+ struct mrvl_ie_header *tlv_h;
uint16_t length;
ssize_t pos = 0;
while (pos < size) {
- tlv_h = (struct mrvlietypesheader *) tlv;
+ tlv_h = (struct mrvl_ie_header *) tlv;
if (!tlv_h->len)
return NULL;
if (tlv_h->type == cpu_to_le16(tlv_type))
@@ -206,7 +206,7 @@ static ssize_t lbs_threshold_read(uint16_t tlv_type, uint16_t event_mask,
size_t count, loff_t *ppos)
{
struct cmd_ds_802_11_subscribe_event *subscribed;
- struct mrvlietypes_thresholds *got;
+ struct mrvl_ie_thresholds *got;
struct lbs_private *priv = file->private_data;
ssize_t ret = 0;
size_t pos = 0;
@@ -259,7 +259,7 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask,
loff_t *ppos)
{
struct cmd_ds_802_11_subscribe_event *events;
- struct mrvlietypes_thresholds *tlv;
+ struct mrvl_ie_thresholds *tlv;
struct lbs_private *priv = file->private_data;
ssize_t buf_size;
int value, freq, new_mask;
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index e8dfde39abf..48da157d6cd 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -227,6 +227,20 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
#define TxPD_CONTROL_WDS_FRAME (1<<17)
#define TxPD_MESH_FRAME TxPD_CONTROL_WDS_FRAME
+/** Mesh interface ID */
+#define MESH_IFACE_ID 0x0001
+/** Mesh id should be in bits 14-13-12 */
+#define MESH_IFACE_BIT_OFFSET 0x000c
+/** Mesh enable bit in FW capability */
+#define MESH_CAPINFO_ENABLE_MASK (1<<16)
+
+/** FW definition from Marvell v5 */
+#define MRVL_FW_V5 (0x05)
+/** FW definition from Marvell v10 */
+#define MRVL_FW_V10 (0x0a)
+/** FW major revision definition */
+#define MRVL_FW_MAJOR_REV(x) ((x)>>24)
+
/** RxPD status */
#define MRVDRV_RXPD_STATUS_OK 0x0001
@@ -380,6 +394,13 @@ enum KEY_INFO_WPA {
KEY_INFO_WPA_ENABLED = 0x04
};
+/** mesh_fw_ver */
+enum _mesh_fw_ver {
+ MESH_NONE = 0, /* MESH is not supported */
+ MESH_FW_OLD, /* MESH is supported in FW V5 */
+ MESH_FW_NEW, /* MESH is supported in FW V10 and newer */
+};
+
/* Default values for fwt commands. */
#define FWT_DEFAULT_METRIC 0
#define FWT_DEFAULT_DIR 1
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 27e81fd97c9..f9ec69e0473 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -101,6 +101,7 @@ struct lbs_mesh_stats {
/** Private structure for the MV device */
struct lbs_private {
int mesh_open;
+ int mesh_fw_ver;
int infra_open;
int mesh_autostart_enabled;
@@ -337,7 +338,7 @@ struct bss_descriptor {
u32 rssi;
u32 channel;
u16 beaconperiod;
- u32 atimwindow;
+ __le16 atimwindow;
/* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */
u8 mode;
@@ -347,10 +348,10 @@ struct bss_descriptor {
unsigned long last_scanned;
- union ieeetypes_phyparamset phyparamset;
- union IEEEtypes_ssparamset ssparamset;
+ union ieee_phy_param_set phy;
+ union ieee_ss_param_set ss;
- struct ieeetypes_countryinfofullset countryinfo;
+ struct ieee_ie_country_info_full_set countryinfo;
u8 wpa_ie[MAX_WPA_IE_LEN];
size_t wpa_ie_len;
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index d4457ef808a..fe8f0cb737b 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -83,8 +83,11 @@
#define CMD_FWT_ACCESS 0x0095
#define CMD_802_11_MONITOR_MODE 0x0098
#define CMD_MESH_ACCESS 0x009b
-#define CMD_MESH_CONFIG 0x00a3
+#define CMD_MESH_CONFIG_OLD 0x00a3
+#define CMD_MESH_CONFIG 0x00ac
#define CMD_SET_BOOT2_VER 0x00a5
+#define CMD_FUNC_INIT 0x00a9
+#define CMD_FUNC_SHUTDOWN 0x00aa
#define CMD_802_11_BEACON_CTRL 0x00b0
/* For the IEEE Power Save */
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index a899aeb676b..0a2e29140ad 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -13,8 +13,19 @@
/* TxPD descriptor */
struct txpd {
- /* Current Tx packet status */
- __le32 tx_status;
+ /* union to cope up with later FW revisions */
+ union {
+ /* Current Tx packet status */
+ __le32 tx_status;
+ struct {
+ /* BSS type: client, AP, etc. */
+ u8 bss_type;
+ /* BSS number */
+ u8 bss_num;
+ /* Reserved */
+ __le16 reserved;
+ } bss;
+ } u;
/* Tx control */
__le32 tx_control;
__le32 tx_packet_location;
@@ -36,8 +47,17 @@ struct txpd {
/* RxPD Descriptor */
struct rxpd {
- /* Current Rx packet status */
- __le16 status;
+ /* union to cope up with later FW revisions */
+ union {
+ /* Current Rx packet status */
+ __le16 status;
+ struct {
+ /* BSS type: client, AP, etc. */
+ u8 bss_type;
+ /* BSS number */
+ u8 bss_num;
+ } bss;
+ } u;
/* SNR */
u8 snr;
@@ -230,7 +250,9 @@ struct cmd_ds_gspi_bus_config {
} __attribute__ ((packed));
struct cmd_ds_802_11_authenticate {
- u8 macaddr[ETH_ALEN];
+ struct cmd_header hdr;
+
+ u8 bssid[ETH_ALEN];
u8 authtype;
u8 reserved[10];
} __attribute__ ((packed));
@@ -243,22 +265,23 @@ struct cmd_ds_802_11_deauthenticate {
} __attribute__ ((packed));
struct cmd_ds_802_11_associate {
- u8 peerstaaddr[6];
+ struct cmd_header hdr;
+
+ u8 bssid[6];
__le16 capability;
__le16 listeninterval;
__le16 bcnperiod;
u8 dtimperiod;
-
-#if 0
- mrvlietypes_ssidparamset_t ssidParamSet;
- mrvlietypes_phyparamset_t phyparamset;
- mrvlietypes_ssparamset_t ssparamset;
- mrvlietypes_ratesparamset_t ratesParamSet;
-#endif
+ u8 iebuf[512]; /* Enough for required and most optional IEs */
} __attribute__ ((packed));
-struct cmd_ds_802_11_associate_rsp {
- struct ieeetypes_assocrsp assocRsp;
+struct cmd_ds_802_11_associate_response {
+ struct cmd_header hdr;
+
+ __le16 capability;
+ __le16 statuscode;
+ __le16 aid;
+ u8 iebuf[512];
} __attribute__ ((packed));
struct cmd_ds_802_11_set_wep {
@@ -515,9 +538,11 @@ struct cmd_ds_802_11_ad_hoc_start {
u8 bsstype;
__le16 beaconperiod;
u8 dtimperiod; /* Reserved on v9 and later */
- union IEEEtypes_ssparamset ssparamset;
- union ieeetypes_phyparamset phyparamset;
- __le16 probedelay;
+ struct ieee_ie_ibss_param_set ibss;
+ u8 reserved1[4];
+ struct ieee_ie_ds_param_set ds;
+ u8 reserved2[4];
+ __le16 probedelay; /* Reserved on v9 and later */
__le16 capability;
u8 rates[MAX_RATES];
u8 tlv_memory_size_pad[100];
@@ -538,8 +563,10 @@ struct adhoc_bssdesc {
u8 dtimperiod;
__le64 timestamp;
__le64 localtime;
- union ieeetypes_phyparamset phyparamset;
- union IEEEtypes_ssparamset ssparamset;
+ struct ieee_ie_ds_param_set ds;
+ u8 reserved1[4];
+ struct ieee_ie_ibss_param_set ibss;
+ u8 reserved2[4];
__le16 capability;
u8 rates[MAX_RATES];
@@ -745,8 +772,6 @@ struct cmd_ds_command {
/* command Body */
union {
struct cmd_ds_802_11_ps_mode psmode;
- struct cmd_ds_802_11_associate associate;
- struct cmd_ds_802_11_authenticate auth;
struct cmd_ds_802_11_get_stat gstat;
struct cmd_ds_802_3_get_stat gstat_8023;
struct cmd_ds_802_11_rf_antenna rant;
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index cedeac6322f..2a5b083bf9b 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -273,7 +273,28 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
*/
#define IF_CS_PRODUCT_ID 0x0000001C
#define IF_CS_CF8385_B1_REV 0x12
+#define IF_CS_CF8381_B3_REV 0x04
+/*
+ * Used to detect other cards than CF8385 since their revisions of silicon
+ * doesn't match those from CF8385, eg. CF8381 B3 works with this driver.
+ */
+#define CF8381_MANFID 0x02db
+#define CF8381_CARDID 0x6064
+#define CF8385_MANFID 0x02df
+#define CF8385_CARDID 0x8103
+
+static inline int if_cs_hw_is_cf8381(struct pcmcia_device *p_dev)
+{
+ return (p_dev->manf_id == CF8381_MANFID &&
+ p_dev->card_id == CF8381_CARDID);
+}
+
+static inline int if_cs_hw_is_cf8385(struct pcmcia_device *p_dev)
+{
+ return (p_dev->manf_id == CF8385_MANFID &&
+ p_dev->card_id == CF8385_CARDID);
+}
/********************************************************************/
/* I/O and interrupt handling */
@@ -757,6 +778,7 @@ static void if_cs_release(struct pcmcia_device *p_dev)
static int if_cs_probe(struct pcmcia_device *p_dev)
{
int ret = -ENOMEM;
+ unsigned int prod_id;
struct lbs_private *priv;
struct if_cs_card *card;
/* CIS parsing */
@@ -859,7 +881,14 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1);
/* Check if we have a current silicon */
- if (if_cs_read8(card, IF_CS_PRODUCT_ID) < IF_CS_CF8385_B1_REV) {
+ prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID);
+ if (if_cs_hw_is_cf8381(p_dev) && prod_id < IF_CS_CF8381_B3_REV) {
+ lbs_pr_err("old chips like 8381 rev B3 aren't supported\n");
+ ret = -ENODEV;
+ goto out2;
+ }
+
+ if (if_cs_hw_is_cf8385(p_dev) && prod_id < IF_CS_CF8385_B1_REV) {
lbs_pr_err("old chips like 8385 rev B1 aren't supported\n");
ret = -ENODEV;
goto out2;
@@ -950,7 +979,8 @@ static void if_cs_detach(struct pcmcia_device *p_dev)
/********************************************************************/
static struct pcmcia_device_id if_cs_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x02df, 0x8103),
+ PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID),
+ PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID),
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, if_cs_ids);
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 76f4c653d64..8cdb88c6ca2 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -39,8 +39,24 @@
#include "decl.h"
#include "defs.h"
#include "dev.h"
+#include "cmd.h"
#include "if_sdio.h"
+/* The if_sdio_remove() callback function is called when
+ * user removes this module from kernel space or ejects
+ * the card from the slot. The driver handles these 2 cases
+ * differently for SD8688 combo chip.
+ * If the user is removing the module, the FUNC_SHUTDOWN
+ * command for SD8688 is sent to the firmware.
+ * If the card is removed, there is no need to send this command.
+ *
+ * The variable 'user_rmmod' is used to distinguish these two
+ * scenarios. This flag is initialized as FALSE in case the card
+ * is removed, and will be set to TRUE for module removal when
+ * module_exit function is called.
+ */
+static u8 user_rmmod;
+
static char *lbs_helper_name = NULL;
module_param_named(helper_name, lbs_helper_name, charp, 0644);
@@ -48,8 +64,11 @@ static char *lbs_fw_name = NULL;
module_param_named(fw_name, lbs_fw_name, charp, 0644);
static const struct sdio_device_id if_sdio_ids[] = {
- { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_LIBERTAS) },
- { /* end: all zeroes */ },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL,
+ SDIO_DEVICE_ID_MARVELL_LIBERTAS) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL,
+ SDIO_DEVICE_ID_MARVELL_8688WLAN) },
+ { /* end: all zeroes */ },
};
MODULE_DEVICE_TABLE(sdio, if_sdio_ids);
@@ -63,16 +82,22 @@ struct if_sdio_model {
static struct if_sdio_model if_sdio_models[] = {
{
/* 8385 */
- .model = 0x04,
+ .model = IF_SDIO_MODEL_8385,
.helper = "sd8385_helper.bin",
.firmware = "sd8385.bin",
},
{
/* 8686 */
- .model = 0x0B,
+ .model = IF_SDIO_MODEL_8686,
.helper = "sd8686_helper.bin",
.firmware = "sd8686.bin",
},
+ {
+ /* 8688 */
+ .model = IF_SDIO_MODEL_8688,
+ .helper = "sd8688_helper.bin",
+ .firmware = "sd8688.bin",
+ },
};
struct if_sdio_packet {
@@ -87,6 +112,7 @@ struct if_sdio_card {
int model;
unsigned long ioport;
+ unsigned int scratch_reg;
const char *helper;
const char *firmware;
@@ -98,25 +124,29 @@ struct if_sdio_card {
struct workqueue_struct *workqueue;
struct work_struct packet_worker;
+
+ u8 rx_unit;
};
/********************************************************************/
/* I/O */
/********************************************************************/
+/*
+ * For SD8385/SD8686, this function reads firmware status after
+ * the image is downloaded, or reads RX packet length when
+ * interrupt (with IF_SDIO_H_INT_UPLD bit set) is received.
+ * For SD8688, this function reads firmware status only.
+ */
static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err)
{
- int ret, reg;
+ int ret;
u16 scratch;
- if (card->model == 0x04)
- reg = IF_SDIO_SCRATCH_OLD;
- else
- reg = IF_SDIO_SCRATCH;
-
- scratch = sdio_readb(card->func, reg, &ret);
+ scratch = sdio_readb(card->func, card->scratch_reg, &ret);
if (!ret)
- scratch |= sdio_readb(card->func, reg + 1, &ret) << 8;
+ scratch |= sdio_readb(card->func, card->scratch_reg + 1,
+ &ret) << 8;
if (err)
*err = ret;
@@ -127,6 +157,46 @@ static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err)
return scratch;
}
+static u8 if_sdio_read_rx_unit(struct if_sdio_card *card)
+{
+ int ret;
+ u8 rx_unit;
+
+ rx_unit = sdio_readb(card->func, IF_SDIO_RX_UNIT, &ret);
+
+ if (ret)
+ rx_unit = 0;
+
+ return rx_unit;
+}
+
+static u16 if_sdio_read_rx_len(struct if_sdio_card *card, int *err)
+{
+ int ret;
+ u16 rx_len;
+
+ switch (card->model) {
+ case IF_SDIO_MODEL_8385:
+ case IF_SDIO_MODEL_8686:
+ rx_len = if_sdio_read_scratch(card, &ret);
+ break;
+ case IF_SDIO_MODEL_8688:
+ default: /* for newer chipsets */
+ rx_len = sdio_readb(card->func, IF_SDIO_RX_LEN, &ret);
+ if (!ret)
+ rx_len <<= card->rx_unit;
+ else
+ rx_len = 0xffff; /* invalid length */
+
+ break;
+ }
+
+ if (err)
+ *err = ret;
+
+ return rx_len;
+}
+
static int if_sdio_handle_cmd(struct if_sdio_card *card,
u8 *buffer, unsigned size)
{
@@ -207,7 +277,7 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
lbs_deb_enter(LBS_DEB_SDIO);
- if (card->model == 0x04) {
+ if (card->model == IF_SDIO_MODEL_8385) {
event = sdio_readb(card->func, IF_SDIO_EVENT, &ret);
if (ret)
goto out;
@@ -245,7 +315,7 @@ static int if_sdio_card_to_host(struct if_sdio_card *card)
lbs_deb_enter(LBS_DEB_SDIO);
- size = if_sdio_read_scratch(card, &ret);
+ size = if_sdio_read_rx_len(card, &ret);
if (ret)
goto out;
@@ -488,7 +558,6 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
ret = 0;
release:
- sdio_set_block_size(card->func, 0);
sdio_release_host(card->func);
kfree(chunk_buffer);
release_fw:
@@ -624,7 +693,6 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
ret = 0;
release:
- sdio_set_block_size(card->func, 0);
sdio_release_host(card->func);
kfree(chunk_buffer);
release_fw:
@@ -653,6 +721,8 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
if (ret)
goto out;
+ lbs_deb_sdio("firmware status = %#x\n", scratch);
+
if (scratch == IF_SDIO_FIRMWARE_OK) {
lbs_deb_sdio("firmware already loaded\n");
goto success;
@@ -667,6 +737,9 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
goto out;
success:
+ sdio_claim_host(card->func);
+ sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE);
+ sdio_release_host(card->func);
ret = 0;
out:
@@ -820,10 +893,10 @@ static int if_sdio_probe(struct sdio_func *func,
if (sscanf(func->card->info[i],
"ID: %x", &model) == 1)
break;
- if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) {
- model = 4;
- break;
- }
+ if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) {
+ model = IF_SDIO_MODEL_8385;
+ break;
+ }
}
if (i == func->card->num_info) {
@@ -837,6 +910,20 @@ static int if_sdio_probe(struct sdio_func *func,
card->func = func;
card->model = model;
+
+ switch (card->model) {
+ case IF_SDIO_MODEL_8385:
+ card->scratch_reg = IF_SDIO_SCRATCH_OLD;
+ break;
+ case IF_SDIO_MODEL_8686:
+ card->scratch_reg = IF_SDIO_SCRATCH;
+ break;
+ case IF_SDIO_MODEL_8688:
+ default: /* for newer chipsets */
+ card->scratch_reg = IF_SDIO_FW_STATUS;
+ break;
+ }
+
spin_lock_init(&card->lock);
card->workqueue = create_workqueue("libertas_sdio");
INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
@@ -914,15 +1001,40 @@ static int if_sdio_probe(struct sdio_func *func,
priv->fw_ready = 1;
+ sdio_claim_host(func);
+
+ /*
+ * Get rx_unit if the chip is SD8688 or newer.
+ * SD8385 & SD8686 do not have rx_unit.
+ */
+ if ((card->model != IF_SDIO_MODEL_8385)
+ && (card->model != IF_SDIO_MODEL_8686))
+ card->rx_unit = if_sdio_read_rx_unit(card);
+ else
+ card->rx_unit = 0;
+
/*
* Enable interrupts now that everything is set up
*/
- sdio_claim_host(func);
sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret);
sdio_release_host(func);
if (ret)
goto reclaim;
+ /*
+ * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
+ */
+ if (card->model == IF_SDIO_MODEL_8688) {
+ struct cmd_header cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ lbs_deb_sdio("send function INIT command\n");
+ if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),
+ lbs_cmd_copyback, (unsigned long) &cmd))
+ lbs_pr_alert("CMD_FUNC_INIT cmd failed\n");
+ }
+
ret = lbs_start_card(priv);
if (ret)
goto err_activate_card;
@@ -968,6 +1080,22 @@ static void if_sdio_remove(struct sdio_func *func)
card = sdio_get_drvdata(func);
+ if (user_rmmod && (card->model == IF_SDIO_MODEL_8688)) {
+ /*
+ * FUNC_SHUTDOWN is required for SD8688 WLAN/BT
+ * multiple functions
+ */
+ struct cmd_header cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ lbs_deb_sdio("send function SHUTDOWN command\n");
+ if (__lbs_cmd(card->priv, CMD_FUNC_SHUTDOWN,
+ &cmd, sizeof(cmd), lbs_cmd_copyback,
+ (unsigned long) &cmd))
+ lbs_pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n");
+ }
+
card->priv->surpriseremoved = 1;
lbs_deb_sdio("call remove card\n");
@@ -1015,6 +1143,9 @@ static int __init if_sdio_init_module(void)
ret = sdio_register_driver(&if_sdio_driver);
+ /* Clear the flag in case user removes the card. */
+ user_rmmod = 0;
+
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
return ret;
@@ -1024,6 +1155,9 @@ static void __exit if_sdio_exit_module(void)
{
lbs_deb_enter(LBS_DEB_SDIO);
+ /* Set the flag as user is removing this module. */
+ user_rmmod = 1;
+
sdio_unregister_driver(&if_sdio_driver);
lbs_deb_leave(LBS_DEB_SDIO);
diff --git a/drivers/net/wireless/libertas/if_sdio.h b/drivers/net/wireless/libertas/if_sdio.h
index 533bdfbf5d2..60c9b2fcef0 100644
--- a/drivers/net/wireless/libertas/if_sdio.h
+++ b/drivers/net/wireless/libertas/if_sdio.h
@@ -12,6 +12,10 @@
#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
@@ -38,8 +42,14 @@
#define IF_SDIO_SCRATCH 0x34
#define IF_SDIO_SCRATCH_OLD 0x80fe
+#define IF_SDIO_FW_STATUS 0x40
#define IF_SDIO_FIRMWARE_OK 0xfedc
+#define IF_SDIO_RX_LEN 0x42
+#define IF_SDIO_RX_UNIT 0x43
+
#define IF_SDIO_EVENT 0x80fc
+#define IF_SDIO_BLOCK_SIZE 256
+
#endif
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 07311e71af9..f8c2898d82b 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -19,7 +19,6 @@
#include <linux/moduleparam.h>
#include <linux/firmware.h>
-#include <linux/gpio.h>
#include <linux/jiffies.h>
#include <linux/kthread.h>
#include <linux/list.h>
@@ -51,13 +50,6 @@ struct if_spi_card {
u16 card_id;
u8 card_rev;
- /* Pin number for our GPIO chip-select. */
- /* TODO: Once the generic SPI layer has some additional features, we
- * should take this out and use the normal chip select here.
- * We need support for chip select delays, and not dropping chipselect
- * after each word. */
- int gpio_cs;
-
/* The last time that we initiated an SPU operation */
unsigned long prev_xfer_time;
@@ -119,9 +111,6 @@ static struct chip_ident chip_id_to_device_name[] = {
* First we have to put a SPU register name on the bus. Then we can
* either read from or write to that register.
*
- * For 16-bit transactions, byte order on the bus is big-endian.
- * We don't have to worry about that here, though.
- * The translation takes place in the SPI routines.
*/
static void spu_transaction_init(struct if_spi_card *card)
@@ -133,12 +122,10 @@ static void spu_transaction_init(struct if_spi_card *card)
* If not, we have to busy-wait to be on the safe side. */
ndelay(400);
}
- gpio_set_value(card->gpio_cs, 0); /* assert CS */
}
static void spu_transaction_finish(struct if_spi_card *card)
{
- gpio_set_value(card->gpio_cs, 1); /* drop CS */
card->prev_xfer_time = jiffies;
}
@@ -147,7 +134,14 @@ static void spu_transaction_finish(struct if_spi_card *card)
static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
{
int err = 0;
- u16 reg_out = reg | IF_SPI_WRITE_OPERATION_MASK;
+ u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK);
+ struct spi_message m;
+ struct spi_transfer reg_trans;
+ struct spi_transfer data_trans;
+
+ spi_message_init(&m);
+ memset(&reg_trans, 0, sizeof(reg_trans));
+ memset(&data_trans, 0, sizeof(data_trans));
/* You must give an even number of bytes to the SPU, even if it
* doesn't care about the last one. */
@@ -156,29 +150,26 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
spu_transaction_init(card);
/* write SPU register index */
- err = spi_write(card->spi, (u8 *)&reg_out, sizeof(u16));
- if (err)
- goto out;
+ reg_trans.tx_buf = &reg_out;
+ reg_trans.len = sizeof(reg_out);
- err = spi_write(card->spi, buf, len);
+ data_trans.tx_buf = buf;
+ data_trans.len = len;
-out:
+ spi_message_add_tail(&reg_trans, &m);
+ spi_message_add_tail(&data_trans, &m);
+
+ err = spi_sync(card->spi, &m);
spu_transaction_finish(card);
return err;
}
static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val)
{
- return spu_write(card, reg, (u8 *)&val, sizeof(u16));
-}
+ u16 buff;
-static inline int spu_write_u32(struct if_spi_card *card, u16 reg, u32 val)
-{
- /* The lower 16 bits are written first. */
- u16 out[2];
- out[0] = val & 0xffff;
- out[1] = (val & 0xffff0000) >> 16;
- return spu_write(card, reg, (u8 *)&out, sizeof(u32));
+ buff = cpu_to_le16(val);
+ return spu_write(card, reg, (u8 *)&buff, sizeof(u16));
}
static inline int spu_reg_is_port_reg(u16 reg)
@@ -195,10 +186,13 @@ static inline int spu_reg_is_port_reg(u16 reg)
static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
{
- unsigned int i, delay;
+ unsigned int delay;
int err = 0;
- u16 zero = 0;
- u16 reg_out = reg | IF_SPI_READ_OPERATION_MASK;
+ u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK);
+ struct spi_message m;
+ struct spi_transfer reg_trans;
+ struct spi_transfer dummy_trans;
+ struct spi_transfer data_trans;
/* You must take an even number of bytes from the SPU, even if you
* don't care about the last one. */
@@ -206,29 +200,34 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
spu_transaction_init(card);
+ spi_message_init(&m);
+ memset(&reg_trans, 0, sizeof(reg_trans));
+ memset(&dummy_trans, 0, sizeof(dummy_trans));
+ memset(&data_trans, 0, sizeof(data_trans));
+
/* write SPU register index */
- err = spi_write(card->spi, (u8 *)&reg_out, sizeof(u16));
- if (err)
- goto out;
+ reg_trans.tx_buf = &reg_out;
+ reg_trans.len = sizeof(reg_out);
+ spi_message_add_tail(&reg_trans, &m);
delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay :
card->spu_reg_delay;
if (card->use_dummy_writes) {
/* Clock in dummy cycles while the SPU fills the FIFO */
- for (i = 0; i < delay / 16; ++i) {
- err = spi_write(card->spi, (u8 *)&zero, sizeof(u16));
- if (err)
- return err;
- }
+ dummy_trans.len = delay / 8;
+ spi_message_add_tail(&dummy_trans, &m);
} else {
/* Busy-wait while the SPU fills the FIFO */
- ndelay(100 + (delay * 10));
+ reg_trans.delay_usecs =
+ DIV_ROUND_UP((100 + (delay * 10)), 1000);
}
/* read in data */
- err = spi_read(card->spi, buf, len);
+ data_trans.rx_buf = buf;
+ data_trans.len = len;
+ spi_message_add_tail(&data_trans, &m);
-out:
+ err = spi_sync(card->spi, &m);
spu_transaction_finish(card);
return err;
}
@@ -236,18 +235,25 @@ out:
/* Read 16 bits from an SPI register */
static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
{
- return spu_read(card, reg, (u8 *)val, sizeof(u16));
+ u16 buf;
+ int ret;
+
+ ret = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
+ if (ret == 0)
+ *val = le16_to_cpup(&buf);
+ return ret;
}
/* Read 32 bits from an SPI register.
* The low 16 bits are read first. */
static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
{
- u16 buf[2];
+ u32 buf;
int err;
- err = spu_read(card, reg, (u8 *)buf, sizeof(u32));
+
+ err = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
if (!err)
- *val = buf[0] | (buf[1] << 16);
+ *val = le32_to_cpup(&buf);
return err;
}
@@ -731,7 +737,7 @@ static int if_spi_c2h_data(struct if_spi_card *card)
goto out;
} else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
lbs_pr_err("%s: error: card has %d bytes of data, but "
- "our maximum skb size is %u\n",
+ "our maximum skb size is %lu\n",
__func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
err = -EINVAL;
goto out;
@@ -814,6 +820,13 @@ static void if_spi_e2h(struct if_spi_card *card)
if (err)
goto out;
+ /* re-enable the card event interrupt */
+ spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG,
+ ~IF_SPI_HICU_CARD_EVENT);
+
+ /* generate a card interrupt */
+ spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, IF_SPI_CIC_HOST_EVENT);
+
spin_lock_irqsave(&priv->driver_lock, flags);
lbs_queue_event(priv, cause & 0xff);
spin_unlock_irqrestore(&priv->driver_lock, flags);
@@ -1020,6 +1033,7 @@ static int __devinit if_spi_probe(struct spi_device *spi)
struct libertas_spi_platform_data *pdata = spi->dev.platform_data;
int err = 0;
u32 scratch;
+ struct sched_param param = { .sched_priority = 1 };
lbs_deb_enter(LBS_DEB_SPI);
@@ -1043,7 +1057,6 @@ static int __devinit if_spi_probe(struct spi_device *spi)
spi_set_drvdata(spi, card);
card->pdata = pdata;
card->spi = spi;
- card->gpio_cs = pdata->gpio_cs;
card->prev_xfer_time = jiffies;
sema_init(&card->spi_ready, 0);
@@ -1052,26 +1065,18 @@ static int __devinit if_spi_probe(struct spi_device *spi)
INIT_LIST_HEAD(&card->data_packet_list);
spin_lock_init(&card->buffer_lock);
- /* set up GPIO CS line. TODO: use regular CS line */
- err = gpio_request(card->gpio_cs, "if_spi_gpio_chip_select");
- if (err)
- goto free_card;
- err = gpio_direction_output(card->gpio_cs, 1);
- if (err)
- goto free_gpio;
-
/* Initialize the SPI Interface Unit */
err = spu_init(card, pdata->use_dummy_writes);
if (err)
- goto free_gpio;
+ goto free_card;
err = spu_get_chip_revision(card, &card->card_id, &card->card_rev);
if (err)
- goto free_gpio;
+ goto free_card;
/* Firmware load */
err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch);
if (err)
- goto free_gpio;
+ goto free_card;
if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC)
lbs_deb_spi("Firmware is already loaded for "
"Marvell WLAN 802.11 adapter\n");
@@ -1079,7 +1084,7 @@ static int __devinit if_spi_probe(struct spi_device *spi)
err = if_spi_calculate_fw_names(card->card_id,
card->helper_fw_name, card->main_fw_name);
if (err)
- goto free_gpio;
+ goto free_card;
lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter "
"(chip_id = 0x%04x, chip_rev = 0x%02x) "
@@ -1090,23 +1095,23 @@ static int __devinit if_spi_probe(struct spi_device *spi)
spi->max_speed_hz);
err = if_spi_prog_helper_firmware(card);
if (err)
- goto free_gpio;
+ goto free_card;
err = if_spi_prog_main_firmware(card);
if (err)
- goto free_gpio;
+ goto free_card;
lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n");
}
err = spu_set_interrupt_mode(card, 0, 1);
if (err)
- goto free_gpio;
+ goto free_card;
/* Register our card with libertas.
* This will call alloc_etherdev */
priv = lbs_add_card(card, &spi->dev);
if (!priv) {
err = -ENOMEM;
- goto free_gpio;
+ goto free_card;
}
card->priv = priv;
priv->card = card;
@@ -1123,6 +1128,9 @@ static int __devinit if_spi_probe(struct spi_device *spi)
lbs_pr_err("error creating SPI thread: err=%d\n", err);
goto remove_card;
}
+ if (sched_setscheduler(card->spi_thread, SCHED_FIFO, &param))
+ lbs_pr_err("Error setting scheduler, using default.\n");
+
err = request_irq(spi->irq, if_spi_host_interrupt,
IRQF_TRIGGER_FALLING, "libertas_spi", card);
if (err) {
@@ -1148,8 +1156,6 @@ terminate_thread:
if_spi_terminate_spi_thread(card);
remove_card:
lbs_remove_card(priv); /* will call free_netdev */
-free_gpio:
- gpio_free(card->gpio_cs);
free_card:
free_if_spi_card(card);
out:
@@ -1170,7 +1176,6 @@ static int __devexit libertas_spi_remove(struct spi_device *spi)
free_irq(spi->irq, card);
if_spi_terminate_spi_thread(card);
lbs_remove_card(priv); /* will call free_netdev */
- gpio_free(card->gpio_cs);
if (card->pdata->teardown)
card->pdata->teardown(spi);
free_if_spi_card(card);
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index ea3dc038be7..d649caebf08 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -686,8 +686,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
return;
}
- if (!in_interrupt())
- BUG();
+ BUG_ON(!in_interrupt());
spin_lock(&priv->driver_lock);
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 8ae935ac32f..89575e44801 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1307,8 +1307,10 @@ int lbs_start_card(struct lbs_private *priv)
lbs_update_channel(priv);
- /* 5.0.16p0 is known to NOT support any mesh */
- if (priv->fwrelease > 0x05001000) {
+ /* Check mesh FW version and appropriately send the mesh start
+ * command
+ */
+ if (priv->mesh_fw_ver == MESH_FW_OLD) {
/* Enable mesh, if supported, and work out which TLV it uses.
0x100 + 291 is an unofficial value used in 5.110.20.pXX
0x100 + 37 is the official value used in 5.110.21.pXX
@@ -1322,27 +1324,35 @@ int lbs_start_card(struct lbs_private *priv)
It's just that 5.110.20.pXX will not have done anything
useful */
- priv->mesh_tlv = 0x100 + 291;
+ priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
priv->curbssparams.channel)) {
- priv->mesh_tlv = 0x100 + 37;
+ priv->mesh_tlv = TLV_TYPE_MESH_ID;
if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
priv->curbssparams.channel))
priv->mesh_tlv = 0;
}
- if (priv->mesh_tlv) {
- lbs_add_mesh(priv);
-
- if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
- lbs_pr_err("cannot register lbs_mesh attribute\n");
-
- /* While rtap isn't related to mesh, only mesh-enabled
- * firmware implements the rtap functionality via
- * CMD_802_11_MONITOR_MODE.
- */
- if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
- lbs_pr_err("cannot register lbs_rtap attribute\n");
- }
+ } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
+ /* 10.0.0.pXX new firmwares should succeed with TLV
+ * 0x100+37; Do not invoke command with old TLV.
+ */
+ priv->mesh_tlv = TLV_TYPE_MESH_ID;
+ if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->curbssparams.channel))
+ priv->mesh_tlv = 0;
+ }
+ if (priv->mesh_tlv) {
+ lbs_add_mesh(priv);
+
+ if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
+ lbs_pr_err("cannot register lbs_mesh attribute\n");
+
+ /* While rtap isn't related to mesh, only mesh-enabled
+ * firmware implements the rtap functionality via
+ * CMD_802_11_MONITOR_MODE.
+ */
+ if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
+ lbs_pr_err("cannot register lbs_rtap attribute\n");
}
lbs_debugfs_init_one(priv, dev);
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 8e669775cb5..65f02cc6752 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -25,7 +25,6 @@ struct rfc1042hdr {
} __attribute__ ((packed));
struct rxpackethdr {
- struct rxpd rx_pd;
struct eth803hdr eth803_hdr;
struct rfc1042hdr rfc1042_hdr;
} __attribute__ ((packed));
@@ -158,10 +157,18 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
if (priv->monitormode)
return process_rxed_802_11_packet(priv, skb);
- p_rx_pkt = (struct rxpackethdr *) skb->data;
- p_rx_pd = &p_rx_pkt->rx_pd;
- if (priv->mesh_dev && (p_rx_pd->rx_control & RxPD_MESH_FRAME))
- dev = priv->mesh_dev;
+ p_rx_pd = (struct rxpd *) skb->data;
+ p_rx_pkt = (struct rxpackethdr *) ((u8 *)p_rx_pd +
+ le32_to_cpu(p_rx_pd->pkt_ptr));
+ if (priv->mesh_dev) {
+ if (priv->mesh_fw_ver == MESH_FW_OLD) {
+ if (p_rx_pd->rx_control & RxPD_MESH_FRAME)
+ dev = priv->mesh_dev;
+ } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
+ if (p_rx_pd->u.bss.bss_num == MESH_IFACE_ID)
+ dev = priv->mesh_dev;
+ }
+ }
lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data,
min_t(unsigned int, skb->len, 100));
@@ -174,20 +181,9 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
goto done;
}
- /*
- * Check rxpd status and update 802.3 stat,
- */
- if (!(p_rx_pd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
- lbs_deb_rx("rx err: frame received with bad status\n");
- lbs_pr_alert("rxpd not ok\n");
- dev->stats.rx_errors++;
- ret = 0;
- dev_kfree_skb(skb);
- goto done;
- }
-
- lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
- skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
+ lbs_deb_rx("rx data: skb->len - pkt_ptr = %d-%zd = %zd\n",
+ skb->len, (size_t)le32_to_cpu(p_rx_pd->pkt_ptr),
+ skb->len - (size_t)le32_to_cpu(p_rx_pd->pkt_ptr));
lbs_deb_hex(LBS_DEB_RX, "RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr,
sizeof(p_rx_pkt->eth803_hdr.dest_addr));
@@ -221,14 +217,14 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
/* Chop off the rxpd + the excess memory from the 802.2/llc/snap header
* that was removed
*/
- hdrchop = (u8 *) p_ethhdr - (u8 *) p_rx_pkt;
+ hdrchop = (u8 *)p_ethhdr - (u8 *)p_rx_pd;
} else {
lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP",
(u8 *) & p_rx_pkt->rfc1042_hdr,
sizeof(p_rx_pkt->rfc1042_hdr));
/* Chop off the rxpd */
- hdrchop = (u8 *) & p_rx_pkt->eth803_hdr - (u8 *) p_rx_pkt;
+ hdrchop = (u8 *)&p_rx_pkt->eth803_hdr - (u8 *)p_rx_pd;
}
/* Chop off the leading header bytes so the skb points to the start of
@@ -334,14 +330,6 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
goto done;
}
- /*
- * Check rxpd status and update 802.3 stat,
- */
- if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
- //lbs_deb_rx("rx err: frame received with bad status\n");
- dev->stats.rx_errors++;
- }
-
lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
@@ -353,8 +341,6 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
radiotap_hdr.hdr.it_pad = 0;
radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));
radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);
- if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
- radiotap_hdr.flags |= IEEE80211_RADIOTAP_F_BADFCS;
radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
/* XXX must check no carryout */
radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 8124db36aaf..601b5424967 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -27,12 +27,12 @@
+ 40) /* 40 for WPAIE */
//! Memory needed to store a max sized channel List TLV for a firmware scan
-#define CHAN_TLV_MAX_SIZE (sizeof(struct mrvlietypesheader) \
+#define CHAN_TLV_MAX_SIZE (sizeof(struct mrvl_ie_header) \
+ (MRVDRV_MAX_CHANNELS_PER_SCAN \
* sizeof(struct chanscanparamset)))
//! Memory needed to store a max number/size SSID TLV for a firmware scan
-#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvlietypes_ssidparamset))
+#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvl_ie_ssid_param_set))
//! Maximum memory needed for a cmd_ds_802_11_scan with all TLVs at max
#define MAX_SCAN_CFG_ALLOC (sizeof(struct cmd_ds_802_11_scan) \
@@ -211,7 +211,7 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv,
*/
static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv)
{
- struct mrvlietypes_ssidparamset *ssid_tlv = (void *)tlv;
+ struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv;
ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
ssid_tlv->header.len = cpu_to_le16(priv->scan_ssid_len);
@@ -249,7 +249,7 @@ static int lbs_scan_add_chanlist_tlv(uint8_t *tlv,
int chan_count)
{
size_t size = sizeof(struct chanscanparamset) *chan_count;
- struct mrvlietypes_chanlistparamset *chan_tlv = (void *)tlv;
+ struct mrvl_ie_chanlist_param_set *chan_tlv = (void *)tlv;
chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
memcpy(chan_tlv->chanscanparam, chan_list, size);
@@ -270,7 +270,7 @@ static int lbs_scan_add_chanlist_tlv(uint8_t *tlv,
static int lbs_scan_add_rates_tlv(uint8_t *tlv)
{
int i;
- struct mrvlietypes_ratesparamset *rate_tlv = (void *)tlv;
+ struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
tlv += sizeof(rate_tlv->header);
@@ -513,12 +513,12 @@ void lbs_scan_worker(struct work_struct *work)
static int lbs_process_bss(struct bss_descriptor *bss,
uint8_t **pbeaconinfo, int *bytesleft)
{
- struct ieeetypes_fhparamset *pFH;
- struct ieeetypes_dsparamset *pDS;
- struct ieeetypes_cfparamset *pCF;
- struct ieeetypes_ibssparamset *pibss;
+ struct ieee_ie_fh_param_set *fh;
+ struct ieee_ie_ds_param_set *ds;
+ struct ieee_ie_cf_param_set *cf;
+ struct ieee_ie_ibss_param_set *ibss;
DECLARE_SSID_BUF(ssid);
- struct ieeetypes_countryinfoset *pcountryinfo;
+ struct ieee_ie_country_info_set *pcountryinfo;
uint8_t *pos, *end, *p;
uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0;
uint16_t beaconsize = 0;
@@ -616,50 +616,49 @@ static int lbs_process_bss(struct bss_descriptor *bss,
break;
case WLAN_EID_FH_PARAMS:
- pFH = (struct ieeetypes_fhparamset *) pos;
- memmove(&bss->phyparamset.fhparamset, pFH,
- sizeof(struct ieeetypes_fhparamset));
+ fh = (struct ieee_ie_fh_param_set *) pos;
+ memcpy(&bss->phy.fh, fh, sizeof(*fh));
lbs_deb_scan("got FH IE\n");
break;
case WLAN_EID_DS_PARAMS:
- pDS = (struct ieeetypes_dsparamset *) pos;
- bss->channel = pDS->currentchan;
- memcpy(&bss->phyparamset.dsparamset, pDS,
- sizeof(struct ieeetypes_dsparamset));
+ ds = (struct ieee_ie_ds_param_set *) pos;
+ bss->channel = ds->channel;
+ memcpy(&bss->phy.ds, ds, sizeof(*ds));
lbs_deb_scan("got DS IE, channel %d\n", bss->channel);
break;
case WLAN_EID_CF_PARAMS:
- pCF = (struct ieeetypes_cfparamset *) pos;
- memcpy(&bss->ssparamset.cfparamset, pCF,
- sizeof(struct ieeetypes_cfparamset));
+ cf = (struct ieee_ie_cf_param_set *) pos;
+ memcpy(&bss->ss.cf, cf, sizeof(*cf));
lbs_deb_scan("got CF IE\n");
break;
case WLAN_EID_IBSS_PARAMS:
- pibss = (struct ieeetypes_ibssparamset *) pos;
- bss->atimwindow = le16_to_cpu(pibss->atimwindow);
- memmove(&bss->ssparamset.ibssparamset, pibss,
- sizeof(struct ieeetypes_ibssparamset));
+ ibss = (struct ieee_ie_ibss_param_set *) pos;
+ bss->atimwindow = ibss->atimwindow;
+ memcpy(&bss->ss.ibss, ibss, sizeof(*ibss));
lbs_deb_scan("got IBSS IE\n");
break;
case WLAN_EID_COUNTRY:
- pcountryinfo = (struct ieeetypes_countryinfoset *) pos;
+ pcountryinfo = (struct ieee_ie_country_info_set *) pos;
lbs_deb_scan("got COUNTRY IE\n");
- if (pcountryinfo->len < sizeof(pcountryinfo->countrycode)
- || pcountryinfo->len > 254) {
- lbs_deb_scan("process_bss: 11D- Err CountryInfo len %d, min %zd, max 254\n",
- pcountryinfo->len, sizeof(pcountryinfo->countrycode));
+ if (pcountryinfo->header.len < sizeof(pcountryinfo->countrycode)
+ || pcountryinfo->header.len > 254) {
+ lbs_deb_scan("%s: 11D- Err CountryInfo len %d, min %zd, max 254\n",
+ __func__,
+ pcountryinfo->header.len,
+ sizeof(pcountryinfo->countrycode));
ret = -1;
goto done;
}
- memcpy(&bss->countryinfo, pcountryinfo, pcountryinfo->len + 2);
+ memcpy(&bss->countryinfo, pcountryinfo,
+ pcountryinfo->header.len + 2);
lbs_deb_hex(LBS_DEB_SCAN, "process_bss: 11d countryinfo",
(uint8_t *) pcountryinfo,
- (int) (pcountryinfo->len + 2));
+ (int) (pcountryinfo->header.len + 2));
break;
case WLAN_EID_EXT_SUPP_RATES:
@@ -1130,7 +1129,7 @@ static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
goto done;
}
- bytesleft = le16_to_cpu(scanresp->bssdescriptsize);
+ bytesleft = get_unaligned_le16(&scanresp->bssdescriptsize);
lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft);
scanrespsize = le16_to_cpu(resp->size);
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index f10aa39a6b6..160cfd8311c 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -132,8 +132,12 @@ int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
txpd->tx_packet_length = cpu_to_le16(pkt_len);
txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
- if (dev == priv->mesh_dev)
- txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
+ if (dev == priv->mesh_dev) {
+ if (priv->mesh_fw_ver == MESH_FW_OLD)
+ txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
+ else if (priv->mesh_fw_ver == MESH_FW_NEW)
+ txpd->u.bss.bss_num = MESH_IFACE_ID;
+ }
lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) &txpd, sizeof(struct txpd));
diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h
index fb7a2d1a252..99905df65b2 100644
--- a/drivers/net/wireless/libertas/types.h
+++ b/drivers/net/wireless/libertas/types.h
@@ -8,9 +8,14 @@
#include <asm/byteorder.h>
#include <linux/wireless.h>
-struct ieeetypes_cfparamset {
- u8 elementid;
+struct ieee_ie_header {
+ u8 id;
u8 len;
+} __attribute__ ((packed));
+
+struct ieee_ie_cf_param_set {
+ struct ieee_ie_header header;
+
u8 cfpcnt;
u8 cfpperiod;
__le16 cfpmaxduration;
@@ -18,42 +23,35 @@ struct ieeetypes_cfparamset {
} __attribute__ ((packed));
-struct ieeetypes_ibssparamset {
- u8 elementid;
- u8 len;
+struct ieee_ie_ibss_param_set {
+ struct ieee_ie_header header;
+
__le16 atimwindow;
} __attribute__ ((packed));
-union IEEEtypes_ssparamset {
- struct ieeetypes_cfparamset cfparamset;
- struct ieeetypes_ibssparamset ibssparamset;
+union ieee_ss_param_set {
+ struct ieee_ie_cf_param_set cf;
+ struct ieee_ie_ibss_param_set ibss;
} __attribute__ ((packed));
-struct ieeetypes_fhparamset {
- u8 elementid;
- u8 len;
+struct ieee_ie_fh_param_set {
+ struct ieee_ie_header header;
+
__le16 dwelltime;
u8 hopset;
u8 hoppattern;
u8 hopindex;
} __attribute__ ((packed));
-struct ieeetypes_dsparamset {
- u8 elementid;
- u8 len;
- u8 currentchan;
-} __attribute__ ((packed));
+struct ieee_ie_ds_param_set {
+ struct ieee_ie_header header;
-union ieeetypes_phyparamset {
- struct ieeetypes_fhparamset fhparamset;
- struct ieeetypes_dsparamset dsparamset;
+ u8 channel;
} __attribute__ ((packed));
-struct ieeetypes_assocrsp {
- __le16 capability;
- __le16 statuscode;
- __le16 aid;
- u8 iebuffer[1];
+union ieee_phy_param_set {
+ struct ieee_ie_fh_param_set fh;
+ struct ieee_ie_ds_param_set ds;
} __attribute__ ((packed));
/** TLV type ID definition */
@@ -94,30 +92,33 @@ struct ieeetypes_assocrsp {
#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19)
#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22)
#define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 23)
+#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31)
+#define TLV_TYPE_MESH_ID (PROPRIETARY_TLV_BASE_ID + 37)
+#define TLV_TYPE_OLD_MESH_ID (PROPRIETARY_TLV_BASE_ID + 291)
/** TLV related data structures*/
-struct mrvlietypesheader {
+struct mrvl_ie_header {
__le16 type;
__le16 len;
} __attribute__ ((packed));
-struct mrvlietypes_data {
- struct mrvlietypesheader header;
+struct mrvl_ie_data {
+ struct mrvl_ie_header header;
u8 Data[1];
} __attribute__ ((packed));
-struct mrvlietypes_ratesparamset {
- struct mrvlietypesheader header;
+struct mrvl_ie_rates_param_set {
+ struct mrvl_ie_header header;
u8 rates[1];
} __attribute__ ((packed));
-struct mrvlietypes_ssidparamset {
- struct mrvlietypesheader header;
+struct mrvl_ie_ssid_param_set {
+ struct mrvl_ie_header header;
u8 ssid[1];
} __attribute__ ((packed));
-struct mrvlietypes_wildcardssidparamset {
- struct mrvlietypesheader header;
+struct mrvl_ie_wildcard_ssid_param_set {
+ struct mrvl_ie_header header;
u8 MaxSsidlength;
u8 ssid[1];
} __attribute__ ((packed));
@@ -142,91 +143,72 @@ struct chanscanparamset {
__le16 maxscantime;
} __attribute__ ((packed));
-struct mrvlietypes_chanlistparamset {
- struct mrvlietypesheader header;
+struct mrvl_ie_chanlist_param_set {
+ struct mrvl_ie_header header;
struct chanscanparamset chanscanparam[1];
} __attribute__ ((packed));
-struct cfparamset {
+struct mrvl_ie_cf_param_set {
+ struct mrvl_ie_header header;
u8 cfpcnt;
u8 cfpperiod;
__le16 cfpmaxduration;
__le16 cfpdurationremaining;
} __attribute__ ((packed));
-struct ibssparamset {
- __le16 atimwindow;
-} __attribute__ ((packed));
-
-struct mrvlietypes_ssparamset {
- struct mrvlietypesheader header;
- union {
- struct cfparamset cfparamset[1];
- struct ibssparamset ibssparamset[1];
- } cf_ibss;
+struct mrvl_ie_ds_param_set {
+ struct mrvl_ie_header header;
+ u8 channel;
} __attribute__ ((packed));
-struct fhparamset {
- __le16 dwelltime;
- u8 hopset;
- u8 hoppattern;
- u8 hopindex;
-} __attribute__ ((packed));
-
-struct dsparamset {
- u8 currentchan;
-} __attribute__ ((packed));
-
-struct mrvlietypes_phyparamset {
- struct mrvlietypesheader header;
- union {
- struct fhparamset fhparamset[1];
- struct dsparamset dsparamset[1];
- } fh_ds;
-} __attribute__ ((packed));
-
-struct mrvlietypes_rsnparamset {
- struct mrvlietypesheader header;
+struct mrvl_ie_rsn_param_set {
+ struct mrvl_ie_header header;
u8 rsnie[1];
} __attribute__ ((packed));
-struct mrvlietypes_tsftimestamp {
- struct mrvlietypesheader header;
+struct mrvl_ie_tsf_timestamp {
+ struct mrvl_ie_header header;
__le64 tsftable[1];
} __attribute__ ((packed));
+/* v9 and later firmware only */
+struct mrvl_ie_auth_type {
+ struct mrvl_ie_header header;
+ __le16 auth;
+} __attribute__ ((packed));
+
/** Local Power capability */
-struct mrvlietypes_powercapability {
- struct mrvlietypesheader header;
+struct mrvl_ie_power_capability {
+ struct mrvl_ie_header header;
s8 minpower;
s8 maxpower;
} __attribute__ ((packed));
/* used in CMD_802_11_SUBSCRIBE_EVENT for SNR, RSSI and Failure */
-struct mrvlietypes_thresholds {
- struct mrvlietypesheader header;
+struct mrvl_ie_thresholds {
+ struct mrvl_ie_header header;
u8 value;
u8 freq;
} __attribute__ ((packed));
-struct mrvlietypes_beaconsmissed {
- struct mrvlietypesheader header;
+struct mrvl_ie_beacons_missed {
+ struct mrvl_ie_header header;
u8 beaconmissed;
u8 reserved;
} __attribute__ ((packed));
-struct mrvlietypes_numprobes {
- struct mrvlietypesheader header;
+struct mrvl_ie_num_probes {
+ struct mrvl_ie_header header;
__le16 numprobes;
} __attribute__ ((packed));
-struct mrvlietypes_bcastprobe {
- struct mrvlietypesheader header;
+struct mrvl_ie_bcast_probe {
+ struct mrvl_ie_header header;
__le16 bcastprobe;
} __attribute__ ((packed));
-struct mrvlietypes_numssidprobe {
- struct mrvlietypesheader header;
+struct mrvl_ie_num_ssid_probe {
+ struct mrvl_ie_header header;
__le16 numssidprobe;
} __attribute__ ((packed));
@@ -235,8 +217,8 @@ struct led_pin {
u8 pin;
} __attribute__ ((packed));
-struct mrvlietypes_ledgpio {
- struct mrvlietypesheader header;
+struct mrvl_ie_ledgpio {
+ struct mrvl_ie_header header;
struct led_pin ledpin[1];
} __attribute__ ((packed));
@@ -248,8 +230,8 @@ struct led_bhv {
} __attribute__ ((packed));
-struct mrvlietypes_ledbhv {
- struct mrvlietypesheader header;
+struct mrvl_ie_ledbhv {
+ struct mrvl_ie_header header;
struct led_bhv ledbhv[1];
} __attribute__ ((packed));
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c
index 59634c33b1f..392337b37b1 100644
--- a/drivers/net/wireless/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/libertas_tf/if_usb.c
@@ -461,8 +461,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
return;
}
- if (!in_interrupt())
- BUG();
+ BUG_ON(!in_interrupt());
spin_lock(&priv->driver_lock);
memcpy(priv->cmd_resp_buff, recvbuff + MESSAGE_HEADER_LEN,
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index e7289e2e7f1..10a99e26d39 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -366,36 +366,6 @@ static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed)
return 0;
}
-static int lbtf_op_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct lbtf_private *priv = hw->priv;
- struct sk_buff *beacon;
-
- switch (priv->vif->type) {
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_MESH_POINT:
- beacon = ieee80211_beacon_get(hw, vif);
- if (beacon) {
- lbtf_beacon_set(priv, beacon);
- kfree_skb(beacon);
- lbtf_beacon_ctrl(priv, 1, hw->conf.beacon_int);
- }
- break;
- default:
- break;
- }
-
- if (conf->bssid) {
- u8 null_bssid[ETH_ALEN] = {0};
- bool activate = compare_ether_addr(conf->bssid, null_bssid);
- lbtf_set_bssid(priv, activate, conf->bssid);
- }
-
- return 0;
-}
-
#define SUPPORTED_FIF_FLAGS (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)
static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
@@ -451,6 +421,29 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
u32 changes)
{
struct lbtf_private *priv = hw->priv;
+ struct sk_buff *beacon;
+
+ if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_INT)) {
+ switch (priv->vif->type) {
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_MESH_POINT:
+ beacon = ieee80211_beacon_get(hw, vif);
+ if (beacon) {
+ lbtf_beacon_set(priv, beacon);
+ kfree_skb(beacon);
+ lbtf_beacon_ctrl(priv, 1,
+ bss_conf->beacon_int);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (changes & BSS_CHANGED_BSSID) {
+ bool activate = !is_zero_ether_addr(bss_conf->bssid);
+ lbtf_set_bssid(priv, activate, bss_conf->bssid);
+ }
if (changes & BSS_CHANGED_ERP_PREAMBLE) {
if (bss_conf->use_short_preamble)
@@ -459,8 +452,6 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
priv->preamble = CMD_TYPE_LONG_PREAMBLE;
lbtf_set_radio_control(priv);
}
-
- return;
}
static const struct ieee80211_ops lbtf_ops = {
@@ -470,7 +461,6 @@ static const struct ieee80211_ops lbtf_ops = {
.add_interface = lbtf_op_add_interface,
.remove_interface = lbtf_op_remove_interface,
.config = lbtf_op_config,
- .config_interface = lbtf_op_config_interface,
.configure_filter = lbtf_op_configure_filter,
.bss_info_changed = lbtf_op_bss_info_changed,
};
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index d4fdc8b7d7d..e789c6e9938 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -280,7 +280,6 @@ struct mac80211_hwsim_data {
struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
struct ieee80211_channel *channel;
- int radio_enabled;
unsigned long beacon_int; /* in jiffies unit */
unsigned int rx_filter;
int started;
@@ -291,6 +290,14 @@ struct mac80211_hwsim_data {
bool ps_poll_pending;
struct dentry *debugfs;
struct dentry *debugfs_ps;
+
+ /*
+ * Only radios in the same group can communicate together (the
+ * channel has to match too). Each bit represents a group. A
+ * radio can be in more then one group.
+ */
+ u64 group;
+ struct dentry *debugfs_group;
};
@@ -410,9 +417,9 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
if (data == data2)
continue;
- if (!data2->started || !data2->radio_enabled ||
- !hwsim_ps_rx_ok(data2, skb) ||
- data->channel->center_freq != data2->channel->center_freq)
+ if (!data2->started || !hwsim_ps_rx_ok(data2, skb) ||
+ data->channel->center_freq != data2->channel->center_freq ||
+ !(data->group & data2->group))
continue;
nskb = skb_copy(skb, GFP_ATOMIC);
@@ -432,7 +439,6 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
- struct mac80211_hwsim_data *data = hw->priv;
bool ack;
struct ieee80211_tx_info *txi;
@@ -444,13 +450,6 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}
- if (!data->radio_enabled) {
- printk(KERN_DEBUG "%s: dropped TX frame since radio "
- "disabled\n", wiphy_name(hw->wiphy));
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
- }
-
ack = mac80211_hwsim_tx_frame(hw, skb);
txi = IEEE80211_SKB_CB(skb);
@@ -537,7 +536,7 @@ static void mac80211_hwsim_beacon(unsigned long arg)
struct ieee80211_hw *hw = (struct ieee80211_hw *) arg;
struct mac80211_hwsim_data *data = hw->priv;
- if (!data->started || !data->radio_enabled)
+ if (!data->started)
return;
ieee80211_iterate_active_interfaces_atomic(
@@ -553,18 +552,14 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
struct mac80211_hwsim_data *data = hw->priv;
struct ieee80211_conf *conf = &hw->conf;
- printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d beacon_int=%d)\n",
+ printk(KERN_DEBUG "%s:%s (freq=%d idle=%d ps=%d)\n",
wiphy_name(hw->wiphy), __func__,
- conf->channel->center_freq, conf->radio_enabled,
- conf->beacon_int);
+ conf->channel->center_freq,
+ !!(conf->flags & IEEE80211_CONF_IDLE),
+ !!(conf->flags & IEEE80211_CONF_PS));
data->channel = conf->channel;
- data->radio_enabled = conf->radio_enabled;
- data->beacon_int = 1024 * conf->beacon_int / 1000 * HZ / 1000;
- if (data->beacon_int < 1)
- data->beacon_int = 1;
-
- if (!data->started || !data->radio_enabled)
+ if (!data->started || !data->beacon_int)
del_timer(&data->beacon_timer);
else
mod_timer(&data->beacon_timer, jiffies + data->beacon_int);
@@ -592,35 +587,26 @@ static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw,
*total_flags = data->rx_filter;
}
-static int mac80211_hwsim_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
-
- hwsim_check_magic(vif);
- if (conf->changed & IEEE80211_IFCC_BSSID) {
- DECLARE_MAC_BUF(mac);
- printk(KERN_DEBUG "%s:%s: BSSID changed: %pM\n",
- wiphy_name(hw->wiphy), __func__,
- conf->bssid);
- memcpy(vp->bssid, conf->bssid, ETH_ALEN);
- }
- return 0;
-}
-
static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info,
u32 changed)
{
struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
+ struct mac80211_hwsim_data *data = hw->priv;
hwsim_check_magic(vif);
printk(KERN_DEBUG "%s:%s(changed=0x%x)\n",
wiphy_name(hw->wiphy), __func__, changed);
+ if (changed & BSS_CHANGED_BSSID) {
+ printk(KERN_DEBUG "%s:%s: BSSID changed: %pM\n",
+ wiphy_name(hw->wiphy), __func__,
+ info->bssid);
+ memcpy(vp->bssid, info->bssid, ETH_ALEN);
+ }
+
if (changed & BSS_CHANGED_ASSOC) {
printk(KERN_DEBUG " %s: ASSOC: assoc=%d aid=%d\n",
wiphy_name(hw->wiphy), info->assoc, info->aid);
@@ -628,6 +614,14 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
vp->aid = info->aid;
}
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ printk(KERN_DEBUG " %s: BCNINT: %d\n",
+ wiphy_name(hw->wiphy), info->beacon_int);
+ data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000;
+ if (WARN_ON(!data->beacon_int))
+ data->beacon_int = 1;
+ }
+
if (changed & BSS_CHANGED_ERP_CTS_PROT) {
printk(KERN_DEBUG " %s: ERP_CTS_PROT: %d\n",
wiphy_name(hw->wiphy), info->use_cts_prot);
@@ -646,7 +640,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_HT) {
printk(KERN_DEBUG " %s: HT: op_mode=0x%x\n",
wiphy_name(hw->wiphy),
- info->ht.operation_mode);
+ info->ht_operation_mode);
}
if (changed & BSS_CHANGED_BASIC_RATES) {
@@ -704,7 +698,6 @@ static const struct ieee80211_ops mac80211_hwsim_ops =
.remove_interface = mac80211_hwsim_remove_interface,
.config = mac80211_hwsim_config,
.configure_filter = mac80211_hwsim_configure_filter,
- .config_interface = mac80211_hwsim_config_interface,
.bss_info_changed = mac80211_hwsim_bss_info_changed,
.sta_notify = mac80211_hwsim_sta_notify,
.set_tim = mac80211_hwsim_set_tim,
@@ -725,6 +718,7 @@ static void mac80211_hwsim_free(void)
spin_unlock_bh(&hwsim_radio_lock);
list_for_each_entry(data, &tmplist, list) {
+ debugfs_remove(data->debugfs_group);
debugfs_remove(data->debugfs_ps);
debugfs_remove(data->debugfs);
ieee80211_unregister_hw(data->hw);
@@ -782,8 +776,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
pspoll->aid = cpu_to_le16(0xc000 | vp->aid);
memcpy(pspoll->bssid, vp->bssid, ETH_ALEN);
memcpy(pspoll->ta, mac, ETH_ALEN);
- if (data->radio_enabled &&
- !mac80211_hwsim_tx_frame(data->hw, skb))
+ if (!mac80211_hwsim_tx_frame(data->hw, skb))
printk(KERN_DEBUG "%s: PS-Poll frame not ack'ed\n", __func__);
dev_kfree_skb(skb);
}
@@ -814,8 +807,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
memcpy(hdr->addr1, vp->bssid, ETH_ALEN);
memcpy(hdr->addr2, mac, ETH_ALEN);
memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
- if (data->radio_enabled &&
- !mac80211_hwsim_tx_frame(data->hw, skb))
+ if (!mac80211_hwsim_tx_frame(data->hw, skb))
printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__);
dev_kfree_skb(skb);
}
@@ -877,6 +869,24 @@ DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_ps, hwsim_fops_ps_read, hwsim_fops_ps_write,
"%llu\n");
+static int hwsim_fops_group_read(void *dat, u64 *val)
+{
+ struct mac80211_hwsim_data *data = dat;
+ *val = data->group;
+ return 0;
+}
+
+static int hwsim_fops_group_write(void *dat, u64 val)
+{
+ struct mac80211_hwsim_data *data = dat;
+ data->group = val;
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_group,
+ hwsim_fops_group_read, hwsim_fops_group_write,
+ "%llx\n");
+
static int __init init_mac80211_hwsim(void)
{
int i, err = 0;
@@ -981,6 +991,8 @@ static int __init init_mac80211_hwsim(void)
hw->wiphy->bands[band] = sband;
}
+ /* By default all radios are belonging to the first group */
+ data->group = 1;
/* Work to be done prior to ieee80211_register_hw() */
switch (regtest) {
@@ -1105,6 +1117,9 @@ static int __init init_mac80211_hwsim(void)
data->debugfs_ps = debugfs_create_file("ps", 0666,
data->debugfs, data,
&hwsim_fops_ps);
+ data->debugfs_group = debugfs_create_file("group", 0666,
+ data->debugfs, data,
+ &hwsim_fops_group);
setup_timer(&data->beacon_timer, mac80211_hwsim_beacon,
(unsigned long) hw);
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index a9a970469c2..a263d5c84c0 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2369,7 +2369,7 @@ static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
if (info->use_cts_prot) {
prot_mode = MWL8K_FRAME_PROT_11G;
} else {
- switch (info->ht.operation_mode &
+ switch (info->ht_operation_mode &
IEEE80211_HT_OP_MODE_PROTECTION) {
case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY;
@@ -3089,19 +3089,6 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
return rc ? -EINVAL : 0;
}
-static int mwl8k_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
- u32 changed = conf->changed;
-
- if (changed & IEEE80211_IFCC_BSSID)
- memcpy(mv_vif->bssid, conf->bssid, IEEE80211_ADDR_LEN);
-
- return 0;
-}
-
struct mwl8k_bss_info_changed_worker {
struct mwl8k_work_struct header;
struct ieee80211_vif *vif;
@@ -3183,8 +3170,12 @@ static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
{
struct mwl8k_bss_info_changed_worker *worker;
struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
int rc;
+ if (changed & BSS_CHANGED_BSSID)
+ memcpy(mv_vif->bssid, info->bssid, IEEE80211_ADDR_LEN);
+
if ((changed & BSS_CHANGED_ASSOC) == 0)
return;
@@ -3442,7 +3433,6 @@ static const struct ieee80211_ops mwl8k_ops = {
.add_interface = mwl8k_add_interface,
.remove_interface = mwl8k_remove_interface,
.config = mwl8k_config,
- .config_interface = mwl8k_config_interface,
.bss_info_changed = mwl8k_bss_info_changed,
.configure_filter = mwl8k_configure_filter,
.set_rts_threshold = mwl8k_set_rts_threshold,
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index ecf8b6ed5a4..db3df947d8e 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -125,6 +125,7 @@ struct p54_led_dev {
struct led_classdev led_dev;
char name[P54_LED_MAX_NAME_LEN + 1];
+ unsigned int toggled;
unsigned int index;
unsigned int registered;
};
@@ -133,55 +134,74 @@ struct p54_led_dev {
struct p54_common {
struct ieee80211_hw *hw;
- u32 rx_start;
- u32 rx_end;
- struct sk_buff_head tx_queue;
+ struct ieee80211_vif *vif;
void (*tx)(struct ieee80211_hw *dev, struct sk_buff *skb);
int (*open)(struct ieee80211_hw *dev);
void (*stop)(struct ieee80211_hw *dev);
- int mode;
+ struct sk_buff_head tx_queue;
+ struct mutex conf_mutex;
+
+ /* memory management (as seen by the firmware) */
+ u32 rx_start;
+ u32 rx_end;
u16 rx_mtu;
u8 headroom;
u8 tailroom;
- struct mutex conf_mutex;
- u8 mac_addr[ETH_ALEN];
- u8 bssid[ETH_ALEN];
+
+ /* firmware/hardware info */
+ unsigned int tx_hdr_len;
+ unsigned int fw_var;
+ unsigned int fw_interface;
+ u8 version;
+
+ /* (e)DCF / QOS state */
+ bool use_short_slot;
+ struct ieee80211_tx_queue_stats tx_stats[8];
+ struct p54_edcf_queue_param qos_params[8];
+
+ /* Radio data */
+ u16 rxhw;
u8 rx_diversity_mask;
u8 tx_diversity_mask;
+ unsigned int output_power;
+ int noise;
+ /* calibration, output power limit and rssi<->dBm conversation data */
struct pda_iq_autocal_entry *iq_autocal;
unsigned int iq_autocal_len;
- struct p54_cal_database *output_limit;
struct p54_cal_database *curve_data;
+ struct p54_cal_database *output_limit;
struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS];
+
+ /* BBP/MAC state */
+ u8 mac_addr[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
+ u16 wakeup_timer;
unsigned int filter_flags;
- bool use_short_slot;
- u16 rxhw;
- u8 version;
- unsigned int tx_hdr_len;
- unsigned int fw_var;
- unsigned int fw_interface;
- unsigned int output_power;
- u32 tsf_low32;
- u32 tsf_high32;
+ int mode;
+ u32 tsf_low32, tsf_high32;
u32 basic_rate_mask;
- u16 wakeup_timer;
u16 aid;
- struct ieee80211_tx_queue_stats tx_stats[8];
- struct p54_edcf_queue_param qos_params[8];
- struct ieee80211_low_level_stats stats;
- struct delayed_work work;
struct sk_buff *cached_beacon;
- int noise;
- void *eeprom;
- struct completion eeprom_comp;
+
+ /* cryptographic engine information */
u8 privacy_caps;
u8 rx_keycache_size;
+ unsigned long *used_rxkeys;
+
/* LED management */
#ifdef CONFIG_P54_LEDS
- struct p54_led_dev assoc_led;
- struct p54_led_dev tx_led;
+ struct p54_led_dev leds[4];
+ struct delayed_work led_work;
#endif /* CONFIG_P54_LEDS */
u16 softled_state; /* bit field of glowing LEDs */
+
+ /* statistics */
+ struct ieee80211_low_level_stats stats;
+ struct delayed_work work;
+
+ /* eeprom handling */
+ void *eeprom;
+ struct completion eeprom_comp;
};
int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb);
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index c8f0232ee5e..b618bd14583 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -249,7 +249,7 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
dev->queues = P54_QUEUE_AC_NUM;
}
- if (!modparam_nohwcrypt)
+ if (!modparam_nohwcrypt) {
printk(KERN_INFO "%s: cryptographic accelerator "
"WEP:%s, TKIP:%s, CCMP:%s\n",
wiphy_name(dev->wiphy),
@@ -259,6 +259,26 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) ?
"YES" : "no");
+ if (priv->rx_keycache_size) {
+ /*
+ * NOTE:
+ *
+ * The firmware provides at most 255 (0 - 254) slots
+ * for keys which are then used to offload decryption.
+ * As a result the 255 entry (aka 0xff) can be used
+ * safely by the driver to mark keys that didn't fit
+ * into the full cache. This trick saves us from
+ * keeping a extra list for uploaded keys.
+ */
+
+ priv->used_rxkeys = kzalloc(BITS_TO_LONGS(
+ priv->rx_keycache_size), GFP_KERNEL);
+
+ if (!priv->used_rxkeys)
+ return -ENOMEM;
+ }
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(p54_parse_firmware);
@@ -749,8 +769,6 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
rx_status.signal = p54_rssi_to_dbm(dev, hdr->rssi);
rx_status.noise = priv->noise;
- /* XX correct? */
- rx_status.qual = (100 * hdr->rssi) / 127;
if (hdr->rate & 0x10)
rx_status.flag |= RX_FLAG_SHORTPRE;
if (dev->conf.channel->band == IEEE80211_BAND_5GHZ)
@@ -804,44 +822,37 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
struct ieee80211_tx_info *info;
struct p54_tx_info *range;
unsigned long flags;
- u32 freed = 0, last_addr = priv->rx_start;
- if (unlikely(!skb || !dev || !skb_queue_len(&priv->tx_queue)))
+ if (unlikely(!skb || !dev || skb_queue_empty(&priv->tx_queue)))
return;
- /*
- * don't try to free an already unlinked skb
+ /* There used to be a check here to see if the SKB was on the
+ * TX queue or not. This can never happen because all SKBs we
+ * see here successfully went through p54_assign_address()
+ * which means the SKB is on the ->tx_queue.
*/
- if (unlikely((!skb->next) || (!skb->prev)))
- return;
spin_lock_irqsave(&priv->tx_queue.lock, flags);
info = IEEE80211_SKB_CB(skb);
range = (void *)info->rate_driver_data;
- if (skb->prev != (struct sk_buff *)&priv->tx_queue) {
+ if (!skb_queue_is_first(&priv->tx_queue, skb)) {
struct ieee80211_tx_info *ni;
struct p54_tx_info *mr;
- ni = IEEE80211_SKB_CB(skb->prev);
+ ni = IEEE80211_SKB_CB(skb_queue_prev(&priv->tx_queue, skb));
mr = (struct p54_tx_info *)ni->rate_driver_data;
- last_addr = mr->end_addr;
}
- if (skb->next != (struct sk_buff *)&priv->tx_queue) {
+ if (!skb_queue_is_last(&priv->tx_queue, skb)) {
struct ieee80211_tx_info *ni;
struct p54_tx_info *mr;
- ni = IEEE80211_SKB_CB(skb->next);
+ ni = IEEE80211_SKB_CB(skb_queue_next(&priv->tx_queue, skb));
mr = (struct p54_tx_info *)ni->rate_driver_data;
- freed = mr->start_addr - last_addr;
- } else
- freed = priv->rx_end - last_addr;
+ }
__skb_unlink(skb, &priv->tx_queue);
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
dev_kfree_skb_any(skb);
-
- if (freed >= priv->headroom + sizeof(struct p54_hdr) + 48 +
- IEEE80211_MAX_RTS_THRESHOLD + priv->tailroom)
- p54_wake_free_queues(dev);
+ p54_wake_free_queues(dev);
}
EXPORT_SYMBOL_GPL(p54_free_skb);
@@ -853,15 +864,13 @@ static struct sk_buff *p54_find_tx_entry(struct ieee80211_hw *dev,
unsigned long flags;
spin_lock_irqsave(&priv->tx_queue.lock, flags);
- entry = priv->tx_queue.next;
- while (entry != (struct sk_buff *)&priv->tx_queue) {
+ skb_queue_walk(&priv->tx_queue, entry) {
struct p54_hdr *hdr = (struct p54_hdr *) entry->data;
if (hdr->req_id == req_id) {
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
return entry;
}
- entry = entry->next;
}
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
return NULL;
@@ -875,37 +884,29 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
struct sk_buff *entry;
u32 addr = le32_to_cpu(hdr->req_id) - priv->headroom;
struct p54_tx_info *range = NULL;
- u32 freed = 0;
- u32 last_addr = priv->rx_start;
unsigned long flags;
int count, idx;
spin_lock_irqsave(&priv->tx_queue.lock, flags);
- entry = (struct sk_buff *) priv->tx_queue.next;
- while (entry != (struct sk_buff *)&priv->tx_queue) {
+ skb_queue_walk(&priv->tx_queue, entry) {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
struct p54_hdr *entry_hdr;
struct p54_tx_data *entry_data;
unsigned int pad = 0, frame_len;
range = (void *)info->rate_driver_data;
- if (range->start_addr != addr) {
- last_addr = range->end_addr;
- entry = entry->next;
+ if (range->start_addr != addr)
continue;
- }
- if (entry->next != (struct sk_buff *)&priv->tx_queue) {
+ if (!skb_queue_is_last(&priv->tx_queue, entry)) {
struct ieee80211_tx_info *ni;
struct p54_tx_info *mr;
- ni = IEEE80211_SKB_CB(entry->next);
+ ni = IEEE80211_SKB_CB(skb_queue_next(&priv->tx_queue,
+ entry));
mr = (struct p54_tx_info *)ni->rate_driver_data;
- freed = mr->start_addr - last_addr;
- } else
- freed = priv->rx_end - last_addr;
+ }
- last_addr = range->end_addr;
__skb_unlink(entry, &priv->tx_queue);
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
@@ -992,9 +993,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
out:
- if (freed >= priv->headroom + sizeof(struct p54_hdr) + 48 +
- IEEE80211_MAX_RTS_THRESHOLD + priv->tailroom)
- p54_wake_free_queues(dev);
+ p54_wake_free_queues(dev);
}
static void p54_rx_eeprom_readback(struct ieee80211_hw *dev,
@@ -1044,6 +1043,7 @@ static void p54_rx_stats(struct ieee80211_hw *dev, struct sk_buff *skb)
static void p54_rx_trap(struct ieee80211_hw *dev, struct sk_buff *skb)
{
+ struct p54_common *priv = dev->priv;
struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
struct p54_trap *trap = (struct p54_trap *) hdr->data;
u16 event = le16_to_cpu(trap->event);
@@ -1057,6 +1057,8 @@ static void p54_rx_trap(struct ieee80211_hw *dev, struct sk_buff *skb)
wiphy_name(dev->wiphy), freq);
break;
case P54_TRAP_NO_BEACON:
+ if (priv->vif)
+ ieee80211_beacon_loss(priv->vif);
break;
case P54_TRAP_SCAN:
break;
@@ -1162,23 +1164,21 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
}
}
- entry = priv->tx_queue.next;
- while (left--) {
+ skb_queue_walk(&priv->tx_queue, entry) {
u32 hole_size;
info = IEEE80211_SKB_CB(entry);
range = (void *)info->rate_driver_data;
hole_size = range->start_addr - last_addr;
if (!target_skb && hole_size >= len) {
- target_skb = entry->prev;
+ target_skb = skb_queue_prev(&priv->tx_queue, entry);
hole_size -= len;
target_addr = last_addr;
}
largest_hole = max(largest_hole, hole_size);
last_addr = range->end_addr;
- entry = entry->next;
}
if (!target_skb && priv->rx_end - last_addr >= len) {
- target_skb = priv->tx_queue.prev;
+ target_skb = skb_peek_tail(&priv->tx_queue);
largest_hole = max(largest_hole, priv->rx_end - last_addr - len);
if (!skb_queue_empty(&priv->tx_queue)) {
info = IEEE80211_SKB_CB(target_skb);
@@ -1452,7 +1452,8 @@ static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb,
if (info->control.sta)
*aid = info->control.sta->aid;
- else
+
+ if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
*flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
break;
}
@@ -1939,7 +1940,8 @@ static int p54_set_ps(struct ieee80211_hw *dev)
int i;
if (dev->conf.flags & IEEE80211_CONF_PS)
- mode = P54_PSM | P54_PSM_DTIM | P54_PSM_MCBC;
+ mode = P54_PSM | P54_PSM_BEACON_TIMEOUT | P54_PSM_DTIM |
+ P54_PSM_CHECKSUM | P54_PSM_MCBC;
else
mode = P54_PSM_CAM;
@@ -1957,9 +1959,10 @@ static int p54_set_ps(struct ieee80211_hw *dev)
psm->intervals[i].periods = cpu_to_le16(1);
}
- psm->beacon_rssi_skip_max = 60;
+ psm->beacon_rssi_skip_max = 200;
psm->rssi_delta_threshold = 0;
- psm->nr = 0;
+ psm->nr = 10;
+ psm->exclude[0] = 0;
priv->tx(dev, skb);
@@ -2081,20 +2084,21 @@ out:
static void p54_stop(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
- struct sk_buff *skb;
mutex_lock(&priv->conf_mutex);
priv->mode = NL80211_IFTYPE_UNSPECIFIED;
priv->softled_state = 0;
p54_set_leds(dev);
+#ifdef CONFIG_P54_LEDS
+ cancel_delayed_work_sync(&priv->led_work);
+#endif /* CONFIG_P54_LEDS */
cancel_delayed_work_sync(&priv->work);
if (priv->cached_beacon)
p54_tx_cancel(dev, priv->cached_beacon);
priv->stop(dev);
- while ((skb = skb_dequeue(&priv->tx_queue)))
- kfree_skb(skb);
+ skb_queue_purge(&priv->tx_queue);
priv->cached_beacon = NULL;
priv->tsf_high32 = priv->tsf_low32 = 0;
mutex_unlock(&priv->conf_mutex);
@@ -2111,6 +2115,8 @@ static int p54_add_interface(struct ieee80211_hw *dev,
return -EOPNOTSUPP;
}
+ priv->vif = conf->vif;
+
switch (conf->type) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
@@ -2135,6 +2141,7 @@ static void p54_remove_interface(struct ieee80211_hw *dev,
struct p54_common *priv = dev->priv;
mutex_lock(&priv->conf_mutex);
+ priv->vif = NULL;
if (priv->cached_beacon)
p54_tx_cancel(dev, priv->cached_beacon);
priv->mode = NL80211_IFTYPE_MONITOR;
@@ -2174,41 +2181,6 @@ out:
return ret;
}
-static int p54_config_interface(struct ieee80211_hw *dev,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct p54_common *priv = dev->priv;
- int ret = 0;
-
- mutex_lock(&priv->conf_mutex);
- if (conf->changed & IEEE80211_IFCC_BSSID) {
- memcpy(priv->bssid, conf->bssid, ETH_ALEN);
- ret = p54_setup_mac(dev);
- if (ret)
- goto out;
- }
-
- if (conf->changed & IEEE80211_IFCC_BEACON) {
- ret = p54_scan(dev, P54_SCAN_EXIT, 0);
- if (ret)
- goto out;
- ret = p54_setup_mac(dev);
- if (ret)
- goto out;
- ret = p54_beacon_update(dev, vif);
- if (ret)
- goto out;
- ret = p54_set_edcf(dev);
- if (ret)
- goto out;
- }
-
-out:
- mutex_unlock(&priv->conf_mutex);
- return ret;
-}
-
static void p54_configure_filter(struct ieee80211_hw *dev,
unsigned int changed_flags,
unsigned int *total_flags,
@@ -2312,8 +2284,32 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
u32 changed)
{
struct p54_common *priv = dev->priv;
+ int ret;
+
+ mutex_lock(&priv->conf_mutex);
+ if (changed & BSS_CHANGED_BSSID) {
+ memcpy(priv->bssid, info->bssid, ETH_ALEN);
+ ret = p54_setup_mac(dev);
+ if (ret)
+ goto out;
+ }
+
+ if (changed & BSS_CHANGED_BEACON) {
+ ret = p54_scan(dev, P54_SCAN_EXIT, 0);
+ if (ret)
+ goto out;
+ ret = p54_setup_mac(dev);
+ if (ret)
+ goto out;
+ ret = p54_beacon_update(dev, vif);
+ if (ret)
+ goto out;
+ }
+ /* XXX: this mimics having two callbacks... clean up */
+ out:
+ mutex_unlock(&priv->conf_mutex);
- if (changed & BSS_CHANGED_ERP_SLOT) {
+ if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BEACON)) {
priv->use_short_slot = info->use_short_slot;
p54_set_edcf(dev);
}
@@ -2334,7 +2330,6 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
p54_setup_mac(dev);
}
}
-
}
static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
@@ -2344,61 +2339,84 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
struct p54_common *priv = dev->priv;
struct sk_buff *skb;
struct p54_keycache *rxkey;
+ int slot, ret = 0;
u8 algo = 0;
if (modparam_nohwcrypt)
return -EOPNOTSUPP;
- if (cmd == DISABLE_KEY)
- algo = 0;
- else {
+ mutex_lock(&priv->conf_mutex);
+ if (cmd == SET_KEY) {
switch (key->alg) {
case ALG_TKIP:
if (!(priv->privacy_caps & (BR_DESC_PRIV_CAP_MICHAEL |
- BR_DESC_PRIV_CAP_TKIP)))
- return -EOPNOTSUPP;
+ BR_DESC_PRIV_CAP_TKIP))) {
+ ret = -EOPNOTSUPP;
+ goto out_unlock;
+ }
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
algo = P54_CRYPTO_TKIPMICHAEL;
break;
case ALG_WEP:
- if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP))
- return -EOPNOTSUPP;
+ if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) {
+ ret = -EOPNOTSUPP;
+ goto out_unlock;
+ }
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
algo = P54_CRYPTO_WEP;
break;
case ALG_CCMP:
- if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP))
- return -EOPNOTSUPP;
+ if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) {
+ ret = -EOPNOTSUPP;
+ goto out_unlock;
+ }
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
algo = P54_CRYPTO_AESCCMP;
break;
default:
- return -EOPNOTSUPP;
+ ret = -EOPNOTSUPP;
+ goto out_unlock;
}
- }
+ slot = bitmap_find_free_region(priv->used_rxkeys,
+ priv->rx_keycache_size, 0);
- if (key->keyidx > priv->rx_keycache_size) {
- /*
- * The device supports the choosen algorithm, but the firmware
- * does not provide enough key slots to store all of them.
- * So, incoming frames have to be decoded by the mac80211 stack,
- * but we can still offload encryption for outgoing frames.
- */
+ if (slot < 0) {
+ /*
+ * The device supports the choosen algorithm, but the
+ * firmware does not provide enough key slots to store
+ * all of them.
+ * But encryption offload for outgoing frames is always
+ * possible, so we just pretend that the upload was
+ * successful and do the decryption in software.
+ */
- return 0;
+ /* mark the key as invalid. */
+ key->hw_key_idx = 0xff;
+ goto out_unlock;
+ }
+ } else {
+ slot = key->hw_key_idx;
+
+ if (slot == 0xff) {
+ /* This key was not uploaded into the rx key cache. */
+
+ goto out_unlock;
+ }
+
+ bitmap_release_region(priv->used_rxkeys, slot, 0);
+ algo = 0;
}
- mutex_lock(&priv->conf_mutex);
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey),
- P54_CONTROL_TYPE_RX_KEYCACHE, GFP_ATOMIC);
+ P54_CONTROL_TYPE_RX_KEYCACHE, GFP_KERNEL);
if (!skb) {
- mutex_unlock(&priv->conf_mutex);
- return -ENOMEM;
+ bitmap_release_region(priv->used_rxkeys, slot, 0);
+ ret = -ENOSPC;
+ goto out_unlock;
}
- /* TODO: some devices have 4 more free slots for rx keys */
rxkey = (struct p54_keycache *)skb_put(skb, sizeof(*rxkey));
- rxkey->entry = key->keyidx;
+ rxkey->entry = slot;
rxkey->key_id = key->keyidx;
rxkey->key_type = algo;
if (sta)
@@ -2416,11 +2434,51 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
}
priv->tx(dev, skb);
+ key->hw_key_idx = slot;
+
+out_unlock:
mutex_unlock(&priv->conf_mutex);
- return 0;
+ return ret;
}
#ifdef CONFIG_P54_LEDS
+static void p54_update_leds(struct work_struct *work)
+{
+ struct p54_common *priv = container_of(work, struct p54_common,
+ led_work.work);
+ int err, i, tmp, blink_delay = 400;
+ bool rerun = false;
+
+ /* Don't toggle the LED, when the device is down. */
+ if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+ return ;
+
+ for (i = 0; i < ARRAY_SIZE(priv->leds); i++)
+ if (priv->leds[i].toggled) {
+ priv->softled_state |= BIT(i);
+
+ tmp = 70 + 200 / (priv->leds[i].toggled);
+ if (tmp < blink_delay)
+ blink_delay = tmp;
+
+ if (priv->leds[i].led_dev.brightness == LED_OFF)
+ rerun = true;
+
+ priv->leds[i].toggled =
+ !!priv->leds[i].led_dev.brightness;
+ } else
+ priv->softled_state &= ~BIT(i);
+
+ err = p54_set_leds(priv->hw);
+ if (err && net_ratelimit())
+ printk(KERN_ERR "%s: failed to update LEDs.\n",
+ wiphy_name(priv->hw->wiphy));
+
+ if (rerun)
+ queue_delayed_work(priv->hw->workqueue, &priv->led_work,
+ msecs_to_jiffies(blink_delay));
+}
+
static void p54_led_brightness_set(struct led_classdev *led_dev,
enum led_brightness brightness)
{
@@ -2428,28 +2486,23 @@ static void p54_led_brightness_set(struct led_classdev *led_dev,
led_dev);
struct ieee80211_hw *dev = led->hw_dev;
struct p54_common *priv = dev->priv;
- int err;
- /* Don't toggle the LED, when the device is down. */
if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
return ;
- if (brightness != LED_OFF)
- priv->softled_state |= BIT(led->index);
- else
- priv->softled_state &= ~BIT(led->index);
-
- err = p54_set_leds(dev);
- if (err && net_ratelimit())
- printk(KERN_ERR "%s: failed to update %s LED.\n",
- wiphy_name(dev->wiphy), led_dev->name);
+ if (brightness) {
+ led->toggled++;
+ queue_delayed_work(priv->hw->workqueue, &priv->led_work,
+ HZ/10);
+ }
}
static int p54_register_led(struct ieee80211_hw *dev,
- struct p54_led_dev *led,
unsigned int led_index,
char *name, char *trigger)
{
+ struct p54_common *priv = dev->priv;
+ struct p54_led_dev *led = &priv->leds[led_index];
int err;
if (led->registered)
@@ -2482,19 +2535,30 @@ static int p54_init_leds(struct ieee80211_hw *dev)
* TODO:
* Figure out if the EEPROM contains some hints about the number
* of available/programmable LEDs of the device.
- * But for now, we can assume that we have two programmable LEDs.
*/
- err = p54_register_led(dev, &priv->assoc_led, 0, "assoc",
+ INIT_DELAYED_WORK(&priv->led_work, p54_update_leds);
+
+ err = p54_register_led(dev, 0, "assoc",
ieee80211_get_assoc_led_name(dev));
if (err)
return err;
- err = p54_register_led(dev, &priv->tx_led, 1, "tx",
+ err = p54_register_led(dev, 1, "tx",
ieee80211_get_tx_led_name(dev));
if (err)
return err;
+ err = p54_register_led(dev, 2, "rx",
+ ieee80211_get_rx_led_name(dev));
+ if (err)
+ return err;
+
+ err = p54_register_led(dev, 3, "radio",
+ ieee80211_get_radio_led_name(dev));
+ if (err)
+ return err;
+
err = p54_set_leds(dev);
return err;
}
@@ -2502,11 +2566,11 @@ static int p54_init_leds(struct ieee80211_hw *dev)
static void p54_unregister_leds(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
+ int i;
- if (priv->tx_led.registered)
- led_classdev_unregister(&priv->tx_led.led_dev);
- if (priv->assoc_led.registered)
- led_classdev_unregister(&priv->assoc_led.led_dev);
+ for (i = 0; i < ARRAY_SIZE(priv->leds); i++)
+ if (priv->leds[i].registered)
+ led_classdev_unregister(&priv->leds[i].led_dev);
}
#endif /* CONFIG_P54_LEDS */
@@ -2520,7 +2584,6 @@ static const struct ieee80211_ops p54_ops = {
.sta_notify = p54_sta_notify,
.set_key = p54_set_key,
.config = p54_config,
- .config_interface = p54_config_interface,
.bss_info_changed = p54_bss_info_changed,
.configure_filter = p54_configure_filter,
.conf_tx = p54_conf_tx,
@@ -2607,21 +2670,10 @@ void p54_free_common(struct ieee80211_hw *dev)
kfree(priv->iq_autocal);
kfree(priv->output_limit);
kfree(priv->curve_data);
+ kfree(priv->used_rxkeys);
#ifdef CONFIG_P54_LEDS
p54_unregister_leds(dev);
#endif /* CONFIG_P54_LEDS */
}
EXPORT_SYMBOL_GPL(p54_free_common);
-
-static int __init p54_init(void)
-{
- return 0;
-}
-
-static void __exit p54_exit(void)
-{
-}
-
-module_init(p54_init);
-module_exit(p54_exit);
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index d1fe577de3d..83116baeb11 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -96,7 +96,7 @@ static void p54spi_spi_write(struct p54s_priv *priv, u8 address,
spi_message_add_tail(&t[0], &m);
t[1].tx_buf = buf;
- t[1].len = len;
+ t[1].len = len & ~1;
spi_message_add_tail(&t[1], &m);
if (len % 2) {
@@ -167,15 +167,31 @@ static const struct p54spi_spi_reg p54spi_registers_array[] =
static int p54spi_wait_bit(struct p54s_priv *priv, u16 reg, __le32 bits)
{
int i;
- __le32 buffer;
for (i = 0; i < 2000; i++) {
- p54spi_spi_read(priv, reg, &buffer, sizeof(buffer));
- if (buffer == bits)
+ __le32 buffer = p54spi_read32(priv, reg);
+ if ((buffer & bits) == bits)
return 1;
+ }
+ return 0;
+}
- msleep(1);
+static int p54spi_spi_write_dma(struct p54s_priv *priv, __le32 base,
+ const void *buf, size_t len)
+{
+ if (!p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL,
+ cpu_to_le32(HOST_ALLOWED))) {
+ dev_err(&priv->spi->dev, "spi_write_dma not allowed "
+ "to DMA write.\n");
+ return -EAGAIN;
}
+
+ p54spi_write16(priv, SPI_ADRS_DMA_WRITE_CTRL,
+ cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE));
+
+ p54spi_write16(priv, SPI_ADRS_DMA_WRITE_LEN, cpu_to_le16(len));
+ p54spi_write32(priv, SPI_ADRS_DMA_WRITE_BASE, base);
+ p54spi_spi_write(priv, SPI_ADRS_DMA_DATA, buf, len);
return 0;
}
@@ -228,8 +244,15 @@ static int p54spi_request_eeprom(struct ieee80211_hw *dev)
static int p54spi_upload_firmware(struct ieee80211_hw *dev)
{
struct p54s_priv *priv = dev->priv;
- unsigned long fw_len, fw_addr;
- long _fw_len;
+ unsigned long fw_len, _fw_len;
+ unsigned int offset = 0;
+ int err = 0;
+ u8 *fw;
+
+ fw_len = priv->firmware->size;
+ fw = kmemdup(priv->firmware->data, fw_len, GFP_KERNEL);
+ if (!fw)
+ return -ENOMEM;
/* stop the device */
p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
@@ -244,36 +267,17 @@ static int p54spi_upload_firmware(struct ieee80211_hw *dev)
msleep(TARGET_BOOT_SLEEP);
- fw_addr = ISL38XX_DEV_FIRMWARE_ADDR;
- fw_len = priv->firmware->size;
-
while (fw_len > 0) {
_fw_len = min_t(long, fw_len, SPI_MAX_PACKET_SIZE);
- p54spi_write16(priv, SPI_ADRS_DMA_WRITE_CTRL,
- cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE));
-
- if (p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL,
- cpu_to_le32(HOST_ALLOWED)) == 0) {
- dev_err(&priv->spi->dev, "fw_upload not allowed "
- "to DMA write.");
- return -EAGAIN;
- }
-
- p54spi_write16(priv, SPI_ADRS_DMA_WRITE_LEN,
- cpu_to_le16(_fw_len));
- p54spi_write32(priv, SPI_ADRS_DMA_WRITE_BASE,
- cpu_to_le32(fw_addr));
-
- p54spi_spi_write(priv, SPI_ADRS_DMA_DATA,
- &priv->firmware->data, _fw_len);
+ err = p54spi_spi_write_dma(priv, cpu_to_le32(
+ ISL38XX_DEV_FIRMWARE_ADDR + offset),
+ (fw + offset), _fw_len);
+ if (err < 0)
+ goto out;
fw_len -= _fw_len;
- fw_addr += _fw_len;
-
- /* FIXME: I think this doesn't work if firmware is large,
- * this loop goes to second round. fw->data is not
- * increased at all! */
+ offset += _fw_len;
}
BUG_ON(fw_len != 0);
@@ -292,7 +296,10 @@ static int p54spi_upload_firmware(struct ieee80211_hw *dev)
p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT));
msleep(TARGET_BOOT_SLEEP);
- return 0;
+
+out:
+ kfree(fw);
+ return err;
}
static void p54spi_power_off(struct p54s_priv *priv)
@@ -318,29 +325,21 @@ static inline void p54spi_int_ack(struct p54s_priv *priv, u32 val)
p54spi_write32(priv, SPI_ADRS_HOST_INT_ACK, cpu_to_le32(val));
}
-static void p54spi_wakeup(struct p54s_priv *priv)
+static int p54spi_wakeup(struct p54s_priv *priv)
{
- unsigned long timeout;
- u32 ints;
-
/* wake the chip */
p54spi_write32(priv, SPI_ADRS_ARM_INTERRUPTS,
cpu_to_le32(SPI_TARGET_INT_WAKEUP));
/* And wait for the READY interrupt */
- timeout = jiffies + HZ;
-
- ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
- while (!(ints & SPI_HOST_INT_READY)) {
- if (time_after(jiffies, timeout))
- goto out;
- ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+ if (!p54spi_wait_bit(priv, SPI_ADRS_HOST_INTERRUPTS,
+ cpu_to_le32(SPI_HOST_INT_READY))) {
+ dev_err(&priv->spi->dev, "INT_READY timeout\n");
+ return -EBUSY;
}
p54spi_int_ack(priv, SPI_HOST_INT_READY);
-
-out:
- return;
+ return 0;
}
static inline void p54spi_sleep(struct p54s_priv *priv)
@@ -372,27 +371,48 @@ static int p54spi_rx(struct p54s_priv *priv)
{
struct sk_buff *skb;
u16 len;
+ u16 rx_head[2];
+#define READAHEAD_SZ (sizeof(rx_head)-sizeof(u16))
- p54spi_wakeup(priv);
-
- /* dummy read to flush SPI DMA controller bug */
- p54spi_read16(priv, SPI_ADRS_GEN_PURP_1);
+ if (p54spi_wakeup(priv) < 0)
+ return -EBUSY;
- len = p54spi_read16(priv, SPI_ADRS_DMA_DATA);
+ /* Read data size and first data word in one SPI transaction
+ * This is workaround for firmware/DMA bug,
+ * when first data word gets lost under high load.
+ */
+ p54spi_spi_read(priv, SPI_ADRS_DMA_DATA, rx_head, sizeof(rx_head));
+ len = rx_head[0];
if (len == 0) {
- dev_err(&priv->spi->dev, "rx request of zero bytes");
+ p54spi_sleep(priv);
+ dev_err(&priv->spi->dev, "rx request of zero bytes\n");
return 0;
}
- skb = dev_alloc_skb(len);
+ /* Firmware may insert up to 4 padding bytes after the lmac header,
+ * but it does not amend the size of SPI data transfer.
+ * Such packets has correct data size in header, thus referencing
+ * past the end of allocated skb. Reserve extra 4 bytes for this case */
+ skb = dev_alloc_skb(len + 4);
if (!skb) {
+ p54spi_sleep(priv);
dev_err(&priv->spi->dev, "could not alloc skb");
- return 0;
+ return -ENOMEM;
}
- p54spi_spi_read(priv, SPI_ADRS_DMA_DATA, skb_put(skb, len), len);
+ if (len <= READAHEAD_SZ) {
+ memcpy(skb_put(skb, len), rx_head + 1, len);
+ } else {
+ memcpy(skb_put(skb, READAHEAD_SZ), rx_head + 1, READAHEAD_SZ);
+ p54spi_spi_read(priv, SPI_ADRS_DMA_DATA,
+ skb_put(skb, len - READAHEAD_SZ),
+ len - READAHEAD_SZ);
+ }
p54spi_sleep(priv);
+ /* Put additional bytes to compensate for the possible
+ * alignment-caused truncation */
+ skb_put(skb, 4);
if (p54_rx(priv->hw, skb) == 0)
dev_kfree_skb(skb);
@@ -414,39 +434,28 @@ static irqreturn_t p54spi_interrupt(int irq, void *config)
static int p54spi_tx_frame(struct p54s_priv *priv, struct sk_buff *skb)
{
struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
- struct p54s_dma_regs dma_regs;
- unsigned long timeout;
int ret = 0;
- u32 ints;
-
- p54spi_wakeup(priv);
- dma_regs.cmd = cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE);
- dma_regs.len = cpu_to_le16(skb->len);
- dma_regs.addr = hdr->req_id;
+ if (p54spi_wakeup(priv) < 0)
+ return -EBUSY;
- p54spi_spi_write(priv, SPI_ADRS_DMA_WRITE_CTRL, &dma_regs,
- sizeof(dma_regs));
-
- p54spi_spi_write(priv, SPI_ADRS_DMA_DATA, skb->data, skb->len);
+ ret = p54spi_spi_write_dma(priv, hdr->req_id, skb->data, skb->len);
+ if (ret < 0)
+ goto out;
- timeout = jiffies + 2 * HZ;
- ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
- while (!(ints & SPI_HOST_INT_WR_READY)) {
- if (time_after(jiffies, timeout)) {
- dev_err(&priv->spi->dev, "WR_READY timeout");
- ret = -1;
- goto out;
- }
- ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+ if (!p54spi_wait_bit(priv, SPI_ADRS_HOST_INTERRUPTS,
+ cpu_to_le32(SPI_HOST_INT_WR_READY))) {
+ dev_err(&priv->spi->dev, "WR_READY timeout\n");
+ ret = -EAGAIN;
+ goto out;
}
p54spi_int_ack(priv, SPI_HOST_INT_WR_READY);
- p54spi_sleep(priv);
-out:
if (FREE_AFTER_TX(skb))
p54_free_skb(priv->hw, skb);
+out:
+ p54spi_sleep(priv);
return ret;
}
@@ -516,8 +525,7 @@ static void p54spi_work(struct work_struct *work)
mutex_lock(&priv->mutex);
- if (priv->fw_state == FW_STATE_OFF &&
- priv->fw_state == FW_STATE_RESET)
+ if (priv->fw_state == FW_STATE_OFF)
goto out;
ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
@@ -544,11 +552,6 @@ static void p54spi_work(struct work_struct *work)
}
ret = p54spi_wq_tx(priv);
- if (ret < 0)
- goto out;
-
- ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
-
out:
mutex_unlock(&priv->mutex);
}
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 6cc6cbc9234..0e877a104a8 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -81,6 +81,29 @@ static struct usb_device_id p54u_table[] __devinitdata = {
MODULE_DEVICE_TABLE(usb, p54u_table);
+static const struct {
+ u32 intf;
+ enum p54u_hw_type type;
+ const char *fw;
+ const char *fw_legacy;
+ char hw[20];
+} p54u_fwlist[__NUM_P54U_HWTYPES] = {
+ {
+ .type = P54U_NET2280,
+ .intf = FW_LM86,
+ .fw = "isl3886usb",
+ .fw_legacy = "isl3890usb",
+ .hw = "ISL3886 + net2280",
+ },
+ {
+ .type = P54U_3887,
+ .intf = FW_LM87,
+ .fw = "isl3887usb",
+ .fw_legacy = "isl3887usb_bare",
+ .hw = "ISL3887",
+ },
+};
+
static void p54u_rx_cb(struct urb *urb)
{
struct sk_buff *skb = (struct sk_buff *) urb->context;
@@ -125,11 +148,7 @@ static void p54u_rx_cb(struct urb *urb)
}
skb_reset_tail_pointer(skb);
skb_trim(skb, 0);
- if (urb->transfer_buffer != skb_tail_pointer(skb)) {
- /* this should not happen */
- WARN_ON(1);
- urb->transfer_buffer = skb_tail_pointer(skb);
- }
+ urb->transfer_buffer = skb_tail_pointer(skb);
}
skb_queue_tail(&priv->rx_queue, skb);
usb_anchor_urb(urb, &priv->submitted);
@@ -206,53 +225,6 @@ static int p54u_init_urbs(struct ieee80211_hw *dev)
return ret;
}
-static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb)
-{
- struct p54u_priv *priv = dev->priv;
- struct urb *addr_urb, *data_urb;
- int err = 0;
-
- addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!addr_urb)
- return;
-
- data_urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!data_urb) {
- usb_free_urb(addr_urb);
- return;
- }
-
- usb_fill_bulk_urb(addr_urb, priv->udev,
- usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
- &((struct p54_hdr *)skb->data)->req_id, 4,
- p54u_tx_dummy_cb, dev);
- usb_fill_bulk_urb(data_urb, priv->udev,
- usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
- skb->data, skb->len, FREE_AFTER_TX(skb) ?
- p54u_tx_cb : p54u_tx_dummy_cb, skb);
- addr_urb->transfer_flags |= URB_ZERO_PACKET;
- data_urb->transfer_flags |= URB_ZERO_PACKET;
-
- usb_anchor_urb(addr_urb, &priv->submitted);
- err = usb_submit_urb(addr_urb, GFP_ATOMIC);
- if (err) {
- usb_unanchor_urb(addr_urb);
- goto out;
- }
-
- usb_anchor_urb(data_urb, &priv->submitted);
- err = usb_submit_urb(data_urb, GFP_ATOMIC);
- if (err)
- usb_unanchor_urb(data_urb);
-
- out:
- usb_free_urb(addr_urb);
- usb_free_urb(data_urb);
-
- if (err)
- p54_free_skb(dev, skb);
-}
-
static __le32 p54u_lm87_chksum(const __le32 *data, size_t length)
{
u32 chk = 0;
@@ -425,20 +397,16 @@ static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
data, len, &alen, 2000);
}
-static const char p54u_romboot_3887[] = "~~~~";
-static const char p54u_firmware_upload_3887[] = "<\r";
-
-static int p54u_device_reset_3887(struct ieee80211_hw *dev)
+static int p54u_device_reset(struct ieee80211_hw *dev)
{
struct p54u_priv *priv = dev->priv;
int ret, lock = (priv->intf->condition != USB_INTERFACE_BINDING);
- u8 buf[4];
if (lock) {
ret = usb_lock_device_for_reset(priv->udev, priv->intf);
if (ret < 0) {
dev_err(&priv->udev->dev, "(p54usb) unable to lock "
- " device for reset: %d\n", ret);
+ "device for reset (%d)!\n", ret);
return ret;
}
}
@@ -447,26 +415,34 @@ static int p54u_device_reset_3887(struct ieee80211_hw *dev)
if (lock)
usb_unlock_device(priv->udev);
- if (ret) {
+ if (ret)
dev_err(&priv->udev->dev, "(p54usb) unable to reset "
- "device: %d\n", ret);
- return ret;
- }
+ "device (%d)!\n", ret);
+
+ return ret;
+}
+
+static const char p54u_romboot_3887[] = "~~~~";
+static int p54u_firmware_reset_3887(struct ieee80211_hw *dev)
+{
+ struct p54u_priv *priv = dev->priv;
+ u8 buf[4];
+ int ret;
memcpy(&buf, p54u_romboot_3887, sizeof(buf));
ret = p54u_bulk_msg(priv, P54U_PIPE_DATA,
buf, sizeof(buf));
if (ret)
dev_err(&priv->udev->dev, "(p54usb) unable to jump to "
- "boot ROM: %d\n", ret);
+ "boot ROM (%d)!\n", ret);
return ret;
}
+static const char p54u_firmware_upload_3887[] = "<\r";
static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
{
struct p54u_priv *priv = dev->priv;
- const struct firmware *fw_entry = NULL;
int err, alen;
u8 carry = 0;
u8 *buf, *tmp;
@@ -475,51 +451,29 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
struct x2_header *hdr;
unsigned long timeout;
+ err = p54u_firmware_reset_3887(dev);
+ if (err)
+ return err;
+
tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
if (!buf) {
dev_err(&priv->udev->dev, "(p54usb) cannot allocate firmware"
"upload buffer!\n");
- err = -ENOMEM;
- goto err_bufalloc;
- }
-
- err = p54u_device_reset_3887(dev);
- if (err)
- goto err_reset;
-
- err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev);
- if (err) {
- dev_err(&priv->udev->dev, "p54usb: cannot find firmware "
- "(isl3887usb)\n");
- err = request_firmware(&fw_entry, "isl3887usb_bare",
- &priv->udev->dev);
- if (err)
- goto err_req_fw_failed;
- }
-
- err = p54_parse_firmware(dev, fw_entry);
- if (err)
- goto err_upload_failed;
-
- if (priv->common.fw_interface != FW_LM87) {
- dev_err(&priv->udev->dev, "wrong firmware, "
- "please get a LM87 firmware and try again.\n");
- err = -EINVAL;
- goto err_upload_failed;
+ return -ENOMEM;
}
- left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
+ left = block_size = min((size_t)P54U_FW_BLOCK, priv->fw->size);
strcpy(buf, p54u_firmware_upload_3887);
left -= strlen(p54u_firmware_upload_3887);
tmp += strlen(p54u_firmware_upload_3887);
- data = fw_entry->data;
- remains = fw_entry->size;
+ data = priv->fw->data;
+ remains = priv->fw->size;
hdr = (struct x2_header *)(buf + strlen(p54u_firmware_upload_3887));
memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
- hdr->fw_length = cpu_to_le32(fw_entry->size);
+ hdr->fw_length = cpu_to_le32(priv->fw->size);
hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
sizeof(u32)*2));
left -= sizeof(*hdr);
@@ -561,7 +515,8 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
}
- *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size));
+ *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, priv->fw->data,
+ priv->fw->size));
err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
if (err) {
dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");
@@ -612,19 +567,14 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
if (err)
goto err_upload_failed;
- err_upload_failed:
- release_firmware(fw_entry);
- err_req_fw_failed:
- err_reset:
+err_upload_failed:
kfree(buf);
- err_bufalloc:
return err;
}
static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
{
struct p54u_priv *priv = dev->priv;
- const struct firmware *fw_entry = NULL;
const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
int err, alen;
void *buf;
@@ -639,33 +589,6 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
return -ENOMEM;
}
- err = request_firmware(&fw_entry, "isl3886usb", &priv->udev->dev);
- if (err) {
- dev_err(&priv->udev->dev, "(p54usb) cannot find firmware "
- "(isl3886usb)\n");
- err = request_firmware(&fw_entry, "isl3890usb",
- &priv->udev->dev);
- if (err) {
- kfree(buf);
- return err;
- }
- }
-
- err = p54_parse_firmware(dev, fw_entry);
- if (err) {
- kfree(buf);
- release_firmware(fw_entry);
- return err;
- }
-
- if (priv->common.fw_interface != FW_LM86) {
- dev_err(&priv->udev->dev, "wrong firmware, "
- "please get a LM86(USB) firmware and try again.\n");
- kfree(buf);
- release_firmware(fw_entry);
- return -EINVAL;
- }
-
#define P54U_WRITE(type, addr, data) \
do {\
err = p54u_write(priv, buf, type,\
@@ -765,8 +688,8 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
/* finally, we can upload firmware now! */
- remains = fw_entry->size;
- data = fw_entry->data;
+ remains = priv->fw->size;
+ data = priv->fw->data;
offset = ISL38XX_DEV_FIRMWARE_ADDR;
while (remains) {
@@ -875,12 +798,54 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
#undef P54U_WRITE
#undef P54U_READ
- fail:
- release_firmware(fw_entry);
+fail:
kfree(buf);
return err;
}
+static int p54u_load_firmware(struct ieee80211_hw *dev)
+{
+ struct p54u_priv *priv = dev->priv;
+ int err, i;
+
+ BUILD_BUG_ON(ARRAY_SIZE(p54u_fwlist) != __NUM_P54U_HWTYPES);
+
+ for (i = 0; i < __NUM_P54U_HWTYPES; i++)
+ if (p54u_fwlist[i].type == priv->hw_type)
+ break;
+
+ if (i == __NUM_P54U_HWTYPES)
+ return -EOPNOTSUPP;
+
+ err = request_firmware(&priv->fw, p54u_fwlist[i].fw, &priv->udev->dev);
+ if (err) {
+ dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s "
+ "(%d)!\n", p54u_fwlist[i].fw, err);
+
+ err = request_firmware(&priv->fw, p54u_fwlist[i].fw_legacy,
+ &priv->udev->dev);
+ if (err)
+ return err;
+ }
+
+ err = p54_parse_firmware(dev, priv->fw);
+ if (err)
+ goto out;
+
+ if (priv->common.fw_interface != p54u_fwlist[i].intf) {
+ dev_err(&priv->udev->dev, "wrong firmware, please get "
+ "a firmware for \"%s\" and try again.\n",
+ p54u_fwlist[i].hw);
+ err = -EINVAL;
+ }
+
+out:
+ if (err)
+ release_firmware(priv->fw);
+
+ return err;
+}
+
static int p54u_open(struct ieee80211_hw *dev)
{
struct p54u_priv *priv = dev->priv;
@@ -922,6 +887,7 @@ static int __devinit p54u_probe(struct usb_interface *intf,
}
priv = dev->priv;
+ priv->hw_type = P54U_INVALID_HW;
SET_IEEE80211_DEV(dev, &intf->dev);
usb_set_intfdata(intf, dev);
@@ -953,37 +919,48 @@ static int __devinit p54u_probe(struct usb_interface *intf,
priv->common.open = p54u_open;
priv->common.stop = p54u_stop;
if (recognized_pipes < P54U_PIPE_NUMBER) {
+#ifdef CONFIG_PM
+ /* ISL3887 needs a full reset on resume */
+ udev->reset_resume = 1;
+ err = p54u_device_reset(dev);
+#endif
+
priv->hw_type = P54U_3887;
- err = p54u_upload_firmware_3887(dev);
- if (priv->common.fw_interface == FW_LM87) {
- dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
- priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);
- priv->common.tx = p54u_tx_lm87;
- } else
- priv->common.tx = p54u_tx_3887;
+ dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
+ priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);
+ priv->common.tx = p54u_tx_lm87;
+ priv->upload_fw = p54u_upload_firmware_3887;
} else {
priv->hw_type = P54U_NET2280;
dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
priv->common.tx = p54u_tx_net2280;
- err = p54u_upload_firmware_net2280(dev);
+ priv->upload_fw = p54u_upload_firmware_net2280;
}
+ err = p54u_load_firmware(dev);
if (err)
goto err_free_dev;
+ err = priv->upload_fw(dev);
+ if (err)
+ goto err_free_fw;
+
p54u_open(dev);
err = p54_read_eeprom(dev);
p54u_stop(dev);
if (err)
- goto err_free_dev;
+ goto err_free_fw;
err = p54_register_common(dev, &udev->dev);
if (err)
- goto err_free_dev;
+ goto err_free_fw;
return 0;
- err_free_dev:
+err_free_fw:
+ release_firmware(priv->fw);
+
+err_free_dev:
ieee80211_free_hw(dev);
usb_set_intfdata(intf, NULL);
usb_put_dev(udev);
@@ -1002,20 +979,64 @@ static void __devexit p54u_disconnect(struct usb_interface *intf)
priv = dev->priv;
usb_put_dev(interface_to_usbdev(intf));
+ release_firmware(priv->fw);
p54_free_common(dev);
ieee80211_free_hw(dev);
}
static int p54u_pre_reset(struct usb_interface *intf)
{
+ struct ieee80211_hw *dev = usb_get_intfdata(intf);
+
+ if (!dev)
+ return -ENODEV;
+
+ p54u_stop(dev);
return 0;
}
+static int p54u_resume(struct usb_interface *intf)
+{
+ struct ieee80211_hw *dev = usb_get_intfdata(intf);
+ struct p54u_priv *priv;
+
+ if (!dev)
+ return -ENODEV;
+
+ priv = dev->priv;
+ if (unlikely(!(priv->upload_fw && priv->fw)))
+ return 0;
+
+ return priv->upload_fw(dev);
+}
+
static int p54u_post_reset(struct usb_interface *intf)
{
+ struct ieee80211_hw *dev = usb_get_intfdata(intf);
+ struct p54u_priv *priv;
+ int err;
+
+ err = p54u_resume(intf);
+ if (err)
+ return err;
+
+ /* reinitialize old device state */
+ priv = dev->priv;
+ if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED)
+ ieee80211_restart_hw(dev);
+
return 0;
}
+#ifdef CONFIG_PM
+
+static int p54u_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ return p54u_pre_reset(intf);
+}
+
+#endif /* CONFIG_PM */
+
static struct usb_driver p54u_driver = {
.name = "p54usb",
.id_table = p54u_table,
@@ -1023,6 +1044,11 @@ static struct usb_driver p54u_driver = {
.disconnect = p54u_disconnect,
.pre_reset = p54u_pre_reset,
.post_reset = p54u_post_reset,
+#ifdef CONFIG_PM
+ .suspend = p54u_suspend,
+ .resume = p54u_resume,
+ .reset_resume = p54u_resume,
+#endif /* CONFIG_PM */
.soft_unbind = 1,
};
diff --git a/drivers/net/wireless/p54/p54usb.h b/drivers/net/wireless/p54/p54usb.h
index 8bc58982d8d..e935b79f7f7 100644
--- a/drivers/net/wireless/p54/p54usb.h
+++ b/drivers/net/wireless/p54/p54usb.h
@@ -123,18 +123,26 @@ struct p54u_rx_info {
struct ieee80211_hw *dev;
};
+enum p54u_hw_type {
+ P54U_INVALID_HW,
+ P54U_NET2280,
+ P54U_3887,
+
+ /* keep last */
+ __NUM_P54U_HWTYPES,
+};
+
struct p54u_priv {
struct p54_common common;
struct usb_device *udev;
struct usb_interface *intf;
- enum {
- P54U_NET2280 = 0,
- P54U_3887
- } hw_type;
+ int (*upload_fw)(struct ieee80211_hw *dev);
+ enum p54u_hw_type hw_type;
spinlock_t lock;
struct sk_buff_head rx_queue;
struct usb_anchor submitted;
+ const struct firmware *fw;
};
#endif /* P54USB_H */
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index ef3ef4551b3..8f621099344 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -87,7 +87,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
unsigned long flags;
unsigned char wds_mac[6];
u32 curr_frag;
- int err = 0;
#if VERBOSE > SHOW_ERROR_MESSAGES
DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_transmit \n");
@@ -107,8 +106,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
isl38xx_w32_flush(priv->device_base, ISL38XX_DEV_INT_UPDATE,
ISL38XX_DEV_INT_REG);
udelay(ISL38XX_WRITEIO_DELAY);
-
- err = -EBUSY;
goto drop_free;
}
/* Check alignment and WDS frame formatting. The start of the packet should
@@ -152,7 +149,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
if (unlikely(newskb == NULL)) {
printk(KERN_ERR "%s: Cannot allocate skb\n",
ndev->name);
- err = -ENOMEM;
goto drop_free;
}
newskb_offset = (4 - (long) newskb->data) & 0x03;
@@ -197,8 +193,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
if (unlikely(pci_map_address == 0)) {
printk(KERN_WARNING "%s: cannot map buffer to PCI\n",
ndev->name);
-
- err = -EIO;
goto drop_free;
}
/* Place the fragment in the control block structure. */
@@ -246,7 +240,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
ndev->stats.tx_dropped++;
spin_unlock_irqrestore(&priv->slock, flags);
dev_kfree_skb(skb);
- return err;
+ return NETDEV_TX_OK;
}
static inline int
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index fa90d1d8d82..b10b0383dfa 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -892,7 +892,7 @@ static int ray_dev_init(struct net_device *dev)
#endif /* RAY_IMMEDIATE_INIT */
/* copy mac and broadcast addresses to linux device */
- memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
+ memcpy(dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
memset(dev->broadcast, 0xff, ETH_ALEN);
DEBUG(2, "ray_dev_init ending\n");
@@ -923,7 +923,7 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (!(pcmcia_dev_present(link))) {
DEBUG(2, "ray_dev_start_xmit - device not present\n");
- return -1;
+ return NETDEV_TX_LOCKED;
}
DEBUG(3, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev);
if (local->authentication_state == NEED_TO_AUTH) {
@@ -931,7 +931,7 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (!build_auth_frame(local, local->auth_id, OPEN_AUTH_REQUEST)) {
local->authentication_state = AUTHENTICATED;
netif_stop_queue(dev);
- return 1;
+ return NETDEV_TX_BUSY;
}
}
@@ -944,7 +944,7 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
case XMIT_NO_CCS:
case XMIT_NEED_AUTH:
netif_stop_queue(dev);
- return 1;
+ return NETDEV_TX_BUSY;
case XMIT_NO_INTR:
case XMIT_MSG_BAD:
case XMIT_OK:
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index ff0042ffe3e..3bec3dbd345 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -2,7 +2,7 @@
* Driver for RNDIS based wireless USB devices.
*
* Copyright (C) 2007 by Bjorge Dijkstra <bjd@jooz.net>
- * Copyright (C) 2008 by Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+ * Copyright (C) 2008-2009 by Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -42,6 +42,7 @@
#include <linux/ctype.h>
#include <linux/spinlock.h>
#include <net/iw_handler.h>
+#include <net/cfg80211.h>
#include <linux/usb/usbnet.h>
#include <linux/usb/rndis_host.h>
@@ -156,43 +157,55 @@ MODULE_PARM_DESC(workaround_interval,
#define NDIS_802_11_LENGTH_RATES_EX 16
enum ndis_80211_net_type {
- ndis_80211_type_freq_hop,
- ndis_80211_type_direct_seq,
- ndis_80211_type_ofdm_a,
- ndis_80211_type_ofdm_g
+ NDIS_80211_TYPE_FREQ_HOP,
+ NDIS_80211_TYPE_DIRECT_SEQ,
+ NDIS_80211_TYPE_OFDM_A,
+ NDIS_80211_TYPE_OFDM_G
};
enum ndis_80211_net_infra {
- ndis_80211_infra_adhoc,
- ndis_80211_infra_infra,
- ndis_80211_infra_auto_unknown
+ NDIS_80211_INFRA_ADHOC,
+ NDIS_80211_INFRA_INFRA,
+ NDIS_80211_INFRA_AUTO_UNKNOWN
};
enum ndis_80211_auth_mode {
- ndis_80211_auth_open,
- ndis_80211_auth_shared,
- ndis_80211_auth_auto_switch,
- ndis_80211_auth_wpa,
- ndis_80211_auth_wpa_psk,
- ndis_80211_auth_wpa_none,
- ndis_80211_auth_wpa2,
- ndis_80211_auth_wpa2_psk
+ NDIS_80211_AUTH_OPEN,
+ NDIS_80211_AUTH_SHARED,
+ NDIS_80211_AUTH_AUTO_SWITCH,
+ NDIS_80211_AUTH_WPA,
+ NDIS_80211_AUTH_WPA_PSK,
+ NDIS_80211_AUTH_WPA_NONE,
+ NDIS_80211_AUTH_WPA2,
+ NDIS_80211_AUTH_WPA2_PSK
};
enum ndis_80211_encr_status {
- ndis_80211_encr_wep_enabled,
- ndis_80211_encr_disabled,
- ndis_80211_encr_wep_key_absent,
- ndis_80211_encr_not_supported,
- ndis_80211_encr_tkip_enabled,
- ndis_80211_encr_tkip_key_absent,
- ndis_80211_encr_ccmp_enabled,
- ndis_80211_encr_ccmp_key_absent
+ NDIS_80211_ENCR_WEP_ENABLED,
+ NDIS_80211_ENCR_DISABLED,
+ NDIS_80211_ENCR_WEP_KEY_ABSENT,
+ NDIS_80211_ENCR_NOT_SUPPORTED,
+ NDIS_80211_ENCR_TKIP_ENABLED,
+ NDIS_80211_ENCR_TKIP_KEY_ABSENT,
+ NDIS_80211_ENCR_CCMP_ENABLED,
+ NDIS_80211_ENCR_CCMP_KEY_ABSENT
};
enum ndis_80211_priv_filter {
- ndis_80211_priv_accept_all,
- ndis_80211_priv_8021x_wep
+ NDIS_80211_PRIV_ACCEPT_ALL,
+ NDIS_80211_PRIV_8021X_WEP
+};
+
+enum ndis_80211_addkey_bits {
+ NDIS_80211_ADDKEY_8021X_AUTH = cpu_to_le32(1 << 28),
+ NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ = cpu_to_le32(1 << 29),
+ NDIS_80211_ADDKEY_PAIRWISE_KEY = cpu_to_le32(1 << 30),
+ NDIS_80211_ADDKEY_TRANSMIT_KEY = cpu_to_le32(1 << 31)
+};
+
+enum ndis_80211_addwep_bits {
+ NDIS_80211_ADDWEP_PERCLIENT_KEY = cpu_to_le32(1 << 30),
+ NDIS_80211_ADDWEP_TRANSMIT_KEY = cpu_to_le32(1 << 31)
};
struct ndis_80211_ssid {
@@ -308,7 +321,6 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
#define CAP_MODE_80211B 2
#define CAP_MODE_80211G 4
#define CAP_MODE_MASK 7
-#define CAP_SUPPORT_TXPOWER 8
#define WORK_LINK_UP (1<<0)
#define WORK_LINK_DOWN (1<<1)
@@ -316,25 +328,61 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
#define COMMAND_BUFFER_SIZE (CONTROL_BUFFER_SIZE + sizeof(struct rndis_set))
-/* RNDIS device private data */
-struct rndis_wext_private {
- char name[32];
+static const struct ieee80211_channel rndis_channels[] = {
+ { .center_freq = 2412 },
+ { .center_freq = 2417 },
+ { .center_freq = 2422 },
+ { .center_freq = 2427 },
+ { .center_freq = 2432 },
+ { .center_freq = 2437 },
+ { .center_freq = 2442 },
+ { .center_freq = 2447 },
+ { .center_freq = 2452 },
+ { .center_freq = 2457 },
+ { .center_freq = 2462 },
+ { .center_freq = 2467 },
+ { .center_freq = 2472 },
+ { .center_freq = 2484 },
+};
+static const struct ieee80211_rate rndis_rates[] = {
+ { .bitrate = 10 },
+ { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 60 },
+ { .bitrate = 90 },
+ { .bitrate = 120 },
+ { .bitrate = 180 },
+ { .bitrate = 240 },
+ { .bitrate = 360 },
+ { .bitrate = 480 },
+ { .bitrate = 540 }
+};
+
+/* RNDIS device private data */
+struct rndis_wlan_private {
struct usbnet *usbdev;
+ struct wireless_dev wdev;
+
+ struct cfg80211_scan_request *scan_request;
+
struct workqueue_struct *workqueue;
struct delayed_work stats_work;
+ struct delayed_work scan_work;
struct work_struct work;
struct mutex command_lock;
spinlock_t stats_lock;
unsigned long work_pending;
+ struct ieee80211_supported_band band;
+ struct ieee80211_channel channels[ARRAY_SIZE(rndis_channels)];
+ struct ieee80211_rate rates[ARRAY_SIZE(rndis_rates)];
+
struct iw_statistics iwstats;
struct iw_statistics privstats;
- int nick_len;
- char nick[32];
-
int caps;
int multicast_size;
@@ -357,6 +405,7 @@ struct rndis_wext_private {
int encr_tx_key_index;
char encr_keys[4][32];
int encr_key_len[4];
+ char encr_key_wpa[4];
int wpa_version;
int wpa_keymgmt;
int wpa_authalg;
@@ -368,8 +417,22 @@ struct rndis_wext_private {
u8 command_buffer[COMMAND_BUFFER_SIZE];
};
+/*
+ * cfg80211 ops
+ */
+static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params);
+
+static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_scan_request *request);
-static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 };
+static struct cfg80211_ops rndis_config_ops = {
+ .change_virtual_intf = rndis_change_virtual_intf,
+ .scan = rndis_scan,
+};
+
+static void *rndis_wiphy_privid = &rndis_wiphy_privid;
static const int bcm4320_power_output[4] = { 25, 50, 75, 100 };
@@ -378,13 +441,13 @@ static const unsigned char ffff_bssid[ETH_ALEN] = { 0xff, 0xff, 0xff,
0xff, 0xff, 0xff };
-static struct rndis_wext_private *get_rndis_wext_priv(struct usbnet *dev)
+static struct rndis_wlan_private *get_rndis_wlan_priv(struct usbnet *dev)
{
- return (struct rndis_wext_private *)dev->driver_priv;
+ return (struct rndis_wlan_private *)dev->driver_priv;
}
-static u32 get_bcm4320_power(struct rndis_wext_private *priv)
+static u32 get_bcm4320_power(struct rndis_wlan_private *priv)
{
return BCM4320_DEFAULT_TXPOWER *
bcm4320_power_output[priv->param_power_output] / 100;
@@ -417,7 +480,7 @@ static int rndis_error_status(__le32 rndis_status)
static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
union {
void *buf;
struct rndis_msg_hdr *header;
@@ -463,7 +526,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
union {
void *buf;
struct rndis_msg_hdr *header;
@@ -684,7 +747,7 @@ static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
int ret;
ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid));
@@ -731,7 +794,7 @@ static int is_associated(struct usbnet *usbdev)
static int disassociate(struct usbnet *usbdev, int reset_ssid)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
struct ndis_80211_ssid ssid;
int i, ret = 0;
@@ -763,7 +826,7 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid)
static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
__le32 tmp;
int auth_mode, ret;
@@ -772,23 +835,23 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) {
if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
- auth_mode = ndis_80211_auth_wpa2;
+ auth_mode = NDIS_80211_AUTH_WPA2;
else
- auth_mode = ndis_80211_auth_wpa2_psk;
+ auth_mode = NDIS_80211_AUTH_WPA2_PSK;
} else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) {
if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
- auth_mode = ndis_80211_auth_wpa;
+ auth_mode = NDIS_80211_AUTH_WPA;
else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK)
- auth_mode = ndis_80211_auth_wpa_psk;
+ auth_mode = NDIS_80211_AUTH_WPA_PSK;
else
- auth_mode = ndis_80211_auth_wpa_none;
+ auth_mode = NDIS_80211_AUTH_WPA_NONE;
} else if (authalg & IW_AUTH_ALG_SHARED_KEY) {
if (authalg & IW_AUTH_ALG_OPEN_SYSTEM)
- auth_mode = ndis_80211_auth_auto_switch;
+ auth_mode = NDIS_80211_AUTH_AUTO_SWITCH;
else
- auth_mode = ndis_80211_auth_shared;
+ auth_mode = NDIS_80211_AUTH_SHARED;
} else
- auth_mode = ndis_80211_auth_open;
+ auth_mode = NDIS_80211_AUTH_OPEN;
tmp = cpu_to_le32(auth_mode);
ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp,
@@ -806,16 +869,16 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
static int set_priv_filter(struct usbnet *usbdev)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
__le32 tmp;
devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version);
if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 ||
priv->wpa_version & IW_AUTH_WPA_VERSION_WPA)
- tmp = cpu_to_le32(ndis_80211_priv_8021x_wep);
+ tmp = cpu_to_le32(NDIS_80211_PRIV_8021X_WEP);
else
- tmp = cpu_to_le32(ndis_80211_priv_accept_all);
+ tmp = cpu_to_le32(NDIS_80211_PRIV_ACCEPT_ALL);
return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp,
sizeof(tmp));
@@ -824,7 +887,7 @@ static int set_priv_filter(struct usbnet *usbdev)
static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
__le32 tmp;
int encr_mode, ret;
@@ -833,18 +896,18 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
groupwise);
if (pairwise & IW_AUTH_CIPHER_CCMP)
- encr_mode = ndis_80211_encr_ccmp_enabled;
+ encr_mode = NDIS_80211_ENCR_CCMP_ENABLED;
else if (pairwise & IW_AUTH_CIPHER_TKIP)
- encr_mode = ndis_80211_encr_tkip_enabled;
+ encr_mode = NDIS_80211_ENCR_TKIP_ENABLED;
else if (pairwise &
(IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
- encr_mode = ndis_80211_encr_wep_enabled;
+ encr_mode = NDIS_80211_ENCR_WEP_ENABLED;
else if (groupwise & IW_AUTH_CIPHER_CCMP)
- encr_mode = ndis_80211_encr_ccmp_enabled;
+ encr_mode = NDIS_80211_ENCR_CCMP_ENABLED;
else if (groupwise & IW_AUTH_CIPHER_TKIP)
- encr_mode = ndis_80211_encr_tkip_enabled;
+ encr_mode = NDIS_80211_ENCR_TKIP_ENABLED;
else
- encr_mode = ndis_80211_encr_disabled;
+ encr_mode = NDIS_80211_ENCR_DISABLED;
tmp = cpu_to_le32(encr_mode);
ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp,
@@ -862,7 +925,7 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
static int set_assoc_params(struct usbnet *usbdev)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg);
set_priv_filter(usbdev);
@@ -874,7 +937,7 @@ static int set_assoc_params(struct usbnet *usbdev)
static int set_infra_mode(struct usbnet *usbdev, int mode)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
__le32 tmp;
int ret, i;
@@ -894,7 +957,7 @@ static int set_infra_mode(struct usbnet *usbdev, int mode)
if (priv->wpa_keymgmt == 0 ||
priv->wpa_keymgmt == IW_AUTH_KEY_MGMT_802_1X) {
for (i = 0; i < 4; i++) {
- if (priv->encr_key_len[i] > 0)
+ if (priv->encr_key_len[i] > 0 && !priv->encr_key_wpa[i])
add_wep_key(usbdev, priv->encr_keys[i],
priv->encr_key_len[i], i);
}
@@ -907,12 +970,12 @@ static int set_infra_mode(struct usbnet *usbdev, int mode)
static void set_default_iw_params(struct usbnet *usbdev)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
priv->wpa_keymgmt = 0;
priv->wpa_version = 0;
- set_infra_mode(usbdev, ndis_80211_infra_infra);
+ set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA);
set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
IW_AUTH_ALG_OPEN_SYSTEM);
set_priv_filter(usbdev);
@@ -933,7 +996,7 @@ static int deauthenticate(struct usbnet *usbdev)
/* index must be 0 - N, as per NDIS */
static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
struct ndis_80211_wep_key ndis_key;
int ret;
@@ -948,7 +1011,7 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
memcpy(&ndis_key.material, key, key_len);
if (index == priv->encr_tx_key_index) {
- ndis_key.index |= cpu_to_le32(1 << 31);
+ ndis_key.index |= NDIS_80211_ADDWEP_TRANSMIT_KEY;
ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104,
IW_AUTH_CIPHER_NONE);
if (ret)
@@ -965,16 +1028,85 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
}
priv->encr_key_len[index] = key_len;
+ priv->encr_key_wpa[index] = 0;
memcpy(&priv->encr_keys[index], key, key_len);
return 0;
}
+static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
+ int index, const struct sockaddr *addr,
+ const u8 *rx_seq, int alg, int flags)
+{
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+ struct ndis_80211_key ndis_key;
+ int ret;
+
+ if (index < 0 || index >= 4)
+ return -EINVAL;
+ if (key_len > sizeof(ndis_key.material) || key_len < 0)
+ return -EINVAL;
+ if ((flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) && !rx_seq)
+ return -EINVAL;
+ if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !addr)
+ return -EINVAL;
+
+ devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index,
+ !!(flags & NDIS_80211_ADDKEY_TRANSMIT_KEY),
+ !!(flags & NDIS_80211_ADDKEY_PAIRWISE_KEY),
+ !!(flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ));
+
+ memset(&ndis_key, 0, sizeof(ndis_key));
+
+ ndis_key.size = cpu_to_le32(sizeof(ndis_key) -
+ sizeof(ndis_key.material) + key_len);
+ ndis_key.length = cpu_to_le32(key_len);
+ ndis_key.index = cpu_to_le32(index) | flags;
+
+ if (alg == IW_ENCODE_ALG_TKIP && key_len == 32) {
+ /* wpa_supplicant gives us the Michael MIC RX/TX keys in
+ * different order than NDIS spec, so swap the order here. */
+ memcpy(ndis_key.material, key, 16);
+ memcpy(ndis_key.material + 16, key + 24, 8);
+ memcpy(ndis_key.material + 24, key + 16, 8);
+ } else
+ memcpy(ndis_key.material, key, key_len);
+
+ if (flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ)
+ memcpy(ndis_key.rsc, rx_seq, 6);
+
+ if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) {
+ /* pairwise key */
+ memcpy(ndis_key.bssid, addr->sa_data, ETH_ALEN);
+ } else {
+ /* group key */
+ if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
+ memset(ndis_key.bssid, 0xff, ETH_ALEN);
+ else
+ get_bssid(usbdev, ndis_key.bssid);
+ }
+
+ ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key,
+ le32_to_cpu(ndis_key.size));
+ devdbg(usbdev, "add_wpa_key: OID_802_11_ADD_KEY -> %08X", ret);
+ if (ret != 0)
+ return ret;
+
+ priv->encr_key_len[index] = key_len;
+ priv->encr_key_wpa[index] = 1;
+
+ if (flags & NDIS_80211_ADDKEY_TRANSMIT_KEY)
+ priv->encr_tx_key_index = index;
+
+ return 0;
+}
+
+
/* remove_key is for both wep and wpa */
static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
struct ndis_80211_remove_key remove_key;
__le32 keyindex;
int ret;
@@ -983,6 +1115,7 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
return 0;
priv->encr_key_len[index] = 0;
+ priv->encr_key_wpa[index] = 0;
memset(&priv->encr_keys[index], 0, sizeof(priv->encr_keys[index]));
if (priv->wpa_cipher_pair == IW_AUTH_CIPHER_TKIP ||
@@ -994,7 +1127,8 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
if (bssid) {
/* pairwise key */
if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0)
- remove_key.index |= cpu_to_le32(1 << 30);
+ remove_key.index |=
+ NDIS_80211_ADDKEY_PAIRWISE_KEY;
memcpy(remove_key.bssid, bssid,
sizeof(remove_key.bssid));
} else
@@ -1027,7 +1161,7 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
static void set_multicast_list(struct usbnet *usbdev)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
struct dev_mc_list *mclist;
__le32 filter;
int ret, i, size;
@@ -1086,131 +1220,180 @@ static void set_multicast_list(struct usbnet *usbdev)
/*
- * wireless extension handlers
+ * cfg80211 ops
*/
-
-static int rndis_iw_commit(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
{
- /* dummy op */
- return 0;
+ struct net_device *dev;
+ struct usbnet *usbdev;
+ int mode;
+
+ /* we're under RTNL */
+ dev = __dev_get_by_index(&init_net, ifindex);
+ if (!dev)
+ return -ENODEV;
+ usbdev = netdev_priv(dev);
+
+ switch (type) {
+ case NL80211_IFTYPE_ADHOC:
+ mode = NDIS_80211_INFRA_ADHOC;
+ break;
+ case NL80211_IFTYPE_STATION:
+ mode = NDIS_80211_INFRA_INFRA;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return set_infra_mode(usbdev, mode);
}
-static int rndis_iw_get_range(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+#define SCAN_DELAY_JIFFIES (HZ)
+static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_scan_request *request)
{
- struct iw_range *range = (struct iw_range *)extra;
struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
- int len, ret, i, j, num, has_80211g_rates;
- u8 rates[8];
- __le32 tx_power;
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+ int ret;
+ __le32 tmp;
+
+ devdbg(usbdev, "cfg80211.scan");
- devdbg(usbdev, "SIOCGIWRANGE");
+ if (!request)
+ return -EINVAL;
- /* clear iw_range struct */
- memset(range, 0, sizeof(*range));
- wrqu->data.length = sizeof(*range);
+ if (priv->scan_request && priv->scan_request != request)
+ return -EBUSY;
- range->txpower_capa = IW_TXPOW_MWATT;
- range->num_txpower = 1;
- if (priv->caps & CAP_SUPPORT_TXPOWER) {
- len = sizeof(tx_power);
- ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
- &tx_power, &len);
- if (ret == 0 && le32_to_cpu(tx_power) != 0xFF)
- range->txpower[0] = le32_to_cpu(tx_power);
- else
- range->txpower[0] = get_bcm4320_power(priv);
- } else
- range->txpower[0] = get_bcm4320_power(priv);
+ priv->scan_request = request;
- len = sizeof(rates);
- ret = rndis_query_oid(usbdev, OID_802_11_SUPPORTED_RATES, &rates,
- &len);
- has_80211g_rates = 0;
+ tmp = cpu_to_le32(1);
+ ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
+ sizeof(tmp));
if (ret == 0) {
- j = 0;
- for (i = 0; i < len; i++) {
- if (rates[i] == 0)
- break;
- range->bitrate[j] = (rates[i] & 0x7f) * 500000;
- /* check for non 802.11b rates */
- if (range->bitrate[j] == 6000000 ||
- range->bitrate[j] == 9000000 ||
- (range->bitrate[j] >= 12000000 &&
- range->bitrate[j] != 22000000))
- has_80211g_rates = 1;
- j++;
- }
- range->num_bitrates = j;
- } else
- range->num_bitrates = 0;
-
- /* fill in 802.11g rates */
- if (has_80211g_rates) {
- num = range->num_bitrates;
- for (i = 0; i < ARRAY_SIZE(rates_80211g); i++) {
- for (j = 0; j < num; j++) {
- if (range->bitrate[j] ==
- rates_80211g[i] * 1000000)
- break;
- }
- if (j == num)
- range->bitrate[range->num_bitrates++] =
- rates_80211g[i] * 1000000;
- if (range->num_bitrates == IW_MAX_BITRATES)
- break;
- }
+ /* Wait before retrieving scan results from device */
+ queue_delayed_work(priv->workqueue, &priv->scan_work,
+ SCAN_DELAY_JIFFIES);
+ }
- /* estimated max real througput in bps */
- range->throughput = 54 * 1000 * 1000 / 2;
+ return ret;
+}
- /* ~35% more with afterburner */
- if (priv->param_afterburner)
- range->throughput = range->throughput / 100 * 135;
- } else {
- /* estimated max real througput in bps */
- range->throughput = 11 * 1000 * 1000 / 2;
+
+static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
+ struct ndis_80211_bssid_ex *bssid)
+{
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+ struct ieee80211_channel *channel;
+ s32 signal;
+ u64 timestamp;
+ u16 capability;
+ u16 beacon_interval;
+ struct ndis_80211_fixed_ies *fixed;
+ int ie_len, bssid_len;
+ u8 *ie;
+
+ /* parse bssid structure */
+ bssid_len = le32_to_cpu(bssid->length);
+
+ if (bssid_len < sizeof(struct ndis_80211_bssid_ex) +
+ sizeof(struct ndis_80211_fixed_ies))
+ return NULL;
+
+ fixed = (struct ndis_80211_fixed_ies *)bssid->ies;
+
+ ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
+ ie_len = min(bssid_len - (int)sizeof(*bssid),
+ (int)le32_to_cpu(bssid->ie_length));
+ ie_len -= sizeof(struct ndis_80211_fixed_ies);
+ if (ie_len < 0)
+ return NULL;
+
+ /* extract data for cfg80211_inform_bss */
+ channel = ieee80211_get_channel(priv->wdev.wiphy,
+ KHZ_TO_MHZ(le32_to_cpu(bssid->config.ds_config)));
+ if (!channel)
+ return NULL;
+
+ signal = level_to_qual(le32_to_cpu(bssid->rssi));
+ timestamp = le64_to_cpu(*(__le64 *)fixed->timestamp);
+ capability = le16_to_cpu(fixed->capabilities);
+ beacon_interval = le16_to_cpu(fixed->beacon_interval);
+
+ return cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid->mac,
+ timestamp, capability, beacon_interval, ie, ie_len, signal,
+ GFP_KERNEL);
+}
+
+
+static int rndis_check_bssid_list(struct usbnet *usbdev)
+{
+ void *buf = NULL;
+ struct ndis_80211_bssid_list_ex *bssid_list;
+ struct ndis_80211_bssid_ex *bssid;
+ int ret = -EINVAL, len, count, bssid_len;
+
+ devdbg(usbdev, "check_bssid_list");
+
+ len = CONTROL_BUFFER_SIZE;
+ buf = kmalloc(len, GFP_KERNEL);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto out;
}
- range->num_channels = 14;
+ ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
+ if (ret != 0)
+ goto out;
- for (i = 0; (i < 14) && (i < IW_MAX_FREQUENCIES); i++) {
- range->freq[i].i = i + 1;
- range->freq[i].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000;
- range->freq[i].e = 1;
+ bssid_list = buf;
+ bssid = bssid_list->bssid;
+ bssid_len = le32_to_cpu(bssid->length);
+ count = le32_to_cpu(bssid_list->num_items);
+ devdbg(usbdev, "check_bssid_list: %d BSSIDs found", count);
+
+ while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
+ rndis_bss_info_update(usbdev, bssid);
+
+ bssid = (void *)bssid + bssid_len;
+ bssid_len = le32_to_cpu(bssid->length);
+ count--;
}
- range->num_frequency = i;
- range->min_rts = 0;
- range->max_rts = 2347;
- range->min_frag = 256;
- range->max_frag = 2346;
+out:
+ kfree(buf);
+ return ret;
+}
- range->max_qual.qual = 100;
- range->max_qual.level = 154;
- range->max_qual.updated = IW_QUAL_QUAL_UPDATED
- | IW_QUAL_LEVEL_UPDATED
- | IW_QUAL_NOISE_INVALID;
- range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = WIRELESS_EXT;
+static void rndis_get_scan_results(struct work_struct *work)
+{
+ struct rndis_wlan_private *priv =
+ container_of(work, struct rndis_wlan_private, scan_work.work);
+ struct usbnet *usbdev = priv->usbdev;
+ int ret;
+
+ devdbg(usbdev, "get_scan_results");
- range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
- IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
- return 0;
+ ret = rndis_check_bssid_list(usbdev);
+
+ cfg80211_scan_done(priv->scan_request, ret < 0);
+
+ priv->scan_request = NULL;
}
-static int rndis_iw_get_name(struct net_device *dev,
+/*
+ * wireless extension handlers
+ */
+
+static int rndis_iw_commit(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
{
- struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-
- strcpy(wrqu->name, priv->name);
+ /* dummy op */
return 0;
}
@@ -1314,7 +1497,7 @@ static int rndis_iw_set_auth(struct net_device *dev,
{
struct iw_param *p = &wrqu->param;
struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
int ret = -ENOTSUPP;
switch (p->flags & IW_AUTH_INDEX) {
@@ -1395,7 +1578,7 @@ static int rndis_iw_get_auth(struct net_device *dev,
{
struct iw_param *p = &wrqu->param;
struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
switch (p->flags & IW_AUTH_INDEX) {
case IW_AUTH_WPA_VERSION:
@@ -1422,60 +1605,11 @@ static int rndis_iw_get_auth(struct net_device *dev,
}
-static int rndis_iw_get_mode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-
- switch (priv->infra_mode) {
- case ndis_80211_infra_adhoc:
- wrqu->mode = IW_MODE_ADHOC;
- break;
- case ndis_80211_infra_infra:
- wrqu->mode = IW_MODE_INFRA;
- break;
- /*case ndis_80211_infra_auto_unknown:*/
- default:
- wrqu->mode = IW_MODE_AUTO;
- break;
- }
- devdbg(usbdev, "SIOCGIWMODE: %08x", wrqu->mode);
- return 0;
-}
-
-
-static int rndis_iw_set_mode(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
- struct usbnet *usbdev = netdev_priv(dev);
- int mode;
-
- devdbg(usbdev, "SIOCSIWMODE: %08x", wrqu->mode);
-
- switch (wrqu->mode) {
- case IW_MODE_ADHOC:
- mode = ndis_80211_infra_adhoc;
- break;
- case IW_MODE_INFRA:
- mode = ndis_80211_infra_infra;
- break;
- /*case IW_MODE_AUTO:*/
- default:
- mode = ndis_80211_infra_auto_unknown;
- break;
- }
-
- return set_infra_mode(usbdev, mode);
-}
-
-
static int rndis_iw_set_encode(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
{
struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
int ret, index, key_len;
u8 *key;
@@ -1538,10 +1672,8 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
{
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
- struct ndis_80211_key ndis_key;
- int keyidx, ret;
- u8 *addr;
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+ int keyidx, flags;
keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX;
@@ -1564,250 +1696,16 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0)
return remove_key(usbdev, keyidx, NULL);
- if (ext->key_len > sizeof(ndis_key.material))
- return -1;
-
- memset(&ndis_key, 0, sizeof(ndis_key));
-
- ndis_key.size = cpu_to_le32(sizeof(ndis_key) -
- sizeof(ndis_key.material) + ext->key_len);
- ndis_key.length = cpu_to_le32(ext->key_len);
- ndis_key.index = cpu_to_le32(keyidx);
-
- if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
- memcpy(ndis_key.rsc, ext->rx_seq, 6);
- ndis_key.index |= cpu_to_le32(1 << 29);
- }
-
- addr = ext->addr.sa_data;
- if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
- /* group key */
- if (priv->infra_mode == ndis_80211_infra_adhoc)
- memset(ndis_key.bssid, 0xff, ETH_ALEN);
- else
- get_bssid(usbdev, ndis_key.bssid);
- } else {
- /* pairwise key */
- ndis_key.index |= cpu_to_le32(1 << 30);
- memcpy(ndis_key.bssid, addr, ETH_ALEN);
- }
-
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
- ndis_key.index |= cpu_to_le32(1 << 31);
-
- if (ext->alg == IW_ENCODE_ALG_TKIP && ext->key_len == 32) {
- /* wpa_supplicant gives us the Michael MIC RX/TX keys in
- * different order than NDIS spec, so swap the order here. */
- memcpy(ndis_key.material, ext->key, 16);
- memcpy(ndis_key.material + 16, ext->key + 24, 8);
- memcpy(ndis_key.material + 24, ext->key + 16, 8);
- } else
- memcpy(ndis_key.material, ext->key, ext->key_len);
-
- ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key,
- le32_to_cpu(ndis_key.size));
- devdbg(usbdev, "SIOCSIWENCODEEXT: OID_802_11_ADD_KEY -> %08X", ret);
- if (ret != 0)
- return ret;
-
- priv->encr_key_len[keyidx] = ext->key_len;
- memcpy(&priv->encr_keys[keyidx], ndis_key.material, ext->key_len);
+ flags = 0;
+ if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
+ flags |= NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ;
+ if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
+ flags |= NDIS_80211_ADDKEY_PAIRWISE_KEY;
if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
- priv->encr_tx_key_index = keyidx;
-
- return 0;
-}
-
-
-static int rndis_iw_set_scan(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
- struct usbnet *usbdev = netdev_priv(dev);
- union iwreq_data evt;
- int ret = -EINVAL;
- __le32 tmp;
-
- devdbg(usbdev, "SIOCSIWSCAN");
-
- if (wrqu->data.flags == 0) {
- tmp = cpu_to_le32(1);
- ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
- sizeof(tmp));
- evt.data.flags = 0;
- evt.data.length = 0;
- wireless_send_event(dev, SIOCGIWSCAN, &evt, NULL);
- }
- return ret;
-}
-
-
-static char *rndis_translate_scan(struct net_device *dev,
- struct iw_request_info *info, char *cev,
- char *end_buf,
- struct ndis_80211_bssid_ex *bssid)
-{
- struct usbnet *usbdev = netdev_priv(dev);
- u8 *ie;
- char *current_val;
- int bssid_len, ie_len, i;
- u32 beacon, atim;
- struct iw_event iwe;
- unsigned char sbuf[32];
-
- bssid_len = le32_to_cpu(bssid->length);
-
- devdbg(usbdev, "BSSID %pM", bssid->mac);
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN);
- cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_ADDR_LEN);
-
- devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length),
- bssid->ssid.essid);
- iwe.cmd = SIOCGIWESSID;
- iwe.u.essid.length = le32_to_cpu(bssid->ssid.length);
- iwe.u.essid.flags = 1;
- cev = iwe_stream_add_point(info, cev, end_buf, &iwe, bssid->ssid.essid);
-
- devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra));
- iwe.cmd = SIOCGIWMODE;
- switch (le32_to_cpu(bssid->net_infra)) {
- case ndis_80211_infra_adhoc:
- iwe.u.mode = IW_MODE_ADHOC;
- break;
- case ndis_80211_infra_infra:
- iwe.u.mode = IW_MODE_INFRA;
- break;
- /*case ndis_80211_infra_auto_unknown:*/
- default:
- iwe.u.mode = IW_MODE_AUTO;
- break;
- }
- cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_UINT_LEN);
-
- devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config));
- iwe.cmd = SIOCGIWFREQ;
- dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq);
- cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_FREQ_LEN);
-
- devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi));
- iwe.cmd = IWEVQUAL;
- iwe.u.qual.qual = level_to_qual(le32_to_cpu(bssid->rssi));
- iwe.u.qual.level = le32_to_cpu(bssid->rssi);
- iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
- | IW_QUAL_LEVEL_UPDATED
- | IW_QUAL_NOISE_INVALID;
- cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_QUAL_LEN);
-
- devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy));
- iwe.cmd = SIOCGIWENCODE;
- iwe.u.data.length = 0;
- if (le32_to_cpu(bssid->privacy) == ndis_80211_priv_accept_all)
- iwe.u.data.flags = IW_ENCODE_DISABLED;
- else
- iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-
- cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
-
- devdbg(usbdev, "RATES:");
- current_val = cev + iwe_stream_lcp_len(info);
- iwe.cmd = SIOCGIWRATE;
- for (i = 0; i < sizeof(bssid->rates); i++) {
- if (bssid->rates[i] & 0x7f) {
- iwe.u.bitrate.value =
- ((bssid->rates[i] & 0x7f) *
- 500000);
- devdbg(usbdev, " %d", iwe.u.bitrate.value);
- current_val = iwe_stream_add_value(info, cev,
- current_val, end_buf, &iwe,
- IW_EV_PARAM_LEN);
- }
- }
-
- if ((current_val - cev) > iwe_stream_lcp_len(info))
- cev = current_val;
-
- beacon = le32_to_cpu(bssid->config.beacon_period);
- devdbg(usbdev, "BCN_INT %d", beacon);
- iwe.cmd = IWEVCUSTOM;
- snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
- iwe.u.data.length = strlen(sbuf);
- cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
-
- atim = le32_to_cpu(bssid->config.atim_window);
- devdbg(usbdev, "ATIM %d", atim);
- iwe.cmd = IWEVCUSTOM;
- snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
- iwe.u.data.length = strlen(sbuf);
- cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
-
- ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
- ie_len = min(bssid_len - (int)sizeof(*bssid),
- (int)le32_to_cpu(bssid->ie_length));
- ie_len -= sizeof(struct ndis_80211_fixed_ies);
- while (ie_len >= 2 && 2 + ie[1] <= ie_len) {
- if ((ie[0] == WLAN_EID_GENERIC && ie[1] >= 4 &&
- memcmp(ie + 2, "\x00\x50\xf2\x01", 4) == 0) ||
- ie[0] == WLAN_EID_RSN) {
- devdbg(usbdev, "IE: WPA%d",
- (ie[0] == WLAN_EID_RSN) ? 2 : 1);
- iwe.cmd = IWEVGENIE;
- /* arbitrary cut-off at 64 */
- iwe.u.data.length = min(ie[1] + 2, 64);
- cev = iwe_stream_add_point(info, cev, end_buf, &iwe, ie);
- }
-
- ie_len -= 2 + ie[1];
- ie += 2 + ie[1];
- }
-
- return cev;
-}
-
-
-static int rndis_iw_get_scan(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
- struct usbnet *usbdev = netdev_priv(dev);
- void *buf = NULL;
- char *cev = extra;
- struct ndis_80211_bssid_list_ex *bssid_list;
- struct ndis_80211_bssid_ex *bssid;
- int ret = -EINVAL, len, count, bssid_len;
-
- devdbg(usbdev, "SIOCGIWSCAN");
+ flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY;
- len = CONTROL_BUFFER_SIZE;
- buf = kmalloc(len, GFP_KERNEL);
- if (!buf) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
-
- if (ret != 0)
- goto out;
-
- bssid_list = buf;
- bssid = bssid_list->bssid;
- bssid_len = le32_to_cpu(bssid->length);
- count = le32_to_cpu(bssid_list->num_items);
- devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
-
- while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
- cev = rndis_translate_scan(dev, info, cev,
- extra + IW_SCAN_MAX_DATA, bssid);
- bssid = (void *)bssid + bssid_len;
- bssid_len = le32_to_cpu(bssid->length);
- count--;
- }
-
-out:
- wrqu->data.length = cev - extra;
- wrqu->data.flags = 0;
- kfree(buf);
- return ret;
+ return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx, &ext->addr,
+ ext->rx_seq, ext->alg, flags);
}
@@ -1815,7 +1713,7 @@ static int rndis_iw_set_genie(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
{
struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
int ret = 0;
#ifdef DEBUG
@@ -1849,7 +1747,7 @@ static int rndis_iw_get_genie(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
{
struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
devdbg(usbdev, "SIOCGIWGENIE");
@@ -1936,39 +1834,6 @@ static int rndis_iw_get_frag(struct net_device *dev,
}
-static int rndis_iw_set_nick(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
- struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-
- devdbg(usbdev, "SIOCSIWNICK");
-
- priv->nick_len = wrqu->data.length;
- if (priv->nick_len > 32)
- priv->nick_len = 32;
-
- memcpy(priv->nick, extra, priv->nick_len);
- return 0;
-}
-
-
-static int rndis_iw_get_nick(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
- struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-
- wrqu->data.flags = 1;
- wrqu->data.length = priv->nick_len;
- memcpy(extra, priv->nick, priv->nick_len);
-
- devdbg(usbdev, "SIOCGIWNICK: '%s'", priv->nick);
-
- return 0;
-}
-
-
static int rndis_iw_set_freq(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
{
@@ -2021,20 +1886,12 @@ static int rndis_iw_get_txpower(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
{
struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
__le32 tx_power;
- int ret = 0, len;
if (priv->radio_on) {
- if (priv->caps & CAP_SUPPORT_TXPOWER) {
- len = sizeof(tx_power);
- ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
- &tx_power, &len);
- if (ret != 0)
- return ret;
- } else
- /* fake incase not supported */
- tx_power = cpu_to_le32(get_bcm4320_power(priv));
+ /* fake since changing tx_power (by userlevel) not supported */
+ tx_power = cpu_to_le32(get_bcm4320_power(priv));
wrqu->txpower.flags = IW_TXPOW_MWATT;
wrqu->txpower.value = le32_to_cpu(tx_power);
@@ -2047,7 +1904,7 @@ static int rndis_iw_get_txpower(struct net_device *dev,
devdbg(usbdev, "SIOCGIWTXPOW: %d", wrqu->txpower.value);
- return ret;
+ return 0;
}
@@ -2055,9 +1912,8 @@ static int rndis_iw_set_txpower(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
{
struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
__le32 tx_power = 0;
- int ret = 0;
if (!wrqu->txpower.disabled) {
if (wrqu->txpower.flags == IW_TXPOW_MWATT)
@@ -2080,22 +1936,10 @@ static int rndis_iw_set_txpower(struct net_device *dev,
devdbg(usbdev, "SIOCSIWTXPOW: %d", le32_to_cpu(tx_power));
if (le32_to_cpu(tx_power) != 0) {
- if (priv->caps & CAP_SUPPORT_TXPOWER) {
- /* turn radio on first */
- if (!priv->radio_on)
- disassociate(usbdev, 1);
-
- ret = rndis_set_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
- &tx_power, sizeof(tx_power));
- if (ret != 0)
- ret = -EOPNOTSUPP;
- return ret;
- } else {
- /* txpower unsupported, just turn radio on */
- if (!priv->radio_on)
- return disassociate(usbdev, 1);
- return 0; /* all ready on */
- }
+ /* txpower unsupported, just turn radio on */
+ if (!priv->radio_on)
+ return disassociate(usbdev, 1);
+ return 0; /* all ready on */
}
/* tx_power == 0, turn off radio */
@@ -2125,7 +1969,7 @@ static int rndis_iw_set_mlme(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
{
struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
struct iw_mlme *mlme = (struct iw_mlme *)extra;
unsigned char bssid[ETH_ALEN];
@@ -2150,7 +1994,7 @@ static int rndis_iw_set_mlme(struct net_device *dev,
static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev)
{
struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
unsigned long flags;
spin_lock_irqsave(&priv->stats_lock, flags);
@@ -2165,20 +2009,18 @@ static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev)
static const iw_handler rndis_iw_handler[] =
{
IW_IOCTL(SIOCSIWCOMMIT) = rndis_iw_commit,
- IW_IOCTL(SIOCGIWNAME) = rndis_iw_get_name,
+ IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname,
IW_IOCTL(SIOCSIWFREQ) = rndis_iw_set_freq,
IW_IOCTL(SIOCGIWFREQ) = rndis_iw_get_freq,
- IW_IOCTL(SIOCSIWMODE) = rndis_iw_set_mode,
- IW_IOCTL(SIOCGIWMODE) = rndis_iw_get_mode,
- IW_IOCTL(SIOCGIWRANGE) = rndis_iw_get_range,
+ IW_IOCTL(SIOCSIWMODE) = (iw_handler) cfg80211_wext_siwmode,
+ IW_IOCTL(SIOCGIWMODE) = (iw_handler) cfg80211_wext_giwmode,
+ IW_IOCTL(SIOCGIWRANGE) = (iw_handler) cfg80211_wext_giwrange,
IW_IOCTL(SIOCSIWAP) = rndis_iw_set_bssid,
IW_IOCTL(SIOCGIWAP) = rndis_iw_get_bssid,
- IW_IOCTL(SIOCSIWSCAN) = rndis_iw_set_scan,
- IW_IOCTL(SIOCGIWSCAN) = rndis_iw_get_scan,
+ IW_IOCTL(SIOCSIWSCAN) = (iw_handler) cfg80211_wext_siwscan,
+ IW_IOCTL(SIOCGIWSCAN) = (iw_handler) cfg80211_wext_giwscan,
IW_IOCTL(SIOCSIWESSID) = rndis_iw_set_essid,
IW_IOCTL(SIOCGIWESSID) = rndis_iw_get_essid,
- IW_IOCTL(SIOCSIWNICKN) = rndis_iw_set_nick,
- IW_IOCTL(SIOCGIWNICKN) = rndis_iw_get_nick,
IW_IOCTL(SIOCGIWRATE) = rndis_iw_get_rate,
IW_IOCTL(SIOCSIWRTS) = rndis_iw_set_rts,
IW_IOCTL(SIOCGIWRTS) = rndis_iw_get_rts,
@@ -2195,28 +2037,28 @@ static const iw_handler rndis_iw_handler[] =
IW_IOCTL(SIOCSIWMLME) = rndis_iw_set_mlme,
};
-static const iw_handler rndis_wext_private_handler[] = {
+static const iw_handler rndis_wlan_private_handler[] = {
};
-static const struct iw_priv_args rndis_wext_private_args[] = {
+static const struct iw_priv_args rndis_wlan_private_args[] = {
};
static const struct iw_handler_def rndis_iw_handlers = {
.num_standard = ARRAY_SIZE(rndis_iw_handler),
- .num_private = ARRAY_SIZE(rndis_wext_private_handler),
- .num_private_args = ARRAY_SIZE(rndis_wext_private_args),
+ .num_private = ARRAY_SIZE(rndis_wlan_private_handler),
+ .num_private_args = ARRAY_SIZE(rndis_wlan_private_args),
.standard = (iw_handler *)rndis_iw_handler,
- .private = (iw_handler *)rndis_wext_private_handler,
- .private_args = (struct iw_priv_args *)rndis_wext_private_args,
+ .private = (iw_handler *)rndis_wlan_private_handler,
+ .private_args = (struct iw_priv_args *)rndis_wlan_private_args,
.get_wireless_stats = rndis_get_wireless_stats,
};
-static void rndis_wext_worker(struct work_struct *work)
+static void rndis_wlan_worker(struct work_struct *work)
{
- struct rndis_wext_private *priv =
- container_of(work, struct rndis_wext_private, work);
+ struct rndis_wlan_private *priv =
+ container_of(work, struct rndis_wlan_private, work);
struct usbnet *usbdev = priv->usbdev;
union iwreq_data evt;
unsigned char bssid[ETH_ALEN];
@@ -2277,10 +2119,10 @@ get_bssid:
set_multicast_list(usbdev);
}
-static void rndis_wext_set_multicast_list(struct net_device *dev)
+static void rndis_wlan_set_multicast_list(struct net_device *dev)
{
struct usbnet *usbdev = netdev_priv(dev);
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
return;
@@ -2289,9 +2131,9 @@ static void rndis_wext_set_multicast_list(struct net_device *dev)
queue_work(priv->workqueue, &priv->work);
}
-static void rndis_wext_link_change(struct usbnet *usbdev, int state)
+static void rndis_wlan_link_change(struct usbnet *usbdev, int state)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
/* queue work to avoid recursive calls into rndis_command */
set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending);
@@ -2299,22 +2141,14 @@ static void rndis_wext_link_change(struct usbnet *usbdev, int state)
}
-static int rndis_wext_get_caps(struct usbnet *usbdev)
+static int rndis_wlan_get_caps(struct usbnet *usbdev)
{
struct {
__le32 num_items;
__le32 items[8];
} networks_supported;
int len, retval, i, n;
- __le32 tx_power;
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-
- /* determine if supports setting txpower */
- len = sizeof(tx_power);
- retval = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL, &tx_power,
- &len);
- if (retval == 0 && le32_to_cpu(tx_power) != 0xFF)
- priv->caps |= CAP_SUPPORT_TXPOWER;
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
/* determine supported modes */
len = sizeof(networks_supported);
@@ -2326,24 +2160,18 @@ static int rndis_wext_get_caps(struct usbnet *usbdev)
n = 8;
for (i = 0; i < n; i++) {
switch (le32_to_cpu(networks_supported.items[i])) {
- case ndis_80211_type_freq_hop:
- case ndis_80211_type_direct_seq:
+ case NDIS_80211_TYPE_FREQ_HOP:
+ case NDIS_80211_TYPE_DIRECT_SEQ:
priv->caps |= CAP_MODE_80211B;
break;
- case ndis_80211_type_ofdm_a:
+ case NDIS_80211_TYPE_OFDM_A:
priv->caps |= CAP_MODE_80211A;
break;
- case ndis_80211_type_ofdm_g:
+ case NDIS_80211_TYPE_OFDM_G:
priv->caps |= CAP_MODE_80211G;
break;
}
}
- if (priv->caps & CAP_MODE_80211A)
- strcat(priv->name, "a");
- if (priv->caps & CAP_MODE_80211B)
- strcat(priv->name, "b");
- if (priv->caps & CAP_MODE_80211G)
- strcat(priv->name, "g");
}
return retval;
@@ -2353,8 +2181,8 @@ static int rndis_wext_get_caps(struct usbnet *usbdev)
#define STATS_UPDATE_JIFFIES (HZ)
static void rndis_update_wireless_stats(struct work_struct *work)
{
- struct rndis_wext_private *priv =
- container_of(work, struct rndis_wext_private, stats_work.work);
+ struct rndis_wlan_private *priv =
+ container_of(work, struct rndis_wlan_private, stats_work.work);
struct usbnet *usbdev = priv->usbdev;
struct iw_statistics iwstats;
__le32 rssi, tmp;
@@ -2387,7 +2215,7 @@ static void rndis_update_wireless_stats(struct work_struct *work)
if (ret == 0) {
memset(&iwstats.qual, 0, sizeof(iwstats.qual));
iwstats.qual.qual = level_to_qual(le32_to_cpu(rssi));
- iwstats.qual.level = le32_to_cpu(rssi);
+ iwstats.qual.level = level_to_qual(le32_to_cpu(rssi));
iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
| IW_QUAL_LEVEL_UPDATED
| IW_QUAL_NOISE_INVALID;
@@ -2457,9 +2285,19 @@ end:
}
-static int bcm4320_early_init(struct usbnet *usbdev)
+static int bcm4320a_early_init(struct usbnet *usbdev)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ /* bcm4320a doesn't handle configuration parameters well. Try
+ * set any and you get partially zeroed mac and broken device.
+ */
+
+ return 0;
+}
+
+
+static int bcm4320b_early_init(struct usbnet *usbdev)
+{
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
char buf[8];
/* Early initialization settings, setting these won't have effect
@@ -2525,33 +2363,41 @@ static int bcm4320_early_init(struct usbnet *usbdev)
}
/* same as rndis_netdev_ops but with local multicast handler */
-static const struct net_device_ops rndis_wext_netdev_ops = {
+static const struct net_device_ops rndis_wlan_netdev_ops = {
.ndo_open = usbnet_open,
.ndo_stop = usbnet_stop,
.ndo_start_xmit = usbnet_start_xmit,
.ndo_tx_timeout = usbnet_tx_timeout,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_multicast_list = rndis_wext_set_multicast_list,
+ .ndo_set_multicast_list = rndis_wlan_set_multicast_list,
};
-static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
+static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
{
- struct rndis_wext_private *priv;
+ struct wiphy *wiphy;
+ struct rndis_wlan_private *priv;
int retval, len;
__le32 tmp;
- /* allocate rndis private data */
- priv = kzalloc(sizeof(struct rndis_wext_private), GFP_KERNEL);
- if (!priv)
+ /* allocate wiphy and rndis private data
+ * NOTE: We only support a single virtual interface, so wiphy
+ * and wireless_dev are somewhat synonymous for this device.
+ */
+ wiphy = wiphy_new(&rndis_config_ops, sizeof(struct rndis_wlan_private));
+ if (!wiphy)
return -ENOMEM;
+ priv = wiphy_priv(wiphy);
+ usbdev->net->ieee80211_ptr = &priv->wdev;
+ priv->wdev.wiphy = wiphy;
+ priv->wdev.iftype = NL80211_IFTYPE_STATION;
+
/* These have to be initialized before calling generic_rndis_bind().
- * Otherwise we'll be in big trouble in rndis_wext_early_init().
+ * Otherwise we'll be in big trouble in rndis_wlan_early_init().
*/
usbdev->driver_priv = priv;
- strcpy(priv->name, "IEEE802.11");
usbdev->net->wireless_handlers = &rndis_iw_handlers;
priv->usbdev = usbdev;
@@ -2560,8 +2406,9 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
/* because rndis_command() sleeps we need to use workqueue */
priv->workqueue = create_singlethread_workqueue("rndis_wlan");
- INIT_WORK(&priv->work, rndis_wext_worker);
+ INIT_WORK(&priv->work, rndis_wlan_worker);
INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats);
+ INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results);
/* try bind rndis_host */
retval = generic_rndis_bind(usbdev, intf, FLAG_RNDIS_PHYM_WIRELESS);
@@ -2573,9 +2420,9 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
* picks up rssi to closest station instead of to access point).
*
* rndis_host wants to avoid all OID as much as possible
- * so do promisc/multicast handling in rndis_wext.
+ * so do promisc/multicast handling in rndis_wlan.
*/
- usbdev->net->netdev_ops = &rndis_wext_netdev_ops;
+ usbdev->net->netdev_ops = &rndis_wlan_netdev_ops;
tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp,
@@ -2600,7 +2447,32 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
| IW_QUAL_QUAL_INVALID
| IW_QUAL_LEVEL_INVALID;
- rndis_wext_get_caps(usbdev);
+ /* fill-out wiphy structure and register w/ cfg80211 */
+ memcpy(wiphy->perm_addr, usbdev->net->dev_addr, ETH_ALEN);
+ wiphy->privid = rndis_wiphy_privid;
+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
+ | BIT(NL80211_IFTYPE_ADHOC);
+ wiphy->max_scan_ssids = 1;
+
+ /* TODO: fill-out band information based on priv->caps */
+ rndis_wlan_get_caps(usbdev);
+
+ memcpy(priv->channels, rndis_channels, sizeof(rndis_channels));
+ memcpy(priv->rates, rndis_rates, sizeof(rndis_rates));
+ priv->band.channels = priv->channels;
+ priv->band.n_channels = ARRAY_SIZE(rndis_channels);
+ priv->band.bitrates = priv->rates;
+ priv->band.n_bitrates = ARRAY_SIZE(rndis_rates);
+ wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
+ wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
+
+ set_wiphy_dev(wiphy, &usbdev->udev->dev);
+
+ if (wiphy_register(wiphy)) {
+ retval = -ENODEV;
+ goto fail;
+ }
+
set_default_iw_params(usbdev);
/* turn radio on */
@@ -2615,36 +2487,40 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
fail:
cancel_delayed_work_sync(&priv->stats_work);
+ cancel_delayed_work_sync(&priv->scan_work);
cancel_work_sync(&priv->work);
flush_workqueue(priv->workqueue);
destroy_workqueue(priv->workqueue);
- kfree(priv);
+ wiphy_free(wiphy);
return retval;
}
-static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf)
+static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
/* turn radio off */
disassociate(usbdev, 0);
cancel_delayed_work_sync(&priv->stats_work);
+ cancel_delayed_work_sync(&priv->scan_work);
cancel_work_sync(&priv->work);
flush_workqueue(priv->workqueue);
destroy_workqueue(priv->workqueue);
if (priv && priv->wpa_ie_len)
kfree(priv->wpa_ie);
- kfree(priv);
rndis_unbind(usbdev, intf);
+
+ wiphy_unregister(priv->wdev.wiphy);
+ wiphy_free(priv->wdev.wiphy);
}
-static int rndis_wext_reset(struct usbnet *usbdev)
+static int rndis_wlan_reset(struct usbnet *usbdev)
{
return deauthenticate(usbdev);
}
@@ -2653,40 +2529,40 @@ static int rndis_wext_reset(struct usbnet *usbdev)
static const struct driver_info bcm4320b_info = {
.description = "Wireless RNDIS device, BCM4320b based",
.flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
- .bind = rndis_wext_bind,
- .unbind = rndis_wext_unbind,
+ .bind = rndis_wlan_bind,
+ .unbind = rndis_wlan_unbind,
.status = rndis_status,
.rx_fixup = rndis_rx_fixup,
.tx_fixup = rndis_tx_fixup,
- .reset = rndis_wext_reset,
- .early_init = bcm4320_early_init,
- .link_change = rndis_wext_link_change,
+ .reset = rndis_wlan_reset,
+ .early_init = bcm4320b_early_init,
+ .link_change = rndis_wlan_link_change,
};
static const struct driver_info bcm4320a_info = {
.description = "Wireless RNDIS device, BCM4320a based",
.flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
- .bind = rndis_wext_bind,
- .unbind = rndis_wext_unbind,
+ .bind = rndis_wlan_bind,
+ .unbind = rndis_wlan_unbind,
.status = rndis_status,
.rx_fixup = rndis_rx_fixup,
.tx_fixup = rndis_tx_fixup,
- .reset = rndis_wext_reset,
- .early_init = bcm4320_early_init,
- .link_change = rndis_wext_link_change,
+ .reset = rndis_wlan_reset,
+ .early_init = bcm4320a_early_init,
+ .link_change = rndis_wlan_link_change,
};
-static const struct driver_info rndis_wext_info = {
+static const struct driver_info rndis_wlan_info = {
.description = "Wireless RNDIS device",
.flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
- .bind = rndis_wext_bind,
- .unbind = rndis_wext_unbind,
+ .bind = rndis_wlan_bind,
+ .unbind = rndis_wlan_unbind,
.status = rndis_status,
.rx_fixup = rndis_rx_fixup,
.tx_fixup = rndis_tx_fixup,
- .reset = rndis_wext_reset,
- .early_init = bcm4320_early_init,
- .link_change = rndis_wext_link_change,
+ .reset = rndis_wlan_reset,
+ .early_init = bcm4320a_early_init,
+ .link_change = rndis_wlan_link_change,
};
/*-------------------------------------------------------------------------*/
@@ -2796,11 +2672,11 @@ static const struct usb_device_id products [] = {
{
/* RNDIS is MSFT's un-official variant of CDC ACM */
USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
- .driver_info = (unsigned long) &rndis_wext_info,
+ .driver_info = (unsigned long) &rndis_wlan_info,
}, {
/* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
- .driver_info = (unsigned long) &rndis_wext_info,
+ .driver_info = (unsigned long) &rndis_wlan_info,
},
{ }, // END
};
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 1ae11c7f17a..8aab3e6754b 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -77,6 +77,20 @@ config RT73USB
When compiled as a module, this driver will be called rt73usb.
+config RT2800USB
+ tristate "Ralink rt2800 (USB) support"
+ depends on USB
+ select RT2X00_LIB_USB
+ select RT2X00_LIB_HT
+ select RT2X00_LIB_FIRMWARE
+ select RT2X00_LIB_CRYPTO
+ select CRC_CCITT
+ ---help---
+ This adds support for rt2800 wireless chipset family.
+ Supported chips: RT2770, RT2870 & RT3070.
+
+ When compiled as a module, this driver will be called "rt2800usb.ko".
+
config RT2X00_LIB_PCI
tristate
select RT2X00_LIB
@@ -88,6 +102,9 @@ config RT2X00_LIB_USB
config RT2X00_LIB
tristate
+config RT2X00_LIB_HT
+ boolean
+
config RT2X00_LIB_FIRMWARE
boolean
select FW_LOADER
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile
index f22d808d8c5..bfc7226f0af 100644
--- a/drivers/net/wireless/rt2x00/Makefile
+++ b/drivers/net/wireless/rt2x00/Makefile
@@ -8,6 +8,7 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o
rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL) += rt2x00rfkill.o
rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o
+rt2x00lib-$(CONFIG_RT2X00_LIB_HT) += rt2x00ht.o
obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o
obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o
@@ -17,3 +18,4 @@ obj-$(CONFIG_RT2500PCI) += rt2500pci.o
obj-$(CONFIG_RT61PCI) += rt61pci.o
obj-$(CONFIG_RT2500USB) += rt2500usb.o
obj-$(CONFIG_RT73USB) += rt73usb.o
+obj-$(CONFIG_RT2800USB) += rt2800usb.o
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 0f08773328c..435f945fe64 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -335,10 +335,11 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
preamble_mask = erp->short_preamble << 3;
rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
- rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT,
- erp->ack_timeout);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, erp->ack_timeout);
rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME,
erp->ack_consume_time);
+ rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
+ rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
@@ -371,6 +372,11 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
rt2x00pci_register_write(rt2x00dev, CSR11, reg);
+ rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
+ rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL, erp->beacon_int * 16);
+ rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16);
+ rt2x00pci_register_write(rt2x00dev, CSR12, reg);
+
rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
@@ -503,24 +509,6 @@ static void rt2400pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, CSR11, reg);
}
-static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_conf *libconf)
-{
- u32 reg;
-
- rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
- rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
- rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
- rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
-
- rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
- rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL,
- libconf->conf->beacon_int * 16);
- rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION,
- libconf->conf->beacon_int * 16);
- rt2x00pci_register_write(rt2x00dev, CSR12, reg);
-}
-
static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
{
@@ -532,7 +520,7 @@ static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev,
if (state == STATE_SLEEP) {
rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
- (libconf->conf->beacon_int - 20) * 16);
+ (rt2x00dev->beacon_int - 20) * 16);
rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
libconf->conf->listen_interval - 1);
@@ -558,8 +546,6 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev,
libconf->conf->power_level);
if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
rt2400pci_config_retry_limit(rt2x00dev, libconf);
- if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
- rt2400pci_config_duration(rt2x00dev, libconf);
if (flags & IEEE80211_CONF_CHANGE_PS)
rt2400pci_config_ps(rt2x00dev, libconf);
}
@@ -1361,7 +1347,7 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
*/
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
- rt2x00_set_chip(rt2x00dev, RT2460, value, reg);
+ rt2x00_set_chip_rf(rt2x00dev, value, reg);
if (!rt2x00_rf(&rt2x00dev->chip, RF2420) &&
!rt2x00_rf(&rt2x00dev->chip, RF2421)) {
@@ -1580,7 +1566,6 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
- .config_interface = rt2x00mac_config_interface,
.configure_filter = rt2x00mac_configure_filter,
.get_stats = rt2x00mac_get_stats,
.bss_info_changed = rt2x00mac_bss_info_changed,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 276a8232aaa..08b30d01e67 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -341,10 +341,11 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
preamble_mask = erp->short_preamble << 3;
rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
- rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT,
- erp->ack_timeout);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, erp->ack_timeout);
rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME,
erp->ack_consume_time);
+ rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
+ rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
@@ -377,6 +378,11 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
rt2x00pci_register_write(rt2x00dev, CSR11, reg);
+ rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
+ rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL, erp->beacon_int * 16);
+ rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16);
+ rt2x00pci_register_write(rt2x00dev, CSR12, reg);
+
rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
@@ -552,24 +558,6 @@ static void rt2500pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, CSR11, reg);
}
-static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_conf *libconf)
-{
- u32 reg;
-
- rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
- rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
- rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
- rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
-
- rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
- rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL,
- libconf->conf->beacon_int * 16);
- rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION,
- libconf->conf->beacon_int * 16);
- rt2x00pci_register_write(rt2x00dev, CSR12, reg);
-}
-
static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
{
@@ -581,7 +569,7 @@ static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev,
if (state == STATE_SLEEP) {
rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
- (libconf->conf->beacon_int - 20) * 16);
+ (rt2x00dev->beacon_int - 20) * 16);
rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
libconf->conf->listen_interval - 1);
@@ -609,8 +597,6 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
libconf->conf->power_level);
if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
rt2500pci_config_retry_limit(rt2x00dev, libconf);
- if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
- rt2500pci_config_duration(rt2x00dev, libconf);
if (flags & IEEE80211_CONF_CHANGE_PS)
rt2500pci_config_ps(rt2x00dev, libconf);
}
@@ -1525,7 +1511,7 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
*/
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
- rt2x00_set_chip(rt2x00dev, RT2560, value, reg);
+ rt2x00_set_chip_rf(rt2x00dev, value, reg);
if (!rt2x00_rf(&rt2x00dev->chip, RF2522) &&
!rt2x00_rf(&rt2x00dev->chip, RF2523) &&
@@ -1879,7 +1865,6 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
- .config_interface = rt2x00mac_config_interface,
.configure_filter = rt2x00mac_configure_filter,
.get_stats = rt2x00mac_get_stats,
.bss_info_changed = rt2x00mac_bss_info_changed,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 9e630e70fc9..66daf68ff0e 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -503,6 +503,10 @@ static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev,
rt2500usb_register_write(rt2x00dev, TXRX_CSR11, erp->basic_rates);
+ rt2500usb_register_read(rt2x00dev, TXRX_CSR18, &reg);
+ rt2x00_set_field16(&reg, TXRX_CSR18_INTERVAL, erp->beacon_int * 4);
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg);
+
rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time);
rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs);
rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs);
@@ -632,17 +636,6 @@ static void rt2500usb_config_txpower(struct rt2x00_dev *rt2x00dev,
rt2500usb_rf_write(rt2x00dev, 3, rf3);
}
-static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_conf *libconf)
-{
- u16 reg;
-
- rt2500usb_register_read(rt2x00dev, TXRX_CSR18, &reg);
- rt2x00_set_field16(&reg, TXRX_CSR18_INTERVAL,
- libconf->conf->beacon_int * 4);
- rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg);
-}
-
static void rt2500usb_config_ps(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
{
@@ -654,7 +647,7 @@ static void rt2500usb_config_ps(struct rt2x00_dev *rt2x00dev,
if (state == STATE_SLEEP) {
rt2500usb_register_read(rt2x00dev, MAC_CSR18, &reg);
rt2x00_set_field16(&reg, MAC_CSR18_DELAY_AFTER_BEACON,
- libconf->conf->beacon_int - 20);
+ rt2x00dev->beacon_int - 20);
rt2x00_set_field16(&reg, MAC_CSR18_BEACONS_BEFORE_WAKEUP,
libconf->conf->listen_interval - 1);
@@ -680,8 +673,6 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev,
!(flags & IEEE80211_CONF_CHANGE_CHANNEL))
rt2500usb_config_txpower(rt2x00dev,
libconf->conf->power_level);
- if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
- rt2500usb_config_duration(rt2x00dev, libconf);
if (flags & IEEE80211_CONF_CHANGE_PS)
rt2500usb_config_ps(rt2x00dev, libconf);
}
@@ -1559,7 +1550,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg);
rt2x00_set_chip(rt2x00dev, RT2570, value, reg);
- if (!rt2x00_check_rev(&rt2x00dev->chip, 0)) {
+ if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0)) {
ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
return -ENODEV;
}
@@ -1908,7 +1899,6 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
- .config_interface = rt2x00mac_config_interface,
.configure_filter = rt2x00mac_configure_filter,
.set_key = rt2x00mac_set_key,
.get_stats = rt2x00mac_get_stats,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
new file mode 100644
index 00000000000..37561667925
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -0,0 +1,3078 @@
+/*
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+ <http://rt2x00.serialmonkey.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ Module: rt2800usb
+ Abstract: rt2800usb device specific routines.
+ Supported chipsets: RT2800U.
+ */
+
+#include <linux/crc-ccitt.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include "rt2x00.h"
+#include "rt2x00usb.h"
+#include "rt2800usb.h"
+
+/*
+ * Allow hardware encryption to be disabled.
+ */
+static int modparam_nohwcrypt = 1;
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+
+/*
+ * Register access.
+ * All access to the CSR registers will go through the methods
+ * rt2x00usb_register_read and rt2x00usb_register_write.
+ * BBP and RF register require indirect register access,
+ * and use the CSR registers BBPCSR and RFCSR to achieve this.
+ * These indirect registers work with busy bits,
+ * and we will try maximal REGISTER_BUSY_COUNT times to access
+ * the register while taking a REGISTER_BUSY_DELAY us delay
+ * between each attampt. When the busy bit is still set at that time,
+ * the access attempt is considered to have failed,
+ * and we will print an error.
+ * The _lock versions must be used if you already hold the csr_mutex
+ */
+#define WAIT_FOR_BBP(__dev, __reg) \
+ rt2x00usb_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg))
+#define WAIT_FOR_RFCSR(__dev, __reg) \
+ rt2x00usb_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg))
+#define WAIT_FOR_RF(__dev, __reg) \
+ rt2x00usb_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg))
+#define WAIT_FOR_MCU(__dev, __reg) \
+ rt2x00usb_regbusy_read((__dev), H2M_MAILBOX_CSR, \
+ H2M_MAILBOX_CSR_OWNER, (__reg))
+
+static void rt2800usb_bbp_write(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, const u8 value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the BBP becomes available, afterwards we
+ * can safely write the new data into the register.
+ */
+ if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, BBP_CSR_CFG_VALUE, value);
+ rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word);
+ rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1);
+ rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 0);
+
+ rt2x00usb_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
+ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_bbp_read(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, u8 *value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the BBP becomes available, afterwards we
+ * can safely write the read request into the register.
+ * After the data has been written, we wait until hardware
+ * returns the correct value, if at any time the register
+ * doesn't become available in time, reg will be 0xffffffff
+ * which means we return 0xff to the caller.
+ */
+ if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word);
+ rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1);
+ rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 1);
+
+ rt2x00usb_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
+
+ WAIT_FOR_BBP(rt2x00dev, &reg);
+ }
+
+ *value = rt2x00_get_field32(reg, BBP_CSR_CFG_VALUE);
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_rfcsr_write(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, const u8 value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the RFCSR becomes available, afterwards we
+ * can safely write the new data into the register.
+ */
+ if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, RF_CSR_CFG_DATA, value);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 1);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
+
+ rt2x00usb_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
+ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_rfcsr_read(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, u8 *value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the RFCSR becomes available, afterwards we
+ * can safely write the read request into the register.
+ * After the data has been written, we wait until hardware
+ * returns the correct value, if at any time the register
+ * doesn't become available in time, reg will be 0xffffffff
+ * which means we return 0xff to the caller.
+ */
+ if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 0);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
+
+ rt2x00usb_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
+
+ WAIT_FOR_RFCSR(rt2x00dev, &reg);
+ }
+
+ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA);
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_rf_write(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, const u32 value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the RF becomes available, afterwards we
+ * can safely write the new data into the register.
+ */
+ if (WAIT_FOR_RF(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, RF_CSR_CFG0_REG_VALUE_BW, value);
+ rt2x00_set_field32(&reg, RF_CSR_CFG0_STANDBYMODE, 0);
+ rt2x00_set_field32(&reg, RF_CSR_CFG0_SEL, 0);
+ rt2x00_set_field32(&reg, RF_CSR_CFG0_BUSY, 1);
+
+ rt2x00usb_register_write_lock(rt2x00dev, RF_CSR_CFG0, reg);
+ rt2x00_rf_write(rt2x00dev, word, value);
+ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_mcu_request(struct rt2x00_dev *rt2x00dev,
+ const u8 command, const u8 token,
+ const u8 arg0, const u8 arg1)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the MCU becomes available, afterwards we
+ * can safely write the new data into the register.
+ */
+ if (WAIT_FOR_MCU(rt2x00dev, &reg)) {
+ rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_OWNER, 1);
+ rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token);
+ rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG0, arg0);
+ rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG1, arg1);
+ rt2x00usb_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg);
+
+ reg = 0;
+ rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
+ rt2x00usb_register_write_lock(rt2x00dev, HOST_CMD_CSR, reg);
+ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+#ifdef CONFIG_RT2X00_LIB_DEBUGFS
+static const struct rt2x00debug rt2800usb_rt2x00debug = {
+ .owner = THIS_MODULE,
+ .csr = {
+ .read = rt2x00usb_register_read,
+ .write = rt2x00usb_register_write,
+ .flags = RT2X00DEBUGFS_OFFSET,
+ .word_base = CSR_REG_BASE,
+ .word_size = sizeof(u32),
+ .word_count = CSR_REG_SIZE / sizeof(u32),
+ },
+ .eeprom = {
+ .read = rt2x00_eeprom_read,
+ .write = rt2x00_eeprom_write,
+ .word_base = EEPROM_BASE,
+ .word_size = sizeof(u16),
+ .word_count = EEPROM_SIZE / sizeof(u16),
+ },
+ .bbp = {
+ .read = rt2800usb_bbp_read,
+ .write = rt2800usb_bbp_write,
+ .word_base = BBP_BASE,
+ .word_size = sizeof(u8),
+ .word_count = BBP_SIZE / sizeof(u8),
+ },
+ .rf = {
+ .read = rt2x00_rf_read,
+ .write = rt2800usb_rf_write,
+ .word_base = RF_BASE,
+ .word_size = sizeof(u32),
+ .word_count = RF_SIZE / sizeof(u32),
+ },
+};
+#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+static int rt2800usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
+ return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
+}
+#else
+#define rt2800usb_rfkill_poll NULL
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
+#ifdef CONFIG_RT2X00_LIB_LEDS
+static void rt2800usb_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct rt2x00_led *led =
+ container_of(led_cdev, struct rt2x00_led, led_dev);
+ unsigned int enabled = brightness != LED_OFF;
+ unsigned int bg_mode =
+ (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ);
+ unsigned int polarity =
+ rt2x00_get_field16(led->rt2x00dev->led_mcu_reg,
+ EEPROM_FREQ_LED_POLARITY);
+ unsigned int ledmode =
+ rt2x00_get_field16(led->rt2x00dev->led_mcu_reg,
+ EEPROM_FREQ_LED_MODE);
+
+ if (led->type == LED_TYPE_RADIO) {
+ rt2800usb_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
+ enabled ? 0x20 : 0);
+ } else if (led->type == LED_TYPE_ASSOC) {
+ rt2800usb_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
+ enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20);
+ } else if (led->type == LED_TYPE_QUALITY) {
+ /*
+ * The brightness is divided into 6 levels (0 - 5),
+ * The specs tell us the following levels:
+ * 0, 1 ,3, 7, 15, 31
+ * to determine the level in a simple way we can simply
+ * work with bitshifting:
+ * (1 << level) - 1
+ */
+ rt2800usb_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff,
+ (1 << brightness / (LED_FULL / 6)) - 1,
+ polarity);
+ }
+}
+
+static int rt2800usb_blink_set(struct led_classdev *led_cdev,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ struct rt2x00_led *led =
+ container_of(led_cdev, struct rt2x00_led, led_dev);
+ u32 reg;
+
+ rt2x00usb_register_read(led->rt2x00dev, LED_CFG, &reg);
+ rt2x00_set_field32(&reg, LED_CFG_ON_PERIOD, *delay_on);
+ rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, *delay_off);
+ rt2x00_set_field32(&reg, LED_CFG_SLOW_BLINK_PERIOD, 3);
+ rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, 3);
+ rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, 12);
+ rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE, 3);
+ rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, 1);
+ rt2x00usb_register_write(led->rt2x00dev, LED_CFG, reg);
+
+ return 0;
+}
+
+static void rt2800usb_init_led(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_led *led,
+ enum led_type type)
+{
+ led->rt2x00dev = rt2x00dev;
+ led->type = type;
+ led->led_dev.brightness_set = rt2800usb_brightness_set;
+ led->led_dev.blink_set = rt2800usb_blink_set;
+ led->flags = LED_INITIALIZED;
+}
+#endif /* CONFIG_RT2X00_LIB_LEDS */
+
+/*
+ * Configuration handlers.
+ */
+static void rt2800usb_config_wcid_attr(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_crypto *crypto,
+ struct ieee80211_key_conf *key)
+{
+ struct mac_wcid_entry wcid_entry;
+ struct mac_iveiv_entry iveiv_entry;
+ u32 offset;
+ u32 reg;
+
+ offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx);
+
+ rt2x00usb_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
+ !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE));
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER,
+ (crypto->cmd == SET_KEY) * crypto->cipher);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX,
+ (crypto->cmd == SET_KEY) * crypto->bssidx);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
+ rt2x00usb_register_write(rt2x00dev, offset, reg);
+
+ offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
+
+ memset(&iveiv_entry, 0, sizeof(iveiv_entry));
+ if ((crypto->cipher == CIPHER_TKIP) ||
+ (crypto->cipher == CIPHER_TKIP_NO_MIC) ||
+ (crypto->cipher == CIPHER_AES))
+ iveiv_entry.iv[3] |= 0x20;
+ iveiv_entry.iv[3] |= key->keyidx << 6;
+ rt2x00usb_register_multiwrite(rt2x00dev, offset,
+ &iveiv_entry, sizeof(iveiv_entry));
+
+ offset = MAC_WCID_ENTRY(key->hw_key_idx);
+
+ memset(&wcid_entry, 0, sizeof(wcid_entry));
+ if (crypto->cmd == SET_KEY)
+ memcpy(&wcid_entry, crypto->address, ETH_ALEN);
+ rt2x00usb_register_multiwrite(rt2x00dev, offset,
+ &wcid_entry, sizeof(wcid_entry));
+}
+
+static int rt2800usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_crypto *crypto,
+ struct ieee80211_key_conf *key)
+{
+ struct hw_key_entry key_entry;
+ struct rt2x00_field32 field;
+ int timeout;
+ u32 offset;
+ u32 reg;
+
+ if (crypto->cmd == SET_KEY) {
+ key->hw_key_idx = (4 * crypto->bssidx) + key->keyidx;
+
+ memcpy(key_entry.key, crypto->key,
+ sizeof(key_entry.key));
+ memcpy(key_entry.tx_mic, crypto->tx_mic,
+ sizeof(key_entry.tx_mic));
+ memcpy(key_entry.rx_mic, crypto->rx_mic,
+ sizeof(key_entry.rx_mic));
+
+ offset = SHARED_KEY_ENTRY(key->hw_key_idx);
+ timeout = REGISTER_TIMEOUT32(sizeof(key_entry));
+ rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
+ USB_VENDOR_REQUEST_OUT,
+ offset, &key_entry,
+ sizeof(key_entry),
+ timeout);
+ }
+
+ /*
+ * The cipher types are stored over multiple registers
+ * starting with SHARED_KEY_MODE_BASE each word will have
+ * 32 bits and contains the cipher types for 2 bssidx each.
+ * Using the correct defines correctly will cause overhead,
+ * so just calculate the correct offset.
+ */
+ field.bit_offset = 4 * (key->hw_key_idx % 8);
+ field.bit_mask = 0x7 << field.bit_offset;
+
+ offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
+
+ rt2x00usb_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, field,
+ (crypto->cmd == SET_KEY) * crypto->cipher);
+ rt2x00usb_register_write(rt2x00dev, offset, reg);
+
+ /*
+ * Update WCID information
+ */
+ rt2800usb_config_wcid_attr(rt2x00dev, crypto, key);
+
+ return 0;
+}
+
+static int rt2800usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_crypto *crypto,
+ struct ieee80211_key_conf *key)
+{
+ struct hw_key_entry key_entry;
+ int timeout;
+ u32 offset;
+
+ if (crypto->cmd == SET_KEY) {
+ /*
+ * 1 pairwise key is possible per AID, this means that the AID
+ * equals our hw_key_idx. Make sure the WCID starts _after_ the
+ * last possible shared key entry.
+ */
+ if (crypto->aid > (256 - 32))
+ return -ENOSPC;
+
+ key->hw_key_idx = 32 + crypto->aid;
+
+ memcpy(key_entry.key, crypto->key,
+ sizeof(key_entry.key));
+ memcpy(key_entry.tx_mic, crypto->tx_mic,
+ sizeof(key_entry.tx_mic));
+ memcpy(key_entry.rx_mic, crypto->rx_mic,
+ sizeof(key_entry.rx_mic));
+
+ offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
+ timeout = REGISTER_TIMEOUT32(sizeof(key_entry));
+ rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
+ USB_VENDOR_REQUEST_OUT,
+ offset, &key_entry,
+ sizeof(key_entry),
+ timeout);
+ }
+
+ /*
+ * Update WCID information
+ */
+ rt2800usb_config_wcid_attr(rt2x00dev, crypto, key);
+
+ return 0;
+}
+
+static void rt2800usb_config_filter(struct rt2x00_dev *rt2x00dev,
+ const unsigned int filter_flags)
+{
+ u32 reg;
+
+ /*
+ * Start configuration steps.
+ * Note that the version error will always be dropped
+ * and broadcast frames will always be accepted since
+ * there is no filter for it at this time.
+ */
+ rt2x00usb_register_read(rt2x00dev, RX_FILTER_CFG, &reg);
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CRC_ERROR,
+ !(filter_flags & FIF_FCSFAIL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PHY_ERROR,
+ !(filter_flags & FIF_PLCPFAIL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_TO_ME,
+ !(filter_flags & FIF_PROMISC_IN_BSS));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_MY_BSSD, 0);
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_VER_ERROR, 1);
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_MULTICAST,
+ !(filter_flags & FIF_ALLMULTI));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BROADCAST, 0);
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_DUPLICATE, 1);
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CF_END_ACK,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CF_END,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_ACK,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CTS,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_RTS,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PSPOLL,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BA, 1);
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BAR, 0);
+ rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CNTL,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00usb_register_write(rt2x00dev, RX_FILTER_CFG, reg);
+}
+
+static void rt2800usb_config_intf(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_intf *intf,
+ struct rt2x00intf_conf *conf,
+ const unsigned int flags)
+{
+ unsigned int beacon_base;
+ u32 reg;
+
+ if (flags & CONFIG_UPDATE_TYPE) {
+ /*
+ * Clear current synchronisation setup.
+ * For the Beacon base registers we only need to clear
+ * the first byte since that byte contains the VALID and OWNER
+ * bits which (when set to 0) will invalidate the entire beacon.
+ */
+ beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
+ rt2x00usb_register_write(rt2x00dev, beacon_base, 0);
+
+ /*
+ * Enable synchronisation.
+ */
+ rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, conf->sync);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
+ rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ }
+
+ if (flags & CONFIG_UPDATE_MAC) {
+ reg = le32_to_cpu(conf->mac[1]);
+ rt2x00_set_field32(&reg, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff);
+ conf->mac[1] = cpu_to_le32(reg);
+
+ rt2x00usb_register_multiwrite(rt2x00dev, MAC_ADDR_DW0,
+ conf->mac, sizeof(conf->mac));
+ }
+
+ if (flags & CONFIG_UPDATE_BSSID) {
+ reg = le32_to_cpu(conf->bssid[1]);
+ rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 0);
+ rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 0);
+ conf->bssid[1] = cpu_to_le32(reg);
+
+ rt2x00usb_register_multiwrite(rt2x00dev, MAC_BSSID_DW0,
+ conf->bssid, sizeof(conf->bssid));
+ }
+}
+
+static void rt2800usb_config_erp(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_erp *erp)
+{
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT,
+ DIV_ROUND_UP(erp->ack_timeout, erp->slot_time));
+ rt2x00usb_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY,
+ !!erp->short_preamble);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_AR_PREAMBLE,
+ !!erp->short_preamble);
+ rt2x00usb_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL,
+ erp->cts_protection ? 2 : 0);
+ rt2x00usb_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+
+ rt2x00usb_register_write(rt2x00dev, LEGACY_BASIC_RATE,
+ erp->basic_rates);
+ rt2x00usb_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
+
+ rt2x00usb_register_read(rt2x00dev, BKOFF_SLOT_CFG, &reg);
+ rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time);
+ rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
+ rt2x00usb_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_CCKM_SIFS_TIME, erp->sifs);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_SIFS_TIME, erp->sifs);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, erp->eifs);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1);
+ rt2x00usb_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL,
+ erp->beacon_int * 16);
+ rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+}
+
+static void rt2800usb_config_ant(struct rt2x00_dev *rt2x00dev,
+ struct antenna_setup *ant)
+{
+ u8 r1;
+ u8 r3;
+
+ rt2800usb_bbp_read(rt2x00dev, 1, &r1);
+ rt2800usb_bbp_read(rt2x00dev, 3, &r3);
+
+ /*
+ * Configure the TX antenna.
+ */
+ switch ((int)ant->tx) {
+ case 1:
+ rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
+ break;
+ case 2:
+ rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
+ break;
+ case 3:
+ /* Do nothing */
+ break;
+ }
+
+ /*
+ * Configure the RX antenna.
+ */
+ switch ((int)ant->rx) {
+ case 1:
+ rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
+ break;
+ case 2:
+ rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1);
+ break;
+ case 3:
+ rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 2);
+ break;
+ }
+
+ rt2800usb_bbp_write(rt2x00dev, 3, r3);
+ rt2800usb_bbp_write(rt2x00dev, 1, r1);
+}
+
+static void rt2800usb_config_lna_gain(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf)
+{
+ u16 eeprom;
+ short lna_gain;
+
+ if (libconf->rf.channel <= 14) {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_BG);
+ } else if (libconf->rf.channel <= 64) {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
+ } else if (libconf->rf.channel <= 128) {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_LNA_A1);
+ } else {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
+ lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_LNA_A2);
+ }
+
+ rt2x00dev->lna_gain = lna_gain;
+}
+
+static void rt2800usb_config_channel_rt2x(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf,
+ struct rf_channel *rf,
+ struct channel_info *info)
+{
+ rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
+
+ if (rt2x00dev->default_ant.tx == 1)
+ rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1);
+
+ if (rt2x00dev->default_ant.rx == 1) {
+ rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1);
+ rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
+ } else if (rt2x00dev->default_ant.rx == 2)
+ rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
+
+ if (rf->channel > 14) {
+ /*
+ * When TX power is below 0, we should increase it by 7 to
+ * make it a positive value (Minumum value is -7).
+ * However this means that values between 0 and 7 have
+ * double meaning, and we should set a 7DBm boost flag.
+ */
+ rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST,
+ (info->tx_power1 >= 0));
+
+ if (info->tx_power1 < 0)
+ info->tx_power1 += 7;
+
+ rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A,
+ TXPOWER_A_TO_DEV(info->tx_power1));
+
+ rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST,
+ (info->tx_power2 >= 0));
+
+ if (info->tx_power2 < 0)
+ info->tx_power2 += 7;
+
+ rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A,
+ TXPOWER_A_TO_DEV(info->tx_power2));
+ } else {
+ rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G,
+ TXPOWER_G_TO_DEV(info->tx_power1));
+ rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G,
+ TXPOWER_G_TO_DEV(info->tx_power2));
+ }
+
+ rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf));
+
+ rt2800usb_rf_write(rt2x00dev, 1, rf->rf1);
+ rt2800usb_rf_write(rt2x00dev, 2, rf->rf2);
+ rt2800usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+ rt2800usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+ udelay(200);
+
+ rt2800usb_rf_write(rt2x00dev, 1, rf->rf1);
+ rt2800usb_rf_write(rt2x00dev, 2, rf->rf2);
+ rt2800usb_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
+ rt2800usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+ udelay(200);
+
+ rt2800usb_rf_write(rt2x00dev, 1, rf->rf1);
+ rt2800usb_rf_write(rt2x00dev, 2, rf->rf2);
+ rt2800usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+ rt2800usb_rf_write(rt2x00dev, 4, rf->rf4);
+}
+
+static void rt2800usb_config_channel_rt3x(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf,
+ struct rf_channel *rf,
+ struct channel_info *info)
+{
+ u8 rfcsr;
+
+ rt2800usb_rfcsr_write(rt2x00dev, 2, rf->rf1);
+ rt2800usb_rfcsr_write(rt2x00dev, 2, rf->rf3);
+
+ rt2800usb_rfcsr_read(rt2x00dev, 6, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR6_R, rf->rf2);
+ rt2800usb_rfcsr_write(rt2x00dev, 6, rfcsr);
+
+ rt2800usb_rfcsr_read(rt2x00dev, 12, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
+ TXPOWER_G_TO_DEV(info->tx_power1));
+ rt2800usb_rfcsr_write(rt2x00dev, 12, rfcsr);
+
+ rt2800usb_rfcsr_read(rt2x00dev, 23, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
+ rt2800usb_rfcsr_write(rt2x00dev, 23, rfcsr);
+
+ rt2800usb_rfcsr_write(rt2x00dev, 24,
+ rt2x00dev->calibration[conf_is_ht40(conf)]);
+
+ rt2800usb_rfcsr_read(rt2x00dev, 23, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
+ rt2800usb_rfcsr_write(rt2x00dev, 23, rfcsr);
+}
+
+static void rt2800usb_config_channel(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf,
+ struct rf_channel *rf,
+ struct channel_info *info)
+{
+ u32 reg;
+ unsigned int tx_pin;
+ u8 bbp;
+
+ if (rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION)
+ rt2800usb_config_channel_rt2x(rt2x00dev, conf, rf, info);
+ else
+ rt2800usb_config_channel_rt3x(rt2x00dev, conf, rf, info);
+
+ /*
+ * Change BBP settings
+ */
+ rt2800usb_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+ rt2800usb_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+ rt2800usb_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+ rt2800usb_bbp_write(rt2x00dev, 86, 0);
+
+ if (rf->channel <= 14) {
+ if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
+ rt2800usb_bbp_write(rt2x00dev, 82, 0x62);
+ rt2800usb_bbp_write(rt2x00dev, 75, 0x46);
+ } else {
+ rt2800usb_bbp_write(rt2x00dev, 82, 0x84);
+ rt2800usb_bbp_write(rt2x00dev, 75, 0x50);
+ }
+ } else {
+ rt2800usb_bbp_write(rt2x00dev, 82, 0xf2);
+
+ if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
+ rt2800usb_bbp_write(rt2x00dev, 75, 0x46);
+ else
+ rt2800usb_bbp_write(rt2x00dev, 75, 0x50);
+ }
+
+ rt2x00usb_register_read(rt2x00dev, TX_BAND_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_BAND_CFG_HT40_PLUS, conf_is_ht40_plus(conf));
+ rt2x00_set_field32(&reg, TX_BAND_CFG_A, rf->channel > 14);
+ rt2x00_set_field32(&reg, TX_BAND_CFG_BG, rf->channel <= 14);
+ rt2x00usb_register_write(rt2x00dev, TX_BAND_CFG, reg);
+
+ tx_pin = 0;
+
+ /* Turn on unused PA or LNA when not using 1T or 1R */
+ if (rt2x00dev->default_ant.tx != 1) {
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1);
+ }
+
+ /* Turn on unused PA or LNA when not using 1T or 1R */
+ if (rt2x00dev->default_ant.rx != 1) {
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1);
+ }
+
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, rf->channel <= 14);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14);
+
+ rt2x00usb_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
+
+ rt2800usb_bbp_read(rt2x00dev, 4, &bbp);
+ rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
+ rt2800usb_bbp_write(rt2x00dev, 4, bbp);
+
+ rt2800usb_bbp_read(rt2x00dev, 3, &bbp);
+ rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf));
+ rt2800usb_bbp_write(rt2x00dev, 3, bbp);
+
+ if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
+ if (conf_is_ht40(conf)) {
+ rt2800usb_bbp_write(rt2x00dev, 69, 0x1a);
+ rt2800usb_bbp_write(rt2x00dev, 70, 0x0a);
+ rt2800usb_bbp_write(rt2x00dev, 73, 0x16);
+ } else {
+ rt2800usb_bbp_write(rt2x00dev, 69, 0x16);
+ rt2800usb_bbp_write(rt2x00dev, 70, 0x08);
+ rt2800usb_bbp_write(rt2x00dev, 73, 0x11);
+ }
+ }
+
+ msleep(1);
+}
+
+static void rt2800usb_config_txpower(struct rt2x00_dev *rt2x00dev,
+ const int txpower)
+{
+ u32 reg;
+ u32 value = TXPOWER_G_TO_DEV(txpower);
+ u8 r1;
+
+ rt2800usb_bbp_read(rt2x00dev, 1, &r1);
+ rt2x00_set_field8(&reg, BBP1_TX_POWER, 0);
+ rt2800usb_bbp_write(rt2x00dev, 1, r1);
+
+ rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_0, &reg);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_1MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_2MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_55MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_11MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_6MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_9MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_12MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_0_18MBS, value);
+ rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_0, reg);
+
+ rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_1, &reg);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_24MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_36MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_48MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_54MBS, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS0, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS1, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS2, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS3, value);
+ rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_1, reg);
+
+ rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_2, &reg);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS4, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS5, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS6, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS7, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS8, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS9, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS10, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS11, value);
+ rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_2, reg);
+
+ rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_3, &reg);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS12, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS13, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS14, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS15, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN1, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN2, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN3, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN4, value);
+ rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_3, reg);
+
+ rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_4, &reg);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN5, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN6, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN7, value);
+ rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN8, value);
+ rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_4, reg);
+}
+
+static void rt2800usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf)
+{
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, TX_RTY_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_SHORT_RTY_LIMIT,
+ libconf->conf->short_frame_max_tx_count);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT,
+ libconf->conf->long_frame_max_tx_count);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_THRE, 2000);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_AGG_RTY_MODE, 0);
+ rt2x00_set_field32(&reg, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1);
+ rt2x00usb_register_write(rt2x00dev, TX_RTY_CFG, reg);
+}
+
+static void rt2800usb_config_ps(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf)
+{
+ enum dev_state state =
+ (libconf->conf->flags & IEEE80211_CONF_PS) ?
+ STATE_SLEEP : STATE_AWAKE;
+ u32 reg;
+
+ if (state == STATE_SLEEP) {
+ rt2x00usb_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0);
+
+ rt2x00usb_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg);
+ rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 5);
+ rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE,
+ libconf->conf->listen_interval - 1);
+ rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 1);
+ rt2x00usb_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
+
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+ } else {
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+
+ rt2x00usb_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg);
+ rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 0);
+ rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE, 0);
+ rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 0);
+ rt2x00usb_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
+ }
+}
+
+static void rt2800usb_config(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf,
+ const unsigned int flags)
+{
+ /* Always recalculate LNA gain before changing configuration */
+ rt2800usb_config_lna_gain(rt2x00dev, libconf);
+
+ if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
+ rt2800usb_config_channel(rt2x00dev, libconf->conf,
+ &libconf->rf, &libconf->channel);
+ if (flags & IEEE80211_CONF_CHANGE_POWER)
+ rt2800usb_config_txpower(rt2x00dev, libconf->conf->power_level);
+ if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
+ rt2800usb_config_retry_limit(rt2x00dev, libconf);
+ if (flags & IEEE80211_CONF_CHANGE_PS)
+ rt2800usb_config_ps(rt2x00dev, libconf);
+}
+
+/*
+ * Link tuning
+ */
+static void rt2800usb_link_stats(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
+{
+ u32 reg;
+
+ /*
+ * Update FCS error count from register.
+ */
+ rt2x00usb_register_read(rt2x00dev, RX_STA_CNT0, &reg);
+ qual->rx_failed = rt2x00_get_field32(reg, RX_STA_CNT0_CRC_ERR);
+}
+
+static u8 rt2800usb_get_default_vgc(struct rt2x00_dev *rt2x00dev)
+{
+ if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
+ if (rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION)
+ return 0x1c + (2 * rt2x00dev->lna_gain);
+ else
+ return 0x2e + rt2x00dev->lna_gain;
+ }
+
+ if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
+ return 0x32 + (rt2x00dev->lna_gain * 5) / 3;
+ else
+ return 0x3a + (rt2x00dev->lna_gain * 5) / 3;
+}
+
+static inline void rt2800usb_set_vgc(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, u8 vgc_level)
+{
+ if (qual->vgc_level != vgc_level) {
+ rt2800usb_bbp_write(rt2x00dev, 66, vgc_level);
+ qual->vgc_level = vgc_level;
+ qual->vgc_level_reg = vgc_level;
+ }
+}
+
+static void rt2800usb_reset_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
+{
+ rt2800usb_set_vgc(rt2x00dev, qual,
+ rt2800usb_get_default_vgc(rt2x00dev));
+}
+
+static void rt2800usb_link_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, const u32 count)
+{
+ if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION)
+ return;
+
+ /*
+ * When RSSI is better then -80 increase VGC level with 0x10
+ */
+ rt2800usb_set_vgc(rt2x00dev, qual,
+ rt2800usb_get_default_vgc(rt2x00dev) +
+ ((qual->rssi > -80) * 0x10));
+}
+
+/*
+ * Firmware functions
+ */
+static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
+{
+ return FIRMWARE_RT2870;
+}
+
+static bool rt2800usb_check_crc(const u8 *data, const size_t len)
+{
+ u16 fw_crc;
+ u16 crc;
+
+ /*
+ * The last 2 bytes in the firmware array are the crc checksum itself,
+ * this means that we should never pass those 2 bytes to the crc
+ * algorithm.
+ */
+ fw_crc = (data[len - 2] << 8 | data[len - 1]);
+
+ /*
+ * Use the crc ccitt algorithm.
+ * This will return the same value as the legacy driver which
+ * used bit ordering reversion on the both the firmware bytes
+ * before input input as well as on the final output.
+ * Obviously using crc ccitt directly is much more efficient.
+ */
+ crc = crc_ccitt(~0, data, len - 2);
+
+ /*
+ * There is a small difference between the crc-itu-t + bitrev and
+ * the crc-ccitt crc calculation. In the latter method the 2 bytes
+ * will be swapped, use swab16 to convert the crc to the correct
+ * value.
+ */
+ crc = swab16(crc);
+
+ return fw_crc == crc;
+}
+
+static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len)
+{
+ u16 chipset = (rt2x00_rev(&rt2x00dev->chip) >> 16) & 0xffff;
+ size_t offset = 0;
+
+ /*
+ * Firmware files:
+ * There are 2 variations of the rt2870 firmware.
+ * a) size: 4kb
+ * b) size: 8kb
+ * Note that (b) contains 2 seperate firmware blobs of 4k
+ * within the file. The first blob is the same firmware as (a),
+ * but the second blob is for the additional chipsets.
+ */
+ if (len != 4096 && len != 8192)
+ return FW_BAD_LENGTH;
+
+ /*
+ * Check if we need the upper 4kb firmware data or not.
+ */
+ if ((len == 4096) &&
+ (chipset != 0x2860) &&
+ (chipset != 0x2872) &&
+ (chipset != 0x3070))
+ return FW_BAD_VERSION;
+
+ /*
+ * 8kb firmware files must be checked as if it were
+ * 2 seperate firmware files.
+ */
+ while (offset < len) {
+ if (!rt2800usb_check_crc(data + offset, 4096))
+ return FW_BAD_CRC;
+
+ offset += 4096;
+ }
+
+ return FW_OK;
+}
+
+static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len)
+{
+ unsigned int i;
+ int status;
+ u32 reg;
+ u32 offset;
+ u32 length;
+ u16 chipset = (rt2x00_rev(&rt2x00dev->chip) >> 16) & 0xffff;
+
+ /*
+ * Check which section of the firmware we need.
+ */
+ if ((chipset == 0x2860) ||
+ (chipset == 0x2872) ||
+ (chipset == 0x3070)) {
+ offset = 0;
+ length = 4096;
+ } else {
+ offset = 4096;
+ length = 4096;
+ }
+
+ /*
+ * Wait for stable hardware.
+ */
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
+ if (reg && reg != ~0)
+ break;
+ msleep(1);
+ }
+
+ if (i == REGISTER_BUSY_COUNT) {
+ ERROR(rt2x00dev, "Unstable hardware.\n");
+ return -EBUSY;
+ }
+
+ /*
+ * Write firmware to device.
+ */
+ rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
+ USB_VENDOR_REQUEST_OUT,
+ FIRMWARE_IMAGE_BASE,
+ data + offset, length,
+ REGISTER_TIMEOUT32(length));
+
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+
+ /*
+ * Send firmware request to device to load firmware,
+ * we need to specify a long timeout time.
+ */
+ status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE,
+ 0, USB_MODE_FIRMWARE,
+ REGISTER_TIMEOUT_FIRMWARE);
+ if (status < 0) {
+ ERROR(rt2x00dev, "Failed to write Firmware to device.\n");
+ return status;
+ }
+
+ msleep(10);
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+
+ /*
+ * Send signal to firmware during boot time.
+ */
+ rt2800usb_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0);
+
+ if ((chipset == 0x3070) ||
+ (chipset == 0x3071) ||
+ (chipset == 0x3572)) {
+ udelay(200);
+ rt2800usb_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
+ udelay(10);
+ }
+
+ /*
+ * Wait for device to stabilize.
+ */
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+ if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
+ break;
+ msleep(1);
+ }
+
+ if (i == REGISTER_BUSY_COUNT) {
+ ERROR(rt2x00dev, "PBF system register not ready.\n");
+ return -EBUSY;
+ }
+
+ /*
+ * Initialize firmware.
+ */
+ rt2x00usb_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+ msleep(1);
+
+ return 0;
+}
+
+/*
+ * Initialization functions.
+ */
+static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+ unsigned int i;
+
+ /*
+ * Wait untill BBP and RF are ready.
+ */
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
+ if (reg && reg != ~0)
+ break;
+ msleep(1);
+ }
+
+ if (i == REGISTER_BUSY_COUNT) {
+ ERROR(rt2x00dev, "Unstable hardware.\n");
+ return -EBUSY;
+ }
+
+ rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+ rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
+
+ rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+ rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
+
+ rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
+ USB_MODE_RESET, REGISTER_TIMEOUT);
+
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+
+ rt2x00usb_register_read(rt2x00dev, BCN_OFFSET0, &reg);
+ rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */
+ rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1, 0xe8); /* 0x3a00 */
+ rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2, 0xf0); /* 0x3c00 */
+ rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3, 0xf8); /* 0x3e00 */
+ rt2x00usb_register_write(rt2x00dev, BCN_OFFSET0, reg);
+
+ rt2x00usb_register_read(rt2x00dev, BCN_OFFSET1, &reg);
+ rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4, 0xc8); /* 0x3200 */
+ rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5, 0xd0); /* 0x3400 */
+ rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6, 0x77); /* 0x1dc0 */
+ rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7, 0x6f); /* 0x1bc0 */
+ rt2x00usb_register_write(rt2x00dev, BCN_OFFSET1, reg);
+
+ rt2x00usb_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
+ rt2x00usb_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
+
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+
+ rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0);
+ rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+ if (rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
+ rt2x00usb_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
+ rt2x00usb_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
+ rt2x00usb_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+ } else {
+ rt2x00usb_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
+ rt2x00usb_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+ }
+
+ rt2x00usb_register_read(rt2x00dev, TX_LINK_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFB_LIFETIME, 32);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_MFB_ENABLE, 0);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_UMFS_ENABLE, 0);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_TX_MRQ_EN, 0);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_TX_RDG_EN, 0);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_TX_CF_ACK_EN, 1);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFB, 0);
+ rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFS, 0);
+ rt2x00usb_register_write(rt2x00dev, TX_LINK_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_MPDU_LIFETIME, 9);
+ rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_TX_OP_TIMEOUT, 10);
+ rt2x00usb_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
+ rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
+ if (rt2x00_rev(&rt2x00dev->chip) >= RT2880E_VERSION &&
+ rt2x00_rev(&rt2x00dev->chip) < RT3070_VERSION)
+ rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
+ else
+ rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
+ rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_PSDU, 0);
+ rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 0);
+ rt2x00usb_register_write(rt2x00dev, MAX_LEN_CFG, reg);
+
+ rt2x00usb_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f);
+
+ rt2x00usb_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_AUTORESPONDER, 1);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MMODE, 0);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MREF, 0);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_DUAL_CTS_EN, 0);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_ACK_CTS_PSM_BIT, 0);
+ rt2x00usb_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_RATE, 8);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_CTRL, 0);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_NAV, 1);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+ rt2x00usb_register_write(rt2x00dev, CCK_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_RATE, 8);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL, 0);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_NAV, 1);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+ rt2x00usb_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_RATE, 0x4004);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_CTRL, 0);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_NAV, 1);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
+ rt2x00usb_register_write(rt2x00dev, MM20_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 0);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV, 1);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+ rt2x00usb_register_write(rt2x00dev, MM40_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_RATE, 0x4004);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_CTRL, 0);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_NAV, 1);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
+ rt2x00usb_register_write(rt2x00dev, GF20_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_RATE, 0x4084);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_CTRL, 0);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_NAV, 1);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+ rt2x00usb_register_write(rt2x00dev, GF40_PROT_CFG, reg);
+
+ rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006);
+
+ rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 3);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_BIG_ENDIAN, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_HDR_SCATTER, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_HDR_SEG_LEN, 0);
+ rt2x00usb_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+ rt2x00usb_register_write(rt2x00dev, TXOP_CTRL_CFG, 0x0000583f);
+ rt2x00usb_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002);
+
+ rt2x00usb_register_read(rt2x00dev, TX_RTS_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32);
+ rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES,
+ IEEE80211_MAX_RTS_THRESHOLD);
+ rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_FBK_EN, 0);
+ rt2x00usb_register_write(rt2x00dev, TX_RTS_CFG, reg);
+
+ rt2x00usb_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca);
+ rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
+
+ /*
+ * ASIC will keep garbage value after boot, clear encryption keys.
+ */
+ for (i = 0; i < 256; i++) {
+ u32 wcid[2] = { 0xffffffff, 0x00ffffff };
+ rt2x00usb_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
+ wcid, sizeof(wcid));
+
+ rt2x00usb_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 1);
+ rt2x00usb_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
+ }
+
+ for (i = 0; i < 16; i++)
+ rt2x00usb_register_write(rt2x00dev,
+ SHARED_KEY_MODE_ENTRY(i), 0);
+
+ /*
+ * Clear all beacons
+ * For the Beacon base registers we only need to clear
+ * the first byte since that byte contains the VALID and OWNER
+ * bits which (when set to 0) will invalidate the entire beacon.
+ */
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE4, 0);
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE5, 0);
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE6, 0);
+ rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE7, 0);
+
+ rt2x00usb_register_read(rt2x00dev, USB_CYC_CFG, &reg);
+ rt2x00_set_field32(&reg, USB_CYC_CFG_CLOCK_CYCLE, 30);
+ rt2x00usb_register_write(rt2x00dev, USB_CYC_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, HT_FBK_CFG0, &reg);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS0FBK, 0);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS1FBK, 0);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS2FBK, 1);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS3FBK, 2);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS4FBK, 3);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS5FBK, 4);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS6FBK, 5);
+ rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS7FBK, 6);
+ rt2x00usb_register_write(rt2x00dev, HT_FBK_CFG0, reg);
+
+ rt2x00usb_register_read(rt2x00dev, HT_FBK_CFG1, &reg);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS8FBK, 8);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS9FBK, 8);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS10FBK, 9);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS11FBK, 10);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS12FBK, 11);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS13FBK, 12);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS14FBK, 13);
+ rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS15FBK, 14);
+ rt2x00usb_register_write(rt2x00dev, HT_FBK_CFG1, reg);
+
+ rt2x00usb_register_read(rt2x00dev, LG_FBK_CFG0, &reg);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS0FBK, 8);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS1FBK, 8);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS2FBK, 3);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS3FBK, 10);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS4FBK, 11);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS5FBK, 12);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS6FBK, 13);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS7FBK, 14);
+ rt2x00usb_register_write(rt2x00dev, LG_FBK_CFG0, reg);
+
+ rt2x00usb_register_read(rt2x00dev, LG_FBK_CFG1, &reg);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS0FBK, 0);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS1FBK, 0);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS2FBK, 1);
+ rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS3FBK, 2);
+ rt2x00usb_register_write(rt2x00dev, LG_FBK_CFG1, reg);
+
+ /*
+ * We must clear the error counters.
+ * These registers are cleared on read,
+ * so we may pass a useless variable to store the value.
+ */
+ rt2x00usb_register_read(rt2x00dev, RX_STA_CNT0, &reg);
+ rt2x00usb_register_read(rt2x00dev, RX_STA_CNT1, &reg);
+ rt2x00usb_register_read(rt2x00dev, RX_STA_CNT2, &reg);
+ rt2x00usb_register_read(rt2x00dev, TX_STA_CNT0, &reg);
+ rt2x00usb_register_read(rt2x00dev, TX_STA_CNT1, &reg);
+ rt2x00usb_register_read(rt2x00dev, TX_STA_CNT2, &reg);
+
+ return 0;
+}
+
+static int rt2800usb_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u32 reg;
+
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2x00usb_register_read(rt2x00dev, MAC_STATUS_CFG, &reg);
+ if (!rt2x00_get_field32(reg, MAC_STATUS_CFG_BBP_RF_BUSY))
+ return 0;
+
+ udelay(REGISTER_BUSY_DELAY);
+ }
+
+ ERROR(rt2x00dev, "BBP/RF register access failed, aborting.\n");
+ return -EACCES;
+}
+
+static int rt2800usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u8 value;
+
+ /*
+ * BBP was enabled after firmware was loaded,
+ * but we need to reactivate it now.
+ */
+ rt2x00usb_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+ msleep(1);
+
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2800usb_bbp_read(rt2x00dev, 0, &value);
+ if ((value != 0xff) && (value != 0x00))
+ return 0;
+ udelay(REGISTER_BUSY_DELAY);
+ }
+
+ ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
+ return -EACCES;
+}
+
+static int rt2800usb_init_bbp(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u16 eeprom;
+ u8 reg_id;
+ u8 value;
+
+ if (unlikely(rt2800usb_wait_bbp_rf_ready(rt2x00dev) ||
+ rt2800usb_wait_bbp_ready(rt2x00dev)))
+ return -EACCES;
+
+ rt2800usb_bbp_write(rt2x00dev, 65, 0x2c);
+ rt2800usb_bbp_write(rt2x00dev, 66, 0x38);
+ rt2800usb_bbp_write(rt2x00dev, 69, 0x12);
+ rt2800usb_bbp_write(rt2x00dev, 70, 0x0a);
+ rt2800usb_bbp_write(rt2x00dev, 73, 0x10);
+ rt2800usb_bbp_write(rt2x00dev, 81, 0x37);
+ rt2800usb_bbp_write(rt2x00dev, 82, 0x62);
+ rt2800usb_bbp_write(rt2x00dev, 83, 0x6a);
+ rt2800usb_bbp_write(rt2x00dev, 84, 0x99);
+ rt2800usb_bbp_write(rt2x00dev, 86, 0x00);
+ rt2800usb_bbp_write(rt2x00dev, 91, 0x04);
+ rt2800usb_bbp_write(rt2x00dev, 92, 0x00);
+ rt2800usb_bbp_write(rt2x00dev, 103, 0x00);
+ rt2800usb_bbp_write(rt2x00dev, 105, 0x05);
+
+ if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
+ rt2800usb_bbp_write(rt2x00dev, 69, 0x16);
+ rt2800usb_bbp_write(rt2x00dev, 73, 0x12);
+ }
+
+ if (rt2x00_rev(&rt2x00dev->chip) > RT2860D_VERSION) {
+ rt2800usb_bbp_write(rt2x00dev, 84, 0x19);
+ }
+
+ if (rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
+ rt2800usb_bbp_write(rt2x00dev, 70, 0x0a);
+ rt2800usb_bbp_write(rt2x00dev, 84, 0x99);
+ rt2800usb_bbp_write(rt2x00dev, 105, 0x05);
+ }
+
+ for (i = 0; i < EEPROM_BBP_SIZE; i++) {
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
+
+ if (eeprom != 0xffff && eeprom != 0x0000) {
+ reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
+ value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE);
+ rt2800usb_bbp_write(rt2x00dev, reg_id, value);
+ }
+ }
+
+ return 0;
+}
+
+static u8 rt2800usb_init_rx_filter(struct rt2x00_dev *rt2x00dev,
+ bool bw40, u8 rfcsr24, u8 filter_target)
+{
+ unsigned int i;
+ u8 bbp;
+ u8 rfcsr;
+ u8 passband;
+ u8 stopband;
+ u8 overtuned = 0;
+
+ rt2800usb_rfcsr_write(rt2x00dev, 24, rfcsr24);
+
+ rt2800usb_bbp_read(rt2x00dev, 4, &bbp);
+ rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * bw40);
+ rt2800usb_bbp_write(rt2x00dev, 4, bbp);
+
+ rt2800usb_rfcsr_read(rt2x00dev, 22, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 1);
+ rt2800usb_rfcsr_write(rt2x00dev, 22, rfcsr);
+
+ /*
+ * Set power & frequency of passband test tone
+ */
+ rt2800usb_bbp_write(rt2x00dev, 24, 0);
+
+ for (i = 0; i < 100; i++) {
+ rt2800usb_bbp_write(rt2x00dev, 25, 0x90);
+ msleep(1);
+
+ rt2800usb_bbp_read(rt2x00dev, 55, &passband);
+ if (passband)
+ break;
+ }
+
+ /*
+ * Set power & frequency of stopband test tone
+ */
+ rt2800usb_bbp_write(rt2x00dev, 24, 0x06);
+
+ for (i = 0; i < 100; i++) {
+ rt2800usb_bbp_write(rt2x00dev, 25, 0x90);
+ msleep(1);
+
+ rt2800usb_bbp_read(rt2x00dev, 55, &stopband);
+
+ if ((passband - stopband) <= filter_target) {
+ rfcsr24++;
+ overtuned += ((passband - stopband) == filter_target);
+ } else
+ break;
+
+ rt2800usb_rfcsr_write(rt2x00dev, 24, rfcsr24);
+ }
+
+ rfcsr24 -= !!overtuned;
+
+ rt2800usb_rfcsr_write(rt2x00dev, 24, rfcsr24);
+ return rfcsr24;
+}
+
+static int rt2800usb_init_rfcsr(struct rt2x00_dev *rt2x00dev)
+{
+ u8 rfcsr;
+ u8 bbp;
+
+ if (rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION)
+ return 0;
+
+ /*
+ * Init RF calibration.
+ */
+ rt2800usb_rfcsr_read(rt2x00dev, 30, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
+ rt2800usb_rfcsr_write(rt2x00dev, 30, rfcsr);
+ msleep(1);
+ rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
+ rt2800usb_rfcsr_write(rt2x00dev, 30, rfcsr);
+
+ rt2800usb_rfcsr_write(rt2x00dev, 4, 0x40);
+ rt2800usb_rfcsr_write(rt2x00dev, 5, 0x03);
+ rt2800usb_rfcsr_write(rt2x00dev, 6, 0x02);
+ rt2800usb_rfcsr_write(rt2x00dev, 7, 0x70);
+ rt2800usb_rfcsr_write(rt2x00dev, 9, 0x0f);
+ rt2800usb_rfcsr_write(rt2x00dev, 10, 0x71);
+ rt2800usb_rfcsr_write(rt2x00dev, 11, 0x21);
+ rt2800usb_rfcsr_write(rt2x00dev, 12, 0x7b);
+ rt2800usb_rfcsr_write(rt2x00dev, 14, 0x90);
+ rt2800usb_rfcsr_write(rt2x00dev, 15, 0x58);
+ rt2800usb_rfcsr_write(rt2x00dev, 16, 0xb3);
+ rt2800usb_rfcsr_write(rt2x00dev, 17, 0x92);
+ rt2800usb_rfcsr_write(rt2x00dev, 18, 0x2c);
+ rt2800usb_rfcsr_write(rt2x00dev, 19, 0x02);
+ rt2800usb_rfcsr_write(rt2x00dev, 20, 0xba);
+ rt2800usb_rfcsr_write(rt2x00dev, 21, 0xdb);
+ rt2800usb_rfcsr_write(rt2x00dev, 24, 0x16);
+ rt2800usb_rfcsr_write(rt2x00dev, 25, 0x01);
+ rt2800usb_rfcsr_write(rt2x00dev, 27, 0x03);
+ rt2800usb_rfcsr_write(rt2x00dev, 29, 0x1f);
+
+ /*
+ * Set RX Filter calibration for 20MHz and 40MHz
+ */
+ rt2x00dev->calibration[0] =
+ rt2800usb_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
+ rt2x00dev->calibration[1] =
+ rt2800usb_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
+
+ /*
+ * Set back to initial state
+ */
+ rt2800usb_bbp_write(rt2x00dev, 24, 0);
+
+ rt2800usb_rfcsr_read(rt2x00dev, 22, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0);
+ rt2800usb_rfcsr_write(rt2x00dev, 22, rfcsr);
+
+ /*
+ * set BBP back to BW20
+ */
+ rt2800usb_bbp_read(rt2x00dev, 4, &bbp);
+ rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0);
+ rt2800usb_bbp_write(rt2x00dev, 4, bbp);
+
+ return 0;
+}
+
+/*
+ * Device state switch handlers.
+ */
+static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
+ enum dev_state state)
+{
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
+ (state == STATE_RADIO_RX_ON) ||
+ (state == STATE_RADIO_RX_ON_LINK));
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+}
+
+static int rt2800usb_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u32 reg;
+
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+ if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
+ !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
+ return 0;
+
+ msleep(1);
+ }
+
+ ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
+ return -EACCES;
+}
+
+static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+ u16 word;
+
+ /*
+ * Initialize all registers.
+ */
+ if (unlikely(rt2800usb_wait_wpdma_ready(rt2x00dev) ||
+ rt2800usb_init_registers(rt2x00dev) ||
+ rt2800usb_init_bbp(rt2x00dev) ||
+ rt2800usb_init_rfcsr(rt2x00dev)))
+ return -EIO;
+
+ rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+ udelay(50);
+
+ rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
+ rt2x00usb_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+
+ rt2x00usb_register_read(rt2x00dev, USB_DMA_CFG, &reg);
+ rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0);
+ /* Don't use bulk in aggregation when working with USB 1.1 */
+ rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN,
+ (rt2x00dev->rx->usb_maxpacket == 512));
+ rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128);
+ /*
+ * Total room for RX frames in kilobytes, PBF might still exceed
+ * this limit so reduce the number to prevent errors.
+ */
+ rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT,
+ ((RX_ENTRIES * DATA_FRAME_SIZE) / 1024) - 3);
+ rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1);
+ rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
+ rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+ /*
+ * Initialize LED control
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
+ rt2800usb_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
+ word & 0xff, (word >> 8) & 0xff);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
+ rt2800usb_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
+ word & 0xff, (word >> 8) & 0xff);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
+ rt2800usb_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
+ word & 0xff, (word >> 8) & 0xff);
+
+ return 0;
+}
+
+static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+ rt2x00usb_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+ rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
+ rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0);
+ rt2x00usb_register_write(rt2x00dev, TX_PIN_CFG, 0);
+
+ /* Wait for DMA, ignore error */
+ rt2800usb_wait_wpdma_ready(rt2x00dev);
+
+ rt2x00usb_disable_radio(rt2x00dev);
+}
+
+static int rt2800usb_set_state(struct rt2x00_dev *rt2x00dev,
+ enum dev_state state)
+{
+ if (state == STATE_AWAKE)
+ rt2800usb_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0);
+ else
+ rt2800usb_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2);
+
+ return 0;
+}
+
+static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
+ enum dev_state state)
+{
+ int retval = 0;
+
+ switch (state) {
+ case STATE_RADIO_ON:
+ /*
+ * Before the radio can be enabled, the device first has
+ * to be woken up. After that it needs a bit of time
+ * to be fully awake and the radio can be enabled.
+ */
+ rt2800usb_set_state(rt2x00dev, STATE_AWAKE);
+ msleep(1);
+ retval = rt2800usb_enable_radio(rt2x00dev);
+ break;
+ case STATE_RADIO_OFF:
+ /*
+ * After the radio has been disablee, the device should
+ * be put to sleep for powersaving.
+ */
+ rt2800usb_disable_radio(rt2x00dev);
+ rt2800usb_set_state(rt2x00dev, STATE_SLEEP);
+ break;
+ case STATE_RADIO_RX_ON:
+ case STATE_RADIO_RX_ON_LINK:
+ case STATE_RADIO_RX_OFF:
+ case STATE_RADIO_RX_OFF_LINK:
+ rt2800usb_toggle_rx(rt2x00dev, state);
+ break;
+ case STATE_RADIO_IRQ_ON:
+ case STATE_RADIO_IRQ_OFF:
+ /* No support, but no error either */
+ break;
+ case STATE_DEEP_SLEEP:
+ case STATE_SLEEP:
+ case STATE_STANDBY:
+ case STATE_AWAKE:
+ retval = rt2800usb_set_state(rt2x00dev, state);
+ break;
+ default:
+ retval = -ENOTSUPP;
+ break;
+ }
+
+ if (unlikely(retval))
+ ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",
+ state, retval);
+
+ return retval;
+}
+
+/*
+ * TX descriptor initialization
+ */
+static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
+ struct sk_buff *skb,
+ struct txentry_desc *txdesc)
+{
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+ __le32 *txi = skbdesc->desc;
+ __le32 *txwi = &txi[TXINFO_DESC_SIZE / sizeof(__le32)];
+ u32 word;
+
+ /*
+ * Initialize TX Info descriptor
+ */
+ rt2x00_desc_read(txwi, 0, &word);
+ rt2x00_set_field32(&word, TXWI_W0_FRAG,
+ test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
+ rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0);
+ rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0);
+ rt2x00_set_field32(&word, TXWI_W0_TS,
+ test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
+ rt2x00_set_field32(&word, TXWI_W0_AMPDU,
+ test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags));
+ rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density);
+ rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->ifs);
+ rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs);
+ rt2x00_set_field32(&word, TXWI_W0_BW,
+ test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags));
+ rt2x00_set_field32(&word, TXWI_W0_SHORT_GI,
+ test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags));
+ rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc);
+ rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode);
+ rt2x00_desc_write(txwi, 0, word);
+
+ rt2x00_desc_read(txwi, 1, &word);
+ rt2x00_set_field32(&word, TXWI_W1_ACK,
+ test_bit(ENTRY_TXD_ACK, &txdesc->flags));
+ rt2x00_set_field32(&word, TXWI_W1_NSEQ,
+ test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
+ rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
+ rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
+ test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
+ txdesc->key_idx : 0xff);
+ rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
+ skb->len - txdesc->l2pad);
+ rt2x00_set_field32(&word, TXWI_W1_PACKETID,
+ skbdesc->entry->entry_idx);
+ rt2x00_desc_write(txwi, 1, word);
+
+ /*
+ * Always write 0 to IV/EIV fields, hardware will insert the IV
+ * from the IVEIV register when TXINFO_W0_WIV is set to 0.
+ * When TXINFO_W0_WIV is set to 1 it will use the IV data
+ * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which
+ * crypto entry in the registers should be used to encrypt the frame.
+ */
+ _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */);
+ _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */);
+
+ /*
+ * Initialize TX descriptor
+ */
+ rt2x00_desc_read(txi, 0, &word);
+ rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
+ skb->len + TXWI_DESC_SIZE);
+ rt2x00_set_field32(&word, TXINFO_W0_WIV,
+ !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
+ rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2);
+ rt2x00_set_field32(&word, TXINFO_W0_SW_USE_LAST_ROUND, 0);
+ rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_NEXT_VALID, 0);
+ rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_BURST,
+ test_bit(ENTRY_TXD_BURST, &txdesc->flags));
+ rt2x00_desc_write(txi, 0, word);
+}
+
+/*
+ * TX data initialization
+ */
+static void rt2800usb_write_beacon(struct queue_entry *entry)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ unsigned int beacon_base;
+ u32 reg;
+
+ /*
+ * Add the descriptor in front of the skb.
+ */
+ skb_push(entry->skb, entry->queue->desc_size);
+ memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);
+ skbdesc->desc = entry->skb->data;
+
+ /*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
+ rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+ /*
+ * Write entire beacon with descriptor to register.
+ */
+ beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
+ rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
+ USB_VENDOR_REQUEST_OUT, beacon_base,
+ entry->skb->data, entry->skb->len,
+ REGISTER_TIMEOUT32(entry->skb->len));
+
+ /*
+ * Clean up the beacon skb.
+ */
+ dev_kfree_skb(entry->skb);
+ entry->skb = NULL;
+}
+
+static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
+{
+ int length;
+
+ /*
+ * The length _must_ include 4 bytes padding,
+ * it should always be multiple of 4,
+ * but it must _not_ be a multiple of the USB packet size.
+ */
+ length = roundup(entry->skb->len + 4, 4);
+ length += (4 * !(length % entry->queue->usb_maxpacket));
+
+ return length;
+}
+
+static void rt2800usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid queue)
+{
+ u32 reg;
+
+ if (queue != QID_BEACON) {
+ rt2x00usb_kick_tx_queue(rt2x00dev, queue);
+ return;
+ }
+
+ rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ if (!rt2x00_get_field32(reg, BCN_TIME_CFG_BEACON_GEN)) {
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
+ rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ }
+}
+
+/*
+ * RX control handlers
+ */
+static void rt2800usb_fill_rxdone(struct queue_entry *entry,
+ struct rxdone_entry_desc *rxdesc)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ __le32 *rxd = (__le32 *)entry->skb->data;
+ __le32 *rxwi;
+ u32 rxd0;
+ u32 rxwi0;
+ u32 rxwi1;
+ u32 rxwi2;
+ u32 rxwi3;
+
+ /*
+ * Copy descriptor to the skbdesc->desc buffer, making it safe from
+ * moving of frame data in rt2x00usb.
+ */
+ memcpy(skbdesc->desc, rxd, skbdesc->desc_len);
+ rxd = (__le32 *)skbdesc->desc;
+ rxwi = &rxd[RXD_DESC_SIZE / sizeof(__le32)];
+
+ /*
+ * It is now safe to read the descriptor on all architectures.
+ */
+ rt2x00_desc_read(rxd, 0, &rxd0);
+ rt2x00_desc_read(rxwi, 0, &rxwi0);
+ rt2x00_desc_read(rxwi, 1, &rxwi1);
+ rt2x00_desc_read(rxwi, 2, &rxwi2);
+ rt2x00_desc_read(rxwi, 3, &rxwi3);
+
+ if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR))
+ rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
+
+ if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
+ rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
+ rxdesc->cipher_status =
+ rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR);
+ }
+
+ if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) {
+ /*
+ * Hardware has stripped IV/EIV data from 802.11 frame during
+ * decryption. Unfortunately the descriptor doesn't contain
+ * any fields with the EIV/IV data either, so they can't
+ * be restored by rt2x00lib.
+ */
+ rxdesc->flags |= RX_FLAG_IV_STRIPPED;
+
+ if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS)
+ rxdesc->flags |= RX_FLAG_DECRYPTED;
+ else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC)
+ rxdesc->flags |= RX_FLAG_MMIC_ERROR;
+ }
+
+ if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS))
+ rxdesc->dev_flags |= RXDONE_MY_BSS;
+
+ if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD))
+ rxdesc->dev_flags |= RXDONE_L2PAD;
+
+ if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
+ rxdesc->flags |= RX_FLAG_SHORT_GI;
+
+ if (rt2x00_get_field32(rxwi1, RXWI_W1_BW))
+ rxdesc->flags |= RX_FLAG_40MHZ;
+
+ /*
+ * Detect RX rate, always use MCS as signal type.
+ */
+ rxdesc->dev_flags |= RXDONE_SIGNAL_MCS;
+ rxdesc->rate_mode = rt2x00_get_field32(rxwi1, RXWI_W1_PHYMODE);
+ rxdesc->signal = rt2x00_get_field32(rxwi1, RXWI_W1_MCS);
+
+ /*
+ * Mask of 0x8 bit to remove the short preamble flag.
+ */
+ if (rxdesc->rate_mode == RATE_MODE_CCK)
+ rxdesc->signal &= ~0x8;
+
+ rxdesc->rssi =
+ (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) +
+ rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2;
+
+ rxdesc->noise =
+ (rt2x00_get_field32(rxwi3, RXWI_W3_SNR0) +
+ rt2x00_get_field32(rxwi3, RXWI_W3_SNR1)) / 2;
+
+ rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT);
+
+ /*
+ * Remove RXWI descriptor from start of buffer.
+ */
+ skb_pull(entry->skb, skbdesc->desc_len);
+ skb_trim(entry->skb, rxdesc->size);
+}
+
+/*
+ * Device probe functions.
+ */
+static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
+{
+ u16 word;
+ u8 *mac;
+ u8 default_lna_gain;
+
+ rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE);
+
+ /*
+ * Start validation of the data that has been read.
+ */
+ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
+ if (!is_valid_ether_addr(mac)) {
+ DECLARE_MAC_BUF(macbuf);
+
+ random_ether_addr(mac);
+ EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac));
+ }
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
+ if (word == 0xffff) {
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1);
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
+ EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
+ } else if (rt2x00_rev(&rt2x00dev->chip) < RT2883_VERSION) {
+ /*
+ * There is a max of 2 RX streams for RT2870 series
+ */
+ if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2)
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
+ }
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word);
+ if (word == 0xffff) {
+ rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word);
+ EEPROM(rt2x00dev, "NIC: 0x%04x\n", word);
+ }
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word);
+ if ((word & 0x00ff) == 0x00ff) {
+ rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0);
+ rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE,
+ LED_MODE_TXRX_ACTIVITY);
+ rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8);
+ EEPROM(rt2x00dev, "Freq: 0x%04x\n", word);
+ }
+
+ /*
+ * During the LNA validation we are going to use
+ * lna0 as correct value. Note that EEPROM_LNA
+ * is never validated.
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &word);
+ default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word);
+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10)
+ rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0);
+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10)
+ rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
+ rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
+ if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
+ rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
+ rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
+ default_lna_gain);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10)
+ rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0);
+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10)
+ rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
+ rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
+ if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
+ rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
+ rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
+ default_lna_gain);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
+
+ return 0;
+}
+
+static int rt2800usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+ u16 value;
+ u16 eeprom;
+
+ /*
+ * Read EEPROM word for configuration.
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+
+ /*
+ * Identify RF chipset.
+ */
+ value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
+ rt2x00_set_chip(rt2x00dev, RT2870, value, reg);
+
+ /*
+ * The check for rt2860 is not a typo, some rt2870 hardware
+ * identifies itself as rt2860 in the CSR register.
+ */
+ if (!rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28600000) &&
+ !rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28700000) &&
+ !rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28800000) &&
+ !rt2x00_check_rev(&rt2x00dev->chip, 0xffff0000, 0x30700000)) {
+ ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
+ return -ENODEV;
+ }
+
+ if (!rt2x00_rf(&rt2x00dev->chip, RF2820) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF2850) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF2720) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF2750) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF3020) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF2020)) {
+ ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
+ return -ENODEV;
+ }
+
+ /*
+ * Identify default antenna configuration.
+ */
+ rt2x00dev->default_ant.tx =
+ rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH);
+ rt2x00dev->default_ant.rx =
+ rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH);
+
+ /*
+ * Read frequency offset and RF programming sequence.
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
+ rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
+
+ /*
+ * Read external LNA informations.
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
+
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A))
+ __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
+ __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+
+ /*
+ * Detect if this device has an hardware controlled radio.
+ */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO))
+ __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
+ /*
+ * Store led settings, for correct led behaviour.
+ */
+#ifdef CONFIG_RT2X00_LIB_LEDS
+ rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
+ rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
+ rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ,
+ &rt2x00dev->led_mcu_reg);
+#endif /* CONFIG_RT2X00_LIB_LEDS */
+
+ return 0;
+}
+
+/*
+ * RF value list for rt2870
+ * Supports: 2.4 GHz (all) & 5.2 GHz (RF2850 & RF2750)
+ */
+static const struct rf_channel rf_vals[] = {
+ { 1, 0x18402ecc, 0x184c0786, 0x1816b455, 0x1800510b },
+ { 2, 0x18402ecc, 0x184c0786, 0x18168a55, 0x1800519f },
+ { 3, 0x18402ecc, 0x184c078a, 0x18168a55, 0x1800518b },
+ { 4, 0x18402ecc, 0x184c078a, 0x18168a55, 0x1800519f },
+ { 5, 0x18402ecc, 0x184c078e, 0x18168a55, 0x1800518b },
+ { 6, 0x18402ecc, 0x184c078e, 0x18168a55, 0x1800519f },
+ { 7, 0x18402ecc, 0x184c0792, 0x18168a55, 0x1800518b },
+ { 8, 0x18402ecc, 0x184c0792, 0x18168a55, 0x1800519f },
+ { 9, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800518b },
+ { 10, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800519f },
+ { 11, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800518b },
+ { 12, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800519f },
+ { 13, 0x18402ecc, 0x184c079e, 0x18168a55, 0x1800518b },
+ { 14, 0x18402ecc, 0x184c07a2, 0x18168a55, 0x18005193 },
+
+ /* 802.11 UNI / HyperLan 2 */
+ { 36, 0x18402ecc, 0x184c099a, 0x18158a55, 0x180ed1a3 },
+ { 38, 0x18402ecc, 0x184c099e, 0x18158a55, 0x180ed193 },
+ { 40, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed183 },
+ { 44, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed1a3 },
+ { 46, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed18b },
+ { 48, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed19b },
+ { 52, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed193 },
+ { 54, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed1a3 },
+ { 56, 0x18402ec8, 0x184c068e, 0x18158a55, 0x180ed18b },
+ { 60, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed183 },
+ { 62, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed193 },
+ { 64, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed1a3 },
+
+ /* 802.11 HyperLan 2 */
+ { 100, 0x18402ec8, 0x184c06b2, 0x18178a55, 0x180ed783 },
+ { 102, 0x18402ec8, 0x184c06b2, 0x18578a55, 0x180ed793 },
+ { 104, 0x18402ec8, 0x185c06b2, 0x18578a55, 0x180ed1a3 },
+ { 108, 0x18402ecc, 0x185c0a32, 0x18578a55, 0x180ed193 },
+ { 110, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed183 },
+ { 112, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed19b },
+ { 116, 0x18402ecc, 0x184c0a3a, 0x18178a55, 0x180ed1a3 },
+ { 118, 0x18402ecc, 0x184c0a3e, 0x18178a55, 0x180ed193 },
+ { 120, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed183 },
+ { 124, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed193 },
+ { 126, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed15b },
+ { 128, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed1a3 },
+ { 132, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed18b },
+ { 134, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed193 },
+ { 136, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed19b },
+ { 140, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed183 },
+
+ /* 802.11 UNII */
+ { 149, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed1a7 },
+ { 151, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed187 },
+ { 153, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed18f },
+ { 157, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed19f },
+ { 159, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed1a7 },
+ { 161, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed187 },
+ { 165, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed197 },
+ { 167, 0x18402ec4, 0x184c03d2, 0x18179855, 0x1815531f },
+ { 169, 0x18402ec4, 0x184c03d2, 0x18179855, 0x18155327 },
+ { 171, 0x18402ec4, 0x184c03d6, 0x18179855, 0x18155307 },
+ { 173, 0x18402ec4, 0x184c03d6, 0x18179855, 0x1815530f },
+
+ /* 802.11 Japan */
+ { 184, 0x15002ccc, 0x1500491e, 0x1509be55, 0x150c0a0b },
+ { 188, 0x15002ccc, 0x15004922, 0x1509be55, 0x150c0a13 },
+ { 192, 0x15002ccc, 0x15004926, 0x1509be55, 0x150c0a1b },
+ { 196, 0x15002ccc, 0x1500492a, 0x1509be55, 0x150c0a23 },
+ { 208, 0x15002ccc, 0x1500493a, 0x1509be55, 0x150c0a13 },
+ { 212, 0x15002ccc, 0x1500493e, 0x1509be55, 0x150c0a1b },
+ { 216, 0x15002ccc, 0x15004982, 0x1509be55, 0x150c0a23 },
+};
+
+/*
+ * RF value list for rt3070
+ * Supports: 2.4 GHz
+ */
+static const struct rf_channel rf_vals_3070[] = {
+ {1, 241, 2, 2 },
+ {2, 241, 2, 7 },
+ {3, 242, 2, 2 },
+ {4, 242, 2, 7 },
+ {5, 243, 2, 2 },
+ {6, 243, 2, 7 },
+ {7, 244, 2, 2 },
+ {8, 244, 2, 7 },
+ {9, 245, 2, 2 },
+ {10, 245, 2, 7 },
+ {11, 246, 2, 2 },
+ {12, 246, 2, 7 },
+ {13, 247, 2, 2 },
+ {14, 248, 2, 4 },
+};
+
+static int rt2800usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+{
+ struct hw_mode_spec *spec = &rt2x00dev->spec;
+ struct channel_info *info;
+ char *tx_power1;
+ char *tx_power2;
+ unsigned int i;
+ u16 eeprom;
+
+ /*
+ * Initialize all hw fields.
+ */
+ rt2x00dev->hw->flags =
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK;
+ rt2x00dev->hw->extra_tx_headroom = TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
+
+ SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
+ SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
+ rt2x00_eeprom_addr(rt2x00dev,
+ EEPROM_MAC_ADDR_0));
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+
+ /*
+ * Initialize HT information.
+ */
+ spec->ht.ht_supported = true;
+ spec->ht.cap =
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+ IEEE80211_HT_CAP_GRN_FLD |
+ IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_SGI_40 |
+ IEEE80211_HT_CAP_TX_STBC |
+ IEEE80211_HT_CAP_RX_STBC |
+ IEEE80211_HT_CAP_PSMP_SUPPORT;
+ spec->ht.ampdu_factor = 3;
+ spec->ht.ampdu_density = 4;
+ spec->ht.mcs.tx_params =
+ IEEE80211_HT_MCS_TX_DEFINED |
+ IEEE80211_HT_MCS_TX_RX_DIFF |
+ ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
+ IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
+
+ switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
+ case 3:
+ spec->ht.mcs.rx_mask[2] = 0xff;
+ case 2:
+ spec->ht.mcs.rx_mask[1] = 0xff;
+ case 1:
+ spec->ht.mcs.rx_mask[0] = 0xff;
+ spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */
+ break;
+ }
+
+ /*
+ * Initialize hw_mode information.
+ */
+ spec->supported_bands = SUPPORT_BAND_2GHZ;
+ spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
+
+ if (rt2x00_rf(&rt2x00dev->chip, RF2820) ||
+ rt2x00_rf(&rt2x00dev->chip, RF2720)) {
+ spec->num_channels = 14;
+ spec->channels = rf_vals;
+ } else if (rt2x00_rf(&rt2x00dev->chip, RF2850) ||
+ rt2x00_rf(&rt2x00dev->chip, RF2750)) {
+ spec->supported_bands |= SUPPORT_BAND_5GHZ;
+ spec->num_channels = ARRAY_SIZE(rf_vals);
+ spec->channels = rf_vals;
+ } else if (rt2x00_rf(&rt2x00dev->chip, RF3020) ||
+ rt2x00_rf(&rt2x00dev->chip, RF2020)) {
+ spec->num_channels = ARRAY_SIZE(rf_vals_3070);
+ spec->channels = rf_vals_3070;
+ }
+
+ /*
+ * Create channel information array
+ */
+ info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ spec->channels_info = info;
+
+ tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
+ tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
+
+ for (i = 0; i < 14; i++) {
+ info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]);
+ info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]);
+ }
+
+ if (spec->num_channels > 14) {
+ tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1);
+ tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
+
+ for (i = 14; i < spec->num_channels; i++) {
+ info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]);
+ info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]);
+ }
+ }
+
+ return 0;
+}
+
+static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
+{
+ int retval;
+
+ /*
+ * Allocate eeprom data.
+ */
+ retval = rt2800usb_validate_eeprom(rt2x00dev);
+ if (retval)
+ return retval;
+
+ retval = rt2800usb_init_eeprom(rt2x00dev);
+ if (retval)
+ return retval;
+
+ /*
+ * Initialize hw specifications.
+ */
+ retval = rt2800usb_probe_hw_mode(rt2x00dev);
+ if (retval)
+ return retval;
+
+ /*
+ * This device requires firmware.
+ */
+ __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
+ if (!modparam_nohwcrypt)
+ __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
+
+ /*
+ * Set the rssi offset.
+ */
+ rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
+
+ return 0;
+}
+
+/*
+ * IEEE80211 stack callback functions.
+ */
+static void rt2800usb_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx,
+ u32 *iv32, u16 *iv16)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct mac_iveiv_entry iveiv_entry;
+ u32 offset;
+
+ offset = MAC_IVEIV_ENTRY(hw_key_idx);
+ rt2x00usb_register_multiread(rt2x00dev, offset,
+ &iveiv_entry, sizeof(iveiv_entry));
+
+ memcpy(&iveiv_entry.iv[0], iv16, sizeof(iv16));
+ memcpy(&iveiv_entry.iv[4], iv32, sizeof(iv32));
+}
+
+static int rt2800usb_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ u32 reg;
+ bool enabled = (value < IEEE80211_MAX_RTS_THRESHOLD);
+
+ rt2x00usb_register_read(rt2x00dev, TX_RTS_CFG, &reg);
+ rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES, value);
+ rt2x00usb_register_write(rt2x00dev, TX_RTS_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, CCK_PROT_CFG_RTS_TH_EN, enabled);
+ rt2x00usb_register_write(rt2x00dev, CCK_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_RTS_TH_EN, enabled);
+ rt2x00usb_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_RTS_TH_EN, enabled);
+ rt2x00usb_register_write(rt2x00dev, MM20_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_RTS_TH_EN, enabled);
+ rt2x00usb_register_write(rt2x00dev, MM40_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_RTS_TH_EN, enabled);
+ rt2x00usb_register_write(rt2x00dev, GF20_PROT_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_RTS_TH_EN, enabled);
+ rt2x00usb_register_write(rt2x00dev, GF40_PROT_CFG, reg);
+
+ return 0;
+}
+
+static int rt2800usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
+ const struct ieee80211_tx_queue_params *params)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct data_queue *queue;
+ struct rt2x00_field32 field;
+ int retval;
+ u32 reg;
+ u32 offset;
+
+ /*
+ * First pass the configuration through rt2x00lib, that will
+ * update the queue settings and validate the input. After that
+ * we are free to update the registers based on the value
+ * in the queue parameter.
+ */
+ retval = rt2x00mac_conf_tx(hw, queue_idx, params);
+ if (retval)
+ return retval;
+
+ /*
+ * We only need to perform additional register initialization
+ * for WMM queues/
+ */
+ if (queue_idx >= 4)
+ return 0;
+
+ queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
+
+ /* Update WMM TXOP register */
+ offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2)));
+ field.bit_offset = (queue_idx & 1) * 16;
+ field.bit_mask = 0xffff << field.bit_offset;
+
+ rt2x00usb_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, field, queue->txop);
+ rt2x00usb_register_write(rt2x00dev, offset, reg);
+
+ /* Update WMM registers */
+ field.bit_offset = queue_idx * 4;
+ field.bit_mask = 0xf << field.bit_offset;
+
+ rt2x00usb_register_read(rt2x00dev, WMM_AIFSN_CFG, &reg);
+ rt2x00_set_field32(&reg, field, queue->aifs);
+ rt2x00usb_register_write(rt2x00dev, WMM_AIFSN_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, WMM_CWMIN_CFG, &reg);
+ rt2x00_set_field32(&reg, field, queue->cw_min);
+ rt2x00usb_register_write(rt2x00dev, WMM_CWMIN_CFG, reg);
+
+ rt2x00usb_register_read(rt2x00dev, WMM_CWMAX_CFG, &reg);
+ rt2x00_set_field32(&reg, field, queue->cw_max);
+ rt2x00usb_register_write(rt2x00dev, WMM_CWMAX_CFG, reg);
+
+ /* Update EDCA registers */
+ offset = EDCA_AC0_CFG + (sizeof(u32) * queue_idx);
+
+ rt2x00usb_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, EDCA_AC0_CFG_TX_OP, queue->txop);
+ rt2x00_set_field32(&reg, EDCA_AC0_CFG_AIFSN, queue->aifs);
+ rt2x00_set_field32(&reg, EDCA_AC0_CFG_CWMIN, queue->cw_min);
+ rt2x00_set_field32(&reg, EDCA_AC0_CFG_CWMAX, queue->cw_max);
+ rt2x00usb_register_write(rt2x00dev, offset, reg);
+
+ return 0;
+}
+
+static u64 rt2800usb_get_tsf(struct ieee80211_hw *hw)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ u64 tsf;
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, TSF_TIMER_DW1, &reg);
+ tsf = (u64) rt2x00_get_field32(reg, TSF_TIMER_DW1_HIGH_WORD) << 32;
+ rt2x00usb_register_read(rt2x00dev, TSF_TIMER_DW0, &reg);
+ tsf |= rt2x00_get_field32(reg, TSF_TIMER_DW0_LOW_WORD);
+
+ return tsf;
+}
+
+static const struct ieee80211_ops rt2800usb_mac80211_ops = {
+ .tx = rt2x00mac_tx,
+ .start = rt2x00mac_start,
+ .stop = rt2x00mac_stop,
+ .add_interface = rt2x00mac_add_interface,
+ .remove_interface = rt2x00mac_remove_interface,
+ .config = rt2x00mac_config,
+ .configure_filter = rt2x00mac_configure_filter,
+ .set_key = rt2x00mac_set_key,
+ .get_stats = rt2x00mac_get_stats,
+ .get_tkip_seq = rt2800usb_get_tkip_seq,
+ .set_rts_threshold = rt2800usb_set_rts_threshold,
+ .bss_info_changed = rt2x00mac_bss_info_changed,
+ .conf_tx = rt2800usb_conf_tx,
+ .get_tx_stats = rt2x00mac_get_tx_stats,
+ .get_tsf = rt2800usb_get_tsf,
+};
+
+static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
+ .probe_hw = rt2800usb_probe_hw,
+ .get_firmware_name = rt2800usb_get_firmware_name,
+ .check_firmware = rt2800usb_check_firmware,
+ .load_firmware = rt2800usb_load_firmware,
+ .initialize = rt2x00usb_initialize,
+ .uninitialize = rt2x00usb_uninitialize,
+ .clear_entry = rt2x00usb_clear_entry,
+ .set_device_state = rt2800usb_set_device_state,
+ .rfkill_poll = rt2800usb_rfkill_poll,
+ .link_stats = rt2800usb_link_stats,
+ .reset_tuner = rt2800usb_reset_tuner,
+ .link_tuner = rt2800usb_link_tuner,
+ .write_tx_desc = rt2800usb_write_tx_desc,
+ .write_tx_data = rt2x00usb_write_tx_data,
+ .write_beacon = rt2800usb_write_beacon,
+ .get_tx_data_len = rt2800usb_get_tx_data_len,
+ .kick_tx_queue = rt2800usb_kick_tx_queue,
+ .kill_tx_queue = rt2x00usb_kill_tx_queue,
+ .fill_rxdone = rt2800usb_fill_rxdone,
+ .config_shared_key = rt2800usb_config_shared_key,
+ .config_pairwise_key = rt2800usb_config_pairwise_key,
+ .config_filter = rt2800usb_config_filter,
+ .config_intf = rt2800usb_config_intf,
+ .config_erp = rt2800usb_config_erp,
+ .config_ant = rt2800usb_config_ant,
+ .config = rt2800usb_config,
+};
+
+static const struct data_queue_desc rt2800usb_queue_rx = {
+ .entry_num = RX_ENTRIES,
+ .data_size = AGGREGATION_SIZE,
+ .desc_size = RXD_DESC_SIZE + RXWI_DESC_SIZE,
+ .priv_size = sizeof(struct queue_entry_priv_usb),
+};
+
+static const struct data_queue_desc rt2800usb_queue_tx = {
+ .entry_num = TX_ENTRIES,
+ .data_size = AGGREGATION_SIZE,
+ .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
+ .priv_size = sizeof(struct queue_entry_priv_usb),
+};
+
+static const struct data_queue_desc rt2800usb_queue_bcn = {
+ .entry_num = 8 * BEACON_ENTRIES,
+ .data_size = MGMT_FRAME_SIZE,
+ .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
+ .priv_size = sizeof(struct queue_entry_priv_usb),
+};
+
+static const struct rt2x00_ops rt2800usb_ops = {
+ .name = KBUILD_MODNAME,
+ .max_sta_intf = 1,
+ .max_ap_intf = 8,
+ .eeprom_size = EEPROM_SIZE,
+ .rf_size = RF_SIZE,
+ .tx_queues = NUM_TX_QUEUES,
+ .rx = &rt2800usb_queue_rx,
+ .tx = &rt2800usb_queue_tx,
+ .bcn = &rt2800usb_queue_bcn,
+ .lib = &rt2800usb_rt2x00_ops,
+ .hw = &rt2800usb_mac80211_ops,
+#ifdef CONFIG_RT2X00_LIB_DEBUGFS
+ .debugfs = &rt2800usb_rt2x00debug,
+#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+};
+
+/*
+ * rt2800usb module information.
+ */
+static struct usb_device_id rt2800usb_device_table[] = {
+ /* Abocom */
+ { USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* AirTies */
+ { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Amigo */
+ { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Amit */
+ { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* ASUS */
+ { USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* AzureWave */
+ { USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Belkin */
+ { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x050d, 0x815c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Buffalo */
+ { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0411, 0x012e), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Conceptronic */
+ { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Corega */
+ { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x18c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* D-Link */
+ { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Edimax */
+ { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Encore */
+ { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* EnGenius */
+ { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Gemtek */
+ { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Gigabyte */
+ { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1044, 0x800c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Hawking */
+ { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* I-O DATA */
+ { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* LevelOne */
+ { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Linksys */
+ { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Logitec */
+ { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Motorola */
+ { USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Ovislink */
+ { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Pegatron */
+ { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Philips */
+ { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Planex */
+ { USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Qcom */
+ { USB_DEVICE(0x18e8, 0x6259), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Quanta */
+ { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Ralink */
+ { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Samsung */
+ { USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Siemens */
+ { USB_DEVICE(0x129b, 0x1828), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Sitecom */
+ { USB_DEVICE(0x0df6, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x002b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* SMC */
+ { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Sparklan */
+ { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Sweex */
+ { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* U-Media*/
+ { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* ZCOM */
+ { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Zinwell */
+ { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Zyxel */
+ { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { 0, }
+};
+
+MODULE_AUTHOR(DRV_PROJECT);
+MODULE_VERSION(DRV_VERSION);
+MODULE_DESCRIPTION("Ralink RT2800 USB Wireless LAN driver.");
+MODULE_SUPPORTED_DEVICE("Ralink RT2870 USB chipset based cards");
+MODULE_DEVICE_TABLE(usb, rt2800usb_device_table);
+MODULE_FIRMWARE(FIRMWARE_RT2870);
+MODULE_LICENSE("GPL");
+
+static struct usb_driver rt2800usb_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = rt2800usb_device_table,
+ .probe = rt2x00usb_probe,
+ .disconnect = rt2x00usb_disconnect,
+ .suspend = rt2x00usb_suspend,
+ .resume = rt2x00usb_resume,
+};
+
+static int __init rt2800usb_init(void)
+{
+ return usb_register(&rt2800usb_driver);
+}
+
+static void __exit rt2800usb_exit(void)
+{
+ usb_deregister(&rt2800usb_driver);
+}
+
+module_init(rt2800usb_init);
+module_exit(rt2800usb_exit);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
new file mode 100644
index 00000000000..61a8be61d3f
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -0,0 +1,1945 @@
+/*
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+ <http://rt2x00.serialmonkey.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ Module: rt2800usb
+ Abstract: Data structures and registers for the rt2800usb module.
+ Supported chipsets: RT2800U.
+ */
+
+#ifndef RT2800USB_H
+#define RT2800USB_H
+
+/*
+ * RF chip defines.
+ *
+ * RF2820 2.4G 2T3R
+ * RF2850 2.4G/5G 2T3R
+ * RF2720 2.4G 1T2R
+ * RF2750 2.4G/5G 1T2R
+ * RF3020 2.4G 1T1R
+ * RF2020 2.4G B/G
+ */
+#define RF2820 0x0001
+#define RF2850 0x0002
+#define RF2720 0x0003
+#define RF2750 0x0004
+#define RF3020 0x0005
+#define RF2020 0x0006
+
+/*
+ * RT2870 version
+ */
+#define RT2860C_VERSION 0x28600100
+#define RT2860D_VERSION 0x28600101
+#define RT2880E_VERSION 0x28720200
+#define RT2883_VERSION 0x28830300
+#define RT3070_VERSION 0x30700200
+
+/*
+ * Signal information.
+ * Defaul offset is required for RSSI <-> dBm conversion.
+ */
+#define DEFAULT_RSSI_OFFSET 120 /* FIXME */
+
+/*
+ * Register layout information.
+ */
+#define CSR_REG_BASE 0x1000
+#define CSR_REG_SIZE 0x0800
+#define EEPROM_BASE 0x0000
+#define EEPROM_SIZE 0x0110
+#define BBP_BASE 0x0000
+#define BBP_SIZE 0x0080
+#define RF_BASE 0x0004
+#define RF_SIZE 0x0010
+
+/*
+ * Number of TX queues.
+ */
+#define NUM_TX_QUEUES 4
+
+/*
+ * USB registers.
+ */
+
+/*
+ * HOST-MCU shared memory
+ */
+#define HOST_CMD_CSR 0x0404
+#define HOST_CMD_CSR_HOST_COMMAND FIELD32(0x000000ff)
+
+/*
+ * INT_SOURCE_CSR: Interrupt source register.
+ * Write one to clear corresponding bit.
+ * TX_FIFO_STATUS: FIFO Statistics is full, sw should read 0x171c
+ */
+#define INT_SOURCE_CSR 0x0200
+#define INT_SOURCE_CSR_RXDELAYINT FIELD32(0x00000001)
+#define INT_SOURCE_CSR_TXDELAYINT FIELD32(0x00000002)
+#define INT_SOURCE_CSR_RX_DONE FIELD32(0x00000004)
+#define INT_SOURCE_CSR_AC0_DMA_DONE FIELD32(0x00000008)
+#define INT_SOURCE_CSR_AC1_DMA_DONE FIELD32(0x00000010)
+#define INT_SOURCE_CSR_AC2_DMA_DONE FIELD32(0x00000020)
+#define INT_SOURCE_CSR_AC3_DMA_DONE FIELD32(0x00000040)
+#define INT_SOURCE_CSR_HCCA_DMA_DONE FIELD32(0x00000080)
+#define INT_SOURCE_CSR_MGMT_DMA_DONE FIELD32(0x00000100)
+#define INT_SOURCE_CSR_MCU_COMMAND FIELD32(0x00000200)
+#define INT_SOURCE_CSR_RXTX_COHERENT FIELD32(0x00000400)
+#define INT_SOURCE_CSR_TBTT FIELD32(0x00000800)
+#define INT_SOURCE_CSR_PRE_TBTT FIELD32(0x00001000)
+#define INT_SOURCE_CSR_TX_FIFO_STATUS FIELD32(0x00002000)
+#define INT_SOURCE_CSR_AUTO_WAKEUP FIELD32(0x00004000)
+#define INT_SOURCE_CSR_GPTIMER FIELD32(0x00008000)
+#define INT_SOURCE_CSR_RX_COHERENT FIELD32(0x00010000)
+#define INT_SOURCE_CSR_TX_COHERENT FIELD32(0x00020000)
+
+/*
+ * INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF.
+ */
+#define INT_MASK_CSR 0x0204
+#define INT_MASK_CSR_RXDELAYINT FIELD32(0x00000001)
+#define INT_MASK_CSR_TXDELAYINT FIELD32(0x00000002)
+#define INT_MASK_CSR_RX_DONE FIELD32(0x00000004)
+#define INT_MASK_CSR_AC0_DMA_DONE FIELD32(0x00000008)
+#define INT_MASK_CSR_AC1_DMA_DONE FIELD32(0x00000010)
+#define INT_MASK_CSR_AC2_DMA_DONE FIELD32(0x00000020)
+#define INT_MASK_CSR_AC3_DMA_DONE FIELD32(0x00000040)
+#define INT_MASK_CSR_HCCA_DMA_DONE FIELD32(0x00000080)
+#define INT_MASK_CSR_MGMT_DMA_DONE FIELD32(0x00000100)
+#define INT_MASK_CSR_MCU_COMMAND FIELD32(0x00000200)
+#define INT_MASK_CSR_RXTX_COHERENT FIELD32(0x00000400)
+#define INT_MASK_CSR_TBTT FIELD32(0x00000800)
+#define INT_MASK_CSR_PRE_TBTT FIELD32(0x00001000)
+#define INT_MASK_CSR_TX_FIFO_STATUS FIELD32(0x00002000)
+#define INT_MASK_CSR_AUTO_WAKEUP FIELD32(0x00004000)
+#define INT_MASK_CSR_GPTIMER FIELD32(0x00008000)
+#define INT_MASK_CSR_RX_COHERENT FIELD32(0x00010000)
+#define INT_MASK_CSR_TX_COHERENT FIELD32(0x00020000)
+
+/*
+ * WPDMA_GLO_CFG
+ */
+#define WPDMA_GLO_CFG 0x0208
+#define WPDMA_GLO_CFG_ENABLE_TX_DMA FIELD32(0x00000001)
+#define WPDMA_GLO_CFG_TX_DMA_BUSY FIELD32(0x00000002)
+#define WPDMA_GLO_CFG_ENABLE_RX_DMA FIELD32(0x00000004)
+#define WPDMA_GLO_CFG_RX_DMA_BUSY FIELD32(0x00000008)
+#define WPDMA_GLO_CFG_WP_DMA_BURST_SIZE FIELD32(0x00000030)
+#define WPDMA_GLO_CFG_TX_WRITEBACK_DONE FIELD32(0x00000040)
+#define WPDMA_GLO_CFG_BIG_ENDIAN FIELD32(0x00000080)
+#define WPDMA_GLO_CFG_RX_HDR_SCATTER FIELD32(0x0000ff00)
+#define WPDMA_GLO_CFG_HDR_SEG_LEN FIELD32(0xffff0000)
+
+/*
+ * WPDMA_RST_IDX
+ */
+#define WPDMA_RST_IDX 0x020c
+#define WPDMA_RST_IDX_DTX_IDX0 FIELD32(0x00000001)
+#define WPDMA_RST_IDX_DTX_IDX1 FIELD32(0x00000002)
+#define WPDMA_RST_IDX_DTX_IDX2 FIELD32(0x00000004)
+#define WPDMA_RST_IDX_DTX_IDX3 FIELD32(0x00000008)
+#define WPDMA_RST_IDX_DTX_IDX4 FIELD32(0x00000010)
+#define WPDMA_RST_IDX_DTX_IDX5 FIELD32(0x00000020)
+#define WPDMA_RST_IDX_DRX_IDX0 FIELD32(0x00010000)
+
+/*
+ * DELAY_INT_CFG
+ */
+#define DELAY_INT_CFG 0x0210
+#define DELAY_INT_CFG_RXMAX_PTIME FIELD32(0x000000ff)
+#define DELAY_INT_CFG_RXMAX_PINT FIELD32(0x00007f00)
+#define DELAY_INT_CFG_RXDLY_INT_EN FIELD32(0x00008000)
+#define DELAY_INT_CFG_TXMAX_PTIME FIELD32(0x00ff0000)
+#define DELAY_INT_CFG_TXMAX_PINT FIELD32(0x7f000000)
+#define DELAY_INT_CFG_TXDLY_INT_EN FIELD32(0x80000000)
+
+/*
+ * WMM_AIFSN_CFG: Aifsn for each EDCA AC
+ * AIFSN0: AC_BE
+ * AIFSN1: AC_BK
+ * AIFSN1: AC_VI
+ * AIFSN1: AC_VO
+ */
+#define WMM_AIFSN_CFG 0x0214
+#define WMM_AIFSN_CFG_AIFSN0 FIELD32(0x0000000f)
+#define WMM_AIFSN_CFG_AIFSN1 FIELD32(0x000000f0)
+#define WMM_AIFSN_CFG_AIFSN2 FIELD32(0x00000f00)
+#define WMM_AIFSN_CFG_AIFSN3 FIELD32(0x0000f000)
+
+/*
+ * WMM_CWMIN_CSR: CWmin for each EDCA AC
+ * CWMIN0: AC_BE
+ * CWMIN1: AC_BK
+ * CWMIN1: AC_VI
+ * CWMIN1: AC_VO
+ */
+#define WMM_CWMIN_CFG 0x0218
+#define WMM_CWMIN_CFG_CWMIN0 FIELD32(0x0000000f)
+#define WMM_CWMIN_CFG_CWMIN1 FIELD32(0x000000f0)
+#define WMM_CWMIN_CFG_CWMIN2 FIELD32(0x00000f00)
+#define WMM_CWMIN_CFG_CWMIN3 FIELD32(0x0000f000)
+
+/*
+ * WMM_CWMAX_CSR: CWmax for each EDCA AC
+ * CWMAX0: AC_BE
+ * CWMAX1: AC_BK
+ * CWMAX1: AC_VI
+ * CWMAX1: AC_VO
+ */
+#define WMM_CWMAX_CFG 0x021c
+#define WMM_CWMAX_CFG_CWMAX0 FIELD32(0x0000000f)
+#define WMM_CWMAX_CFG_CWMAX1 FIELD32(0x000000f0)
+#define WMM_CWMAX_CFG_CWMAX2 FIELD32(0x00000f00)
+#define WMM_CWMAX_CFG_CWMAX3 FIELD32(0x0000f000)
+
+/*
+ * AC_TXOP0: AC_BK/AC_BE TXOP register
+ * AC0TXOP: AC_BK in unit of 32us
+ * AC1TXOP: AC_BE in unit of 32us
+ */
+#define WMM_TXOP0_CFG 0x0220
+#define WMM_TXOP0_CFG_AC0TXOP FIELD32(0x0000ffff)
+#define WMM_TXOP0_CFG_AC1TXOP FIELD32(0xffff0000)
+
+/*
+ * AC_TXOP1: AC_VO/AC_VI TXOP register
+ * AC2TXOP: AC_VI in unit of 32us
+ * AC3TXOP: AC_VO in unit of 32us
+ */
+#define WMM_TXOP1_CFG 0x0224
+#define WMM_TXOP1_CFG_AC2TXOP FIELD32(0x0000ffff)
+#define WMM_TXOP1_CFG_AC3TXOP FIELD32(0xffff0000)
+
+/*
+ * GPIO_CTRL_CFG:
+ */
+#define GPIO_CTRL_CFG 0x0228
+#define GPIO_CTRL_CFG_BIT0 FIELD32(0x00000001)
+#define GPIO_CTRL_CFG_BIT1 FIELD32(0x00000002)
+#define GPIO_CTRL_CFG_BIT2 FIELD32(0x00000004)
+#define GPIO_CTRL_CFG_BIT3 FIELD32(0x00000008)
+#define GPIO_CTRL_CFG_BIT4 FIELD32(0x00000010)
+#define GPIO_CTRL_CFG_BIT5 FIELD32(0x00000020)
+#define GPIO_CTRL_CFG_BIT6 FIELD32(0x00000040)
+#define GPIO_CTRL_CFG_BIT7 FIELD32(0x00000080)
+#define GPIO_CTRL_CFG_BIT8 FIELD32(0x00000100)
+
+/*
+ * MCU_CMD_CFG
+ */
+#define MCU_CMD_CFG 0x022c
+
+/*
+ * AC_BK register offsets
+ */
+#define TX_BASE_PTR0 0x0230
+#define TX_MAX_CNT0 0x0234
+#define TX_CTX_IDX0 0x0238
+#define TX_DTX_IDX0 0x023c
+
+/*
+ * AC_BE register offsets
+ */
+#define TX_BASE_PTR1 0x0240
+#define TX_MAX_CNT1 0x0244
+#define TX_CTX_IDX1 0x0248
+#define TX_DTX_IDX1 0x024c
+
+/*
+ * AC_VI register offsets
+ */
+#define TX_BASE_PTR2 0x0250
+#define TX_MAX_CNT2 0x0254
+#define TX_CTX_IDX2 0x0258
+#define TX_DTX_IDX2 0x025c
+
+/*
+ * AC_VO register offsets
+ */
+#define TX_BASE_PTR3 0x0260
+#define TX_MAX_CNT3 0x0264
+#define TX_CTX_IDX3 0x0268
+#define TX_DTX_IDX3 0x026c
+
+/*
+ * HCCA register offsets
+ */
+#define TX_BASE_PTR4 0x0270
+#define TX_MAX_CNT4 0x0274
+#define TX_CTX_IDX4 0x0278
+#define TX_DTX_IDX4 0x027c
+
+/*
+ * MGMT register offsets
+ */
+#define TX_BASE_PTR5 0x0280
+#define TX_MAX_CNT5 0x0284
+#define TX_CTX_IDX5 0x0288
+#define TX_DTX_IDX5 0x028c
+
+/*
+ * RX register offsets
+ */
+#define RX_BASE_PTR 0x0290
+#define RX_MAX_CNT 0x0294
+#define RX_CRX_IDX 0x0298
+#define RX_DRX_IDX 0x029c
+
+/*
+ * USB_DMA_CFG
+ * RX_BULK_AGG_TIMEOUT: Rx Bulk Aggregation TimeOut in unit of 33ns.
+ * RX_BULK_AGG_LIMIT: Rx Bulk Aggregation Limit in unit of 256 bytes.
+ * PHY_CLEAR: phy watch dog enable.
+ * TX_CLEAR: Clear USB DMA TX path.
+ * TXOP_HALT: Halt TXOP count down when TX buffer is full.
+ * RX_BULK_AGG_EN: Enable Rx Bulk Aggregation.
+ * RX_BULK_EN: Enable USB DMA Rx.
+ * TX_BULK_EN: Enable USB DMA Tx.
+ * EP_OUT_VALID: OUT endpoint data valid.
+ * RX_BUSY: USB DMA RX FSM busy.
+ * TX_BUSY: USB DMA TX FSM busy.
+ */
+#define USB_DMA_CFG 0x02a0
+#define USB_DMA_CFG_RX_BULK_AGG_TIMEOUT FIELD32(0x000000ff)
+#define USB_DMA_CFG_RX_BULK_AGG_LIMIT FIELD32(0x0000ff00)
+#define USB_DMA_CFG_PHY_CLEAR FIELD32(0x00010000)
+#define USB_DMA_CFG_TX_CLEAR FIELD32(0x00080000)
+#define USB_DMA_CFG_TXOP_HALT FIELD32(0x00100000)
+#define USB_DMA_CFG_RX_BULK_AGG_EN FIELD32(0x00200000)
+#define USB_DMA_CFG_RX_BULK_EN FIELD32(0x00400000)
+#define USB_DMA_CFG_TX_BULK_EN FIELD32(0x00800000)
+#define USB_DMA_CFG_EP_OUT_VALID FIELD32(0x3f000000)
+#define USB_DMA_CFG_RX_BUSY FIELD32(0x40000000)
+#define USB_DMA_CFG_TX_BUSY FIELD32(0x80000000)
+
+/*
+ * USB_CYC_CFG
+ */
+#define USB_CYC_CFG 0x02a4
+#define USB_CYC_CFG_CLOCK_CYCLE FIELD32(0x000000ff)
+
+/*
+ * PBF_SYS_CTRL
+ * HOST_RAM_WRITE: enable Host program ram write selection
+ */
+#define PBF_SYS_CTRL 0x0400
+#define PBF_SYS_CTRL_READY FIELD32(0x00000080)
+#define PBF_SYS_CTRL_HOST_RAM_WRITE FIELD32(0x00010000)
+
+/*
+ * PBF registers
+ * Most are for debug. Driver doesn't touch PBF register.
+ */
+#define PBF_CFG 0x0408
+#define PBF_MAX_PCNT 0x040c
+#define PBF_CTRL 0x0410
+#define PBF_INT_STA 0x0414
+#define PBF_INT_ENA 0x0418
+
+/*
+ * BCN_OFFSET0:
+ */
+#define BCN_OFFSET0 0x042c
+#define BCN_OFFSET0_BCN0 FIELD32(0x000000ff)
+#define BCN_OFFSET0_BCN1 FIELD32(0x0000ff00)
+#define BCN_OFFSET0_BCN2 FIELD32(0x00ff0000)
+#define BCN_OFFSET0_BCN3 FIELD32(0xff000000)
+
+/*
+ * BCN_OFFSET1:
+ */
+#define BCN_OFFSET1 0x0430
+#define BCN_OFFSET1_BCN4 FIELD32(0x000000ff)
+#define BCN_OFFSET1_BCN5 FIELD32(0x0000ff00)
+#define BCN_OFFSET1_BCN6 FIELD32(0x00ff0000)
+#define BCN_OFFSET1_BCN7 FIELD32(0xff000000)
+
+/*
+ * PBF registers
+ * Most are for debug. Driver doesn't touch PBF register.
+ */
+#define TXRXQ_PCNT 0x0438
+#define PBF_DBG 0x043c
+
+/*
+ * RF registers
+ */
+#define RF_CSR_CFG 0x0500
+#define RF_CSR_CFG_DATA FIELD32(0x000000ff)
+#define RF_CSR_CFG_REGNUM FIELD32(0x00001f00)
+#define RF_CSR_CFG_WRITE FIELD32(0x00010000)
+#define RF_CSR_CFG_BUSY FIELD32(0x00020000)
+
+/*
+ * MAC Control/Status Registers(CSR).
+ * Some values are set in TU, whereas 1 TU == 1024 us.
+ */
+
+/*
+ * MAC_CSR0: ASIC revision number.
+ * ASIC_REV: 0
+ * ASIC_VER: 2870
+ */
+#define MAC_CSR0 0x1000
+#define MAC_CSR0_ASIC_REV FIELD32(0x0000ffff)
+#define MAC_CSR0_ASIC_VER FIELD32(0xffff0000)
+
+/*
+ * MAC_SYS_CTRL:
+ */
+#define MAC_SYS_CTRL 0x1004
+#define MAC_SYS_CTRL_RESET_CSR FIELD32(0x00000001)
+#define MAC_SYS_CTRL_RESET_BBP FIELD32(0x00000002)
+#define MAC_SYS_CTRL_ENABLE_TX FIELD32(0x00000004)
+#define MAC_SYS_CTRL_ENABLE_RX FIELD32(0x00000008)
+#define MAC_SYS_CTRL_CONTINUOUS_TX FIELD32(0x00000010)
+#define MAC_SYS_CTRL_LOOPBACK FIELD32(0x00000020)
+#define MAC_SYS_CTRL_WLAN_HALT FIELD32(0x00000040)
+#define MAC_SYS_CTRL_RX_TIMESTAMP FIELD32(0x00000080)
+
+/*
+ * MAC_ADDR_DW0: STA MAC register 0
+ */
+#define MAC_ADDR_DW0 0x1008
+#define MAC_ADDR_DW0_BYTE0 FIELD32(0x000000ff)
+#define MAC_ADDR_DW0_BYTE1 FIELD32(0x0000ff00)
+#define MAC_ADDR_DW0_BYTE2 FIELD32(0x00ff0000)
+#define MAC_ADDR_DW0_BYTE3 FIELD32(0xff000000)
+
+/*
+ * MAC_ADDR_DW1: STA MAC register 1
+ * UNICAST_TO_ME_MASK:
+ * Used to mask off bits from byte 5 of the MAC address
+ * to determine the UNICAST_TO_ME bit for RX frames.
+ * The full mask is complemented by BSS_ID_MASK:
+ * MASK = BSS_ID_MASK & UNICAST_TO_ME_MASK
+ */
+#define MAC_ADDR_DW1 0x100c
+#define MAC_ADDR_DW1_BYTE4 FIELD32(0x000000ff)
+#define MAC_ADDR_DW1_BYTE5 FIELD32(0x0000ff00)
+#define MAC_ADDR_DW1_UNICAST_TO_ME_MASK FIELD32(0x00ff0000)
+
+/*
+ * MAC_BSSID_DW0: BSSID register 0
+ */
+#define MAC_BSSID_DW0 0x1010
+#define MAC_BSSID_DW0_BYTE0 FIELD32(0x000000ff)
+#define MAC_BSSID_DW0_BYTE1 FIELD32(0x0000ff00)
+#define MAC_BSSID_DW0_BYTE2 FIELD32(0x00ff0000)
+#define MAC_BSSID_DW0_BYTE3 FIELD32(0xff000000)
+
+/*
+ * MAC_BSSID_DW1: BSSID register 1
+ * BSS_ID_MASK:
+ * 0: 1-BSSID mode (BSS index = 0)
+ * 1: 2-BSSID mode (BSS index: Byte5, bit 0)
+ * 2: 4-BSSID mode (BSS index: byte5, bit 0 - 1)
+ * 3: 8-BSSID mode (BSS index: byte5, bit 0 - 2)
+ * This mask is used to mask off bits 0, 1 and 2 of byte 5 of the
+ * BSSID. This will make sure that those bits will be ignored
+ * when determining the MY_BSS of RX frames.
+ */
+#define MAC_BSSID_DW1 0x1014
+#define MAC_BSSID_DW1_BYTE4 FIELD32(0x000000ff)
+#define MAC_BSSID_DW1_BYTE5 FIELD32(0x0000ff00)
+#define MAC_BSSID_DW1_BSS_ID_MASK FIELD32(0x00030000)
+#define MAC_BSSID_DW1_BSS_BCN_NUM FIELD32(0x001c0000)
+
+/*
+ * MAX_LEN_CFG: Maximum frame length register.
+ * MAX_MPDU: rt2860b max 16k bytes
+ * MAX_PSDU: Maximum PSDU length
+ * (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16
+ */
+#define MAX_LEN_CFG 0x1018
+#define MAX_LEN_CFG_MAX_MPDU FIELD32(0x00000fff)
+#define MAX_LEN_CFG_MAX_PSDU FIELD32(0x00003000)
+#define MAX_LEN_CFG_MIN_PSDU FIELD32(0x0000c000)
+#define MAX_LEN_CFG_MIN_MPDU FIELD32(0x000f0000)
+
+/*
+ * BBP_CSR_CFG: BBP serial control register
+ * VALUE: Register value to program into BBP
+ * REG_NUM: Selected BBP register
+ * READ_CONTROL: 0 write BBP, 1 read BBP
+ * BUSY: ASIC is busy executing BBP commands
+ * BBP_PAR_DUR: 0 4 MAC clocks, 1 8 MAC clocks
+ * BBP_RW_MODE: 0 serial, 1 paralell
+ */
+#define BBP_CSR_CFG 0x101c
+#define BBP_CSR_CFG_VALUE FIELD32(0x000000ff)
+#define BBP_CSR_CFG_REGNUM FIELD32(0x0000ff00)
+#define BBP_CSR_CFG_READ_CONTROL FIELD32(0x00010000)
+#define BBP_CSR_CFG_BUSY FIELD32(0x00020000)
+#define BBP_CSR_CFG_BBP_PAR_DUR FIELD32(0x00040000)
+#define BBP_CSR_CFG_BBP_RW_MODE FIELD32(0x00080000)
+
+/*
+ * RF_CSR_CFG0: RF control register
+ * REGID_AND_VALUE: Register value to program into RF
+ * BITWIDTH: Selected RF register
+ * STANDBYMODE: 0 high when standby, 1 low when standby
+ * SEL: 0 RF_LE0 activate, 1 RF_LE1 activate
+ * BUSY: ASIC is busy executing RF commands
+ */
+#define RF_CSR_CFG0 0x1020
+#define RF_CSR_CFG0_REGID_AND_VALUE FIELD32(0x00ffffff)
+#define RF_CSR_CFG0_BITWIDTH FIELD32(0x1f000000)
+#define RF_CSR_CFG0_REG_VALUE_BW FIELD32(0x1fffffff)
+#define RF_CSR_CFG0_STANDBYMODE FIELD32(0x20000000)
+#define RF_CSR_CFG0_SEL FIELD32(0x40000000)
+#define RF_CSR_CFG0_BUSY FIELD32(0x80000000)
+
+/*
+ * RF_CSR_CFG1: RF control register
+ * REGID_AND_VALUE: Register value to program into RF
+ * RFGAP: Gap between BB_CONTROL_RF and RF_LE
+ * 0: 3 system clock cycle (37.5usec)
+ * 1: 5 system clock cycle (62.5usec)
+ */
+#define RF_CSR_CFG1 0x1024
+#define RF_CSR_CFG1_REGID_AND_VALUE FIELD32(0x00ffffff)
+#define RF_CSR_CFG1_RFGAP FIELD32(0x1f000000)
+
+/*
+ * RF_CSR_CFG2: RF control register
+ * VALUE: Register value to program into RF
+ * RFGAP: Gap between BB_CONTROL_RF and RF_LE
+ * 0: 3 system clock cycle (37.5usec)
+ * 1: 5 system clock cycle (62.5usec)
+ */
+#define RF_CSR_CFG2 0x1028
+#define RF_CSR_CFG2_VALUE FIELD32(0x00ffffff)
+
+/*
+ * LED_CFG: LED control
+ * color LED's:
+ * 0: off
+ * 1: blinking upon TX2
+ * 2: periodic slow blinking
+ * 3: always on
+ * LED polarity:
+ * 0: active low
+ * 1: active high
+ */
+#define LED_CFG 0x102c
+#define LED_CFG_ON_PERIOD FIELD32(0x000000ff)
+#define LED_CFG_OFF_PERIOD FIELD32(0x0000ff00)
+#define LED_CFG_SLOW_BLINK_PERIOD FIELD32(0x003f0000)
+#define LED_CFG_R_LED_MODE FIELD32(0x03000000)
+#define LED_CFG_G_LED_MODE FIELD32(0x0c000000)
+#define LED_CFG_Y_LED_MODE FIELD32(0x30000000)
+#define LED_CFG_LED_POLAR FIELD32(0x40000000)
+
+/*
+ * XIFS_TIME_CFG: MAC timing
+ * CCKM_SIFS_TIME: unit 1us. Applied after CCK RX/TX
+ * OFDM_SIFS_TIME: unit 1us. Applied after OFDM RX/TX
+ * OFDM_XIFS_TIME: unit 1us. Applied after OFDM RX
+ * when MAC doesn't reference BBP signal BBRXEND
+ * EIFS: unit 1us
+ * BB_RXEND_ENABLE: reference RXEND signal to begin XIFS defer
+ *
+ */
+#define XIFS_TIME_CFG 0x1100
+#define XIFS_TIME_CFG_CCKM_SIFS_TIME FIELD32(0x000000ff)
+#define XIFS_TIME_CFG_OFDM_SIFS_TIME FIELD32(0x0000ff00)
+#define XIFS_TIME_CFG_OFDM_XIFS_TIME FIELD32(0x000f0000)
+#define XIFS_TIME_CFG_EIFS FIELD32(0x1ff00000)
+#define XIFS_TIME_CFG_BB_RXEND_ENABLE FIELD32(0x20000000)
+
+/*
+ * BKOFF_SLOT_CFG:
+ */
+#define BKOFF_SLOT_CFG 0x1104
+#define BKOFF_SLOT_CFG_SLOT_TIME FIELD32(0x000000ff)
+#define BKOFF_SLOT_CFG_CC_DELAY_TIME FIELD32(0x0000ff00)
+
+/*
+ * NAV_TIME_CFG:
+ */
+#define NAV_TIME_CFG 0x1108
+#define NAV_TIME_CFG_SIFS FIELD32(0x000000ff)
+#define NAV_TIME_CFG_SLOT_TIME FIELD32(0x0000ff00)
+#define NAV_TIME_CFG_EIFS FIELD32(0x01ff0000)
+#define NAV_TIME_ZERO_SIFS FIELD32(0x02000000)
+
+/*
+ * CH_TIME_CFG: count as channel busy
+ */
+#define CH_TIME_CFG 0x110c
+
+/*
+ * PBF_LIFE_TIMER: TX/RX MPDU timestamp timer (free run) Unit: 1us
+ */
+#define PBF_LIFE_TIMER 0x1110
+
+/*
+ * BCN_TIME_CFG:
+ * BEACON_INTERVAL: in unit of 1/16 TU
+ * TSF_TICKING: Enable TSF auto counting
+ * TSF_SYNC: Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
+ * BEACON_GEN: Enable beacon generator
+ */
+#define BCN_TIME_CFG 0x1114
+#define BCN_TIME_CFG_BEACON_INTERVAL FIELD32(0x0000ffff)
+#define BCN_TIME_CFG_TSF_TICKING FIELD32(0x00010000)
+#define BCN_TIME_CFG_TSF_SYNC FIELD32(0x00060000)
+#define BCN_TIME_CFG_TBTT_ENABLE FIELD32(0x00080000)
+#define BCN_TIME_CFG_BEACON_GEN FIELD32(0x00100000)
+#define BCN_TIME_CFG_TX_TIME_COMPENSATE FIELD32(0xf0000000)
+
+/*
+ * TBTT_SYNC_CFG:
+ */
+#define TBTT_SYNC_CFG 0x1118
+
+/*
+ * TSF_TIMER_DW0: Local lsb TSF timer, read-only
+ */
+#define TSF_TIMER_DW0 0x111c
+#define TSF_TIMER_DW0_LOW_WORD FIELD32(0xffffffff)
+
+/*
+ * TSF_TIMER_DW1: Local msb TSF timer, read-only
+ */
+#define TSF_TIMER_DW1 0x1120
+#define TSF_TIMER_DW1_HIGH_WORD FIELD32(0xffffffff)
+
+/*
+ * TBTT_TIMER: TImer remains till next TBTT, read-only
+ */
+#define TBTT_TIMER 0x1124
+
+/*
+ * INT_TIMER_CFG:
+ */
+#define INT_TIMER_CFG 0x1128
+
+/*
+ * INT_TIMER_EN: GP-timer and pre-tbtt Int enable
+ */
+#define INT_TIMER_EN 0x112c
+
+/*
+ * CH_IDLE_STA: channel idle time
+ */
+#define CH_IDLE_STA 0x1130
+
+/*
+ * CH_BUSY_STA: channel busy time
+ */
+#define CH_BUSY_STA 0x1134
+
+/*
+ * MAC_STATUS_CFG:
+ * BBP_RF_BUSY: When set to 0, BBP and RF are stable.
+ * if 1 or higher one of the 2 registers is busy.
+ */
+#define MAC_STATUS_CFG 0x1200
+#define MAC_STATUS_CFG_BBP_RF_BUSY FIELD32(0x00000003)
+
+/*
+ * PWR_PIN_CFG:
+ */
+#define PWR_PIN_CFG 0x1204
+
+/*
+ * AUTOWAKEUP_CFG: Manual power control / status register
+ * TBCN_BEFORE_WAKE: ForceWake has high privilege than PutToSleep when both set
+ * AUTOWAKE: 0:sleep, 1:awake
+ */
+#define AUTOWAKEUP_CFG 0x1208
+#define AUTOWAKEUP_CFG_AUTO_LEAD_TIME FIELD32(0x000000ff)
+#define AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE FIELD32(0x00007f00)
+#define AUTOWAKEUP_CFG_AUTOWAKE FIELD32(0x00008000)
+
+/*
+ * EDCA_AC0_CFG:
+ */
+#define EDCA_AC0_CFG 0x1300
+#define EDCA_AC0_CFG_TX_OP FIELD32(0x000000ff)
+#define EDCA_AC0_CFG_AIFSN FIELD32(0x00000f00)
+#define EDCA_AC0_CFG_CWMIN FIELD32(0x0000f000)
+#define EDCA_AC0_CFG_CWMAX FIELD32(0x000f0000)
+
+/*
+ * EDCA_AC1_CFG:
+ */
+#define EDCA_AC1_CFG 0x1304
+#define EDCA_AC1_CFG_TX_OP FIELD32(0x000000ff)
+#define EDCA_AC1_CFG_AIFSN FIELD32(0x00000f00)
+#define EDCA_AC1_CFG_CWMIN FIELD32(0x0000f000)
+#define EDCA_AC1_CFG_CWMAX FIELD32(0x000f0000)
+
+/*
+ * EDCA_AC2_CFG:
+ */
+#define EDCA_AC2_CFG 0x1308
+#define EDCA_AC2_CFG_TX_OP FIELD32(0x000000ff)
+#define EDCA_AC2_CFG_AIFSN FIELD32(0x00000f00)
+#define EDCA_AC2_CFG_CWMIN FIELD32(0x0000f000)
+#define EDCA_AC2_CFG_CWMAX FIELD32(0x000f0000)
+
+/*
+ * EDCA_AC3_CFG:
+ */
+#define EDCA_AC3_CFG 0x130c
+#define EDCA_AC3_CFG_TX_OP FIELD32(0x000000ff)
+#define EDCA_AC3_CFG_AIFSN FIELD32(0x00000f00)
+#define EDCA_AC3_CFG_CWMIN FIELD32(0x0000f000)
+#define EDCA_AC3_CFG_CWMAX FIELD32(0x000f0000)
+
+/*
+ * EDCA_TID_AC_MAP:
+ */
+#define EDCA_TID_AC_MAP 0x1310
+
+/*
+ * TX_PWR_CFG_0:
+ */
+#define TX_PWR_CFG_0 0x1314
+#define TX_PWR_CFG_0_1MBS FIELD32(0x0000000f)
+#define TX_PWR_CFG_0_2MBS FIELD32(0x000000f0)
+#define TX_PWR_CFG_0_55MBS FIELD32(0x00000f00)
+#define TX_PWR_CFG_0_11MBS FIELD32(0x0000f000)
+#define TX_PWR_CFG_0_6MBS FIELD32(0x000f0000)
+#define TX_PWR_CFG_0_9MBS FIELD32(0x00f00000)
+#define TX_PWR_CFG_0_12MBS FIELD32(0x0f000000)
+#define TX_PWR_CFG_0_18MBS FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_1:
+ */
+#define TX_PWR_CFG_1 0x1318
+#define TX_PWR_CFG_1_24MBS FIELD32(0x0000000f)
+#define TX_PWR_CFG_1_36MBS FIELD32(0x000000f0)
+#define TX_PWR_CFG_1_48MBS FIELD32(0x00000f00)
+#define TX_PWR_CFG_1_54MBS FIELD32(0x0000f000)
+#define TX_PWR_CFG_1_MCS0 FIELD32(0x000f0000)
+#define TX_PWR_CFG_1_MCS1 FIELD32(0x00f00000)
+#define TX_PWR_CFG_1_MCS2 FIELD32(0x0f000000)
+#define TX_PWR_CFG_1_MCS3 FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_2:
+ */
+#define TX_PWR_CFG_2 0x131c
+#define TX_PWR_CFG_2_MCS4 FIELD32(0x0000000f)
+#define TX_PWR_CFG_2_MCS5 FIELD32(0x000000f0)
+#define TX_PWR_CFG_2_MCS6 FIELD32(0x00000f00)
+#define TX_PWR_CFG_2_MCS7 FIELD32(0x0000f000)
+#define TX_PWR_CFG_2_MCS8 FIELD32(0x000f0000)
+#define TX_PWR_CFG_2_MCS9 FIELD32(0x00f00000)
+#define TX_PWR_CFG_2_MCS10 FIELD32(0x0f000000)
+#define TX_PWR_CFG_2_MCS11 FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_3:
+ */
+#define TX_PWR_CFG_3 0x1320
+#define TX_PWR_CFG_3_MCS12 FIELD32(0x0000000f)
+#define TX_PWR_CFG_3_MCS13 FIELD32(0x000000f0)
+#define TX_PWR_CFG_3_MCS14 FIELD32(0x00000f00)
+#define TX_PWR_CFG_3_MCS15 FIELD32(0x0000f000)
+#define TX_PWR_CFG_3_UKNOWN1 FIELD32(0x000f0000)
+#define TX_PWR_CFG_3_UKNOWN2 FIELD32(0x00f00000)
+#define TX_PWR_CFG_3_UKNOWN3 FIELD32(0x0f000000)
+#define TX_PWR_CFG_3_UKNOWN4 FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_4:
+ */
+#define TX_PWR_CFG_4 0x1324
+#define TX_PWR_CFG_4_UKNOWN5 FIELD32(0x0000000f)
+#define TX_PWR_CFG_4_UKNOWN6 FIELD32(0x000000f0)
+#define TX_PWR_CFG_4_UKNOWN7 FIELD32(0x00000f00)
+#define TX_PWR_CFG_4_UKNOWN8 FIELD32(0x0000f000)
+
+/*
+ * TX_PIN_CFG:
+ */
+#define TX_PIN_CFG 0x1328
+#define TX_PIN_CFG_PA_PE_A0_EN FIELD32(0x00000001)
+#define TX_PIN_CFG_PA_PE_G0_EN FIELD32(0x00000002)
+#define TX_PIN_CFG_PA_PE_A1_EN FIELD32(0x00000004)
+#define TX_PIN_CFG_PA_PE_G1_EN FIELD32(0x00000008)
+#define TX_PIN_CFG_PA_PE_A0_POL FIELD32(0x00000010)
+#define TX_PIN_CFG_PA_PE_G0_POL FIELD32(0x00000020)
+#define TX_PIN_CFG_PA_PE_A1_POL FIELD32(0x00000040)
+#define TX_PIN_CFG_PA_PE_G1_POL FIELD32(0x00000080)
+#define TX_PIN_CFG_LNA_PE_A0_EN FIELD32(0x00000100)
+#define TX_PIN_CFG_LNA_PE_G0_EN FIELD32(0x00000200)
+#define TX_PIN_CFG_LNA_PE_A1_EN FIELD32(0x00000400)
+#define TX_PIN_CFG_LNA_PE_G1_EN FIELD32(0x00000800)
+#define TX_PIN_CFG_LNA_PE_A0_POL FIELD32(0x00001000)
+#define TX_PIN_CFG_LNA_PE_G0_POL FIELD32(0x00002000)
+#define TX_PIN_CFG_LNA_PE_A1_POL FIELD32(0x00004000)
+#define TX_PIN_CFG_LNA_PE_G1_POL FIELD32(0x00008000)
+#define TX_PIN_CFG_RFTR_EN FIELD32(0x00010000)
+#define TX_PIN_CFG_RFTR_POL FIELD32(0x00020000)
+#define TX_PIN_CFG_TRSW_EN FIELD32(0x00040000)
+#define TX_PIN_CFG_TRSW_POL FIELD32(0x00080000)
+
+/*
+ * TX_BAND_CFG: 0x1 use upper 20MHz, 0x0 use lower 20MHz
+ */
+#define TX_BAND_CFG 0x132c
+#define TX_BAND_CFG_HT40_PLUS FIELD32(0x00000001)
+#define TX_BAND_CFG_A FIELD32(0x00000002)
+#define TX_BAND_CFG_BG FIELD32(0x00000004)
+
+/*
+ * TX_SW_CFG0:
+ */
+#define TX_SW_CFG0 0x1330
+
+/*
+ * TX_SW_CFG1:
+ */
+#define TX_SW_CFG1 0x1334
+
+/*
+ * TX_SW_CFG2:
+ */
+#define TX_SW_CFG2 0x1338
+
+/*
+ * TXOP_THRES_CFG:
+ */
+#define TXOP_THRES_CFG 0x133c
+
+/*
+ * TXOP_CTRL_CFG:
+ */
+#define TXOP_CTRL_CFG 0x1340
+
+/*
+ * TX_RTS_CFG:
+ * RTS_THRES: unit:byte
+ * RTS_FBK_EN: enable rts rate fallback
+ */
+#define TX_RTS_CFG 0x1344
+#define TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT FIELD32(0x000000ff)
+#define TX_RTS_CFG_RTS_THRES FIELD32(0x00ffff00)
+#define TX_RTS_CFG_RTS_FBK_EN FIELD32(0x01000000)
+
+/*
+ * TX_TIMEOUT_CFG:
+ * MPDU_LIFETIME: expiration time = 2^(9+MPDU LIFE TIME) us
+ * RX_ACK_TIMEOUT: unit:slot. Used for TX procedure
+ * TX_OP_TIMEOUT: TXOP timeout value for TXOP truncation.
+ * it is recommended that:
+ * (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
+ */
+#define TX_TIMEOUT_CFG 0x1348
+#define TX_TIMEOUT_CFG_MPDU_LIFETIME FIELD32(0x000000f0)
+#define TX_TIMEOUT_CFG_RX_ACK_TIMEOUT FIELD32(0x0000ff00)
+#define TX_TIMEOUT_CFG_TX_OP_TIMEOUT FIELD32(0x00ff0000)
+
+/*
+ * TX_RTY_CFG:
+ * SHORT_RTY_LIMIT: short retry limit
+ * LONG_RTY_LIMIT: long retry limit
+ * LONG_RTY_THRE: Long retry threshoold
+ * NON_AGG_RTY_MODE: Non-Aggregate MPDU retry mode
+ * 0:expired by retry limit, 1: expired by mpdu life timer
+ * AGG_RTY_MODE: Aggregate MPDU retry mode
+ * 0:expired by retry limit, 1: expired by mpdu life timer
+ * TX_AUTO_FB_ENABLE: Tx retry PHY rate auto fallback enable
+ */
+#define TX_RTY_CFG 0x134c
+#define TX_RTY_CFG_SHORT_RTY_LIMIT FIELD32(0x000000ff)
+#define TX_RTY_CFG_LONG_RTY_LIMIT FIELD32(0x0000ff00)
+#define TX_RTY_CFG_LONG_RTY_THRE FIELD32(0x0fff0000)
+#define TX_RTY_CFG_NON_AGG_RTY_MODE FIELD32(0x10000000)
+#define TX_RTY_CFG_AGG_RTY_MODE FIELD32(0x20000000)
+#define TX_RTY_CFG_TX_AUTO_FB_ENABLE FIELD32(0x40000000)
+
+/*
+ * TX_LINK_CFG:
+ * REMOTE_MFB_LIFETIME: remote MFB life time. unit: 32us
+ * MFB_ENABLE: TX apply remote MFB 1:enable
+ * REMOTE_UMFS_ENABLE: remote unsolicit MFB enable
+ * 0: not apply remote remote unsolicit (MFS=7)
+ * TX_MRQ_EN: MCS request TX enable
+ * TX_RDG_EN: RDG TX enable
+ * TX_CF_ACK_EN: Piggyback CF-ACK enable
+ * REMOTE_MFB: remote MCS feedback
+ * REMOTE_MFS: remote MCS feedback sequence number
+ */
+#define TX_LINK_CFG 0x1350
+#define TX_LINK_CFG_REMOTE_MFB_LIFETIME FIELD32(0x000000ff)
+#define TX_LINK_CFG_MFB_ENABLE FIELD32(0x00000100)
+#define TX_LINK_CFG_REMOTE_UMFS_ENABLE FIELD32(0x00000200)
+#define TX_LINK_CFG_TX_MRQ_EN FIELD32(0x00000400)
+#define TX_LINK_CFG_TX_RDG_EN FIELD32(0x00000800)
+#define TX_LINK_CFG_TX_CF_ACK_EN FIELD32(0x00001000)
+#define TX_LINK_CFG_REMOTE_MFB FIELD32(0x00ff0000)
+#define TX_LINK_CFG_REMOTE_MFS FIELD32(0xff000000)
+
+/*
+ * HT_FBK_CFG0:
+ */
+#define HT_FBK_CFG0 0x1354
+#define HT_FBK_CFG0_HTMCS0FBK FIELD32(0x0000000f)
+#define HT_FBK_CFG0_HTMCS1FBK FIELD32(0x000000f0)
+#define HT_FBK_CFG0_HTMCS2FBK FIELD32(0x00000f00)
+#define HT_FBK_CFG0_HTMCS3FBK FIELD32(0x0000f000)
+#define HT_FBK_CFG0_HTMCS4FBK FIELD32(0x000f0000)
+#define HT_FBK_CFG0_HTMCS5FBK FIELD32(0x00f00000)
+#define HT_FBK_CFG0_HTMCS6FBK FIELD32(0x0f000000)
+#define HT_FBK_CFG0_HTMCS7FBK FIELD32(0xf0000000)
+
+/*
+ * HT_FBK_CFG1:
+ */
+#define HT_FBK_CFG1 0x1358
+#define HT_FBK_CFG1_HTMCS8FBK FIELD32(0x0000000f)
+#define HT_FBK_CFG1_HTMCS9FBK FIELD32(0x000000f0)
+#define HT_FBK_CFG1_HTMCS10FBK FIELD32(0x00000f00)
+#define HT_FBK_CFG1_HTMCS11FBK FIELD32(0x0000f000)
+#define HT_FBK_CFG1_HTMCS12FBK FIELD32(0x000f0000)
+#define HT_FBK_CFG1_HTMCS13FBK FIELD32(0x00f00000)
+#define HT_FBK_CFG1_HTMCS14FBK FIELD32(0x0f000000)
+#define HT_FBK_CFG1_HTMCS15FBK FIELD32(0xf0000000)
+
+/*
+ * LG_FBK_CFG0:
+ */
+#define LG_FBK_CFG0 0x135c
+#define LG_FBK_CFG0_OFDMMCS0FBK FIELD32(0x0000000f)
+#define LG_FBK_CFG0_OFDMMCS1FBK FIELD32(0x000000f0)
+#define LG_FBK_CFG0_OFDMMCS2FBK FIELD32(0x00000f00)
+#define LG_FBK_CFG0_OFDMMCS3FBK FIELD32(0x0000f000)
+#define LG_FBK_CFG0_OFDMMCS4FBK FIELD32(0x000f0000)
+#define LG_FBK_CFG0_OFDMMCS5FBK FIELD32(0x00f00000)
+#define LG_FBK_CFG0_OFDMMCS6FBK FIELD32(0x0f000000)
+#define LG_FBK_CFG0_OFDMMCS7FBK FIELD32(0xf0000000)
+
+/*
+ * LG_FBK_CFG1:
+ */
+#define LG_FBK_CFG1 0x1360
+#define LG_FBK_CFG0_CCKMCS0FBK FIELD32(0x0000000f)
+#define LG_FBK_CFG0_CCKMCS1FBK FIELD32(0x000000f0)
+#define LG_FBK_CFG0_CCKMCS2FBK FIELD32(0x00000f00)
+#define LG_FBK_CFG0_CCKMCS3FBK FIELD32(0x0000f000)
+
+/*
+ * CCK_PROT_CFG: CCK Protection
+ * PROTECT_RATE: Protection control frame rate for CCK TX(RTS/CTS/CFEnd)
+ * PROTECT_CTRL: Protection control frame type for CCK TX
+ * 0:none, 1:RTS/CTS, 2:CTS-to-self
+ * PROTECT_NAV: TXOP protection type for CCK TX
+ * 0:none, 1:ShortNAVprotect, 2:LongNAVProtect
+ * TX_OP_ALLOW_CCK: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_OFDM: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_MM20: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_MM40: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_GF20: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_GF40: CCK TXOP allowance, 0:disallow
+ * RTS_TH_EN: RTS threshold enable on CCK TX
+ */
+#define CCK_PROT_CFG 0x1364
+#define CCK_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
+#define CCK_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
+#define CCK_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define CCK_PROT_CFG_RTS_TH_EN FIELD32(0x04000000)
+
+/*
+ * OFDM_PROT_CFG: OFDM Protection
+ */
+#define OFDM_PROT_CFG 0x1368
+#define OFDM_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
+#define OFDM_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
+#define OFDM_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define OFDM_PROT_CFG_RTS_TH_EN FIELD32(0x04000000)
+
+/*
+ * MM20_PROT_CFG: MM20 Protection
+ */
+#define MM20_PROT_CFG 0x136c
+#define MM20_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
+#define MM20_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
+#define MM20_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define MM20_PROT_CFG_RTS_TH_EN FIELD32(0x04000000)
+
+/*
+ * MM40_PROT_CFG: MM40 Protection
+ */
+#define MM40_PROT_CFG 0x1370
+#define MM40_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
+#define MM40_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
+#define MM40_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define MM40_PROT_CFG_RTS_TH_EN FIELD32(0x04000000)
+
+/*
+ * GF20_PROT_CFG: GF20 Protection
+ */
+#define GF20_PROT_CFG 0x1374
+#define GF20_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
+#define GF20_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
+#define GF20_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define GF20_PROT_CFG_RTS_TH_EN FIELD32(0x04000000)
+
+/*
+ * GF40_PROT_CFG: GF40 Protection
+ */
+#define GF40_PROT_CFG 0x1378
+#define GF40_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
+#define GF40_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
+#define GF40_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define GF40_PROT_CFG_RTS_TH_EN FIELD32(0x04000000)
+
+/*
+ * EXP_CTS_TIME:
+ */
+#define EXP_CTS_TIME 0x137c
+
+/*
+ * EXP_ACK_TIME:
+ */
+#define EXP_ACK_TIME 0x1380
+
+/*
+ * RX_FILTER_CFG: RX configuration register.
+ */
+#define RX_FILTER_CFG 0x1400
+#define RX_FILTER_CFG_DROP_CRC_ERROR FIELD32(0x00000001)
+#define RX_FILTER_CFG_DROP_PHY_ERROR FIELD32(0x00000002)
+#define RX_FILTER_CFG_DROP_NOT_TO_ME FIELD32(0x00000004)
+#define RX_FILTER_CFG_DROP_NOT_MY_BSSD FIELD32(0x00000008)
+#define RX_FILTER_CFG_DROP_VER_ERROR FIELD32(0x00000010)
+#define RX_FILTER_CFG_DROP_MULTICAST FIELD32(0x00000020)
+#define RX_FILTER_CFG_DROP_BROADCAST FIELD32(0x00000040)
+#define RX_FILTER_CFG_DROP_DUPLICATE FIELD32(0x00000080)
+#define RX_FILTER_CFG_DROP_CF_END_ACK FIELD32(0x00000100)
+#define RX_FILTER_CFG_DROP_CF_END FIELD32(0x00000200)
+#define RX_FILTER_CFG_DROP_ACK FIELD32(0x00000400)
+#define RX_FILTER_CFG_DROP_CTS FIELD32(0x00000800)
+#define RX_FILTER_CFG_DROP_RTS FIELD32(0x00001000)
+#define RX_FILTER_CFG_DROP_PSPOLL FIELD32(0x00002000)
+#define RX_FILTER_CFG_DROP_BA FIELD32(0x00004000)
+#define RX_FILTER_CFG_DROP_BAR FIELD32(0x00008000)
+#define RX_FILTER_CFG_DROP_CNTL FIELD32(0x00010000)
+
+/*
+ * AUTO_RSP_CFG:
+ * AUTORESPONDER: 0: disable, 1: enable
+ * BAC_ACK_POLICY: 0:long, 1:short preamble
+ * CTS_40_MMODE: Response CTS 40MHz duplicate mode
+ * CTS_40_MREF: Response CTS 40MHz duplicate mode
+ * AR_PREAMBLE: Auto responder preamble 0:long, 1:short preamble
+ * DUAL_CTS_EN: Power bit value in control frame
+ * ACK_CTS_PSM_BIT:Power bit value in control frame
+ */
+#define AUTO_RSP_CFG 0x1404
+#define AUTO_RSP_CFG_AUTORESPONDER FIELD32(0x00000001)
+#define AUTO_RSP_CFG_BAC_ACK_POLICY FIELD32(0x00000002)
+#define AUTO_RSP_CFG_CTS_40_MMODE FIELD32(0x00000004)
+#define AUTO_RSP_CFG_CTS_40_MREF FIELD32(0x00000008)
+#define AUTO_RSP_CFG_AR_PREAMBLE FIELD32(0x00000010)
+#define AUTO_RSP_CFG_DUAL_CTS_EN FIELD32(0x00000040)
+#define AUTO_RSP_CFG_ACK_CTS_PSM_BIT FIELD32(0x00000080)
+
+/*
+ * LEGACY_BASIC_RATE:
+ */
+#define LEGACY_BASIC_RATE 0x1408
+
+/*
+ * HT_BASIC_RATE:
+ */
+#define HT_BASIC_RATE 0x140c
+
+/*
+ * HT_CTRL_CFG:
+ */
+#define HT_CTRL_CFG 0x1410
+
+/*
+ * SIFS_COST_CFG:
+ */
+#define SIFS_COST_CFG 0x1414
+
+/*
+ * RX_PARSER_CFG:
+ * Set NAV for all received frames
+ */
+#define RX_PARSER_CFG 0x1418
+
+/*
+ * TX_SEC_CNT0:
+ */
+#define TX_SEC_CNT0 0x1500
+
+/*
+ * RX_SEC_CNT0:
+ */
+#define RX_SEC_CNT0 0x1504
+
+/*
+ * CCMP_FC_MUTE:
+ */
+#define CCMP_FC_MUTE 0x1508
+
+/*
+ * TXOP_HLDR_ADDR0:
+ */
+#define TXOP_HLDR_ADDR0 0x1600
+
+/*
+ * TXOP_HLDR_ADDR1:
+ */
+#define TXOP_HLDR_ADDR1 0x1604
+
+/*
+ * TXOP_HLDR_ET:
+ */
+#define TXOP_HLDR_ET 0x1608
+
+/*
+ * QOS_CFPOLL_RA_DW0:
+ */
+#define QOS_CFPOLL_RA_DW0 0x160c
+
+/*
+ * QOS_CFPOLL_RA_DW1:
+ */
+#define QOS_CFPOLL_RA_DW1 0x1610
+
+/*
+ * QOS_CFPOLL_QC:
+ */
+#define QOS_CFPOLL_QC 0x1614
+
+/*
+ * RX_STA_CNT0: RX PLCP error count & RX CRC error count
+ */
+#define RX_STA_CNT0 0x1700
+#define RX_STA_CNT0_CRC_ERR FIELD32(0x0000ffff)
+#define RX_STA_CNT0_PHY_ERR FIELD32(0xffff0000)
+
+/*
+ * RX_STA_CNT1: RX False CCA count & RX LONG frame count
+ */
+#define RX_STA_CNT1 0x1704
+#define RX_STA_CNT1_FALSE_CCA FIELD32(0x0000ffff)
+#define RX_STA_CNT1_PLCP_ERR FIELD32(0xffff0000)
+
+/*
+ * RX_STA_CNT2:
+ */
+#define RX_STA_CNT2 0x1708
+#define RX_STA_CNT2_RX_DUPLI_COUNT FIELD32(0x0000ffff)
+#define RX_STA_CNT2_RX_FIFO_OVERFLOW FIELD32(0xffff0000)
+
+/*
+ * TX_STA_CNT0: TX Beacon count
+ */
+#define TX_STA_CNT0 0x170c
+#define TX_STA_CNT0_TX_FAIL_COUNT FIELD32(0x0000ffff)
+#define TX_STA_CNT0_TX_BEACON_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_STA_CNT1: TX tx count
+ */
+#define TX_STA_CNT1 0x1710
+#define TX_STA_CNT1_TX_SUCCESS FIELD32(0x0000ffff)
+#define TX_STA_CNT1_TX_RETRANSMIT FIELD32(0xffff0000)
+
+/*
+ * TX_STA_CNT2: TX tx count
+ */
+#define TX_STA_CNT2 0x1714
+#define TX_STA_CNT2_TX_ZERO_LEN_COUNT FIELD32(0x0000ffff)
+#define TX_STA_CNT2_TX_UNDER_FLOW_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_STA_FIFO: TX Result for specific PID status fifo register
+ */
+#define TX_STA_FIFO 0x1718
+#define TX_STA_FIFO_VALID FIELD32(0x00000001)
+#define TX_STA_FIFO_PID_TYPE FIELD32(0x0000001e)
+#define TX_STA_FIFO_TX_SUCCESS FIELD32(0x00000020)
+#define TX_STA_FIFO_TX_AGGRE FIELD32(0x00000040)
+#define TX_STA_FIFO_TX_ACK_REQUIRED FIELD32(0x00000080)
+#define TX_STA_FIFO_WCID FIELD32(0x0000ff00)
+#define TX_STA_FIFO_SUCCESS_RATE FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT: Debug counter
+ */
+#define TX_AGG_CNT 0x171c
+#define TX_AGG_CNT_NON_AGG_TX_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT_AGG_TX_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT0:
+ */
+#define TX_AGG_CNT0 0x1720
+#define TX_AGG_CNT0_AGG_SIZE_1_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT0_AGG_SIZE_2_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT1:
+ */
+#define TX_AGG_CNT1 0x1724
+#define TX_AGG_CNT1_AGG_SIZE_3_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT1_AGG_SIZE_4_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT2:
+ */
+#define TX_AGG_CNT2 0x1728
+#define TX_AGG_CNT2_AGG_SIZE_5_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT2_AGG_SIZE_6_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT3:
+ */
+#define TX_AGG_CNT3 0x172c
+#define TX_AGG_CNT3_AGG_SIZE_7_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT3_AGG_SIZE_8_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT4:
+ */
+#define TX_AGG_CNT4 0x1730
+#define TX_AGG_CNT4_AGG_SIZE_9_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT4_AGG_SIZE_10_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT5:
+ */
+#define TX_AGG_CNT5 0x1734
+#define TX_AGG_CNT5_AGG_SIZE_11_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT5_AGG_SIZE_12_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT6:
+ */
+#define TX_AGG_CNT6 0x1738
+#define TX_AGG_CNT6_AGG_SIZE_13_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT6_AGG_SIZE_14_COUNT FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT7:
+ */
+#define TX_AGG_CNT7 0x173c
+#define TX_AGG_CNT7_AGG_SIZE_15_COUNT FIELD32(0x0000ffff)
+#define TX_AGG_CNT7_AGG_SIZE_16_COUNT FIELD32(0xffff0000)
+
+/*
+ * MPDU_DENSITY_CNT:
+ * TX_ZERO_DEL: TX zero length delimiter count
+ * RX_ZERO_DEL: RX zero length delimiter count
+ */
+#define MPDU_DENSITY_CNT 0x1740
+#define MPDU_DENSITY_CNT_TX_ZERO_DEL FIELD32(0x0000ffff)
+#define MPDU_DENSITY_CNT_RX_ZERO_DEL FIELD32(0xffff0000)
+
+/*
+ * Security key table memory.
+ * MAC_WCID_BASE: 8-bytes (use only 6 bytes) * 256 entry
+ * PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry
+ * MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry
+ * MAC_WCID_ATTRIBUTE_BASE: 4-byte * 256-entry
+ * SHARED_KEY_TABLE_BASE: 32-byte * 16-entry
+ * SHARED_KEY_MODE_BASE: 4-byte * 16-entry
+ */
+#define MAC_WCID_BASE 0x1800
+#define PAIRWISE_KEY_TABLE_BASE 0x4000
+#define MAC_IVEIV_TABLE_BASE 0x6000
+#define MAC_WCID_ATTRIBUTE_BASE 0x6800
+#define SHARED_KEY_TABLE_BASE 0x6c00
+#define SHARED_KEY_MODE_BASE 0x7000
+
+#define MAC_WCID_ENTRY(__idx) \
+ ( MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry)) )
+#define PAIRWISE_KEY_ENTRY(__idx) \
+ ( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) )
+#define MAC_IVEIV_ENTRY(__idx) \
+ ( MAC_IVEIV_TABLE_BASE + ((__idx) & sizeof(struct mac_iveiv_entry)) )
+#define MAC_WCID_ATTR_ENTRY(__idx) \
+ ( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) )
+#define SHARED_KEY_ENTRY(__idx) \
+ ( SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) )
+#define SHARED_KEY_MODE_ENTRY(__idx) \
+ ( SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32)) )
+
+struct mac_wcid_entry {
+ u8 mac[6];
+ u8 reserved[2];
+} __attribute__ ((packed));
+
+struct hw_key_entry {
+ u8 key[16];
+ u8 tx_mic[8];
+ u8 rx_mic[8];
+} __attribute__ ((packed));
+
+struct mac_iveiv_entry {
+ u8 iv[8];
+} __attribute__ ((packed));
+
+/*
+ * MAC_WCID_ATTRIBUTE:
+ */
+#define MAC_WCID_ATTRIBUTE_KEYTAB FIELD32(0x00000001)
+#define MAC_WCID_ATTRIBUTE_CIPHER FIELD32(0x0000000e)
+#define MAC_WCID_ATTRIBUTE_BSS_IDX FIELD32(0x00000070)
+#define MAC_WCID_ATTRIBUTE_RX_WIUDF FIELD32(0x00000380)
+
+/*
+ * SHARED_KEY_MODE:
+ */
+#define SHARED_KEY_MODE_BSS0_KEY0 FIELD32(0x00000007)
+#define SHARED_KEY_MODE_BSS0_KEY1 FIELD32(0x00000070)
+#define SHARED_KEY_MODE_BSS0_KEY2 FIELD32(0x00000700)
+#define SHARED_KEY_MODE_BSS0_KEY3 FIELD32(0x00007000)
+#define SHARED_KEY_MODE_BSS1_KEY0 FIELD32(0x00070000)
+#define SHARED_KEY_MODE_BSS1_KEY1 FIELD32(0x00700000)
+#define SHARED_KEY_MODE_BSS1_KEY2 FIELD32(0x07000000)
+#define SHARED_KEY_MODE_BSS1_KEY3 FIELD32(0x70000000)
+
+/*
+ * HOST-MCU communication
+ */
+
+/*
+ * H2M_MAILBOX_CSR: Host-to-MCU Mailbox.
+ */
+#define H2M_MAILBOX_CSR 0x7010
+#define H2M_MAILBOX_CSR_ARG0 FIELD32(0x000000ff)
+#define H2M_MAILBOX_CSR_ARG1 FIELD32(0x0000ff00)
+#define H2M_MAILBOX_CSR_CMD_TOKEN FIELD32(0x00ff0000)
+#define H2M_MAILBOX_CSR_OWNER FIELD32(0xff000000)
+
+/*
+ * H2M_MAILBOX_CID:
+ */
+#define H2M_MAILBOX_CID 0x7014
+#define H2M_MAILBOX_CID_CMD0 FIELD32(0x000000ff)
+#define H2M_MAILBOX_CID_CMD1 FIELD32(0x0000ff00)
+#define H2M_MAILBOX_CID_CMD2 FIELD32(0x00ff0000)
+#define H2M_MAILBOX_CID_CMD3 FIELD32(0xff000000)
+
+/*
+ * H2M_MAILBOX_STATUS:
+ */
+#define H2M_MAILBOX_STATUS 0x701c
+
+/*
+ * H2M_INT_SRC:
+ */
+#define H2M_INT_SRC 0x7024
+
+/*
+ * H2M_BBP_AGENT:
+ */
+#define H2M_BBP_AGENT 0x7028
+
+/*
+ * MCU_LEDCS: LED control for MCU Mailbox.
+ */
+#define MCU_LEDCS_LED_MODE FIELD8(0x1f)
+#define MCU_LEDCS_POLARITY FIELD8(0x01)
+
+/*
+ * HW_CS_CTS_BASE:
+ * Carrier-sense CTS frame base address.
+ * It's where mac stores carrier-sense frame for carrier-sense function.
+ */
+#define HW_CS_CTS_BASE 0x7700
+
+/*
+ * HW_DFS_CTS_BASE:
+ * FS CTS frame base address. It's where mac stores CTS frame for DFS.
+ */
+#define HW_DFS_CTS_BASE 0x7780
+
+/*
+ * TXRX control registers - base address 0x3000
+ */
+
+/*
+ * TXRX_CSR1:
+ * rt2860b UNKNOWN reg use R/O Reg Addr 0x77d0 first..
+ */
+#define TXRX_CSR1 0x77d0
+
+/*
+ * HW_DEBUG_SETTING_BASE:
+ * since NULL frame won't be that long (256 byte)
+ * We steal 16 tail bytes to save debugging settings
+ */
+#define HW_DEBUG_SETTING_BASE 0x77f0
+#define HW_DEBUG_SETTING_BASE2 0x7770
+
+/*
+ * HW_BEACON_BASE
+ * In order to support maximum 8 MBSS and its maximum length
+ * is 512 bytes for each beacon
+ * Three section discontinue memory segments will be used.
+ * 1. The original region for BCN 0~3
+ * 2. Extract memory from FCE table for BCN 4~5
+ * 3. Extract memory from Pair-wise key table for BCN 6~7
+ * It occupied those memory of wcid 238~253 for BCN 6
+ * and wcid 222~237 for BCN 7
+ *
+ * IMPORTANT NOTE: Not sure why legacy driver does this,
+ * but HW_BEACON_BASE7 is 0x0200 bytes below HW_BEACON_BASE6.
+ */
+#define HW_BEACON_BASE0 0x7800
+#define HW_BEACON_BASE1 0x7a00
+#define HW_BEACON_BASE2 0x7c00
+#define HW_BEACON_BASE3 0x7e00
+#define HW_BEACON_BASE4 0x7200
+#define HW_BEACON_BASE5 0x7400
+#define HW_BEACON_BASE6 0x5dc0
+#define HW_BEACON_BASE7 0x5bc0
+
+#define HW_BEACON_OFFSET(__index) \
+ ( ((__index) < 4) ? ( HW_BEACON_BASE0 + (__index * 0x0200) ) : \
+ (((__index) < 6) ? ( HW_BEACON_BASE4 + ((__index - 4) * 0x0200) ) : \
+ (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))) )
+
+/*
+ * 8051 firmware image.
+ */
+#define FIRMWARE_RT2870 "rt2870.bin"
+#define FIRMWARE_IMAGE_BASE 0x3000
+
+/*
+ * BBP registers.
+ * The wordsize of the BBP is 8 bits.
+ */
+
+/*
+ * BBP 1: TX Antenna
+ */
+#define BBP1_TX_POWER FIELD8(0x07)
+#define BBP1_TX_ANTENNA FIELD8(0x18)
+
+/*
+ * BBP 3: RX Antenna
+ */
+#define BBP3_RX_ANTENNA FIELD8(0x18)
+#define BBP3_HT40_PLUS FIELD8(0x20)
+
+/*
+ * BBP 4: Bandwidth
+ */
+#define BBP4_TX_BF FIELD8(0x01)
+#define BBP4_BANDWIDTH FIELD8(0x18)
+
+/*
+ * RFCSR registers
+ * The wordsize of the RFCSR is 8 bits.
+ */
+
+/*
+ * RFCSR 6:
+ */
+#define RFCSR6_R FIELD8(0x03)
+
+/*
+ * RFCSR 7:
+ */
+#define RFCSR7_RF_TUNING FIELD8(0x01)
+
+/*
+ * RFCSR 12:
+ */
+#define RFCSR12_TX_POWER FIELD8(0x1f)
+
+/*
+ * RFCSR 22:
+ */
+#define RFCSR22_BASEBAND_LOOPBACK FIELD8(0x01)
+
+/*
+ * RFCSR 23:
+ */
+#define RFCSR23_FREQ_OFFSET FIELD8(0x7f)
+
+/*
+ * RFCSR 30:
+ */
+#define RFCSR30_RF_CALIBRATION FIELD8(0x80)
+
+/*
+ * RF registers
+ */
+
+/*
+ * RF 2
+ */
+#define RF2_ANTENNA_RX2 FIELD32(0x00000040)
+#define RF2_ANTENNA_TX1 FIELD32(0x00004000)
+#define RF2_ANTENNA_RX1 FIELD32(0x00020000)
+
+/*
+ * RF 3
+ */
+#define RF3_TXPOWER_G FIELD32(0x00003e00)
+#define RF3_TXPOWER_A_7DBM_BOOST FIELD32(0x00000200)
+#define RF3_TXPOWER_A FIELD32(0x00003c00)
+
+/*
+ * RF 4
+ */
+#define RF4_TXPOWER_G FIELD32(0x000007c0)
+#define RF4_TXPOWER_A_7DBM_BOOST FIELD32(0x00000040)
+#define RF4_TXPOWER_A FIELD32(0x00000780)
+#define RF4_FREQ_OFFSET FIELD32(0x001f8000)
+#define RF4_HT40 FIELD32(0x00200000)
+
+/*
+ * EEPROM content.
+ * The wordsize of the EEPROM is 16 bits.
+ */
+
+/*
+ * EEPROM Version
+ */
+#define EEPROM_VERSION 0x0001
+#define EEPROM_VERSION_FAE FIELD16(0x00ff)
+#define EEPROM_VERSION_VERSION FIELD16(0xff00)
+
+/*
+ * HW MAC address.
+ */
+#define EEPROM_MAC_ADDR_0 0x0002
+#define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff)
+#define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00)
+#define EEPROM_MAC_ADDR_1 0x0003
+#define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff)
+#define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00)
+#define EEPROM_MAC_ADDR_2 0x0004
+#define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff)
+#define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00)
+
+/*
+ * EEPROM ANTENNA config
+ * RXPATH: 1: 1R, 2: 2R, 3: 3R
+ * TXPATH: 1: 1T, 2: 2T
+ */
+#define EEPROM_ANTENNA 0x001a
+#define EEPROM_ANTENNA_RXPATH FIELD16(0x000f)
+#define EEPROM_ANTENNA_TXPATH FIELD16(0x00f0)
+#define EEPROM_ANTENNA_RF_TYPE FIELD16(0x0f00)
+
+/*
+ * EEPROM NIC config
+ * CARDBUS_ACCEL: 0 - enable, 1 - disable
+ */
+#define EEPROM_NIC 0x001b
+#define EEPROM_NIC_HW_RADIO FIELD16(0x0001)
+#define EEPROM_NIC_DYNAMIC_TX_AGC FIELD16(0x0002)
+#define EEPROM_NIC_EXTERNAL_LNA_BG FIELD16(0x0004)
+#define EEPROM_NIC_EXTERNAL_LNA_A FIELD16(0x0008)
+#define EEPROM_NIC_CARDBUS_ACCEL FIELD16(0x0010)
+#define EEPROM_NIC_BW40M_SB_BG FIELD16(0x0020)
+#define EEPROM_NIC_BW40M_SB_A FIELD16(0x0040)
+#define EEPROM_NIC_WPS_PBC FIELD16(0x0080)
+#define EEPROM_NIC_BW40M_BG FIELD16(0x0100)
+#define EEPROM_NIC_BW40M_A FIELD16(0x0200)
+
+/*
+ * EEPROM frequency
+ */
+#define EEPROM_FREQ 0x001d
+#define EEPROM_FREQ_OFFSET FIELD16(0x00ff)
+#define EEPROM_FREQ_LED_MODE FIELD16(0x7f00)
+#define EEPROM_FREQ_LED_POLARITY FIELD16(0x1000)
+
+/*
+ * EEPROM LED
+ * POLARITY_RDY_G: Polarity RDY_G setting.
+ * POLARITY_RDY_A: Polarity RDY_A setting.
+ * POLARITY_ACT: Polarity ACT setting.
+ * POLARITY_GPIO_0: Polarity GPIO0 setting.
+ * POLARITY_GPIO_1: Polarity GPIO1 setting.
+ * POLARITY_GPIO_2: Polarity GPIO2 setting.
+ * POLARITY_GPIO_3: Polarity GPIO3 setting.
+ * POLARITY_GPIO_4: Polarity GPIO4 setting.
+ * LED_MODE: Led mode.
+ */
+#define EEPROM_LED1 0x001e
+#define EEPROM_LED2 0x001f
+#define EEPROM_LED3 0x0020
+#define EEPROM_LED_POLARITY_RDY_BG FIELD16(0x0001)
+#define EEPROM_LED_POLARITY_RDY_A FIELD16(0x0002)
+#define EEPROM_LED_POLARITY_ACT FIELD16(0x0004)
+#define EEPROM_LED_POLARITY_GPIO_0 FIELD16(0x0008)
+#define EEPROM_LED_POLARITY_GPIO_1 FIELD16(0x0010)
+#define EEPROM_LED_POLARITY_GPIO_2 FIELD16(0x0020)
+#define EEPROM_LED_POLARITY_GPIO_3 FIELD16(0x0040)
+#define EEPROM_LED_POLARITY_GPIO_4 FIELD16(0x0080)
+#define EEPROM_LED_LED_MODE FIELD16(0x1f00)
+
+/*
+ * EEPROM LNA
+ */
+#define EEPROM_LNA 0x0022
+#define EEPROM_LNA_BG FIELD16(0x00ff)
+#define EEPROM_LNA_A0 FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI BG offset
+ */
+#define EEPROM_RSSI_BG 0x0023
+#define EEPROM_RSSI_BG_OFFSET0 FIELD16(0x00ff)
+#define EEPROM_RSSI_BG_OFFSET1 FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI BG2 offset
+ */
+#define EEPROM_RSSI_BG2 0x0024
+#define EEPROM_RSSI_BG2_OFFSET2 FIELD16(0x00ff)
+#define EEPROM_RSSI_BG2_LNA_A1 FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI A offset
+ */
+#define EEPROM_RSSI_A 0x0025
+#define EEPROM_RSSI_A_OFFSET0 FIELD16(0x00ff)
+#define EEPROM_RSSI_A_OFFSET1 FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI A2 offset
+ */
+#define EEPROM_RSSI_A2 0x0026
+#define EEPROM_RSSI_A2_OFFSET2 FIELD16(0x00ff)
+#define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00)
+
+/*
+ * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power.
+ * This is delta in 40MHZ.
+ * VALUE: Tx Power dalta value (MAX=4)
+ * TYPE: 1: Plus the delta value, 0: minus the delta value
+ * TXPOWER: Enable:
+ */
+#define EEPROM_TXPOWER_DELTA 0x0028
+#define EEPROM_TXPOWER_DELTA_VALUE FIELD16(0x003f)
+#define EEPROM_TXPOWER_DELTA_TYPE FIELD16(0x0040)
+#define EEPROM_TXPOWER_DELTA_TXPOWER FIELD16(0x0080)
+
+/*
+ * EEPROM TXPOWER 802.11BG
+ */
+#define EEPROM_TXPOWER_BG1 0x0029
+#define EEPROM_TXPOWER_BG2 0x0030
+#define EEPROM_TXPOWER_BG_SIZE 7
+#define EEPROM_TXPOWER_BG_1 FIELD16(0x00ff)
+#define EEPROM_TXPOWER_BG_2 FIELD16(0xff00)
+
+/*
+ * EEPROM TXPOWER 802.11A
+ */
+#define EEPROM_TXPOWER_A1 0x003c
+#define EEPROM_TXPOWER_A2 0x0053
+#define EEPROM_TXPOWER_A_SIZE 6
+#define EEPROM_TXPOWER_A_1 FIELD16(0x00ff)
+#define EEPROM_TXPOWER_A_2 FIELD16(0xff00)
+
+/*
+ * EEPROM TXpower byrate: 20MHZ power
+ */
+#define EEPROM_TXPOWER_BYRATE 0x006f
+
+/*
+ * EEPROM BBP.
+ */
+#define EEPROM_BBP_START 0x0078
+#define EEPROM_BBP_SIZE 16
+#define EEPROM_BBP_VALUE FIELD16(0x00ff)
+#define EEPROM_BBP_REG_ID FIELD16(0xff00)
+
+/*
+ * MCU mailbox commands.
+ */
+#define MCU_SLEEP 0x30
+#define MCU_WAKEUP 0x31
+#define MCU_RADIO_OFF 0x35
+#define MCU_CURRENT 0x36
+#define MCU_LED 0x50
+#define MCU_LED_STRENGTH 0x51
+#define MCU_LED_1 0x52
+#define MCU_LED_2 0x53
+#define MCU_LED_3 0x54
+#define MCU_RADAR 0x60
+#define MCU_BOOT_SIGNAL 0x72
+#define MCU_BBP_SIGNAL 0x80
+#define MCU_POWER_SAVE 0x83
+
+/*
+ * MCU mailbox tokens
+ */
+#define TOKEN_WAKUP 3
+
+/*
+ * DMA descriptor defines.
+ */
+#define TXD_DESC_SIZE ( 4 * sizeof(__le32) )
+#define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) )
+#define TXWI_DESC_SIZE ( 4 * sizeof(__le32) )
+#define RXD_DESC_SIZE ( 1 * sizeof(__le32) )
+#define RXWI_DESC_SIZE ( 4 * sizeof(__le32) )
+
+/*
+ * TX descriptor format for TX, PRIO and Beacon Ring.
+ */
+
+/*
+ * Word0
+ */
+#define TXD_W0_SD_PTR0 FIELD32(0xffffffff)
+
+/*
+ * Word1
+ */
+#define TXD_W1_SD_LEN1 FIELD32(0x00003fff)
+#define TXD_W1_LAST_SEC1 FIELD32(0x00004000)
+#define TXD_W1_BURST FIELD32(0x00008000)
+#define TXD_W1_SD_LEN0 FIELD32(0x3fff0000)
+#define TXD_W1_LAST_SEC0 FIELD32(0x40000000)
+#define TXD_W1_DMA_DONE FIELD32(0x80000000)
+
+/*
+ * Word2
+ */
+#define TXD_W2_SD_PTR1 FIELD32(0xffffffff)
+
+/*
+ * Word3
+ * WIV: Wireless Info Valid. 1: Driver filled WI, 0: DMA needs to copy WI
+ * QSEL: Select on-chip FIFO ID for 2nd-stage output scheduler.
+ * 0:MGMT, 1:HCCA 2:EDCA
+ */
+#define TXD_W3_WIV FIELD32(0x01000000)
+#define TXD_W3_QSEL FIELD32(0x06000000)
+#define TXD_W3_TCO FIELD32(0x20000000)
+#define TXD_W3_UCO FIELD32(0x40000000)
+#define TXD_W3_ICO FIELD32(0x80000000)
+
+/*
+ * TX Info structure
+ */
+
+/*
+ * Word0
+ * WIV: Wireless Info Valid. 1: Driver filled WI, 0: DMA needs to copy WI
+ * QSEL: Select on-chip FIFO ID for 2nd-stage output scheduler.
+ * 0:MGMT, 1:HCCA 2:EDCA
+ * USB_DMA_NEXT_VALID: Used ONLY in USB bulk Aggregation, NextValid
+ * DMA_TX_BURST: used ONLY in USB bulk Aggregation.
+ * Force USB DMA transmit frame from current selected endpoint
+ */
+#define TXINFO_W0_USB_DMA_TX_PKT_LEN FIELD32(0x0000ffff)
+#define TXINFO_W0_WIV FIELD32(0x01000000)
+#define TXINFO_W0_QSEL FIELD32(0x06000000)
+#define TXINFO_W0_SW_USE_LAST_ROUND FIELD32(0x08000000)
+#define TXINFO_W0_USB_DMA_NEXT_VALID FIELD32(0x40000000)
+#define TXINFO_W0_USB_DMA_TX_BURST FIELD32(0x80000000)
+
+/*
+ * TX WI structure
+ */
+
+/*
+ * Word0
+ * FRAG: 1 To inform TKIP engine this is a fragment.
+ * MIMO_PS: The remote peer is in dynamic MIMO-PS mode
+ * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs
+ * BW: Channel bandwidth 20MHz or 40 MHz
+ * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED
+ */
+#define TXWI_W0_FRAG FIELD32(0x00000001)
+#define TXWI_W0_MIMO_PS FIELD32(0x00000002)
+#define TXWI_W0_CF_ACK FIELD32(0x00000004)
+#define TXWI_W0_TS FIELD32(0x00000008)
+#define TXWI_W0_AMPDU FIELD32(0x00000010)
+#define TXWI_W0_MPDU_DENSITY FIELD32(0x000000e0)
+#define TXWI_W0_TX_OP FIELD32(0x00000300)
+#define TXWI_W0_MCS FIELD32(0x007f0000)
+#define TXWI_W0_BW FIELD32(0x00800000)
+#define TXWI_W0_SHORT_GI FIELD32(0x01000000)
+#define TXWI_W0_STBC FIELD32(0x06000000)
+#define TXWI_W0_IFS FIELD32(0x08000000)
+#define TXWI_W0_PHYMODE FIELD32(0xc0000000)
+
+/*
+ * Word1
+ */
+#define TXWI_W1_ACK FIELD32(0x00000001)
+#define TXWI_W1_NSEQ FIELD32(0x00000002)
+#define TXWI_W1_BW_WIN_SIZE FIELD32(0x000000fc)
+#define TXWI_W1_WIRELESS_CLI_ID FIELD32(0x0000ff00)
+#define TXWI_W1_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000)
+#define TXWI_W1_PACKETID FIELD32(0xf0000000)
+
+/*
+ * Word2
+ */
+#define TXWI_W2_IV FIELD32(0xffffffff)
+
+/*
+ * Word3
+ */
+#define TXWI_W3_EIV FIELD32(0xffffffff)
+
+/*
+ * RX descriptor format for RX Ring.
+ */
+
+/*
+ * Word0
+ * UNICAST_TO_ME: This RX frame is unicast to me.
+ * MULTICAST: This is a multicast frame.
+ * BROADCAST: This is a broadcast frame.
+ * MY_BSS: this frame belongs to the same BSSID.
+ * CRC_ERROR: CRC error.
+ * CIPHER_ERROR: 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid.
+ * AMSDU: rx with 802.3 header, not 802.11 header.
+ */
+
+#define RXD_W0_BA FIELD32(0x00000001)
+#define RXD_W0_DATA FIELD32(0x00000002)
+#define RXD_W0_NULLDATA FIELD32(0x00000004)
+#define RXD_W0_FRAG FIELD32(0x00000008)
+#define RXD_W0_UNICAST_TO_ME FIELD32(0x00000010)
+#define RXD_W0_MULTICAST FIELD32(0x00000020)
+#define RXD_W0_BROADCAST FIELD32(0x00000040)
+#define RXD_W0_MY_BSS FIELD32(0x00000080)
+#define RXD_W0_CRC_ERROR FIELD32(0x00000100)
+#define RXD_W0_CIPHER_ERROR FIELD32(0x00000600)
+#define RXD_W0_AMSDU FIELD32(0x00000800)
+#define RXD_W0_HTC FIELD32(0x00001000)
+#define RXD_W0_RSSI FIELD32(0x00002000)
+#define RXD_W0_L2PAD FIELD32(0x00004000)
+#define RXD_W0_AMPDU FIELD32(0x00008000)
+#define RXD_W0_DECRYPTED FIELD32(0x00010000)
+#define RXD_W0_PLCP_RSSI FIELD32(0x00020000)
+#define RXD_W0_CIPHER_ALG FIELD32(0x00040000)
+#define RXD_W0_LAST_AMSDU FIELD32(0x00080000)
+#define RXD_W0_PLCP_SIGNAL FIELD32(0xfff00000)
+
+/*
+ * RX WI structure
+ */
+
+/*
+ * Word0
+ */
+#define RXWI_W0_WIRELESS_CLI_ID FIELD32(0x000000ff)
+#define RXWI_W0_KEY_INDEX FIELD32(0x00000300)
+#define RXWI_W0_BSSID FIELD32(0x00001c00)
+#define RXWI_W0_UDF FIELD32(0x0000e000)
+#define RXWI_W0_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000)
+#define RXWI_W0_TID FIELD32(0xf0000000)
+
+/*
+ * Word1
+ */
+#define RXWI_W1_FRAG FIELD32(0x0000000f)
+#define RXWI_W1_SEQUENCE FIELD32(0x0000fff0)
+#define RXWI_W1_MCS FIELD32(0x007f0000)
+#define RXWI_W1_BW FIELD32(0x00800000)
+#define RXWI_W1_SHORT_GI FIELD32(0x01000000)
+#define RXWI_W1_STBC FIELD32(0x06000000)
+#define RXWI_W1_PHYMODE FIELD32(0xc0000000)
+
+/*
+ * Word2
+ */
+#define RXWI_W2_RSSI0 FIELD32(0x000000ff)
+#define RXWI_W2_RSSI1 FIELD32(0x0000ff00)
+#define RXWI_W2_RSSI2 FIELD32(0x00ff0000)
+
+/*
+ * Word3
+ */
+#define RXWI_W3_SNR0 FIELD32(0x000000ff)
+#define RXWI_W3_SNR1 FIELD32(0x0000ff00)
+
+/*
+ * Macro's for converting txpower from EEPROM to mac80211 value
+ * and from mac80211 value to register value.
+ */
+#define MIN_G_TXPOWER 0
+#define MIN_A_TXPOWER -7
+#define MAX_G_TXPOWER 31
+#define MAX_A_TXPOWER 15
+#define DEFAULT_TXPOWER 5
+
+#define TXPOWER_G_FROM_DEV(__txpower) \
+ ((__txpower) > MAX_G_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
+
+#define TXPOWER_G_TO_DEV(__txpower) \
+ clamp_t(char, __txpower, MIN_G_TXPOWER, MAX_G_TXPOWER)
+
+#define TXPOWER_A_FROM_DEV(__txpower) \
+ ((__txpower) > MAX_A_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
+
+#define TXPOWER_A_TO_DEV(__txpower) \
+ clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER)
+
+#endif /* RT2800USB_H */
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 84bd6f19acb..a498dde024e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -103,6 +103,15 @@
#define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate))
/*
+ * Determine the alignment requirement,
+ * to make sure the 802.11 payload is padded to a 4-byte boundrary
+ * we must determine the address of the payload and calculate the
+ * amount of bytes needed to move the data.
+ */
+#define ALIGN_SIZE(__skb, __header) \
+ ( ((unsigned long)((__skb)->data + (__header))) & 3 )
+
+/*
* Standard timing and size defines.
* These values should follow the ieee80211 specifications.
*/
@@ -138,6 +147,7 @@ struct rt2x00_chip {
#define RT2561 0x0302
#define RT2661 0x0401
#define RT2571 0x1300
+#define RT2870 0x1600
u16 rf;
u32 rev;
@@ -357,6 +367,7 @@ static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
* for @tx_power_a, @tx_power_bg and @channels.
* @channels: Device/chipset specific channel values (See &struct rf_channel).
* @channels_info: Additional information for channels (See &struct channel_info).
+ * @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap).
*/
struct hw_mode_spec {
unsigned int supported_bands;
@@ -370,6 +381,8 @@ struct hw_mode_spec {
unsigned int num_channels;
const struct rf_channel *channels;
const struct channel_info *channels_info;
+
+ struct ieee80211_sta_ht_cap ht;
};
/*
@@ -404,6 +417,8 @@ struct rt2x00lib_erp {
short pifs;
short difs;
short eifs;
+
+ u16 beacon_int;
};
/*
@@ -590,6 +605,7 @@ enum rt2x00_flags {
DRIVER_REQUIRE_SCHEDULED,
DRIVER_REQUIRE_DMA,
DRIVER_REQUIRE_COPY_IV,
+ DRIVER_REQUIRE_L2PAD,
/*
* Driver features
@@ -606,6 +622,7 @@ enum rt2x00_flags {
CONFIG_EXTERNAL_LNA_BG,
CONFIG_DOUBLE_ANTENNA,
CONFIG_DISABLE_LINK_TUNING,
+ CONFIG_CHANNEL_HT40,
};
/*
@@ -672,6 +689,12 @@ struct rt2x00_dev {
unsigned long flags;
/*
+ * Device information, Bus IRQ and name (PCI, SoC)
+ */
+ int irq;
+ const char *name;
+
+ /*
* Chipset identification.
*/
struct rt2x00_chip chip;
@@ -772,6 +795,18 @@ struct rt2x00_dev {
u8 freq_offset;
/*
+ * Calibration information (for rt2800usb & rt2800pci).
+ * [0] -> BW20
+ * [1] -> BW40
+ */
+ u8 calibration[2];
+
+ /*
+ * Beacon interval.
+ */
+ u16 beacon_int;
+
+ /*
* Low level statistics which will have
* to be kept up to date while device is running.
*/
@@ -860,6 +895,18 @@ static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev,
rt2x00dev->chip.rev = rev;
}
+static inline void rt2x00_set_chip_rt(struct rt2x00_dev *rt2x00dev,
+ const u16 rt)
+{
+ rt2x00dev->chip.rt = rt;
+}
+
+static inline void rt2x00_set_chip_rf(struct rt2x00_dev *rt2x00dev,
+ const u16 rf, const u32 rev)
+{
+ rt2x00_set_chip(rt2x00dev, rt2x00dev->chip.rt, rf, rev);
+}
+
static inline char rt2x00_rt(const struct rt2x00_chip *chipset, const u16 chip)
{
return (chipset->rt == chip);
@@ -875,11 +922,10 @@ static inline u32 rt2x00_rev(const struct rt2x00_chip *chipset)
return chipset->rev;
}
-static inline u16 rt2x00_check_rev(const struct rt2x00_chip *chipset,
- const u32 rev)
+static inline bool rt2x00_check_rev(const struct rt2x00_chip *chipset,
+ const u32 mask, const u32 rev)
{
- return (((chipset->rev & 0xffff0) == rev) &&
- !!(chipset->rev & 0x0000f));
+ return ((chipset->rev & mask) == rev);
}
/**
@@ -925,9 +971,6 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf);
int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed);
-int rt2x00mac_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf);
void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *total_flags,
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 9c2f5517af2..3e019a12df2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -106,6 +106,10 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
}
erp.basic_rates = bss_conf->basic_rates;
+ erp.beacon_int = bss_conf->beacon_int;
+
+ /* Update global beacon interval time, this is needed for PS support */
+ rt2x00dev->beacon_int = bss_conf->beacon_int;
rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp);
}
@@ -173,6 +177,11 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
libconf.conf = conf;
if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) {
+ if (conf_is_ht40(conf))
+ __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
+ else
+ __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
+
memcpy(&libconf.rf,
&rt2x00dev->spec.channels[conf->channel->hw_value],
sizeof(libconf.rf));
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index 0b41845d954..bc4e81e2184 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -33,7 +33,7 @@ enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key)
{
switch (key->alg) {
case ALG_WEP:
- if (key->keylen == LEN_WEP40)
+ if (key->keylen == WLAN_KEY_LEN_WEP40)
return CIPHER_WEP64;
else
return CIPHER_WEP128;
@@ -65,7 +65,8 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
__set_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags);
txdesc->key_idx = hw_key->hw_key_idx;
- txdesc->iv_offset = ieee80211_get_hdrlen_from_skb(entry->skb);
+ txdesc->iv_offset = txdesc->header_length;
+ txdesc->iv_len = hw_key->iv_len;
if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV))
__set_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags);
@@ -103,47 +104,44 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
return overhead;
}
-void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len)
+void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb);
- if (unlikely(!iv_len))
+ if (unlikely(!txdesc->iv_len))
return;
/* Copy IV/EIV data */
- memcpy(skbdesc->iv, skb->data + header_length, iv_len);
+ memcpy(skbdesc->iv, skb->data + txdesc->iv_offset, txdesc->iv_len);
}
-void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len)
+void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb);
- if (unlikely(!iv_len))
+ if (unlikely(!txdesc->iv_len))
return;
/* Copy IV/EIV data */
- memcpy(skbdesc->iv, skb->data + header_length, iv_len);
+ memcpy(skbdesc->iv, skb->data + txdesc->iv_offset, txdesc->iv_len);
/* Move ieee80211 header */
- memmove(skb->data + iv_len, skb->data, header_length);
+ memmove(skb->data + txdesc->iv_len, skb->data, txdesc->iv_offset);
/* Pull buffer to correct size */
- skb_pull(skb, iv_len);
+ skb_pull(skb, txdesc->iv_len);
/* IV/EIV data has officially be stripped */
- skbdesc->flags |= FRAME_DESC_IV_STRIPPED;
+ skbdesc->flags |= SKBDESC_IV_STRIPPED;
}
-void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)
+void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb);
const unsigned int iv_len =
((!!(skbdesc->iv[0])) * 4) + ((!!(skbdesc->iv[1])) * 4);
- if (!(skbdesc->flags & FRAME_DESC_IV_STRIPPED))
+ if (!(skbdesc->flags & SKBDESC_IV_STRIPPED))
return;
skb_push(skb, iv_len);
@@ -155,14 +153,15 @@ void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)
memcpy(skb->data + header_length, skbdesc->iv, iv_len);
/* IV/EIV data has returned into the frame */
- skbdesc->flags &= ~FRAME_DESC_IV_STRIPPED;
+ skbdesc->flags &= ~SKBDESC_IV_STRIPPED;
}
-void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
+void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
unsigned int header_length,
struct rxdone_entry_desc *rxdesc)
{
unsigned int payload_len = rxdesc->size - header_length;
+ unsigned int align = ALIGN_SIZE(skb, header_length);
unsigned int iv_len;
unsigned int icv_len;
unsigned int transfer = 0;
@@ -192,32 +191,48 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
}
/*
- * Make room for new data, note that we increase both
- * headsize and tailsize when required. The tailsize is
- * only needed when ICV data needs to be inserted and
- * the padding is smaller than the ICV data.
- * When alignment requirements is greater than the
- * ICV data we must trim the skb to the correct size
- * because we need to remove the extra bytes.
+ * Make room for new data. There are 2 possibilities
+ * either the alignment is already present between
+ * the 802.11 header and payload. In that case we
+ * we have to move the header less then the iv_len
+ * since we can use the already available l2pad bytes
+ * for the iv data.
+ * When the alignment must be added manually we must
+ * move the header more then iv_len since we must
+ * make room for the payload move as well.
*/
- skb_push(skb, iv_len + align);
- if (align < icv_len)
- skb_put(skb, icv_len - align);
- else if (align > icv_len)
- skb_trim(skb, rxdesc->size + iv_len + icv_len);
+ if (l2pad) {
+ skb_push(skb, iv_len - align);
+ skb_put(skb, icv_len);
- /* Move ieee80211 header */
- memmove(skb->data + transfer,
- skb->data + transfer + iv_len + align,
- header_length);
- transfer += header_length;
+ /* Move ieee80211 header */
+ memmove(skb->data + transfer,
+ skb->data + transfer + (iv_len - align),
+ header_length);
+ transfer += header_length;
+ } else {
+ skb_push(skb, iv_len + align);
+ if (align < icv_len)
+ skb_put(skb, icv_len - align);
+ else if (align > icv_len)
+ skb_trim(skb, rxdesc->size + iv_len + icv_len);
+
+ /* Move ieee80211 header */
+ memmove(skb->data + transfer,
+ skb->data + transfer + iv_len + align,
+ header_length);
+ transfer += header_length;
+ }
/* Copy IV/EIV data */
memcpy(skb->data + transfer, rxdesc->iv, iv_len);
transfer += iv_len;
- /* Move payload */
- if (align) {
+ /*
+ * Move payload for alignment purposes. Note that
+ * this is only needed when no l2 padding is present.
+ */
+ if (!l2pad) {
memmove(skb->data + transfer,
skb->data + transfer + align,
payload_len);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 5752aaae906..57813e72c80 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -227,6 +227,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
+ unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
u8 rate_idx, rate_flags;
/*
@@ -235,13 +236,19 @@ void rt2x00lib_txdone(struct queue_entry *entry,
rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
/*
+ * Remove L2 padding which was added during
+ */
+ if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
+ rt2x00queue_payload_align(entry->skb, true, header_length);
+
+ /*
* If the IV/EIV data was stripped from the frame before it was
* passed to the hardware, we should now reinsert it again because
* mac80211 will expect the the same data to be present it the
* frame as it was passed to us.
*/
if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
- rt2x00crypto_tx_insert_iv(entry->skb);
+ rt2x00crypto_tx_insert_iv(entry->skb, header_length);
/*
* Send frame to debugfs immediately, after this call is completed
@@ -253,7 +260,8 @@ void rt2x00lib_txdone(struct queue_entry *entry,
* Update TX statistics.
*/
rt2x00dev->link.qual.tx_success +=
- test_bit(TXDONE_SUCCESS, &txdesc->flags);
+ test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
+ test_bit(TXDONE_UNKNOWN, &txdesc->flags);
rt2x00dev->link.qual.tx_failed +=
test_bit(TXDONE_FAILURE, &txdesc->flags);
@@ -271,14 +279,16 @@ void rt2x00lib_txdone(struct queue_entry *entry,
tx_info->status.rates[1].idx = -1; /* terminate */
if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
- if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
+ if (test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
+ test_bit(TXDONE_UNKNOWN, &txdesc->flags))
tx_info->flags |= IEEE80211_TX_STAT_ACK;
else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
rt2x00dev->low_level_stats.dot11ACKFailureCount++;
}
if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
- if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
+ if (test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
+ test_bit(TXDONE_UNKNOWN, &txdesc->flags))
rt2x00dev->low_level_stats.dot11RTSSuccessCount++;
else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
rt2x00dev->low_level_stats.dot11RTSFailureCount++;
@@ -316,19 +326,54 @@ void rt2x00lib_txdone(struct queue_entry *entry,
}
EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
+static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
+ struct rxdone_entry_desc *rxdesc)
+{
+ struct ieee80211_supported_band *sband;
+ const struct rt2x00_rate *rate;
+ unsigned int i;
+ int signal;
+ int type;
+
+ /*
+ * For non-HT rates the MCS value needs to contain the
+ * actually used rate modulation (CCK or OFDM).
+ */
+ if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS)
+ signal = RATE_MCS(rxdesc->rate_mode, rxdesc->signal);
+ else
+ signal = rxdesc->signal;
+
+ type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK);
+
+ sband = &rt2x00dev->bands[rt2x00dev->curr_band];
+ for (i = 0; i < sband->n_bitrates; i++) {
+ rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
+
+ if (((type == RXDONE_SIGNAL_PLCP) &&
+ (rate->plcp == signal)) ||
+ ((type == RXDONE_SIGNAL_BITRATE) &&
+ (rate->bitrate == signal)) ||
+ ((type == RXDONE_SIGNAL_MCS) &&
+ (rate->mcs == signal))) {
+ return i;
+ }
+ }
+
+ WARNING(rt2x00dev, "Frame received with unrecognized signal, "
+ "signal=0x%.4x, type=%d.\n", signal, type);
+ return 0;
+}
+
void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry)
{
struct rxdone_entry_desc rxdesc;
struct sk_buff *skb;
struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
- struct ieee80211_supported_band *sband;
- const struct rt2x00_rate *rate;
unsigned int header_length;
- unsigned int align;
- unsigned int i;
- int idx = -1;
-
+ bool l2pad;
+ int rate_idx;
/*
* Allocate a new sk_buffer. If no new buffer available, drop the
* received frame and reuse the existing buffer.
@@ -348,12 +393,15 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
memset(&rxdesc, 0, sizeof(rxdesc));
rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
+ /* Trim buffer to correct size */
+ skb_trim(entry->skb, rxdesc.size);
+
/*
* The data behind the ieee80211 header must be
* aligned on a 4 byte boundary.
*/
header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
- align = ((unsigned long)(entry->skb->data + header_length)) & 3;
+ l2pad = !!(rxdesc.dev_flags & RXDONE_L2PAD);
/*
* Hardware might have stripped the IV/EIV/ICV data,
@@ -362,40 +410,24 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
* in which case we should reinsert the data into the frame.
*/
if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) &&
- (rxdesc.flags & RX_FLAG_IV_STRIPPED)) {
- rt2x00crypto_rx_insert_iv(entry->skb, align,
- header_length, &rxdesc);
- } else if (align) {
- skb_push(entry->skb, align);
- /* Move entire frame in 1 command */
- memmove(entry->skb->data, entry->skb->data + align,
- rxdesc.size);
- }
-
- /* Update data pointers, trim buffer to correct size */
- skb_trim(entry->skb, rxdesc.size);
+ (rxdesc.flags & RX_FLAG_IV_STRIPPED))
+ rt2x00crypto_rx_insert_iv(entry->skb, l2pad, header_length,
+ &rxdesc);
+ else
+ rt2x00queue_payload_align(entry->skb, l2pad, header_length);
/*
- * Update RX statistics.
+ * Check if the frame was received using HT. In that case,
+ * the rate is the MCS index and should be passed to mac80211
+ * directly. Otherwise we need to translate the signal to
+ * the correct bitrate index.
*/
- sband = &rt2x00dev->bands[rt2x00dev->curr_band];
- for (i = 0; i < sband->n_bitrates; i++) {
- rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
-
- if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) &&
- (rate->plcp == rxdesc.signal)) ||
- ((rxdesc.dev_flags & RXDONE_SIGNAL_BITRATE) &&
- (rate->bitrate == rxdesc.signal))) {
- idx = i;
- break;
- }
- }
-
- if (idx < 0) {
- WARNING(rt2x00dev, "Frame received with unrecognized signal,"
- "signal=0x%.2x, type=%d.\n", rxdesc.signal,
- (rxdesc.dev_flags & RXDONE_SIGNAL_MASK));
- idx = 0;
+ if (rxdesc.rate_mode == RATE_MODE_CCK ||
+ rxdesc.rate_mode == RATE_MODE_OFDM) {
+ rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc);
+ } else {
+ rxdesc.flags |= RX_FLAG_HT;
+ rate_idx = rxdesc.signal;
}
/*
@@ -405,7 +437,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
rt2x00debug_update_crypto(rt2x00dev, &rxdesc);
rx_status->mactime = rxdesc.timestamp;
- rx_status->rate_idx = idx;
+ rx_status->rate_idx = rate_idx;
rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi);
rx_status->signal = rxdesc.rssi;
rx_status->noise = rxdesc.noise;
@@ -440,72 +472,84 @@ const struct rt2x00_rate rt2x00_supported_rates[12] = {
.bitrate = 10,
.ratemask = BIT(0),
.plcp = 0x00,
+ .mcs = RATE_MCS(RATE_MODE_CCK, 0),
},
{
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
.bitrate = 20,
.ratemask = BIT(1),
.plcp = 0x01,
+ .mcs = RATE_MCS(RATE_MODE_CCK, 1),
},
{
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
.bitrate = 55,
.ratemask = BIT(2),
.plcp = 0x02,
+ .mcs = RATE_MCS(RATE_MODE_CCK, 2),
},
{
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
.bitrate = 110,
.ratemask = BIT(3),
.plcp = 0x03,
+ .mcs = RATE_MCS(RATE_MODE_CCK, 3),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 60,
.ratemask = BIT(4),
.plcp = 0x0b,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 0),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 90,
.ratemask = BIT(5),
.plcp = 0x0f,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 1),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 120,
.ratemask = BIT(6),
.plcp = 0x0a,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 2),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 180,
.ratemask = BIT(7),
.plcp = 0x0e,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 3),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 240,
.ratemask = BIT(8),
.plcp = 0x09,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 4),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 360,
.ratemask = BIT(9),
.plcp = 0x0d,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 5),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 480,
.ratemask = BIT(10),
.plcp = 0x08,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 6),
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 540,
.ratemask = BIT(11),
.plcp = 0x0c,
+ .mcs = RATE_MCS(RATE_MODE_OFDM, 7),
},
};
@@ -581,6 +625,8 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
rt2x00dev->bands[IEEE80211_BAND_2GHZ].bitrates = rates;
hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&rt2x00dev->bands[IEEE80211_BAND_2GHZ];
+ memcpy(&rt2x00dev->bands[IEEE80211_BAND_2GHZ].ht_cap,
+ &spec->ht, sizeof(spec->ht));
}
/*
@@ -597,6 +643,8 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
rt2x00dev->bands[IEEE80211_BAND_5GHZ].bitrates = &rates[4];
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&rt2x00dev->bands[IEEE80211_BAND_5GHZ];
+ memcpy(&rt2x00dev->bands[IEEE80211_BAND_5GHZ].ht_cap,
+ &spec->ht, sizeof(spec->ht));
}
return 0;
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
new file mode 100644
index 00000000000..e3cec839e54
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
@@ -0,0 +1,69 @@
+/*
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+ <http://rt2x00.serialmonkey.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ Module: rt2x00lib
+ Abstract: rt2x00 HT specific routines.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "rt2x00.h"
+#include "rt2x00lib.h"
+
+void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
+ struct txentry_desc *txdesc,
+ const struct rt2x00_rate *hwrate)
+{
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+ struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
+
+ if (tx_info->control.sta)
+ txdesc->mpdu_density =
+ tx_info->control.sta->ht_cap.ampdu_density;
+ else
+ txdesc->mpdu_density = 0;
+
+ txdesc->ba_size = 7; /* FIXME: What value is needed? */
+ txdesc->stbc = 0; /* FIXME: What value is needed? */
+
+ txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs);
+ if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ txdesc->mcs |= 0x08;
+
+ /*
+ * Convert flags
+ */
+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
+ __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags);
+
+ /*
+ * Determine HT Mix/Greenfield rate mode
+ */
+ if (txrate->flags & IEEE80211_TX_RC_MCS)
+ txdesc->rate_mode = RATE_MODE_HT_MIX;
+ if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
+ txdesc->rate_mode = RATE_MODE_HT_GREENFIELD;
+ if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags);
+ if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
+ __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags);
+}
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index d83e3794d34..0bf2715fa93 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -32,8 +32,8 @@
* Interval defines
* Both the link tuner as the rfkill will be called once per second.
*/
-#define LINK_TUNE_INTERVAL ( round_jiffies_relative(HZ) )
-#define RFKILL_POLL_INTERVAL ( 1000 )
+#define LINK_TUNE_INTERVAL round_jiffies_relative(HZ)
+#define RFKILL_POLL_INTERVAL 1000
/*
* rt2x00_rate: Per rate device information
@@ -48,6 +48,7 @@ struct rt2x00_rate {
unsigned short ratemask;
unsigned short plcp;
+ unsigned short mcs;
};
extern const struct rt2x00_rate rt2x00_supported_rates[12];
@@ -57,6 +58,14 @@ static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value)
return &rt2x00_supported_rates[hw_value & 0xff];
}
+#define RATE_MCS(__mode, __mcs) \
+ ( (((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff) )
+
+static inline int rt2x00_get_rate_mcs(const u16 mcs_value)
+{
+ return (mcs_value & 0x00ff);
+}
+
/*
* Radio control handlers.
*/
@@ -113,6 +122,23 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
/**
+ * rt2x00queue_payload_align - Align 802.11 payload to 4-byte boundary
+ * @skb: The skb to align
+ * @l2pad: Should L2 padding be used
+ * @header_length: Length of 802.11 header
+ *
+ * This function prepares the @skb to be send to the device or mac80211.
+ * If @l2pad is set to true padding will occur between the 802.11 header
+ * and payload. Otherwise the padding will be done in front of the 802.11
+ * header.
+ * When @l2pad is set the function will check for the &SKBDESC_L2_PADDED
+ * flag in &skb_frame_desc. If that flag is set, the padding is removed
+ * and the flag cleared. Otherwise the padding is added and the flag is set.
+ */
+void rt2x00queue_payload_align(struct sk_buff *skb,
+ bool l2pad, unsigned int header_length);
+
+/**
* rt2x00queue_write_tx_frame - Write TX frame to hardware
* @queue: Queue over which the frame should be send
* @skb: The skb to send
@@ -295,10 +321,12 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc);
unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb);
-void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len);
-void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len);
-void rt2x00crypto_tx_insert_iv(struct sk_buff *skb);
-void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
+void rt2x00crypto_tx_copy_iv(struct sk_buff *skb,
+ struct txentry_desc *txdesc);
+void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
+ struct txentry_desc *txdesc);
+void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length);
+void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
unsigned int header_length,
struct rxdone_entry_desc *rxdesc);
#else
@@ -319,21 +347,21 @@ static inline unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev
}
static inline void rt2x00crypto_tx_copy_iv(struct sk_buff *skb,
- unsigned int iv_len)
+ struct txentry_desc *txdesc)
{
}
static inline void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
- unsigned int iv_len)
+ struct txentry_desc *txdesc)
{
}
-static inline void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)
+static inline void rt2x00crypto_tx_insert_iv(struct sk_buff *skb,
+ unsigned int header_length)
{
}
-static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
- unsigned int align,
+static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
unsigned int header_length,
struct rxdone_entry_desc *rxdesc)
{
@@ -341,6 +369,21 @@ static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
#endif /* CONFIG_RT2X00_LIB_CRYPTO */
/*
+ * HT handlers.
+ */
+#ifdef CONFIG_RT2X00_LIB_HT
+void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
+ struct txentry_desc *txdesc,
+ const struct rt2x00_rate *hwrate);
+#else
+static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
+ struct txentry_desc *txdesc,
+ const struct rt2x00_rate *hwrate)
+{
+}
+#endif /* CONFIG_RT2X00_LIB_HT */
+
+/*
* RFkill handlers.
*/
#ifdef CONFIG_RT2X00_LIB_RFKILL
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index 7eb5cd7e5f3..eb9b981b913 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -387,7 +387,7 @@ void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna)
rt2x00link_antenna_reset(rt2x00dev);
}
-void rt2x00link_reset_qual(struct rt2x00_dev *rt2x00dev)
+static void rt2x00link_reset_qual(struct rt2x00_dev *rt2x00dev)
{
struct link_qual *qual = &rt2x00dev->link.qual;
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index c41a0b9e473..c4c06b4e1f0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -390,56 +390,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
}
EXPORT_SYMBOL_GPL(rt2x00mac_config);
-int rt2x00mac_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct rt2x00_dev *rt2x00dev = hw->priv;
- struct rt2x00_intf *intf = vif_to_intf(vif);
- int update_bssid = 0;
- int status = 0;
-
- /*
- * Mac80211 might be calling this function while we are trying
- * to remove the device or perhaps suspending it.
- */
- if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
- return 0;
-
- spin_lock(&intf->lock);
-
- /*
- * conf->bssid can be NULL if coming from the internal
- * beacon update routine.
- */
- if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
- update_bssid = 1;
- memcpy(&intf->bssid, conf->bssid, ETH_ALEN);
- }
-
- spin_unlock(&intf->lock);
-
- /*
- * Call rt2x00_config_intf() outside of the spinlock context since
- * the call will sleep for USB drivers. By using the ieee80211_if_conf
- * values as arguments we make keep access to rt2x00_intf thread safe
- * even without the lock.
- */
- rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
- update_bssid ? conf->bssid : NULL);
-
- /*
- * Update the beacon.
- */
- if (conf->changed & (IEEE80211_IFCC_BEACON |
- IEEE80211_IFCC_BEACON_ENABLED))
- status = rt2x00queue_update_beacon(rt2x00dev, vif,
- conf->enable_beacon);
-
- return status;
-}
-EXPORT_SYMBOL_GPL(rt2x00mac_config_interface);
-
void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *total_flags,
@@ -623,6 +573,44 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
struct rt2x00_dev *rt2x00dev = hw->priv;
struct rt2x00_intf *intf = vif_to_intf(vif);
unsigned int delayed = 0;
+ int update_bssid = 0;
+
+ /*
+ * Mac80211 might be calling this function while we are trying
+ * to remove the device or perhaps suspending it.
+ */
+ if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+ return;
+
+ spin_lock(&intf->lock);
+
+ /*
+ * conf->bssid can be NULL if coming from the internal
+ * beacon update routine.
+ */
+ if (changes & BSS_CHANGED_BSSID) {
+ update_bssid = 1;
+ memcpy(&intf->bssid, bss_conf->bssid, ETH_ALEN);
+ }
+
+ spin_unlock(&intf->lock);
+
+ /*
+ * Call rt2x00_config_intf() outside of the spinlock context since
+ * the call will sleep for USB drivers. By using the ieee80211_if_conf
+ * values as arguments we make keep access to rt2x00_intf thread safe
+ * even without the lock.
+ */
+ if (changes & BSS_CHANGED_BSSID)
+ rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
+ update_bssid ? bss_conf->bssid : NULL);
+
+ /*
+ * Update the beacon.
+ */
+ if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED))
+ rt2x00queue_update_beacon(rt2x00dev, vif,
+ bss_conf->enable_beacon);
/*
* When the association status has changed we must reset the link
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 9730b4f8fd2..cdd5154bd4c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -170,7 +170,6 @@ static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
{
- struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev);
struct data_queue *queue;
int status;
@@ -186,11 +185,11 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
/*
* Register interrupt handler.
*/
- status = request_irq(pci_dev->irq, rt2x00dev->ops->lib->irq_handler,
- IRQF_SHARED, pci_name(pci_dev), rt2x00dev);
+ status = request_irq(rt2x00dev->irq, rt2x00dev->ops->lib->irq_handler,
+ IRQF_SHARED, rt2x00dev->name, rt2x00dev);
if (status) {
ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
- pci_dev->irq, status);
+ rt2x00dev->irq, status);
goto exit;
}
@@ -270,6 +269,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
struct ieee80211_hw *hw;
struct rt2x00_dev *rt2x00dev;
int retval;
+ u16 chip;
retval = pci_request_regions(pci_dev, pci_name(pci_dev));
if (retval) {
@@ -307,6 +307,14 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
rt2x00dev->dev = &pci_dev->dev;
rt2x00dev->ops = ops;
rt2x00dev->hw = hw;
+ rt2x00dev->irq = pci_dev->irq;
+ rt2x00dev->name = pci_name(pci_dev);
+
+ /*
+ * Determine RT chipset by reading PCI header.
+ */
+ pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip);
+ rt2x00_set_chip_rt(rt2x00dev, chip);
retval = rt2x00pci_alloc_reg(rt2x00dev);
if (retval)
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index a5664bd8493..44e5b3279ca 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -148,6 +148,35 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
dev_kfree_skb_any(skb);
}
+void rt2x00queue_payload_align(struct sk_buff *skb,
+ bool l2pad, unsigned int header_length)
+{
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+ unsigned int frame_length = skb->len;
+ unsigned int align = ALIGN_SIZE(skb, header_length);
+
+ if (!align)
+ return;
+
+ if (l2pad) {
+ if (skbdesc->flags & SKBDESC_L2_PADDED) {
+ /* Remove L2 padding */
+ memmove(skb->data + align, skb->data, header_length);
+ skb_pull(skb, align);
+ skbdesc->flags &= ~SKBDESC_L2_PADDED;
+ } else {
+ /* Add L2 padding */
+ skb_push(skb, align);
+ memmove(skb->data, skb->data + align, header_length);
+ skbdesc->flags |= SKBDESC_L2_PADDED;
+ }
+ } else {
+ /* Generic payload alignment to 4-byte boundary */
+ skb_push(skb, align);
+ memmove(skb->data, skb->data + align, frame_length);
+ }
+}
+
static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
@@ -259,6 +288,12 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
txdesc->aifs = entry->queue->aifs;
/*
+ * Header and alignment information.
+ */
+ txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
+ txdesc->l2pad = ALIGN_SIZE(entry->skb, txdesc->header_length);
+
+ /*
* Check whether this frame is to be acked.
*/
if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK))
@@ -326,6 +361,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
* Apply TX descriptor handling by components
*/
rt2x00crypto_create_tx_descriptor(entry, txdesc);
+ rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate);
rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate);
}
@@ -368,7 +404,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
struct txentry_desc txdesc;
struct skb_frame_desc *skbdesc;
- unsigned int iv_len = 0;
u8 rate_idx, rate_flags;
if (unlikely(rt2x00queue_full(queue)))
@@ -390,9 +425,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
entry->skb = skb;
rt2x00queue_create_tx_descriptor(entry, &txdesc);
- if (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)
- iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
-
/*
* All information is retrieved from the skb->cb array,
* now we should claim ownership of the driver part of that
@@ -415,11 +447,15 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags))
- rt2x00crypto_tx_copy_iv(skb, iv_len);
+ rt2x00crypto_tx_copy_iv(skb, &txdesc);
else
- rt2x00crypto_tx_remove_iv(skb, iv_len);
+ rt2x00crypto_tx_remove_iv(skb, &txdesc);
}
+ if (test_bit(DRIVER_REQUIRE_L2PAD, &queue->rt2x00dev->flags))
+ rt2x00queue_payload_align(entry->skb, true,
+ txdesc.header_length);
+
/*
* It could be possible that the queue was corrupted and this
* call failed. Since we always return NETDEV_TX_OK to mac80211,
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 97e2ab08f08..b5e06347c8a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -35,9 +35,12 @@
* for USB devices this restriction does not apply, but the value of
* 2432 makes sense since it is big enough to contain the maximum fragment
* size according to the ieee802.11 specs.
+ * The aggregation size depends on support from the driver, but should
+ * be something around 3840 bytes.
*/
-#define DATA_FRAME_SIZE 2432
-#define MGMT_FRAME_SIZE 256
+#define DATA_FRAME_SIZE 2432
+#define MGMT_FRAME_SIZE 256
+#define AGGREGATION_SIZE 3840
/**
* DOC: Number of entries per queue
@@ -87,13 +90,16 @@ enum data_queue_qid {
*
* @SKBDESC_DMA_MAPPED_RX: &skb_dma field has been mapped for RX
* @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX
- * @FRAME_DESC_IV_STRIPPED: Frame contained a IV/EIV provided by
+ * @SKBDESC_IV_STRIPPED: Frame contained a IV/EIV provided by
* mac80211 but was stripped for processing by the driver.
+ * @SKBDESC_L2_PADDED: Payload has been padded for 4-byte alignment,
+ * the padded bytes are located between header and payload.
*/
enum skb_frame_desc_flags {
SKBDESC_DMA_MAPPED_RX = 1 << 0,
SKBDESC_DMA_MAPPED_TX = 1 << 1,
- FRAME_DESC_IV_STRIPPED = 1 << 2,
+ SKBDESC_IV_STRIPPED = 1 << 2,
+ SKBDESC_L2_PADDED = 1 << 3
};
/**
@@ -145,16 +151,20 @@ static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb)
*
* @RXDONE_SIGNAL_PLCP: Signal field contains the plcp value.
* @RXDONE_SIGNAL_BITRATE: Signal field contains the bitrate value.
+ * @RXDONE_SIGNAL_MCS: Signal field contains the mcs value.
* @RXDONE_MY_BSS: Does this frame originate from device's BSS.
* @RXDONE_CRYPTO_IV: Driver provided IV/EIV data.
* @RXDONE_CRYPTO_ICV: Driver provided ICV data.
+ * @RXDONE_L2PAD: 802.11 payload has been padded to 4-byte boundary.
*/
enum rxdone_entry_desc_flags {
- RXDONE_SIGNAL_PLCP = 1 << 0,
- RXDONE_SIGNAL_BITRATE = 1 << 1,
- RXDONE_MY_BSS = 1 << 2,
- RXDONE_CRYPTO_IV = 1 << 3,
- RXDONE_CRYPTO_ICV = 1 << 4,
+ RXDONE_SIGNAL_PLCP = BIT(0),
+ RXDONE_SIGNAL_BITRATE = BIT(1),
+ RXDONE_SIGNAL_MCS = BIT(2),
+ RXDONE_MY_BSS = BIT(3),
+ RXDONE_CRYPTO_IV = BIT(4),
+ RXDONE_CRYPTO_ICV = BIT(5),
+ RXDONE_L2PAD = BIT(6),
};
/**
@@ -163,7 +173,7 @@ enum rxdone_entry_desc_flags {
* from &rxdone_entry_desc to a signal value type.
*/
#define RXDONE_SIGNAL_MASK \
- ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE )
+ ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE | RXDONE_SIGNAL_MCS )
/**
* struct rxdone_entry_desc: RX Entry descriptor
@@ -177,6 +187,7 @@ enum rxdone_entry_desc_flags {
* @size: Data size of the received frame.
* @flags: MAC80211 receive flags (See &enum mac80211_rx_flags).
* @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags).
+ * @rate_mode: Rate mode (See @enum rate_modulation).
* @cipher: Cipher type used during decryption.
* @cipher_status: Decryption status.
* @iv: IV/EIV data used during decryption.
@@ -190,6 +201,7 @@ struct rxdone_entry_desc {
int size;
int flags;
int dev_flags;
+ u16 rate_mode;
u8 cipher;
u8 cipher_status;
@@ -243,6 +255,9 @@ struct txdone_entry_desc {
* @ENTRY_TXD_ENCRYPT_PAIRWISE: Use pairwise key table (instead of shared).
* @ENTRY_TXD_ENCRYPT_IV: Generate IV/EIV in hardware.
* @ENTRY_TXD_ENCRYPT_MMIC: Generate MIC in hardware.
+ * @ENTRY_TXD_HT_AMPDU: This frame is part of an AMPDU.
+ * @ENTRY_TXD_HT_BW_40: Use 40MHz Bandwidth.
+ * @ENTRY_TXD_HT_SHORT_GI: Use short GI.
*/
enum txentry_desc_flags {
ENTRY_TXD_RTS_FRAME,
@@ -258,6 +273,9 @@ enum txentry_desc_flags {
ENTRY_TXD_ENCRYPT_PAIRWISE,
ENTRY_TXD_ENCRYPT_IV,
ENTRY_TXD_ENCRYPT_MMIC,
+ ENTRY_TXD_HT_AMPDU,
+ ENTRY_TXD_HT_BW_40,
+ ENTRY_TXD_HT_SHORT_GI,
};
/**
@@ -267,11 +285,17 @@ enum txentry_desc_flags {
*
* @flags: Descriptor flags (See &enum queue_entry_flags).
* @queue: Queue identification (See &enum data_queue_qid).
+ * @header_length: Length of 802.11 header.
+ * @l2pad: Amount of padding to align 802.11 payload to 4-byte boundrary.
* @length_high: PLCP length high word.
* @length_low: PLCP length low word.
* @signal: PLCP signal.
* @service: PLCP service.
+ * @msc: MCS.
+ * @stbc: STBC.
+ * @ba_size: BA size.
* @rate_mode: Rate mode (See @enum rate_modulation).
+ * @mpdu_density: MDPU density.
* @retry_limit: Max number of retries.
* @aifs: AIFS value.
* @ifs: IFS value.
@@ -280,18 +304,26 @@ enum txentry_desc_flags {
* @cipher: Cipher type used for encryption.
* @key_idx: Key index used for encryption.
* @iv_offset: Position where IV should be inserted by hardware.
+ * @iv_len: Length of IV data.
*/
struct txentry_desc {
unsigned long flags;
enum data_queue_qid queue;
+ u16 header_length;
+ u16 l2pad;
+
u16 length_high;
u16 length_low;
u16 signal;
u16 service;
+ u16 mcs;
+ u16 stbc;
+ u16 ba_size;
u16 rate_mode;
+ u16 mpdu_density;
short retry_limit;
short aifs;
@@ -302,6 +334,7 @@ struct txentry_desc {
enum cipher cipher;
u16 key_idx;
u16 iv_offset;
+ u16 iv_len;
};
/**
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 2ca8b7a9722..49b29ff90c4 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -603,15 +603,22 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout);
+ rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
!!erp->short_preamble);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
+ rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
+ erp->beacon_int * 16);
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
+
rt2x00pci_register_read(rt2x00dev, MAC_CSR9, &reg);
rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg);
@@ -938,25 +945,6 @@ static void rt61pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
}
-static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_conf *libconf)
-{
- u32 reg;
-
- rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
-
- rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
-
- rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
- libconf->conf->beacon_int * 16);
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
-}
-
static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
{
@@ -968,7 +956,7 @@ static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev,
if (state == STATE_SLEEP) {
rt2x00pci_register_read(rt2x00dev, MAC_CSR11, &reg);
rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
- libconf->conf->beacon_int - 10);
+ rt2x00dev->beacon_int - 10);
rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP,
libconf->conf->listen_interval - 1);
rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5);
@@ -1016,8 +1004,6 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
rt61pci_config_txpower(rt2x00dev, libconf->conf->power_level);
if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
rt61pci_config_retry_limit(rt2x00dev, libconf);
- if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
- rt61pci_config_duration(rt2x00dev, libconf);
if (flags & IEEE80211_CONF_CHANGE_PS)
rt61pci_config_ps(rt2x00dev, libconf);
}
@@ -2308,7 +2294,6 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
u32 reg;
u16 value;
u16 eeprom;
- u16 device;
/*
* Read EEPROM word for configuration.
@@ -2317,14 +2302,10 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Identify RF chipset.
- * To determine the RT chip we have to read the
- * PCI header of the device.
*/
- pci_read_config_word(to_pci_dev(rt2x00dev->dev),
- PCI_CONFIG_HEADER_DEVICE, &device);
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
rt2x00pci_register_read(rt2x00dev, MAC_CSR0, &reg);
- rt2x00_set_chip(rt2x00dev, device, value, reg);
+ rt2x00_set_chip_rf(rt2x00dev, value, reg);
if (!rt2x00_rf(&rt2x00dev->chip, RF5225) &&
!rt2x00_rf(&rt2x00dev->chip, RF5325) &&
@@ -2740,7 +2721,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
- .config_interface = rt2x00mac_config_interface,
.configure_filter = rt2x00mac_configure_filter,
.set_key = rt2x00mac_set_key,
.get_stats = rt2x00mac_get_stats,
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 41e8959919f..6c71f77c816 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -63,12 +63,6 @@
*/
/*
- * PCI Configuration Header
- */
-#define PCI_CONFIG_HEADER_VENDOR 0x0000
-#define PCI_CONFIG_HEADER_DEVICE 0x0002
-
-/*
* HOST_CMD_CSR: For HOST to interrupt embedded processor
*/
#define HOST_CMD_CSR 0x0008
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 853b2b279b6..c18848836f2 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -566,15 +566,22 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout);
+ rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
!!erp->short_preamble);
rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
+ rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
+ erp->beacon_int * 16);
+ rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+
rt2x00usb_register_read(rt2x00dev, MAC_CSR9, &reg);
rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg);
@@ -834,25 +841,6 @@ static void rt73usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
}
-static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_conf *libconf)
-{
- u32 reg;
-
- rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
- rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
-
- rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
- rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
-
- rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
- libconf->conf->beacon_int * 16);
- rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
-}
-
static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
{
@@ -864,7 +852,7 @@ static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
if (state == STATE_SLEEP) {
rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg);
rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
- libconf->conf->beacon_int - 10);
+ rt2x00dev->beacon_int - 10);
rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP,
libconf->conf->listen_interval - 1);
rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5);
@@ -906,8 +894,6 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
rt73usb_config_txpower(rt2x00dev, libconf->conf->power_level);
if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
rt73usb_config_retry_limit(rt2x00dev, libconf);
- if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
- rt73usb_config_duration(rt2x00dev, libconf);
if (flags & IEEE80211_CONF_CHANGE_PS)
rt73usb_config_ps(rt2x00dev, libconf);
}
@@ -1846,7 +1832,8 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
rt2x00_set_chip(rt2x00dev, RT2571, value, reg);
- if (!rt2x00_check_rev(&rt2x00dev->chip, 0x25730)) {
+ if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0x25730) ||
+ rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) {
ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
return -ENODEV;
}
@@ -2259,7 +2246,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
- .config_interface = rt2x00mac_config_interface,
.configure_filter = rt2x00mac_configure_filter,
.set_key = rt2x00mac_set_key,
.get_stats = rt2x00mac_get_stats,
diff --git a/drivers/net/wireless/rtl818x/Makefile b/drivers/net/wireless/rtl818x/Makefile
index c113b3e6904..37e3d4db0c4 100644
--- a/drivers/net/wireless/rtl818x/Makefile
+++ b/drivers/net/wireless/rtl818x/Makefile
@@ -1,5 +1,5 @@
rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
-rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o
+rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o rtl8187_leds.o
obj-$(CONFIG_RTL8180) += rtl8180.o
obj-$(CONFIG_RTL8187) += rtl8187.o
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 387c133ec0f..7e65d7c3180 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -702,30 +702,26 @@ static int rtl8180_config(struct ieee80211_hw *dev, u32 changed)
return 0;
}
-static int rtl8180_config_interface(struct ieee80211_hw *dev,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct rtl8180_priv *priv = dev->priv;
- int i;
-
- for (i = 0; i < ETH_ALEN; i++)
- rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
-
- if (is_valid_ether_addr(conf->bssid))
- rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA);
- else
- rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK);
-
- return 0;
-}
-
static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info,
u32 changed)
{
struct rtl8180_priv *priv = dev->priv;
+ int i;
+
+ if (changed & BSS_CHANGED_BSSID) {
+ for (i = 0; i < ETH_ALEN; i++)
+ rtl818x_iowrite8(priv, &priv->map->BSSID[i],
+ info->bssid[i]);
+
+ if (is_valid_ether_addr(info->bssid))
+ rtl818x_iowrite8(priv, &priv->map->MSR,
+ RTL818X_MSR_INFRA);
+ else
+ rtl818x_iowrite8(priv, &priv->map->MSR,
+ RTL818X_MSR_NO_LINK);
+ }
if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp)
priv->rf->conf_erp(dev, info);
@@ -770,7 +766,6 @@ static const struct ieee80211_ops rtl8180_ops = {
.add_interface = rtl8180_add_interface,
.remove_interface = rtl8180_remove_interface,
.config = rtl8180_config,
- .config_interface = rtl8180_config_interface,
.bss_info_changed = rtl8180_bss_info_changed,
.configure_filter = rtl8180_configure_filter,
};
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h
index edeff82a4d0..c09bfefc70f 100644
--- a/drivers/net/wireless/rtl818x/rtl8187.h
+++ b/drivers/net/wireless/rtl818x/rtl8187.h
@@ -16,6 +16,7 @@
#define RTL8187_H
#include "rtl818x.h"
+#include "rtl8187_leds.h"
#define RTL8187_EEPROM_TXPWR_BASE 0x05
#define RTL8187_EEPROM_MAC_ADDR 0x07
@@ -102,6 +103,12 @@ struct rtl8187_priv {
struct usb_anchor anchored;
struct delayed_work work;
struct ieee80211_hw *dev;
+#ifdef CONFIG_RTL8187_LEDS
+ struct rtl8187_led led_tx;
+ struct rtl8187_led led_rx;
+ struct delayed_work led_on;
+ struct delayed_work led_off;
+#endif
u16 txpwr_base;
u8 asic_rev;
u8 is_rtl8187b;
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index d51ba0a88c2..294250e294d 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -29,6 +29,9 @@
#include "rtl8187.h"
#include "rtl8187_rtl8225.h"
+#ifdef CONFIG_RTL8187_LEDS
+#include "rtl8187_leds.h"
+#endif
MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
@@ -320,12 +323,7 @@ static void rtl8187_rx_cb(struct urb *urb)
unsigned long f;
spin_lock_irqsave(&priv->rx_queue.lock, f);
- if (skb->next)
- __skb_unlink(skb, &priv->rx_queue);
- else {
- spin_unlock_irqrestore(&priv->rx_queue.lock, f);
- return;
- }
+ __skb_unlink(skb, &priv->rx_queue);
spin_unlock_irqrestore(&priv->rx_queue.lock, f);
skb_put(skb, urb->actual_length);
@@ -736,10 +734,10 @@ static const u8 rtl8187b_reg_table[][3] = {
{0x85, 0x24, 0}, {0x88, 0x54, 0}, {0x8B, 0xB8, 0}, {0x8C, 0x07, 0},
{0x8D, 0x00, 0}, {0x94, 0x1B, 0}, {0x95, 0x12, 0}, {0x96, 0x00, 0},
{0x97, 0x06, 0}, {0x9D, 0x1A, 0}, {0x9F, 0x10, 0}, {0xB4, 0x22, 0},
- {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x91, 0x03, 0},
+ {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x4C, 0x00, 2},
- {0x4C, 0x00, 2}, {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0},
- {0x8E, 0x08, 0}, {0x8F, 0x00, 0}
+ {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0}, {0x8E, 0x08, 0},
+ {0x8F, 0x00, 0}
};
static int rtl8187b_init_hw(struct ieee80211_hw *dev)
@@ -1089,32 +1087,6 @@ static int rtl8187_config(struct ieee80211_hw *dev, u32 changed)
return 0;
}
-static int rtl8187_config_interface(struct ieee80211_hw *dev,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct rtl8187_priv *priv = dev->priv;
- int i;
- u8 reg;
-
- mutex_lock(&priv->conf_mutex);
- for (i = 0; i < ETH_ALEN; i++)
- rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
-
- if (is_valid_ether_addr(conf->bssid)) {
- reg = RTL818X_MSR_INFRA;
- if (priv->is_rtl8187b)
- reg |= RTL818X_MSR_ENEDCA;
- rtl818x_iowrite8(priv, &priv->map->MSR, reg);
- } else {
- reg = RTL818X_MSR_NO_LINK;
- rtl818x_iowrite8(priv, &priv->map->MSR, reg);
- }
-
- mutex_unlock(&priv->conf_mutex);
- return 0;
-}
-
/*
* With 8187B, AC_*_PARAM clashes with FEMR definition in struct rtl818x_csr for
* example. Thus we have to use raw values for AC_*_PARAM register addresses.
@@ -1192,6 +1164,27 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
u32 changed)
{
struct rtl8187_priv *priv = dev->priv;
+ int i;
+ u8 reg;
+
+ if (changed & BSS_CHANGED_BSSID) {
+ mutex_lock(&priv->conf_mutex);
+ for (i = 0; i < ETH_ALEN; i++)
+ rtl818x_iowrite8(priv, &priv->map->BSSID[i],
+ info->bssid[i]);
+
+ if (is_valid_ether_addr(info->bssid)) {
+ reg = RTL818X_MSR_INFRA;
+ if (priv->is_rtl8187b)
+ reg |= RTL818X_MSR_ENEDCA;
+ rtl818x_iowrite8(priv, &priv->map->MSR, reg);
+ } else {
+ reg = RTL818X_MSR_NO_LINK;
+ rtl818x_iowrite8(priv, &priv->map->MSR, reg);
+ }
+
+ mutex_unlock(&priv->conf_mutex);
+ }
if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE))
rtl8187_conf_erp(priv, info->use_short_slot,
@@ -1273,7 +1266,6 @@ static const struct ieee80211_ops rtl8187_ops = {
.add_interface = rtl8187_add_interface,
.remove_interface = rtl8187_remove_interface,
.config = rtl8187_config,
- .config_interface = rtl8187_config_interface,
.bss_info_changed = rtl8187_bss_info_changed,
.configure_filter = rtl8187_configure_filter,
.conf_tx = rtl8187_conf_tx
@@ -1480,9 +1472,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
(*channel++).hw_value = txpwr >> 8;
}
- if (priv->is_rtl8187b)
- printk(KERN_WARNING "rtl8187: 8187B chip detected.\n");
-
/*
* XXX: Once this driver supports anything that requires
* beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ.
@@ -1514,6 +1503,12 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
wiphy_name(dev->wiphy), dev->wiphy->perm_addr,
chip_name, priv->asic_rev, priv->rf->name);
+#ifdef CONFIG_RTL8187_LEDS
+ eeprom_93cx6_read(&eeprom, 0x3F, &reg);
+ reg &= 0xFF;
+ rtl8187_leds_init(dev, reg);
+#endif
+
return 0;
err_free_dmabuf:
@@ -1533,6 +1528,9 @@ static void __devexit rtl8187_disconnect(struct usb_interface *intf)
if (!dev)
return;
+#ifdef CONFIG_RTL8187_LEDS
+ rtl8187_leds_exit(dev);
+#endif
ieee80211_unregister_hw(dev);
priv = dev->priv;
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c
new file mode 100644
index 00000000000..b4425359224
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c
@@ -0,0 +1,218 @@
+/*
+ * Linux LED driver for RTL8187
+ *
+ * Copyright 2009 Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ * Based on the LED handling in the r8187 driver, which is:
+ * Copyright (c) Realtek Semiconductor Corp. All rights reserved.
+ *
+ * Thanks to Realtek for their support!
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifdef CONFIG_RTL8187_LEDS
+
+#include <net/mac80211.h>
+#include <linux/usb.h>
+#include <linux/eeprom_93cx6.h>
+
+#include "rtl8187.h"
+#include "rtl8187_leds.h"
+
+static void led_turn_on(struct work_struct *work)
+{
+ /* As this routine does read/write operations on the hardware, it must
+ * be run from a work queue.
+ */
+ u8 reg;
+ struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
+ led_on.work);
+ struct rtl8187_led *led = &priv->led_tx;
+
+ /* Don't change the LED, when the device is down. */
+ if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+ return ;
+
+ /* Skip if the LED is not registered. */
+ if (!led->dev)
+ return;
+ mutex_lock(&priv->conf_mutex);
+ switch (led->ledpin) {
+ case LED_PIN_GPIO0:
+ rtl818x_iowrite8(priv, &priv->map->GPIO, 0x01);
+ rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x00);
+ break;
+ case LED_PIN_LED0:
+ reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 4);
+ rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
+ break;
+ case LED_PIN_LED1:
+ reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 5);
+ rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
+ break;
+ case LED_PIN_HW:
+ default:
+ break;
+ }
+ mutex_unlock(&priv->conf_mutex);
+}
+
+static void led_turn_off(struct work_struct *work)
+{
+ /* As this routine does read/write operations on the hardware, it must
+ * be run from a work queue.
+ */
+ u8 reg;
+ struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
+ led_off.work);
+ struct rtl8187_led *led = &priv->led_tx;
+
+ /* Don't change the LED, when the device is down. */
+ if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+ return ;
+
+ /* Skip if the LED is not registered. */
+ if (!led->dev)
+ return;
+ mutex_lock(&priv->conf_mutex);
+ switch (led->ledpin) {
+ case LED_PIN_GPIO0:
+ rtl818x_iowrite8(priv, &priv->map->GPIO, 0x01);
+ rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x01);
+ break;
+ case LED_PIN_LED0:
+ reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 4);
+ rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
+ break;
+ case LED_PIN_LED1:
+ reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 5);
+ rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
+ break;
+ case LED_PIN_HW:
+ default:
+ break;
+ }
+ mutex_unlock(&priv->conf_mutex);
+}
+
+/* Callback from the LED subsystem. */
+static void rtl8187_led_brightness_set(struct led_classdev *led_dev,
+ enum led_brightness brightness)
+{
+ struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led,
+ led_dev);
+ struct ieee80211_hw *hw = led->dev;
+ struct rtl8187_priv *priv = hw->priv;
+
+ if (brightness == LED_OFF) {
+ queue_delayed_work(hw->workqueue, &priv->led_off, 0);
+ /* The LED is off for 1/20 sec so that it just blinks. */
+ queue_delayed_work(hw->workqueue, &priv->led_on, HZ / 20);
+ } else
+ queue_delayed_work(hw->workqueue, &priv->led_on, 0);
+}
+
+static int rtl8187_register_led(struct ieee80211_hw *dev,
+ struct rtl8187_led *led, const char *name,
+ const char *default_trigger, u8 ledpin)
+{
+ int err;
+ struct rtl8187_priv *priv = dev->priv;
+
+ if (led->dev)
+ return -EEXIST;
+ if (!default_trigger)
+ return -EINVAL;
+ led->dev = dev;
+ led->ledpin = ledpin;
+ strncpy(led->name, name, sizeof(led->name));
+
+ led->led_dev.name = led->name;
+ led->led_dev.default_trigger = default_trigger;
+ led->led_dev.brightness_set = rtl8187_led_brightness_set;
+
+ err = led_classdev_register(&priv->udev->dev, &led->led_dev);
+ if (err) {
+ printk(KERN_INFO "LEDs: Failed to register %s\n", name);
+ led->dev = NULL;
+ return err;
+ }
+ return 0;
+}
+
+static void rtl8187_unregister_led(struct rtl8187_led *led)
+{
+ led_classdev_unregister(&led->led_dev);
+ led->dev = NULL;
+}
+
+void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid)
+{
+ struct rtl8187_priv *priv = dev->priv;
+ char name[RTL8187_LED_MAX_NAME_LEN + 1];
+ u8 ledpin;
+ int err;
+
+ /* According to the vendor driver, the LED operation depends on the
+ * customer ID encoded in the EEPROM
+ */
+ printk(KERN_INFO "rtl8187: Customer ID is 0x%02X\n", custid);
+ switch (custid) {
+ case EEPROM_CID_RSVD0:
+ case EEPROM_CID_RSVD1:
+ case EEPROM_CID_SERCOMM_PS:
+ case EEPROM_CID_QMI:
+ case EEPROM_CID_DELL:
+ case EEPROM_CID_TOSHIBA:
+ ledpin = LED_PIN_GPIO0;
+ break;
+ case EEPROM_CID_ALPHA0:
+ ledpin = LED_PIN_LED0;
+ break;
+ case EEPROM_CID_HW:
+ ledpin = LED_PIN_HW;
+ break;
+ default:
+ ledpin = LED_PIN_GPIO0;
+ }
+
+ INIT_DELAYED_WORK(&priv->led_on, led_turn_on);
+ INIT_DELAYED_WORK(&priv->led_off, led_turn_off);
+
+ snprintf(name, sizeof(name),
+ "rtl8187-%s::tx", wiphy_name(dev->wiphy));
+ err = rtl8187_register_led(dev, &priv->led_tx, name,
+ ieee80211_get_tx_led_name(dev), ledpin);
+ if (err)
+ goto error;
+ snprintf(name, sizeof(name),
+ "rtl8187-%s::rx", wiphy_name(dev->wiphy));
+ err = rtl8187_register_led(dev, &priv->led_rx, name,
+ ieee80211_get_rx_led_name(dev), ledpin);
+ if (!err) {
+ queue_delayed_work(dev->workqueue, &priv->led_on, 0);
+ return;
+ }
+ /* registration of RX LED failed - unregister TX */
+ rtl8187_unregister_led(&priv->led_tx);
+error:
+ /* If registration of either failed, cancel delayed work */
+ cancel_delayed_work_sync(&priv->led_off);
+ cancel_delayed_work_sync(&priv->led_on);
+}
+
+void rtl8187_leds_exit(struct ieee80211_hw *dev)
+{
+ struct rtl8187_priv *priv = dev->priv;
+
+ rtl8187_unregister_led(&priv->led_tx);
+ /* turn the LED off before exiting */
+ queue_delayed_work(dev->workqueue, &priv->led_off, 0);
+ cancel_delayed_work_sync(&priv->led_off);
+ rtl8187_unregister_led(&priv->led_rx);
+}
+#endif /* def CONFIG_RTL8187_LED */
+
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.h b/drivers/net/wireless/rtl818x/rtl8187_leds.h
new file mode 100644
index 00000000000..a0332027aea
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187_leds.h
@@ -0,0 +1,57 @@
+/*
+ * Definitions for RTL8187 leds
+ *
+ * Copyright 2009 Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ * Based on the LED handling in the r8187 driver, which is:
+ * Copyright (c) Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef RTL8187_LED_H
+#define RTL8187_LED_H
+
+#ifdef CONFIG_RTL8187_LEDS
+
+#define RTL8187_LED_MAX_NAME_LEN 21
+
+#include <linux/leds.h>
+#include <linux/types.h>
+
+enum {
+ LED_PIN_LED0,
+ LED_PIN_LED1,
+ LED_PIN_GPIO0,
+ LED_PIN_HW
+};
+
+enum {
+ EEPROM_CID_RSVD0 = 0x00,
+ EEPROM_CID_RSVD1 = 0xFF,
+ EEPROM_CID_ALPHA0 = 0x01,
+ EEPROM_CID_SERCOMM_PS = 0x02,
+ EEPROM_CID_HW = 0x03,
+ EEPROM_CID_TOSHIBA = 0x04,
+ EEPROM_CID_QMI = 0x07,
+ EEPROM_CID_DELL = 0x08
+};
+
+struct rtl8187_led {
+ struct ieee80211_hw *dev;
+ /* The LED class device */
+ struct led_classdev led_dev;
+ /* The pin/method used to control the led */
+ u8 ledpin;
+ /* The unique name string for this LED device. */
+ char name[RTL8187_LED_MAX_NAME_LEN + 1];
+};
+
+void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code);
+void rtl8187_leds_exit(struct ieee80211_hw *dev);
+
+#endif /* def CONFIG_RTL8187_LED */
+
+#endif /* RTL8187_LED_H */
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index f9520463269..38366a56b71 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -1540,7 +1540,7 @@ static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
if (!netif_running(dev)) {
printk(KERN_ERR "%s: xmit call when iface is down\n",
dev->name);
- return (1);
+ return NETDEV_TX_BUSY;
}
netif_stop_queue(dev);
@@ -2509,7 +2509,7 @@ static void strip_dev_setup(struct net_device *dev)
* netdev_priv(dev) Already holds a pointer to our struct strip
*/
- *(MetricomAddress *) & dev->broadcast = broadcast_address;
+ *(MetricomAddress *)dev->broadcast = broadcast_address;
dev->dev_addr[0] = 0;
dev->addr_len = sizeof(MetricomAddress);
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index 3ab3eb95718..ab7fc5c0c8b 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -2867,12 +2867,8 @@ static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev)
spin_unlock_irqrestore(&lp->spinlock, flags);
/* Check that we can continue */
if (lp->tx_n_in_use == (NTXBLOCKS - 1))
- return 1;
+ return NETDEV_TX_BUSY;
}
-#ifdef DEBUG_TX_ERROR
- if (skb->next)
- printk(KERN_INFO "skb has next\n");
-#endif
/* Do we need some padding? */
/* Note : on wireless the propagation time is in the order of 1us,
@@ -2884,10 +2880,10 @@ static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev)
skb_copy_from_linear_data(skb, data, skb->len);
/* Write packet on the card */
if(wv_packet_write(dev, data, ETH_ZLEN))
- return 1; /* We failed */
+ return NETDEV_TX_BUSY; /* We failed */
}
else if(wv_packet_write(dev, skb->data, skb->len))
- return 1; /* We failed */
+ return NETDEV_TX_BUSY; /* We failed */
dev_kfree_skb(skb);
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index fa2821be44c..6af706408ac 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -3107,11 +3107,6 @@ wavelan_packet_xmit(struct sk_buff * skb,
* so the Tx buffer is now free */
}
-#ifdef DEBUG_TX_ERROR
- if (skb->next)
- printk(KERN_INFO "skb has next\n");
-#endif
-
/* Check if we need some padding */
/* Note : on wireless the propagation time is in the order of 1us,
* and we don't have the Ethernet specific requirement of beeing
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
new file mode 100644
index 00000000000..a82c4cd436d
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -0,0 +1,11 @@
+config WL12XX
+ tristate "TI wl1251/wl1271 support"
+ depends on MAC80211 && WLAN_80211 && SPI_MASTER && GENERIC_HARDIRQS && EXPERIMENTAL
+ select FW_LOADER
+ select CRC7
+ ---help---
+ This module adds support for wireless adapters based on
+ TI wl1251/wl1271 chipsets.
+
+ If you choose to build a module, it'll be called wl12xx. Say N if
+ unsure.
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
new file mode 100644
index 00000000000..d43de27dc54
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -0,0 +1,4 @@
+wl12xx-objs = main.o spi.o event.o tx.o rx.o \
+ ps.o cmd.o acx.o boot.o init.o wl1251.o \
+ debugfs.o
+obj-$(CONFIG_WL12XX) += wl12xx.o
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
new file mode 100644
index 00000000000..1cfd458ad5a
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -0,0 +1,689 @@
+#include "acx.h"
+
+#include <linux/module.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+
+#include "wl12xx.h"
+#include "wl12xx_80211.h"
+#include "reg.h"
+#include "spi.h"
+#include "ps.h"
+
+int wl12xx_acx_frame_rates(struct wl12xx *wl, u8 ctrl_rate, u8 ctrl_mod,
+ u8 mgt_rate, u8 mgt_mod)
+{
+ int ret;
+ struct acx_fw_gen_frame_rates rates;
+
+ wl12xx_debug(DEBUG_ACX, "acx frame rates");
+
+ rates.header.id = ACX_FW_GEN_FRAME_RATES;
+ rates.header.len = sizeof(struct acx_fw_gen_frame_rates) -
+ sizeof(struct acx_header);
+
+ rates.tx_ctrl_frame_rate = ctrl_rate;
+ rates.tx_ctrl_frame_mod = ctrl_mod;
+ rates.tx_mgt_frame_rate = mgt_rate;
+ rates.tx_mgt_frame_mod = mgt_mod;
+
+ ret = wl12xx_cmd_configure(wl, &rates, sizeof(rates));
+ if (ret < 0) {
+ wl12xx_error("Failed to set FW rates and modulation");
+ return ret;
+ }
+
+ return 0;
+}
+
+
+int wl12xx_acx_station_id(struct wl12xx *wl)
+{
+ int ret, i;
+ struct dot11_station_id mac;
+
+ wl12xx_debug(DEBUG_ACX, "acx dot11_station_id");
+
+ mac.header.id = DOT11_STATION_ID;
+ mac.header.len = sizeof(mac) - sizeof(struct acx_header);
+
+ for (i = 0; i < ETH_ALEN; i++)
+ mac.mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
+
+ ret = wl12xx_cmd_configure(wl, &mac, sizeof(mac));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_acx_default_key(struct wl12xx *wl, u8 key_id)
+{
+ struct acx_dot11_default_key default_key;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
+
+ default_key.header.id = DOT11_DEFAULT_KEY;
+ default_key.header.len = sizeof(default_key) -
+ sizeof(struct acx_header);
+
+ default_key.id = key_id;
+
+ ret = wl12xx_cmd_configure(wl, &default_key, sizeof(default_key));
+ if (ret < 0) {
+ wl12xx_error("Couldnt set default key");
+ return ret;
+ }
+
+ wl->default_key = key_id;
+
+ return 0;
+}
+
+int wl12xx_acx_wake_up_conditions(struct wl12xx *wl, u8 listen_interval)
+{
+ struct acx_wake_up_condition wake_up;
+
+ wl12xx_debug(DEBUG_ACX, "acx wake up conditions");
+
+ wake_up.header.id = ACX_WAKE_UP_CONDITIONS;
+ wake_up.header.len = sizeof(wake_up) - sizeof(struct acx_header);
+
+ wake_up.wake_up_event = WAKE_UP_EVENT_DTIM_BITMAP;
+ wake_up.listen_interval = listen_interval;
+
+ return wl12xx_cmd_configure(wl, &wake_up, sizeof(wake_up));
+}
+
+int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth)
+{
+ int ret;
+ struct acx_sleep_auth auth;
+
+ wl12xx_debug(DEBUG_ACX, "acx sleep auth");
+
+ auth.header.id = ACX_SLEEP_AUTH;
+ auth.header.len = sizeof(auth) - sizeof(struct acx_header);
+
+ auth.sleep_auth = sleep_auth;
+
+ ret = wl12xx_cmd_configure(wl, &auth, sizeof(auth));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len)
+{
+ struct wl12xx_command cmd;
+ struct acx_revision *rev;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx fw rev");
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ ret = wl12xx_cmd_interrogate(wl, ACX_FW_REV, sizeof(*rev), &cmd);
+ if (ret < 0) {
+ wl12xx_warning("ACX_FW_REV interrogate failed");
+ return ret;
+ }
+
+ rev = (struct acx_revision *) &cmd.parameters;
+
+ /* be careful with the buffer sizes */
+ strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
+
+ /*
+ * if the firmware version string is exactly
+ * sizeof(rev->fw_version) long or fw_len is less than
+ * sizeof(rev->fw_version) it won't be null terminated
+ */
+ buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
+
+ return 0;
+}
+
+int wl12xx_acx_tx_power(struct wl12xx *wl, int power)
+{
+ struct acx_current_tx_power ie;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
+
+ if (power < 0 || power > 25)
+ return -EINVAL;
+
+ memset(&ie, 0, sizeof(ie));
+
+ ie.header.id = DOT11_CUR_TX_PWR;
+ ie.header.len = sizeof(ie) - sizeof(struct acx_header);
+ ie.current_tx_power = power * 10;
+
+ ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
+ if (ret < 0) {
+ wl12xx_warning("configure of tx power failed: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_feature_cfg(struct wl12xx *wl)
+{
+ struct acx_feature_config feature;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx feature cfg");
+
+ memset(&feature, 0, sizeof(feature));
+
+ feature.header.id = ACX_FEATURE_CFG;
+ feature.header.len = sizeof(feature) - sizeof(struct acx_header);
+
+ /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
+ feature.data_flow_options = 0;
+ feature.options = 0;
+
+ ret = wl12xx_cmd_configure(wl, &feature, sizeof(feature));
+ if (ret < 0)
+ wl12xx_error("Couldnt set HW encryption");
+
+ return ret;
+}
+
+int wl12xx_acx_mem_map(struct wl12xx *wl, void *mem_map, size_t len)
+{
+ struct wl12xx_command cmd;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx mem map");
+
+ ret = wl12xx_cmd_interrogate(wl, ACX_MEM_MAP, len, &cmd);
+ if (ret < 0)
+ return ret;
+ else if (cmd.status != CMD_STATUS_SUCCESS)
+ return -EIO;
+
+ memcpy(mem_map, &cmd.parameters, len);
+
+ return 0;
+}
+
+int wl12xx_acx_data_path_params(struct wl12xx *wl,
+ struct acx_data_path_params_resp *data_path)
+{
+ struct acx_data_path_params params;
+ struct wl12xx_command cmd;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx data path params");
+
+ params.rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
+ params.tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
+
+ params.rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
+ params.tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
+
+ params.tx_complete_threshold = 1;
+
+ params.tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
+
+ params.tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
+
+ params.header.id = ACX_DATA_PATH_PARAMS;
+ params.header.len = sizeof(params) - sizeof(struct acx_header);
+
+ ret = wl12xx_cmd_configure(wl, &params, sizeof(params));
+ if (ret < 0)
+ return ret;
+
+
+ ret = wl12xx_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
+ sizeof(struct acx_data_path_params_resp),
+ &cmd);
+
+ if (ret < 0) {
+ wl12xx_warning("failed to read data path parameters: %d", ret);
+ return ret;
+ } else if (cmd.status != CMD_STATUS_SUCCESS) {
+ wl12xx_warning("data path parameter acx status failed");
+ return -EIO;
+ }
+
+ memcpy(data_path, &cmd.parameters, sizeof(*data_path));
+
+ return 0;
+}
+
+int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time)
+{
+ struct rx_msdu_lifetime msdu_lifetime;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx rx msdu life time");
+
+ msdu_lifetime.header.id = DOT11_RX_MSDU_LIFE_TIME;
+ msdu_lifetime.header.len = sizeof(msdu_lifetime) -
+ sizeof(struct acx_header);
+ msdu_lifetime.lifetime = life_time;
+
+ ret = wl12xx_cmd_configure(wl, &msdu_lifetime, sizeof(msdu_lifetime));
+ if (ret < 0) {
+ wl12xx_warning("failed to set rx msdu life time: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_rx_config(struct wl12xx *wl, u32 config, u32 filter)
+{
+ struct acx_rx_config rx_config;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx rx config");
+
+ rx_config.header.id = ACX_RX_CFG;
+ rx_config.header.len = sizeof(rx_config) - sizeof(struct acx_header);
+ rx_config.config_options = config;
+ rx_config.filter_options = filter;
+
+ ret = wl12xx_cmd_configure(wl, &rx_config, sizeof(rx_config));
+ if (ret < 0) {
+ wl12xx_warning("failed to set rx config: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_pd_threshold(struct wl12xx *wl)
+{
+ struct acx_packet_detection packet_detection;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx data pd threshold");
+
+ /* FIXME: threshold value not set */
+ packet_detection.header.id = ACX_PD_THRESHOLD;
+ packet_detection.header.len = sizeof(packet_detection) -
+ sizeof(struct acx_header);
+
+ ret = wl12xx_cmd_configure(wl, &packet_detection,
+ sizeof(packet_detection));
+ if (ret < 0) {
+ wl12xx_warning("failed to set pd threshold: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_slot(struct wl12xx *wl, enum acx_slot_type slot_time)
+{
+ struct acx_slot slot;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx slot");
+
+ slot.header.id = ACX_SLOT;
+ slot.header.len = sizeof(slot) - sizeof(struct acx_header);
+
+ slot.wone_index = STATION_WONE_INDEX;
+ slot.slot_time = slot_time;
+
+ ret = wl12xx_cmd_configure(wl, &slot, sizeof(slot));
+ if (ret < 0) {
+ wl12xx_warning("failed to set slot time: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_group_address_tbl(struct wl12xx *wl)
+{
+ struct multicast_grp_addr_start multicast;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx group address tbl");
+
+ /* MAC filtering */
+ multicast.header.id = DOT11_GROUP_ADDRESS_TBL;
+ multicast.header.len = sizeof(multicast) - sizeof(struct acx_header);
+
+ multicast.enabled = 0;
+ multicast.num_groups = 0;
+ memset(multicast.mac_table, 0, ADDRESS_GROUP_MAX_LEN);
+
+ ret = wl12xx_cmd_configure(wl, &multicast, sizeof(multicast));
+ if (ret < 0) {
+ wl12xx_warning("failed to set group addr table: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_service_period_timeout(struct wl12xx *wl)
+{
+ struct acx_rx_timeout rx_timeout;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx service period timeout");
+
+ /* RX timeout */
+ rx_timeout.header.id = ACX_SERVICE_PERIOD_TIMEOUT;
+ rx_timeout.header.len = sizeof(rx_timeout) - sizeof(struct acx_header);
+
+ rx_timeout.ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
+ rx_timeout.upsd_timeout = RX_TIMEOUT_UPSD_DEF;
+
+ ret = wl12xx_cmd_configure(wl, &rx_timeout, sizeof(rx_timeout));
+ if (ret < 0) {
+ wl12xx_warning("failed to set service period timeout: %d",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_rts_threshold(struct wl12xx *wl, u16 rts_threshold)
+{
+ struct acx_rts_threshold rts;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx rts threshold");
+
+ rts.header.id = DOT11_RTS_THRESHOLD;
+ rts.header.len = sizeof(rts) - sizeof(struct acx_header);
+
+ rts.threshold = rts_threshold;
+
+ ret = wl12xx_cmd_configure(wl, &rts, sizeof(rts));
+ if (ret < 0) {
+ wl12xx_warning("failed to set rts threshold: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_beacon_filter_opt(struct wl12xx *wl)
+{
+ struct acx_beacon_filter_option beacon_filter;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx beacon filter opt");
+
+ beacon_filter.header.id = ACX_BEACON_FILTER_OPT;
+ beacon_filter.header.len = sizeof(beacon_filter) -
+ sizeof(struct acx_header);
+
+ beacon_filter.enable = 0;
+ beacon_filter.max_num_beacons = 0;
+
+ ret = wl12xx_cmd_configure(wl, &beacon_filter, sizeof(beacon_filter));
+ if (ret < 0) {
+ wl12xx_warning("failed to set beacon filter opt: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_beacon_filter_table(struct wl12xx *wl)
+{
+ struct acx_beacon_filter_ie_table ie_table;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx beacon filter table");
+
+ ie_table.header.id = ACX_BEACON_FILTER_TABLE;
+ ie_table.header.len = sizeof(ie_table) - sizeof(struct acx_header);
+
+ ie_table.num_ie = 0;
+ memset(ie_table.table, 0, BEACON_FILTER_TABLE_MAX_SIZE);
+
+ ret = wl12xx_cmd_configure(wl, &ie_table, sizeof(ie_table));
+ if (ret < 0) {
+ wl12xx_warning("failed to set beacon filter table: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_sg_enable(struct wl12xx *wl)
+{
+ struct acx_bt_wlan_coex pta;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx sg enable");
+
+ pta.header.id = ACX_SG_ENABLE;
+ pta.header.len = sizeof(pta) - sizeof(struct acx_header);
+
+ pta.enable = SG_ENABLE;
+
+ ret = wl12xx_cmd_configure(wl, &pta, sizeof(pta));
+ if (ret < 0) {
+ wl12xx_warning("failed to set softgemini enable: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_sg_cfg(struct wl12xx *wl)
+{
+ struct acx_bt_wlan_coex_param param;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx sg cfg");
+
+ /* BT-WLAN coext parameters */
+ param.header.id = ACX_SG_CFG;
+ param.header.len = sizeof(param) - sizeof(struct acx_header);
+
+ param.min_rate = RATE_INDEX_24MBPS;
+ param.bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
+ param.wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
+ param.sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
+ param.rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
+ param.tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
+ param.rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
+ param.tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
+ param.wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
+ param.bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
+ param.next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
+ param.wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
+ param.hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
+ param.next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
+ param.antenna_type = PTA_ANTENNA_TYPE_DEF;
+ param.signal_type = PTA_SIGNALING_TYPE_DEF;
+ param.afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
+ param.quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
+ param.max_cts = PTA_MAX_NUM_CTS_DEF;
+ param.wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
+ param.bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
+ param.missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
+ param.wlan_elp_hp = PTA_ELP_HP_DEF;
+ param.bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
+ param.ack_mode_dual_ant = PTA_ACK_MODE_DEF;
+ param.pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
+ param.pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
+ param.bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
+
+ ret = wl12xx_cmd_configure(wl, &param, sizeof(param));
+ if (ret < 0) {
+ wl12xx_warning("failed to set sg config: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_cca_threshold(struct wl12xx *wl)
+{
+ struct acx_energy_detection detection;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx cca threshold");
+
+ detection.header.id = ACX_CCA_THRESHOLD;
+ detection.header.len = sizeof(detection) - sizeof(struct acx_header);
+
+ detection.rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
+ detection.tx_energy_detection = 0;
+
+ ret = wl12xx_cmd_configure(wl, &detection, sizeof(detection));
+ if (ret < 0) {
+ wl12xx_warning("failed to set cca threshold: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_bcn_dtim_options(struct wl12xx *wl)
+{
+ struct acx_beacon_broadcast bb;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx bcn dtim options");
+
+ bb.header.id = ACX_BCN_DTIM_OPTIONS;
+ bb.header.len = sizeof(bb) - sizeof(struct acx_header);
+
+ bb.beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
+ bb.broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
+ bb.rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
+ bb.ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
+
+ ret = wl12xx_cmd_configure(wl, &bb, sizeof(bb));
+ if (ret < 0) {
+ wl12xx_warning("failed to set rx config: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_aid(struct wl12xx *wl, u16 aid)
+{
+ struct acx_aid acx_aid;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx aid");
+
+ acx_aid.header.id = ACX_AID;
+ acx_aid.header.len = sizeof(acx_aid) - sizeof(struct acx_header);
+
+ acx_aid.aid = aid;
+
+ ret = wl12xx_cmd_configure(wl, &acx_aid, sizeof(acx_aid));
+ if (ret < 0) {
+ wl12xx_warning("failed to set aid: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_event_mbox_mask(struct wl12xx *wl, u32 event_mask)
+{
+ struct acx_event_mask mask;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx event mbox mask");
+
+ mask.header.id = ACX_EVENT_MBOX_MASK;
+ mask.header.len = sizeof(mask) - sizeof(struct acx_header);
+
+ /* high event mask is unused */
+ mask.high_event_mask = 0xffffffff;
+
+ mask.event_mask = event_mask;
+
+ ret = wl12xx_cmd_configure(wl, &mask, sizeof(mask));
+ if (ret < 0) {
+ wl12xx_warning("failed to set aid: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble)
+{
+ struct acx_preamble ie;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx_set_preamble");
+
+ memset(&ie, 0, sizeof(ie));
+
+ ie.header.id = ACX_PREAMBLE_TYPE;
+ ie.header.len = sizeof(ie) - sizeof(struct acx_header);
+ ie.preamble = preamble;
+ ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
+ if (ret < 0) {
+ wl12xx_warning("Setting of preamble failed: %d", ret);
+ return ret;
+ }
+ return 0;
+}
+
+int wl12xx_acx_cts_protect(struct wl12xx *wl,
+ enum acx_ctsprotect_type ctsprotect)
+{
+ struct acx_ctsprotect ie;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx_set_ctsprotect");
+
+ memset(&ie, 0, sizeof(ie));
+
+ ie.header.id = ACX_CTS_PROTECTION;
+ ie.header.len = sizeof(ie) - sizeof(struct acx_header);
+ ie.ctsprotect = ctsprotect;
+ ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
+ if (ret < 0) {
+ wl12xx_warning("Setting of ctsprotect failed: %d", ret);
+ return ret;
+ }
+ return 0;
+}
+
+int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats)
+{
+ struct wl12xx_command *answer;
+ int ret;
+
+ wl12xx_debug(DEBUG_ACX, "acx statistics");
+
+ answer = kmalloc(sizeof(*answer), GFP_KERNEL);
+ if (!answer) {
+ wl12xx_warning("could not allocate memory for acx statistics");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = wl12xx_cmd_interrogate(wl, ACX_STATISTICS, sizeof(*answer),
+ answer);
+ if (ret < 0) {
+ wl12xx_warning("acx statistics failed: %d", ret);
+ goto out;
+ }
+
+ memcpy(stats, answer->parameters, sizeof(*stats));
+
+out:
+ kfree(answer);
+ return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
new file mode 100644
index 00000000000..fb2d2340993
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -0,0 +1,1245 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_ACX_H__
+#define __WL12XX_ACX_H__
+
+#include "wl12xx.h"
+
+/* Target's information element */
+struct acx_header {
+ u16 id;
+ u16 len;
+};
+
+struct acx_error_counter {
+ struct acx_header header;
+
+ /* The number of PLCP errors since the last time this */
+ /* information element was interrogated. This field is */
+ /* automatically cleared when it is interrogated.*/
+ u32 PLCP_error;
+
+ /* The number of FCS errors since the last time this */
+ /* information element was interrogated. This field is */
+ /* automatically cleared when it is interrogated.*/
+ u32 FCS_error;
+
+ /* The number of MPDUs without PLCP header errors received*/
+ /* since the last time this information element was interrogated. */
+ /* This field is automatically cleared when it is interrogated.*/
+ u32 valid_frame;
+
+ /* the number of missed sequence numbers in the squentially */
+ /* values of frames seq numbers */
+ u32 seq_num_miss;
+} __attribute__ ((packed));
+
+struct acx_revision {
+ struct acx_header header;
+
+ /*
+ * The WiLink firmware version, an ASCII string x.x.x.x,
+ * that uniquely identifies the current firmware.
+ * The left most digit is incremented each time a
+ * significant change is made to the firmware, such as
+ * code redesign or new platform support.
+ * The second digit is incremented when major enhancements
+ * are added or major fixes are made.
+ * The third digit is incremented for each GA release.
+ * The fourth digit is incremented for each build.
+ * The first two digits identify a firmware release version,
+ * in other words, a unique set of features.
+ * The first three digits identify a GA release.
+ */
+ char fw_version[20];
+
+ /*
+ * This 4 byte field specifies the WiLink hardware version.
+ * bits 0 - 15: Reserved.
+ * bits 16 - 23: Version ID - The WiLink version ID
+ * (1 = first spin, 2 = second spin, and so on).
+ * bits 24 - 31: Chip ID - The WiLink chip ID.
+ */
+ u32 hw_version;
+} __attribute__ ((packed));
+
+enum wl12xx_psm_mode {
+ /* Active mode */
+ WL12XX_PSM_CAM = 0,
+
+ /* Power save mode */
+ WL12XX_PSM_PS = 1,
+
+ /* Extreme low power */
+ WL12XX_PSM_ELP = 2,
+};
+
+struct acx_sleep_auth {
+ struct acx_header header;
+
+ /* The sleep level authorization of the device. */
+ /* 0 - Always active*/
+ /* 1 - Power down mode: light / fast sleep*/
+ /* 2 - ELP mode: Deep / Max sleep*/
+ u8 sleep_auth;
+ u8 padding[3];
+} __attribute__ ((packed));
+
+#define TIM_ELE_ID 5
+#define PARTIAL_VBM_MAX 251
+
+struct tim {
+ u8 identity;
+ u8 length;
+ u8 dtim_count;
+ u8 dtim_period;
+ u8 bitmap_ctrl;
+ u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */
+} __attribute__ ((packed));
+
+/* Virtual Bit Map update */
+struct vbm_update_request {
+ __le16 len;
+ u8 padding[2];
+ struct tim tim;
+} __attribute__ ((packed));
+
+enum {
+ HOSTIF_PCI_MASTER_HOST_INDIRECT,
+ HOSTIF_PCI_MASTER_HOST_DIRECT,
+ HOSTIF_SLAVE,
+ HOSTIF_PKT_RING,
+ HOSTIF_DONTCARE = 0xFF
+};
+
+#define DEFAULT_UCAST_PRIORITY 0
+#define DEFAULT_RX_Q_PRIORITY 0
+#define DEFAULT_NUM_STATIONS 1
+#define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */
+#define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */
+#define TRACE_BUFFER_MAX_SIZE 256
+
+#define DP_RX_PACKET_RING_CHUNK_SIZE 1600
+#define DP_TX_PACKET_RING_CHUNK_SIZE 1600
+#define DP_RX_PACKET_RING_CHUNK_NUM 2
+#define DP_TX_PACKET_RING_CHUNK_NUM 2
+#define DP_TX_COMPLETE_TIME_OUT 20
+#define FW_TX_CMPLT_BLOCK_SIZE 16
+
+struct acx_data_path_params {
+ struct acx_header header;
+
+ u16 rx_packet_ring_chunk_size;
+ u16 tx_packet_ring_chunk_size;
+
+ u8 rx_packet_ring_chunk_num;
+ u8 tx_packet_ring_chunk_num;
+
+ /*
+ * Maximum number of packets that can be gathered
+ * in the TX complete ring before an interrupt
+ * is generated.
+ */
+ u8 tx_complete_threshold;
+
+ /* Number of pending TX complete entries in cyclic ring.*/
+ u8 tx_complete_ring_depth;
+
+ /*
+ * Max num microseconds since a packet enters the TX
+ * complete ring until an interrupt is generated.
+ */
+ u32 tx_complete_timeout;
+} __attribute__ ((packed));
+
+
+struct acx_data_path_params_resp {
+ struct acx_header header;
+
+ u16 rx_packet_ring_chunk_size;
+ u16 tx_packet_ring_chunk_size;
+
+ u8 rx_packet_ring_chunk_num;
+ u8 tx_packet_ring_chunk_num;
+
+ u8 pad[2];
+
+ u32 rx_packet_ring_addr;
+ u32 tx_packet_ring_addr;
+
+ u32 rx_control_addr;
+ u32 tx_control_addr;
+
+ u32 tx_complete_addr;
+} __attribute__ ((packed));
+
+#define TX_MSDU_LIFETIME_MIN 0
+#define TX_MSDU_LIFETIME_MAX 3000
+#define TX_MSDU_LIFETIME_DEF 512
+#define RX_MSDU_LIFETIME_MIN 0
+#define RX_MSDU_LIFETIME_MAX 0xFFFFFFFF
+#define RX_MSDU_LIFETIME_DEF 512000
+
+struct rx_msdu_lifetime {
+ struct acx_header header;
+
+ /*
+ * The maximum amount of time, in TU, before the
+ * firmware discards the MSDU.
+ */
+ u32 lifetime;
+} __attribute__ ((packed));
+
+/*
+ * RX Config Options Table
+ * Bit Definition
+ * === ==========
+ * 31:14 Reserved
+ * 13 Copy RX Status - when set, write three receive status words
+ * to top of rx'd MPDUs.
+ * When cleared, do not write three status words (added rev 1.5)
+ * 12 Reserved
+ * 11 RX Complete upon FCS error - when set, give rx complete
+ * interrupt for FCS errors, after the rx filtering, e.g. unicast
+ * frames not to us with FCS error will not generate an interrupt.
+ * 10 SSID Filter Enable - When set, the WiLink discards all beacon,
+ * probe request, and probe response frames with an SSID that does
+ * not match the SSID specified by the host in the START/JOIN
+ * command.
+ * When clear, the WiLink receives frames with any SSID.
+ * 9 Broadcast Filter Enable - When set, the WiLink discards all
+ * broadcast frames. When clear, the WiLink receives all received
+ * broadcast frames.
+ * 8:6 Reserved
+ * 5 BSSID Filter Enable - When set, the WiLink discards any frames
+ * with a BSSID that does not match the BSSID specified by the
+ * host.
+ * When clear, the WiLink receives frames from any BSSID.
+ * 4 MAC Addr Filter - When set, the WiLink discards any frames
+ * with a destination address that does not match the MAC address
+ * of the adaptor.
+ * When clear, the WiLink receives frames destined to any MAC
+ * address.
+ * 3 Promiscuous - When set, the WiLink receives all valid frames
+ * (i.e., all frames that pass the FCS check).
+ * When clear, only frames that pass the other filters specified
+ * are received.
+ * 2 FCS - When set, the WiLink includes the FCS with the received
+ * frame.
+ * When cleared, the FCS is discarded.
+ * 1 PLCP header - When set, write all data from baseband to frame
+ * buffer including PHY header.
+ * 0 Reserved - Always equal to 0.
+ *
+ * RX Filter Options Table
+ * Bit Definition
+ * === ==========
+ * 31:12 Reserved - Always equal to 0.
+ * 11 Association - When set, the WiLink receives all association
+ * related frames (association request/response, reassocation
+ * request/response, and disassociation). When clear, these frames
+ * are discarded.
+ * 10 Auth/De auth - When set, the WiLink receives all authentication
+ * and de-authentication frames. When clear, these frames are
+ * discarded.
+ * 9 Beacon - When set, the WiLink receives all beacon frames.
+ * When clear, these frames are discarded.
+ * 8 Contention Free - When set, the WiLink receives all contention
+ * free frames.
+ * When clear, these frames are discarded.
+ * 7 Control - When set, the WiLink receives all control frames.
+ * When clear, these frames are discarded.
+ * 6 Data - When set, the WiLink receives all data frames.
+ * When clear, these frames are discarded.
+ * 5 FCS Error - When set, the WiLink receives frames that have FCS
+ * errors.
+ * When clear, these frames are discarded.
+ * 4 Management - When set, the WiLink receives all management
+ * frames.
+ * When clear, these frames are discarded.
+ * 3 Probe Request - When set, the WiLink receives all probe request
+ * frames.
+ * When clear, these frames are discarded.
+ * 2 Probe Response - When set, the WiLink receives all probe
+ * response frames.
+ * When clear, these frames are discarded.
+ * 1 RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK
+ * frames.
+ * When clear, these frames are discarded.
+ * 0 Rsvd Type/Sub Type - When set, the WiLink receives all frames
+ * that have reserved frame types and sub types as defined by the
+ * 802.11 specification.
+ * When clear, these frames are discarded.
+ */
+struct acx_rx_config {
+ struct acx_header header;
+
+ u32 config_options;
+ u32 filter_options;
+} __attribute__ ((packed));
+
+enum {
+ QOS_AC_BE = 0,
+ QOS_AC_BK,
+ QOS_AC_VI,
+ QOS_AC_VO,
+ QOS_HIGHEST_AC_INDEX = QOS_AC_VO,
+};
+
+#define MAX_NUM_OF_AC (QOS_HIGHEST_AC_INDEX+1)
+#define FIRST_AC_INDEX QOS_AC_BE
+#define MAX_NUM_OF_802_1d_TAGS 8
+#define AC_PARAMS_MAX_TSID 15
+#define MAX_APSD_CONF 0xffff
+
+#define QOS_TX_HIGH_MIN (0)
+#define QOS_TX_HIGH_MAX (100)
+
+#define QOS_TX_HIGH_BK_DEF (25)
+#define QOS_TX_HIGH_BE_DEF (35)
+#define QOS_TX_HIGH_VI_DEF (35)
+#define QOS_TX_HIGH_VO_DEF (35)
+
+#define QOS_TX_LOW_BK_DEF (15)
+#define QOS_TX_LOW_BE_DEF (25)
+#define QOS_TX_LOW_VI_DEF (25)
+#define QOS_TX_LOW_VO_DEF (25)
+
+struct acx_tx_queue_qos_config {
+ struct acx_header header;
+
+ u8 qid;
+ u8 pad[3];
+
+ /* Max number of blocks allowd in the queue */
+ u16 high_threshold;
+
+ /* Lowest memory blocks guaranteed for this queue */
+ u16 low_threshold;
+} __attribute__ ((packed));
+
+struct acx_packet_detection {
+ struct acx_header header;
+
+ u32 threshold;
+} __attribute__ ((packed));
+
+
+enum acx_slot_type {
+ SLOT_TIME_LONG = 0,
+ SLOT_TIME_SHORT = 1,
+ DEFAULT_SLOT_TIME = SLOT_TIME_SHORT,
+ MAX_SLOT_TIMES = 0xFF
+};
+
+#define STATION_WONE_INDEX 0
+
+struct acx_slot {
+ struct acx_header header;
+
+ u8 wone_index; /* Reserved */
+ u8 slot_time;
+ u8 reserved[6];
+} __attribute__ ((packed));
+
+
+#define ADDRESS_GROUP_MAX (8)
+#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ADDRESS_GROUP_MAX)
+
+struct multicast_grp_addr_start {
+ struct acx_header header;
+
+ u8 enabled;
+ u8 num_groups;
+ u8 pad[2];
+ u8 mac_table[ADDRESS_GROUP_MAX_LEN];
+} __attribute__ ((packed));
+
+
+#define RX_TIMEOUT_PS_POLL_MIN 0
+#define RX_TIMEOUT_PS_POLL_MAX (200000)
+#define RX_TIMEOUT_PS_POLL_DEF (15)
+#define RX_TIMEOUT_UPSD_MIN 0
+#define RX_TIMEOUT_UPSD_MAX (200000)
+#define RX_TIMEOUT_UPSD_DEF (15)
+
+struct acx_rx_timeout {
+ struct acx_header header;
+
+ /*
+ * The longest time the STA will wait to receive
+ * traffic from the AP after a PS-poll has been
+ * transmitted.
+ */
+ u16 ps_poll_timeout;
+
+ /*
+ * The longest time the STA will wait to receive
+ * traffic from the AP after a frame has been sent
+ * from an UPSD enabled queue.
+ */
+ u16 upsd_timeout;
+} __attribute__ ((packed));
+
+#define RTS_THRESHOLD_MIN 0
+#define RTS_THRESHOLD_MAX 4096
+#define RTS_THRESHOLD_DEF 2347
+
+struct acx_rts_threshold {
+ struct acx_header header;
+
+ u16 threshold;
+ u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_beacon_filter_option {
+ struct acx_header header;
+
+ u8 enable;
+
+ /*
+ * The number of beacons without the unicast TIM
+ * bit set that the firmware buffers before
+ * signaling the host about ready frames.
+ * When set to 0 and the filter is enabled, beacons
+ * without the unicast TIM bit set are dropped.
+ */
+ u8 max_num_beacons;
+ u8 pad[2];
+} __attribute__ ((packed));
+
+/*
+ * ACXBeaconFilterEntry (not 221)
+ * Byte Offset Size (Bytes) Definition
+ * =========== ============ ==========
+ * 0 1 IE identifier
+ * 1 1 Treatment bit mask
+ *
+ * ACXBeaconFilterEntry (221)
+ * Byte Offset Size (Bytes) Definition
+ * =========== ============ ==========
+ * 0 1 IE identifier
+ * 1 1 Treatment bit mask
+ * 2 3 OUI
+ * 5 1 Type
+ * 6 2 Version
+ *
+ *
+ * Treatment bit mask - The information element handling:
+ * bit 0 - The information element is compared and transferred
+ * in case of change.
+ * bit 1 - The information element is transferred to the host
+ * with each appearance or disappearance.
+ * Note that both bits can be set at the same time.
+ */
+#define BEACON_FILTER_TABLE_MAX_IE_NUM (32)
+#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6)
+#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE (2)
+#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6)
+#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \
+ BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \
+ (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \
+ BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE))
+
+struct acx_beacon_filter_ie_table {
+ struct acx_header header;
+
+ u8 num_ie;
+ u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
+ u8 pad[3];
+} __attribute__ ((packed));
+
+enum {
+ SG_ENABLE = 0,
+ SG_DISABLE,
+ SG_SENSE_NO_ACTIVITY,
+ SG_SENSE_ACTIVE
+};
+
+struct acx_bt_wlan_coex {
+ struct acx_header header;
+
+ /*
+ * 0 -> PTA enabled
+ * 1 -> PTA disabled
+ * 2 -> sense no active mode, i.e.
+ * an interrupt is sent upon
+ * BT activity.
+ * 3 -> PTA is switched on in response
+ * to the interrupt sending.
+ */
+ u8 enable;
+ u8 pad[3];
+} __attribute__ ((packed));
+
+#define PTA_ANTENNA_TYPE_DEF (0)
+#define PTA_BT_HP_MAXTIME_DEF (2000)
+#define PTA_WLAN_HP_MAX_TIME_DEF (5000)
+#define PTA_SENSE_DISABLE_TIMER_DEF (1350)
+#define PTA_PROTECTIVE_RX_TIME_DEF (1500)
+#define PTA_PROTECTIVE_TX_TIME_DEF (1500)
+#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000)
+#define PTA_SIGNALING_TYPE_DEF (1)
+#define PTA_AFH_LEVERAGE_ON_DEF (0)
+#define PTA_NUMBER_QUIET_CYCLE_DEF (0)
+#define PTA_MAX_NUM_CTS_DEF (3)
+#define PTA_NUMBER_OF_WLAN_PACKETS_DEF (2)
+#define PTA_NUMBER_OF_BT_PACKETS_DEF (2)
+#define PTA_PROTECTIVE_RX_TIME_FAST_DEF (1500)
+#define PTA_PROTECTIVE_TX_TIME_FAST_DEF (3000)
+#define PTA_CYCLE_TIME_FAST_DEF (8700)
+#define PTA_RX_FOR_AVALANCHE_DEF (5)
+#define PTA_ELP_HP_DEF (0)
+#define PTA_ANTI_STARVE_PERIOD_DEF (500)
+#define PTA_ANTI_STARVE_NUM_CYCLE_DEF (4)
+#define PTA_ALLOW_PA_SD_DEF (1)
+#define PTA_TIME_BEFORE_BEACON_DEF (6300)
+#define PTA_HPDM_MAX_TIME_DEF (1600)
+#define PTA_TIME_OUT_NEXT_WLAN_DEF (2550)
+#define PTA_AUTO_MODE_NO_CTS_DEF (0)
+#define PTA_BT_HP_RESPECTED_DEF (3)
+#define PTA_WLAN_RX_MIN_RATE_DEF (24)
+#define PTA_ACK_MODE_DEF (1)
+
+struct acx_bt_wlan_coex_param {
+ struct acx_header header;
+
+ /*
+ * The minimum rate of a received WLAN packet in the STA,
+ * during protective mode, of which a new BT-HP request
+ * during this Rx will always be respected and gain the antenna.
+ */
+ u32 min_rate;
+
+ /* Max time the BT HP will be respected. */
+ u16 bt_hp_max_time;
+
+ /* Max time the WLAN HP will be respected. */
+ u16 wlan_hp_max_time;
+
+ /*
+ * The time between the last BT activity
+ * and the moment when the sense mode returns
+ * to SENSE_INACTIVE.
+ */
+ u16 sense_disable_timer;
+
+ /* Time before the next BT HP instance */
+ u16 rx_time_bt_hp;
+ u16 tx_time_bt_hp;
+
+ /* range: 10-20000 default: 1500 */
+ u16 rx_time_bt_hp_fast;
+ u16 tx_time_bt_hp_fast;
+
+ /* range: 2000-65535 default: 8700 */
+ u16 wlan_cycle_fast;
+
+ /* range: 0 - 15000 (Msec) default: 1000 */
+ u16 bt_anti_starvation_period;
+
+ /* range 400-10000(Usec) default: 3000 */
+ u16 next_bt_lp_packet;
+
+ /* Deafult: worst case for BT DH5 traffic */
+ u16 wake_up_beacon;
+
+ /* range: 0-50000(Usec) default: 1050 */
+ u16 hp_dm_max_guard_time;
+
+ /*
+ * This is to prevent both BT & WLAN antenna
+ * starvation.
+ * Range: 100-50000(Usec) default:2550
+ */
+ u16 next_wlan_packet;
+
+ /* 0 -> shared antenna */
+ u8 antenna_type;
+
+ /*
+ * 0 -> TI legacy
+ * 1 -> Palau
+ */
+ u8 signal_type;
+
+ /*
+ * BT AFH status
+ * 0 -> no AFH
+ * 1 -> from dedicated GPIO
+ * 2 -> AFH on (from host)
+ */
+ u8 afh_leverage_on;
+
+ /*
+ * The number of cycles during which no
+ * TX will be sent after 1 cycle of RX
+ * transaction in protective mode
+ */
+ u8 quiet_cycle_num;
+
+ /*
+ * The maximum number of CTSs that will
+ * be sent for receiving RX packet in
+ * protective mode
+ */
+ u8 max_cts;
+
+ /*
+ * The number of WLAN packets
+ * transferred in common mode before
+ * switching to BT.
+ */
+ u8 wlan_packets_num;
+
+ /*
+ * The number of BT packets
+ * transferred in common mode before
+ * switching to WLAN.
+ */
+ u8 bt_packets_num;
+
+ /* range: 1-255 default: 5 */
+ u8 missed_rx_avalanche;
+
+ /* range: 0-1 default: 1 */
+ u8 wlan_elp_hp;
+
+ /* range: 0 - 15 default: 4 */
+ u8 bt_anti_starvation_cycles;
+
+ u8 ack_mode_dual_ant;
+
+ /*
+ * Allow PA_SD assertion/de-assertion
+ * during enabled BT activity.
+ */
+ u8 pa_sd_enable;
+
+ /*
+ * Enable/Disable PTA in auto mode:
+ * Support Both Active & P.S modes
+ */
+ u8 pta_auto_mode_enable;
+
+ /* range: 0 - 20 default: 1 */
+ u8 bt_hp_respected_num;
+} __attribute__ ((packed));
+
+#define CCA_THRSH_ENABLE_ENERGY_D 0x140A
+#define CCA_THRSH_DISABLE_ENERGY_D 0xFFEF
+
+struct acx_energy_detection {
+ struct acx_header header;
+
+ /* The RX Clear Channel Assessment threshold in the PHY */
+ u16 rx_cca_threshold;
+ u8 tx_energy_detection;
+ u8 pad;
+} __attribute__ ((packed));
+
+#define BCN_RX_TIMEOUT_DEF_VALUE 10000
+#define BROADCAST_RX_TIMEOUT_DEF_VALUE 20000
+#define RX_BROADCAST_IN_PS_DEF_VALUE 1
+#define CONSECUTIVE_PS_POLL_FAILURE_DEF 4
+
+struct acx_beacon_broadcast {
+ struct acx_header header;
+
+ u16 beacon_rx_timeout;
+ u16 broadcast_timeout;
+
+ /* Enables receiving of broadcast packets in PS mode */
+ u8 rx_broadcast_in_ps;
+
+ /* Consecutive PS Poll failures before updating the host */
+ u8 ps_poll_threshold;
+ u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_event_mask {
+ struct acx_header header;
+
+ u32 event_mask;
+ u32 high_event_mask; /* Unused */
+} __attribute__ ((packed));
+
+#define CFG_RX_FCS BIT(2)
+#define CFG_RX_ALL_GOOD BIT(3)
+#define CFG_UNI_FILTER_EN BIT(4)
+#define CFG_BSSID_FILTER_EN BIT(5)
+#define CFG_MC_FILTER_EN BIT(6)
+#define CFG_MC_ADDR0_EN BIT(7)
+#define CFG_MC_ADDR1_EN BIT(8)
+#define CFG_BC_REJECT_EN BIT(9)
+#define CFG_SSID_FILTER_EN BIT(10)
+#define CFG_RX_INT_FCS_ERROR BIT(11)
+#define CFG_RX_INT_ENCRYPTED BIT(12)
+#define CFG_RX_WR_RX_STATUS BIT(13)
+#define CFG_RX_FILTER_NULTI BIT(14)
+#define CFG_RX_RESERVE BIT(15)
+#define CFG_RX_TIMESTAMP_TSF BIT(16)
+
+#define CFG_RX_RSV_EN BIT(0)
+#define CFG_RX_RCTS_ACK BIT(1)
+#define CFG_RX_PRSP_EN BIT(2)
+#define CFG_RX_PREQ_EN BIT(3)
+#define CFG_RX_MGMT_EN BIT(4)
+#define CFG_RX_FCS_ERROR BIT(5)
+#define CFG_RX_DATA_EN BIT(6)
+#define CFG_RX_CTL_EN BIT(7)
+#define CFG_RX_CF_EN BIT(8)
+#define CFG_RX_BCN_EN BIT(9)
+#define CFG_RX_AUTH_EN BIT(10)
+#define CFG_RX_ASSOC_EN BIT(11)
+
+#define SCAN_PASSIVE BIT(0)
+#define SCAN_5GHZ_BAND BIT(1)
+#define SCAN_TRIGGERED BIT(2)
+#define SCAN_PRIORITY_HIGH BIT(3)
+
+struct acx_fw_gen_frame_rates {
+ struct acx_header header;
+
+ u8 tx_ctrl_frame_rate; /* RATE_* */
+ u8 tx_ctrl_frame_mod; /* CCK_* or PBCC_* */
+ u8 tx_mgt_frame_rate;
+ u8 tx_mgt_frame_mod;
+} __attribute__ ((packed));
+
+/* STA MAC */
+struct dot11_station_id {
+ struct acx_header header;
+
+ u8 mac[ETH_ALEN];
+ u8 pad[2];
+} __attribute__ ((packed));
+
+/* HW encryption keys */
+#define NUM_ACCESS_CATEGORIES_COPY 4
+#define MAX_KEY_SIZE 32
+
+/* When set, disable HW encryption */
+#define DF_ENCRYPTION_DISABLE 0x01
+/* When set, disable HW decryption */
+#define DF_SNIFF_MODE_ENABLE 0x80
+
+struct acx_feature_config {
+ struct acx_header header;
+
+ u32 options;
+ u32 data_flow_options;
+} __attribute__ ((packed));
+
+enum acx_key_action {
+ KEY_ADD_OR_REPLACE = 1,
+ KEY_REMOVE = 2,
+ KEY_SET_ID = 3,
+ MAX_KEY_ACTION = 0xffff,
+};
+
+enum acx_key_type {
+ KEY_WEP_DEFAULT = 0,
+ KEY_WEP_ADDR = 1,
+ KEY_AES_GROUP = 4,
+ KEY_AES_PAIRWISE = 5,
+ KEY_WEP_GROUP = 6,
+ KEY_TKIP_MIC_GROUP = 10,
+ KEY_TKIP_MIC_PAIRWISE = 11,
+};
+
+/*
+ *
+ * key_type_e key size key format
+ * ---------- --------- ----------
+ * 0x00 5, 13, 29 Key data
+ * 0x01 5, 13, 29 Key data
+ * 0x04 16 16 bytes of key data
+ * 0x05 16 16 bytes of key data
+ * 0x0a 32 16 bytes of TKIP key data
+ * 8 bytes of RX MIC key data
+ * 8 bytes of TX MIC key data
+ * 0x0b 32 16 bytes of TKIP key data
+ * 8 bytes of RX MIC key data
+ * 8 bytes of TX MIC key data
+ *
+ */
+
+struct acx_set_key {
+ /* Ignored for default WEP key */
+ u8 addr[ETH_ALEN];
+
+ /* key_action_e */
+ u16 key_action;
+
+ u16 reserved_1;
+
+ /* key size in bytes */
+ u8 key_size;
+
+ /* key_type_e */
+ u8 key_type;
+ u8 ssid_profile;
+
+ /*
+ * TKIP, AES: frame's key id field.
+ * For WEP default key: key id;
+ */
+ u8 id;
+ u8 reserved_2[6];
+ u8 key[MAX_KEY_SIZE];
+ u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
+ u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
+} __attribute__ ((packed));
+
+struct acx_current_tx_power {
+ struct acx_header header;
+
+ u8 current_tx_power;
+ u8 padding[3];
+} __attribute__ ((packed));
+
+struct acx_dot11_default_key {
+ struct acx_header header;
+
+ u8 id;
+ u8 pad[3];
+} __attribute__ ((packed));
+
+struct acx_tsf_info {
+ struct acx_header header;
+
+ u32 current_tsf_msb;
+ u32 current_tsf_lsb;
+ u32 last_TBTT_msb;
+ u32 last_TBTT_lsb;
+ u8 last_dtim_count;
+ u8 pad[3];
+} __attribute__ ((packed));
+
+/* 802.11 PS */
+enum acx_ps_mode {
+ STATION_ACTIVE_MODE,
+ STATION_POWER_SAVE_MODE
+};
+
+struct acx_ps_params {
+ u8 ps_mode; /* STATION_* */
+ u8 send_null_data; /* Do we have to send NULL data packet ? */
+ u8 retries; /* Number of retires for the initial NULL data packet */
+
+ /*
+ * TUs during which the target stays awake after switching
+ * to power save mode.
+ */
+ u8 hang_over_period;
+ u16 null_data_rate;
+ u8 pad[2];
+} __attribute__ ((packed));
+
+enum acx_wake_up_event {
+ WAKE_UP_EVENT_BEACON_BITMAP = 0x01, /* Wake on every Beacon*/
+ WAKE_UP_EVENT_DTIM_BITMAP = 0x02, /* Wake on every DTIM*/
+ WAKE_UP_EVENT_N_DTIM_BITMAP = 0x04, /* Wake on every Nth DTIM */
+ WAKE_UP_EVENT_N_BEACONS_BITMAP = 0x08, /* Wake on every Nth Beacon */
+ WAKE_UP_EVENT_BITS_MASK = 0x0F
+};
+
+struct acx_wake_up_condition {
+ struct acx_header header;
+
+ u8 wake_up_event; /* Only one bit can be set */
+ u8 listen_interval;
+ u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_aid {
+ struct acx_header header;
+
+ /*
+ * To be set when associated with an AP.
+ */
+ u16 aid;
+ u8 pad[2];
+} __attribute__ ((packed));
+
+enum acx_preamble_type {
+ ACX_PREAMBLE_LONG = 0,
+ ACX_PREAMBLE_SHORT = 1
+};
+
+struct acx_preamble {
+ struct acx_header header;
+ /*
+ * When set, the WiLink transmits the frames with a short preamble and
+ * when cleared, the WiLink transmits the frames with a long preamble.
+ */
+ u8 preamble;
+ u8 padding[3];
+} __attribute__ ((packed));
+
+enum acx_ctsprotect_type {
+ CTSPROTECT_DISABLE = 0,
+ CTSPROTECT_ENABLE = 1
+};
+
+struct acx_ctsprotect {
+ struct acx_header header;
+ u8 ctsprotect;
+ u8 padding[3];
+} __attribute__ ((packed));
+
+struct acx_tx_statistics {
+ u32 internal_desc_overflow;
+} __attribute__ ((packed));
+
+struct acx_rx_statistics {
+ u32 out_of_mem;
+ u32 hdr_overflow;
+ u32 hw_stuck;
+ u32 dropped;
+ u32 fcs_err;
+ u32 xfr_hint_trig;
+ u32 path_reset;
+ u32 reset_counter;
+} __attribute__ ((packed));
+
+struct acx_dma_statistics {
+ u32 rx_requested;
+ u32 rx_errors;
+ u32 tx_requested;
+ u32 tx_errors;
+} __attribute__ ((packed));
+
+struct acx_isr_statistics {
+ /* host command complete */
+ u32 cmd_cmplt;
+
+ /* fiqisr() */
+ u32 fiqs;
+
+ /* (INT_STS_ND & INT_TRIG_RX_HEADER) */
+ u32 rx_headers;
+
+ /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */
+ u32 rx_completes;
+
+ /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */
+ u32 rx_mem_overflow;
+
+ /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */
+ u32 rx_rdys;
+
+ /* irqisr() */
+ u32 irqs;
+
+ /* (INT_STS_ND & INT_TRIG_TX_PROC) */
+ u32 tx_procs;
+
+ /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */
+ u32 decrypt_done;
+
+ /* (INT_STS_ND & INT_TRIG_DMA0) */
+ u32 dma0_done;
+
+ /* (INT_STS_ND & INT_TRIG_DMA1) */
+ u32 dma1_done;
+
+ /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */
+ u32 tx_exch_complete;
+
+ /* (INT_STS_ND & INT_TRIG_COMMAND) */
+ u32 commands;
+
+ /* (INT_STS_ND & INT_TRIG_RX_PROC) */
+ u32 rx_procs;
+
+ /* (INT_STS_ND & INT_TRIG_PM_802) */
+ u32 hw_pm_mode_changes;
+
+ /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */
+ u32 host_acknowledges;
+
+ /* (INT_STS_ND & INT_TRIG_PM_PCI) */
+ u32 pci_pm;
+
+ /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */
+ u32 wakeups;
+
+ /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */
+ u32 low_rssi;
+} __attribute__ ((packed));
+
+struct acx_wep_statistics {
+ /* WEP address keys configured */
+ u32 addr_key_count;
+
+ /* default keys configured */
+ u32 default_key_count;
+
+ u32 reserved;
+
+ /* number of times that WEP key not found on lookup */
+ u32 key_not_found;
+
+ /* number of times that WEP key decryption failed */
+ u32 decrypt_fail;
+
+ /* WEP packets decrypted */
+ u32 packets;
+
+ /* WEP decrypt interrupts */
+ u32 interrupt;
+} __attribute__ ((packed));
+
+#define ACX_MISSED_BEACONS_SPREAD 10
+
+struct acx_pwr_statistics {
+ /* the amount of enters into power save mode (both PD & ELP) */
+ u32 ps_enter;
+
+ /* the amount of enters into ELP mode */
+ u32 elp_enter;
+
+ /* the amount of missing beacon interrupts to the host */
+ u32 missing_bcns;
+
+ /* the amount of wake on host-access times */
+ u32 wake_on_host;
+
+ /* the amount of wake on timer-expire */
+ u32 wake_on_timer_exp;
+
+ /* the number of packets that were transmitted with PS bit set */
+ u32 tx_with_ps;
+
+ /* the number of packets that were transmitted with PS bit clear */
+ u32 tx_without_ps;
+
+ /* the number of received beacons */
+ u32 rcvd_beacons;
+
+ /* the number of entering into PowerOn (power save off) */
+ u32 power_save_off;
+
+ /* the number of entries into power save mode */
+ u16 enable_ps;
+
+ /*
+ * the number of exits from power save, not including failed PS
+ * transitions
+ */
+ u16 disable_ps;
+
+ /*
+ * the number of times the TSF counter was adjusted because
+ * of drift
+ */
+ u32 fix_tsf_ps;
+
+ /* Gives statistics about the spread continuous missed beacons.
+ * The 16 LSB are dedicated for the PS mode.
+ * The 16 MSB are dedicated for the PS mode.
+ * cont_miss_bcns_spread[0] - single missed beacon.
+ * cont_miss_bcns_spread[1] - two continuous missed beacons.
+ * cont_miss_bcns_spread[2] - three continuous missed beacons.
+ * ...
+ * cont_miss_bcns_spread[9] - ten and more continuous missed beacons.
+ */
+ u32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD];
+
+ /* the number of beacons in awake mode */
+ u32 rcvd_awake_beacons;
+} __attribute__ ((packed));
+
+struct acx_mic_statistics {
+ u32 rx_pkts;
+ u32 calc_failure;
+} __attribute__ ((packed));
+
+struct acx_aes_statistics {
+ u32 encrypt_fail;
+ u32 decrypt_fail;
+ u32 encrypt_packets;
+ u32 decrypt_packets;
+ u32 encrypt_interrupt;
+ u32 decrypt_interrupt;
+} __attribute__ ((packed));
+
+struct acx_event_statistics {
+ u32 heart_beat;
+ u32 calibration;
+ u32 rx_mismatch;
+ u32 rx_mem_empty;
+ u32 rx_pool;
+ u32 oom_late;
+ u32 phy_transmit_error;
+ u32 tx_stuck;
+} __attribute__ ((packed));
+
+struct acx_ps_statistics {
+ u32 pspoll_timeouts;
+ u32 upsd_timeouts;
+ u32 upsd_max_sptime;
+ u32 upsd_max_apturn;
+ u32 pspoll_max_apturn;
+ u32 pspoll_utilization;
+ u32 upsd_utilization;
+} __attribute__ ((packed));
+
+struct acx_rxpipe_statistics {
+ u32 rx_prep_beacon_drop;
+ u32 descr_host_int_trig_rx_data;
+ u32 beacon_buffer_thres_host_int_trig_rx_data;
+ u32 missed_beacon_host_int_trig_rx_data;
+ u32 tx_xfr_host_int_trig_rx_data;
+} __attribute__ ((packed));
+
+struct acx_statistics {
+ struct acx_header header;
+
+ struct acx_tx_statistics tx;
+ struct acx_rx_statistics rx;
+ struct acx_dma_statistics dma;
+ struct acx_isr_statistics isr;
+ struct acx_wep_statistics wep;
+ struct acx_pwr_statistics pwr;
+ struct acx_aes_statistics aes;
+ struct acx_mic_statistics mic;
+ struct acx_event_statistics event;
+ struct acx_ps_statistics ps;
+ struct acx_rxpipe_statistics rxpipe;
+} __attribute__ ((packed));
+
+enum {
+ ACX_WAKE_UP_CONDITIONS = 0x0002,
+ ACX_MEM_CFG = 0x0003,
+ ACX_SLOT = 0x0004,
+ ACX_QUEUE_HEAD = 0x0005, /* for MASTER mode only */
+ ACX_AC_CFG = 0x0007,
+ ACX_MEM_MAP = 0x0008,
+ ACX_AID = 0x000A,
+ ACX_RADIO_PARAM = 0x000B, /* Not used */
+ ACX_CFG = 0x000C, /* Not used */
+ ACX_FW_REV = 0x000D,
+ ACX_MEDIUM_USAGE = 0x000F,
+ ACX_RX_CFG = 0x0010,
+ ACX_TX_QUEUE_CFG = 0x0011, /* FIXME: only used by wl1251 */
+ ACX_BSS_IN_PS = 0x0012, /* for AP only */
+ ACX_STATISTICS = 0x0013, /* Debug API */
+ ACX_FEATURE_CFG = 0x0015,
+ ACX_MISC_CFG = 0x0017, /* Not used */
+ ACX_TID_CFG = 0x001A,
+ ACX_BEACON_FILTER_OPT = 0x001F,
+ ACX_LOW_RSSI = 0x0020,
+ ACX_NOISE_HIST = 0x0021,
+ ACX_HDK_VERSION = 0x0022, /* ??? */
+ ACX_PD_THRESHOLD = 0x0023,
+ ACX_DATA_PATH_PARAMS = 0x0024, /* WO */
+ ACX_DATA_PATH_RESP_PARAMS = 0x0024, /* RO */
+ ACX_CCA_THRESHOLD = 0x0025,
+ ACX_EVENT_MBOX_MASK = 0x0026,
+#ifdef FW_RUNNING_AS_AP
+ ACX_DTIM_PERIOD = 0x0027, /* for AP only */
+#else
+ ACX_WR_TBTT_AND_DTIM = 0x0027, /* STA only */
+#endif
+ ACX_ACI_OPTION_CFG = 0x0029, /* OBSOLETE (for 1251)*/
+ ACX_GPIO_CFG = 0x002A, /* Not used */
+ ACX_GPIO_SET = 0x002B, /* Not used */
+ ACX_PM_CFG = 0x002C, /* To Be Documented */
+ ACX_CONN_MONIT_PARAMS = 0x002D,
+ ACX_AVERAGE_RSSI = 0x002E, /* Not used */
+ ACX_CONS_TX_FAILURE = 0x002F,
+ ACX_BCN_DTIM_OPTIONS = 0x0031,
+ ACX_SG_ENABLE = 0x0032,
+ ACX_SG_CFG = 0x0033,
+ ACX_ANTENNA_DIVERSITY_CFG = 0x0035, /* To Be Documented */
+ ACX_LOW_SNR = 0x0037, /* To Be Documented */
+ ACX_BEACON_FILTER_TABLE = 0x0038,
+ ACX_ARP_IP_FILTER = 0x0039,
+ ACX_ROAMING_STATISTICS_TBL = 0x003B,
+ ACX_RATE_POLICY = 0x003D,
+ ACX_CTS_PROTECTION = 0x003E,
+ ACX_SLEEP_AUTH = 0x003F,
+ ACX_PREAMBLE_TYPE = 0x0040,
+ ACX_ERROR_CNT = 0x0041,
+ ACX_FW_GEN_FRAME_RATES = 0x0042,
+ ACX_IBSS_FILTER = 0x0044,
+ ACX_SERVICE_PERIOD_TIMEOUT = 0x0045,
+ ACX_TSF_INFO = 0x0046,
+ ACX_CONFIG_PS_WMM = 0x0049,
+ ACX_ENABLE_RX_DATA_FILTER = 0x004A,
+ ACX_SET_RX_DATA_FILTER = 0x004B,
+ ACX_GET_DATA_FILTER_STATISTICS = 0x004C,
+ ACX_POWER_LEVEL_TABLE = 0x004D,
+ ACX_BET_ENABLE = 0x0050,
+ DOT11_STATION_ID = 0x1001,
+ DOT11_RX_MSDU_LIFE_TIME = 0x1004,
+ DOT11_CUR_TX_PWR = 0x100D,
+ DOT11_DEFAULT_KEY = 0x1010,
+ DOT11_RX_DOT11_MODE = 0x1012,
+ DOT11_RTS_THRESHOLD = 0x1013,
+ DOT11_GROUP_ADDRESS_TBL = 0x1014,
+
+ MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
+
+ MAX_IE = 0xFFFF
+};
+
+
+int wl12xx_acx_frame_rates(struct wl12xx *wl, u8 ctrl_rate, u8 ctrl_mod,
+ u8 mgt_rate, u8 mgt_mod);
+int wl12xx_acx_station_id(struct wl12xx *wl);
+int wl12xx_acx_default_key(struct wl12xx *wl, u8 key_id);
+int wl12xx_acx_wake_up_conditions(struct wl12xx *wl, u8 listen_interval);
+int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth);
+int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len);
+int wl12xx_acx_tx_power(struct wl12xx *wl, int power);
+int wl12xx_acx_feature_cfg(struct wl12xx *wl);
+int wl12xx_acx_mem_map(struct wl12xx *wl, void *mem_map, size_t len);
+int wl12xx_acx_data_path_params(struct wl12xx *wl,
+ struct acx_data_path_params_resp *data_path);
+int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time);
+int wl12xx_acx_rx_config(struct wl12xx *wl, u32 config, u32 filter);
+int wl12xx_acx_pd_threshold(struct wl12xx *wl);
+int wl12xx_acx_slot(struct wl12xx *wl, enum acx_slot_type slot_time);
+int wl12xx_acx_group_address_tbl(struct wl12xx *wl);
+int wl12xx_acx_service_period_timeout(struct wl12xx *wl);
+int wl12xx_acx_rts_threshold(struct wl12xx *wl, u16 rts_threshold);
+int wl12xx_acx_beacon_filter_opt(struct wl12xx *wl);
+int wl12xx_acx_beacon_filter_table(struct wl12xx *wl);
+int wl12xx_acx_sg_enable(struct wl12xx *wl);
+int wl12xx_acx_sg_cfg(struct wl12xx *wl);
+int wl12xx_acx_cca_threshold(struct wl12xx *wl);
+int wl12xx_acx_bcn_dtim_options(struct wl12xx *wl);
+int wl12xx_acx_aid(struct wl12xx *wl, u16 aid);
+int wl12xx_acx_event_mbox_mask(struct wl12xx *wl, u32 event_mask);
+int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble);
+int wl12xx_acx_cts_protect(struct wl12xx *wl,
+ enum acx_ctsprotect_type ctsprotect);
+int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats);
+
+#endif /* __WL12XX_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
new file mode 100644
index 00000000000..48ac08c429b
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -0,0 +1,295 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/gpio.h>
+
+#include "reg.h"
+#include "boot.h"
+#include "spi.h"
+#include "event.h"
+
+static void wl12xx_boot_enable_interrupts(struct wl12xx *wl)
+{
+ enable_irq(wl->irq);
+}
+
+void wl12xx_boot_target_enable_interrupts(struct wl12xx *wl)
+{
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
+ wl12xx_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
+}
+
+int wl12xx_boot_soft_reset(struct wl12xx *wl)
+{
+ unsigned long timeout;
+ u32 boot_data;
+
+ /* perform soft reset */
+ wl12xx_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
+
+ /* SOFT_RESET is self clearing */
+ timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
+ while (1) {
+ boot_data = wl12xx_reg_read32(wl, ACX_REG_SLV_SOFT_RESET);
+ wl12xx_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
+ if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
+ break;
+
+ if (time_after(jiffies, timeout)) {
+ /* 1.2 check pWhalBus->uSelfClearTime if the
+ * timeout was reached */
+ wl12xx_error("soft reset timeout");
+ return -1;
+ }
+
+ udelay(SOFT_RESET_STALL_TIME);
+ }
+
+ /* disable Rx/Tx */
+ wl12xx_reg_write32(wl, ENABLE, 0x0);
+
+ /* disable auto calibration on start*/
+ wl12xx_reg_write32(wl, SPARE_A2, 0xffff);
+
+ return 0;
+}
+
+int wl12xx_boot_init_seq(struct wl12xx *wl)
+{
+ u32 scr_pad6, init_data, tmp, elp_cmd, ref_freq;
+
+ /*
+ * col #1: INTEGER_DIVIDER
+ * col #2: FRACTIONAL_DIVIDER
+ * col #3: ATTN_BB
+ * col #4: ALPHA_BB
+ * col #5: STOP_TIME_BB
+ * col #6: BB_PLL_LOOP_FILTER
+ */
+ static const u32 LUT[REF_FREQ_NUM][LUT_PARAM_NUM] = {
+
+ { 83, 87381, 0xB, 5, 0xF00, 3}, /* REF_FREQ_19_2*/
+ { 61, 141154, 0xB, 5, 0x1450, 2}, /* REF_FREQ_26_0*/
+ { 41, 174763, 0xC, 6, 0x2D00, 1}, /* REF_FREQ_38_4*/
+ { 40, 0, 0xC, 6, 0x2EE0, 1}, /* REF_FREQ_40_0*/
+ { 47, 162280, 0xC, 6, 0x2760, 1} /* REF_FREQ_33_6 */
+ };
+
+ /* read NVS params */
+ scr_pad6 = wl12xx_reg_read32(wl, SCR_PAD6);
+ wl12xx_debug(DEBUG_BOOT, "scr_pad6 0x%x", scr_pad6);
+
+ /* read ELP_CMD */
+ elp_cmd = wl12xx_reg_read32(wl, ELP_CMD);
+ wl12xx_debug(DEBUG_BOOT, "elp_cmd 0x%x", elp_cmd);
+
+ /* set the BB calibration time to be 300 usec (PLL_CAL_TIME) */
+ ref_freq = scr_pad6 & 0x000000FF;
+ wl12xx_debug(DEBUG_BOOT, "ref_freq 0x%x", ref_freq);
+
+ wl12xx_reg_write32(wl, PLL_CAL_TIME, 0x9);
+
+ /*
+ * PG 1.2: set the clock buffer time to be 210 usec (CLK_BUF_TIME)
+ */
+ wl12xx_reg_write32(wl, CLK_BUF_TIME, 0x6);
+
+ /*
+ * set the clock detect feature to work in the restart wu procedure
+ * (ELP_CFG_MODE[14]) and Select the clock source type
+ * (ELP_CFG_MODE[13:12])
+ */
+ tmp = ((scr_pad6 & 0x0000FF00) << 4) | 0x00004000;
+ wl12xx_reg_write32(wl, ELP_CFG_MODE, tmp);
+
+ /* PG 1.2: enable the BB PLL fix. Enable the PLL_LIMP_CLK_EN_CMD */
+ elp_cmd |= 0x00000040;
+ wl12xx_reg_write32(wl, ELP_CMD, elp_cmd);
+
+ /* PG 1.2: Set the BB PLL stable time to be 1000usec
+ * (PLL_STABLE_TIME) */
+ wl12xx_reg_write32(wl, CFG_PLL_SYNC_CNT, 0x20);
+
+ /* PG 1.2: read clock request time */
+ init_data = wl12xx_reg_read32(wl, CLK_REQ_TIME);
+
+ /*
+ * PG 1.2: set the clock request time to be ref_clk_settling_time -
+ * 1ms = 4ms
+ */
+ if (init_data > 0x21)
+ tmp = init_data - 0x21;
+ else
+ tmp = 0;
+ wl12xx_reg_write32(wl, CLK_REQ_TIME, tmp);
+
+ /* set BB PLL configurations in RF AFE */
+ wl12xx_reg_write32(wl, 0x003058cc, 0x4B5);
+
+ /* set RF_AFE_REG_5 */
+ wl12xx_reg_write32(wl, 0x003058d4, 0x50);
+
+ /* set RF_AFE_CTRL_REG_2 */
+ wl12xx_reg_write32(wl, 0x00305948, 0x11c001);
+
+ /*
+ * change RF PLL and BB PLL divider for VCO clock and adjust VCO
+ * bais current(RF_AFE_REG_13)
+ */
+ wl12xx_reg_write32(wl, 0x003058f4, 0x1e);
+
+ /* set BB PLL configurations */
+ tmp = LUT[ref_freq][LUT_PARAM_INTEGER_DIVIDER] | 0x00017000;
+ wl12xx_reg_write32(wl, 0x00305840, tmp);
+
+ /* set fractional divider according to Appendix C-BB PLL
+ * Calculations
+ */
+ tmp = LUT[ref_freq][LUT_PARAM_FRACTIONAL_DIVIDER];
+ wl12xx_reg_write32(wl, 0x00305844, tmp);
+
+ /* set the initial data for the sigma delta */
+ wl12xx_reg_write32(wl, 0x00305848, 0x3039);
+
+ /*
+ * set the accumulator attenuation value, calibration loop1
+ * (alpha), calibration loop2 (beta), calibration loop3 (gamma) and
+ * the VCO gain
+ */
+ tmp = (LUT[ref_freq][LUT_PARAM_ATTN_BB] << 16) |
+ (LUT[ref_freq][LUT_PARAM_ALPHA_BB] << 12) | 0x1;
+ wl12xx_reg_write32(wl, 0x00305854, tmp);
+
+ /*
+ * set the calibration stop time after holdoff time expires and set
+ * settling time HOLD_OFF_TIME_BB
+ */
+ tmp = LUT[ref_freq][LUT_PARAM_STOP_TIME_BB] | 0x000A0000;
+ wl12xx_reg_write32(wl, 0x00305858, tmp);
+
+ /*
+ * set BB PLL Loop filter capacitor3- BB_C3[2:0] and set BB PLL
+ * constant leakage current to linearize PFD to 0uA -
+ * BB_ILOOPF[7:3]
+ */
+ tmp = LUT[ref_freq][LUT_PARAM_BB_PLL_LOOP_FILTER] | 0x00000030;
+ wl12xx_reg_write32(wl, 0x003058f8, tmp);
+
+ /*
+ * set regulator output voltage for n divider to
+ * 1.35-BB_REFDIV[1:0], set charge pump current- BB_CPGAIN[4:2],
+ * set BB PLL Loop filter capacitor2- BB_C2[7:5], set gain of BB
+ * PLL auto-call to normal mode- BB_CALGAIN_3DB[8]
+ */
+ wl12xx_reg_write32(wl, 0x003058f0, 0x29);
+
+ /* enable restart wakeup sequence (ELP_CMD[0]) */
+ wl12xx_reg_write32(wl, ELP_CMD, elp_cmd | 0x1);
+
+ /* restart sequence completed */
+ udelay(2000);
+
+ return 0;
+}
+
+int wl12xx_boot_run_firmware(struct wl12xx *wl)
+{
+ int loop, ret;
+ u32 chip_id, interrupt;
+
+ wl->chip.op_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
+
+ chip_id = wl12xx_reg_read32(wl, CHIP_ID_B);
+
+ wl12xx_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
+
+ if (chip_id != wl->chip.id) {
+ wl12xx_error("chip id doesn't match after firmware boot");
+ return -EIO;
+ }
+
+ /* wait for init to complete */
+ loop = 0;
+ while (loop++ < INIT_LOOP) {
+ udelay(INIT_LOOP_DELAY);
+ interrupt = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+
+ if (interrupt == 0xffffffff) {
+ wl12xx_error("error reading hardware complete "
+ "init indication");
+ return -EIO;
+ }
+ /* check that ACX_INTR_INIT_COMPLETE is enabled */
+ else if (interrupt & wl->chip.intr_init_complete) {
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
+ wl->chip.intr_init_complete);
+ break;
+ }
+ }
+
+ if (loop >= INIT_LOOP) {
+ wl12xx_error("timeout waiting for the hardware to "
+ "complete initialization");
+ return -EIO;
+ }
+
+ /* get hardware config command mail box */
+ wl->cmd_box_addr = wl12xx_reg_read32(wl, REG_COMMAND_MAILBOX_PTR);
+
+ /* get hardware config event mail box */
+ wl->event_box_addr = wl12xx_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
+
+ /* set the working partition to its "running" mode offset */
+ wl12xx_set_partition(wl,
+ wl->chip.p_table[PART_WORK].mem.start,
+ wl->chip.p_table[PART_WORK].mem.size,
+ wl->chip.p_table[PART_WORK].reg.start,
+ wl->chip.p_table[PART_WORK].reg.size);
+
+ wl12xx_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
+ wl->cmd_box_addr, wl->event_box_addr);
+
+ /*
+ * in case of full asynchronous mode the firmware event must be
+ * ready to receive event from the command mailbox
+ */
+
+ /* enable gpio interrupts */
+ wl12xx_boot_enable_interrupts(wl);
+
+ wl->chip.op_target_enable_interrupts(wl);
+
+ /* unmask all mbox events */
+ wl->event_mask = 0xffffffff;
+
+ ret = wl12xx_event_unmask(wl);
+ if (ret < 0) {
+ wl12xx_error("EVENT mask setting failed");
+ return ret;
+ }
+
+ wl12xx_event_mbox_config(wl);
+
+ /* firmware startup completed */
+ return 0;
+}
diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h
new file mode 100644
index 00000000000..4fa73132baa
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/boot.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __BOOT_H__
+#define __BOOT_H__
+
+#include "wl12xx.h"
+
+int wl12xx_boot_soft_reset(struct wl12xx *wl);
+int wl12xx_boot_init_seq(struct wl12xx *wl);
+int wl12xx_boot_run_firmware(struct wl12xx *wl);
+void wl12xx_boot_target_enable_interrupts(struct wl12xx *wl);
+
+/* number of times we try to read the INIT interrupt */
+#define INIT_LOOP 20000
+
+/* delay between retries */
+#define INIT_LOOP_DELAY 50
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
new file mode 100644
index 00000000000..f73ab602b7a
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -0,0 +1,353 @@
+#include "cmd.h"
+
+#include <linux/module.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+
+#include "wl12xx.h"
+#include "wl12xx_80211.h"
+#include "reg.h"
+#include "spi.h"
+#include "ps.h"
+
+int wl12xx_cmd_send(struct wl12xx *wl, u16 type, void *buf, size_t buf_len)
+{
+ struct wl12xx_command cmd;
+ unsigned long timeout;
+ size_t cmd_len;
+ u32 intr;
+ int ret = 0;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.id = type;
+ cmd.status = 0;
+ memcpy(cmd.parameters, buf, buf_len);
+ cmd_len = ALIGN(buf_len, 4) + CMDMBOX_HEADER_LEN;
+
+ wl12xx_ps_elp_wakeup(wl);
+
+ wl12xx_spi_mem_write(wl, wl->cmd_box_addr, &cmd, cmd_len);
+
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
+
+ timeout = jiffies + msecs_to_jiffies(WL12XX_COMMAND_TIMEOUT);
+
+ intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+ while (!(intr & wl->chip.intr_cmd_complete)) {
+ if (time_after(jiffies, timeout)) {
+ wl12xx_error("command complete timeout");
+ ret = -ETIMEDOUT;
+ goto out;
+ }
+
+ msleep(1);
+
+ intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+ }
+
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
+ wl->chip.intr_cmd_complete);
+
+out:
+ wl12xx_ps_elp_sleep(wl);
+
+ return ret;
+}
+
+int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer)
+{
+ int ret;
+
+ wl12xx_debug(DEBUG_CMD, "cmd test");
+
+ ret = wl12xx_cmd_send(wl, CMD_TEST, buf, buf_len);
+ if (ret < 0) {
+ wl12xx_warning("TEST command failed");
+ return ret;
+ }
+
+ if (answer) {
+ struct wl12xx_command *cmd_answer;
+
+ /*
+ * The test command got in, we can read the answer.
+ * The answer would be a wl12xx_command, where the
+ * parameter array contains the actual answer.
+ */
+
+ wl12xx_ps_elp_wakeup(wl);
+
+ wl12xx_spi_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
+
+ wl12xx_ps_elp_sleep(wl);
+
+ cmd_answer = buf;
+ if (cmd_answer->status != CMD_STATUS_SUCCESS)
+ wl12xx_error("TEST command answer error: %d",
+ cmd_answer->status);
+ }
+
+ return 0;
+}
+
+
+int wl12xx_cmd_interrogate(struct wl12xx *wl, u16 ie_id, u16 ie_len,
+ void *answer)
+{
+ struct wl12xx_command *cmd;
+ struct acx_header header;
+ int ret;
+
+ wl12xx_debug(DEBUG_CMD, "cmd interrogate");
+
+ header.id = ie_id;
+ header.len = ie_len - sizeof(header);
+
+ ret = wl12xx_cmd_send(wl, CMD_INTERROGATE, &header, sizeof(header));
+ if (ret < 0) {
+ wl12xx_error("INTERROGATE command failed");
+ return ret;
+ }
+
+ wl12xx_ps_elp_wakeup(wl);
+
+ /* the interrogate command got in, we can read the answer */
+ wl12xx_spi_mem_read(wl, wl->cmd_box_addr, answer,
+ CMDMBOX_HEADER_LEN + ie_len);
+
+ wl12xx_ps_elp_sleep(wl);
+
+ cmd = answer;
+ if (cmd->status != CMD_STATUS_SUCCESS)
+ wl12xx_error("INTERROGATE command error: %d",
+ cmd->status);
+
+ return 0;
+
+}
+
+int wl12xx_cmd_configure(struct wl12xx *wl, void *ie, int ie_len)
+{
+ int ret;
+
+ wl12xx_debug(DEBUG_CMD, "cmd configure");
+
+ ret = wl12xx_cmd_send(wl, CMD_CONFIGURE, ie,
+ ie_len);
+ if (ret < 0) {
+ wl12xx_warning("CONFIGURE command NOK");
+ return ret;
+ }
+
+ return 0;
+
+}
+
+int wl12xx_cmd_vbm(struct wl12xx *wl, u8 identity,
+ void *bitmap, u16 bitmap_len, u8 bitmap_control)
+{
+ struct vbm_update_request vbm;
+ int ret;
+
+ wl12xx_debug(DEBUG_CMD, "cmd vbm");
+
+ /* Count and period will be filled by the target */
+ vbm.tim.bitmap_ctrl = bitmap_control;
+ if (bitmap_len > PARTIAL_VBM_MAX) {
+ wl12xx_warning("cmd vbm len is %d B, truncating to %d",
+ bitmap_len, PARTIAL_VBM_MAX);
+ bitmap_len = PARTIAL_VBM_MAX;
+ }
+ memcpy(vbm.tim.pvb_field, bitmap, bitmap_len);
+ vbm.tim.identity = identity;
+ vbm.tim.length = bitmap_len + 3;
+
+ vbm.len = cpu_to_le16(bitmap_len + 5);
+
+ ret = wl12xx_cmd_send(wl, CMD_VBM, &vbm, sizeof(vbm));
+ if (ret < 0) {
+ wl12xx_error("VBM command failed");
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, u8 enable)
+{
+ int ret;
+ u16 cmd_rx, cmd_tx;
+
+ wl12xx_debug(DEBUG_CMD, "cmd data path");
+
+ if (enable) {
+ cmd_rx = CMD_ENABLE_RX;
+ cmd_tx = CMD_ENABLE_TX;
+ } else {
+ cmd_rx = CMD_DISABLE_RX;
+ cmd_tx = CMD_DISABLE_TX;
+ }
+
+ ret = wl12xx_cmd_send(wl, cmd_rx, &channel, sizeof(channel));
+ if (ret < 0) {
+ wl12xx_error("rx %s cmd for channel %d failed",
+ enable ? "start" : "stop", channel);
+ return ret;
+ }
+
+ wl12xx_debug(DEBUG_BOOT, "rx %s cmd channel %d",
+ enable ? "start" : "stop", channel);
+
+ ret = wl12xx_cmd_send(wl, cmd_tx, &channel, sizeof(channel));
+ if (ret < 0) {
+ wl12xx_error("tx %s cmd for channel %d failed",
+ enable ? "start" : "stop", channel);
+ return ret;
+ }
+
+ wl12xx_debug(DEBUG_BOOT, "tx %s cmd channel %d",
+ enable ? "start" : "stop", channel);
+
+ return 0;
+}
+
+int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval,
+ u16 beacon_interval, u8 wait)
+{
+ unsigned long timeout;
+ struct cmd_join join = {};
+ int ret, i;
+ u8 *bssid;
+
+ /* FIXME: this should be in main.c */
+ ret = wl12xx_acx_frame_rates(wl, DEFAULT_HW_GEN_TX_RATE,
+ DEFAULT_HW_GEN_MODULATION_TYPE,
+ wl->tx_mgmt_frm_rate,
+ wl->tx_mgmt_frm_mod);
+ if (ret < 0)
+ return ret;
+
+ wl12xx_debug(DEBUG_CMD, "cmd join");
+
+ /* Reverse order BSSID */
+ bssid = (u8 *)&join.bssid_lsb;
+ for (i = 0; i < ETH_ALEN; i++)
+ bssid[i] = wl->bssid[ETH_ALEN - i - 1];
+
+ join.rx_config_options = wl->rx_config;
+ join.rx_filter_options = wl->rx_filter;
+
+ join.basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
+ RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
+
+ join.beacon_interval = beacon_interval;
+ join.dtim_interval = dtim_interval;
+ join.bss_type = bss_type;
+ join.channel = wl->channel;
+ join.ctrl = JOIN_CMD_CTRL_TX_FLUSH;
+
+ ret = wl12xx_cmd_send(wl, CMD_START_JOIN, &join, sizeof(join));
+ if (ret < 0) {
+ wl12xx_error("failed to initiate cmd join");
+ return ret;
+ }
+
+ timeout = msecs_to_jiffies(JOIN_TIMEOUT);
+
+ /*
+ * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to
+ * simplify locking we just sleep instead, for now
+ */
+ if (wait)
+ msleep(10);
+
+ return 0;
+}
+
+int wl12xx_cmd_ps_mode(struct wl12xx *wl, u8 ps_mode)
+{
+ int ret;
+ struct acx_ps_params ps_params;
+
+ /* FIXME: this should be in ps.c */
+ ret = wl12xx_acx_wake_up_conditions(wl, wl->listen_int);
+ if (ret < 0) {
+ wl12xx_error("Couldnt set wake up conditions");
+ return ret;
+ }
+
+ wl12xx_debug(DEBUG_CMD, "cmd set ps mode");
+
+ ps_params.ps_mode = ps_mode;
+ ps_params.send_null_data = 1;
+ ps_params.retries = 5;
+ ps_params.hang_over_period = 128;
+ ps_params.null_data_rate = 1; /* 1 Mbps */
+
+ ret = wl12xx_cmd_send(wl, CMD_SET_PS_MODE, &ps_params,
+ sizeof(ps_params));
+ if (ret < 0) {
+ wl12xx_error("cmd set_ps_mode failed");
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_cmd_read_memory(struct wl12xx *wl, u32 addr, u32 len, void *answer)
+{
+ struct cmd_read_write_memory mem_cmd, *mem_answer;
+ struct wl12xx_command cmd;
+ int ret;
+
+ wl12xx_debug(DEBUG_CMD, "cmd read memory");
+
+ memset(&mem_cmd, 0, sizeof(mem_cmd));
+ mem_cmd.addr = addr;
+ mem_cmd.size = len;
+
+ ret = wl12xx_cmd_send(wl, CMD_READ_MEMORY, &mem_cmd, sizeof(mem_cmd));
+ if (ret < 0) {
+ wl12xx_error("read memory command failed: %d", ret);
+ return ret;
+ }
+
+ /* the read command got in, we can now read the answer */
+ wl12xx_spi_mem_read(wl, wl->cmd_box_addr, &cmd,
+ CMDMBOX_HEADER_LEN + sizeof(mem_cmd));
+
+ if (cmd.status != CMD_STATUS_SUCCESS)
+ wl12xx_error("error in read command result: %d", cmd.status);
+
+ mem_answer = (struct cmd_read_write_memory *) cmd.parameters;
+ memcpy(answer, mem_answer->value, len);
+
+ return 0;
+}
+
+int wl12xx_cmd_template_set(struct wl12xx *wl, u16 cmd_id,
+ void *buf, size_t buf_len)
+{
+ struct wl12xx_cmd_packet_template template;
+ int ret;
+
+ wl12xx_debug(DEBUG_CMD, "cmd template %d", cmd_id);
+
+ memset(&template, 0, sizeof(template));
+
+ WARN_ON(buf_len > WL12XX_MAX_TEMPLATE_SIZE);
+ buf_len = min_t(size_t, buf_len, WL12XX_MAX_TEMPLATE_SIZE);
+ template.size = cpu_to_le16(buf_len);
+
+ if (buf)
+ memcpy(template.template, buf, buf_len);
+
+ ret = wl12xx_cmd_send(wl, cmd_id, &template,
+ sizeof(template.size) + buf_len);
+ if (ret < 0) {
+ wl12xx_warning("cmd set_template failed: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
new file mode 100644
index 00000000000..aa307dcd081
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -0,0 +1,265 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_CMD_H__
+#define __WL12XX_CMD_H__
+
+#include "wl12xx.h"
+
+int wl12xx_cmd_send(struct wl12xx *wl, u16 type, void *buf, size_t buf_len);
+int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer);
+int wl12xx_cmd_interrogate(struct wl12xx *wl, u16 ie_id, u16 ie_len,
+ void *answer);
+int wl12xx_cmd_configure(struct wl12xx *wl, void *ie, int ie_len);
+int wl12xx_cmd_vbm(struct wl12xx *wl, u8 identity,
+ void *bitmap, u16 bitmap_len, u8 bitmap_control);
+int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, u8 enable);
+int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval,
+ u16 beacon_interval, u8 wait);
+int wl12xx_cmd_ps_mode(struct wl12xx *wl, u8 ps_mode);
+int wl12xx_cmd_read_memory(struct wl12xx *wl, u32 addr, u32 len, void *answer);
+int wl12xx_cmd_template_set(struct wl12xx *wl, u16 cmd_id,
+ void *buf, size_t buf_len);
+
+/* unit ms */
+#define WL12XX_COMMAND_TIMEOUT 2000
+
+#define WL12XX_MAX_TEMPLATE_SIZE 300
+
+struct wl12xx_cmd_packet_template {
+ __le16 size;
+ u8 template[WL12XX_MAX_TEMPLATE_SIZE];
+} __attribute__ ((packed));
+
+enum wl12xx_commands {
+ CMD_RESET = 0,
+ CMD_INTERROGATE = 1, /*use this to read information elements*/
+ CMD_CONFIGURE = 2, /*use this to write information elements*/
+ CMD_ENABLE_RX = 3,
+ CMD_ENABLE_TX = 4,
+ CMD_DISABLE_RX = 5,
+ CMD_DISABLE_TX = 6,
+ CMD_SCAN = 8,
+ CMD_STOP_SCAN = 9,
+ CMD_VBM = 10,
+ CMD_START_JOIN = 11,
+ CMD_SET_KEYS = 12,
+ CMD_READ_MEMORY = 13,
+ CMD_WRITE_MEMORY = 14,
+ CMD_BEACON = 19,
+ CMD_PROBE_RESP = 20,
+ CMD_NULL_DATA = 21,
+ CMD_PROBE_REQ = 22,
+ CMD_TEST = 23,
+ CMD_RADIO_CALIBRATE = 25, /* OBSOLETE */
+ CMD_ENABLE_RX_PATH = 27, /* OBSOLETE */
+ CMD_NOISE_HIST = 28,
+ CMD_RX_RESET = 29,
+ CMD_PS_POLL = 30,
+ CMD_QOS_NULL_DATA = 31,
+ CMD_LNA_CONTROL = 32,
+ CMD_SET_BCN_MODE = 33,
+ CMD_MEASUREMENT = 34,
+ CMD_STOP_MEASUREMENT = 35,
+ CMD_DISCONNECT = 36,
+ CMD_SET_PS_MODE = 37,
+ CMD_CHANNEL_SWITCH = 38,
+ CMD_STOP_CHANNEL_SWICTH = 39,
+ CMD_AP_DISCOVERY = 40,
+ CMD_STOP_AP_DISCOVERY = 41,
+ CMD_SPS_SCAN = 42,
+ CMD_STOP_SPS_SCAN = 43,
+ CMD_HEALTH_CHECK = 45,
+ CMD_DEBUG = 46,
+ CMD_TRIGGER_SCAN_TO = 47,
+
+ NUM_COMMANDS,
+ MAX_COMMAND_ID = 0xFFFF,
+};
+
+#define MAX_CMD_PARAMS 572
+
+struct wl12xx_command {
+ u16 id;
+ u16 status;
+ u8 parameters[MAX_CMD_PARAMS];
+};
+
+enum {
+ CMD_MAILBOX_IDLE = 0,
+ CMD_STATUS_SUCCESS = 1,
+ CMD_STATUS_UNKNOWN_CMD = 2,
+ CMD_STATUS_UNKNOWN_IE = 3,
+ CMD_STATUS_REJECT_MEAS_SG_ACTIVE = 11,
+ CMD_STATUS_RX_BUSY = 13,
+ CMD_STATUS_INVALID_PARAM = 14,
+ CMD_STATUS_TEMPLATE_TOO_LARGE = 15,
+ CMD_STATUS_OUT_OF_MEMORY = 16,
+ CMD_STATUS_STA_TABLE_FULL = 17,
+ CMD_STATUS_RADIO_ERROR = 18,
+ CMD_STATUS_WRONG_NESTING = 19,
+ CMD_STATUS_TIMEOUT = 21, /* Driver internal use.*/
+ CMD_STATUS_FW_RESET = 22, /* Driver internal use.*/
+ MAX_COMMAND_STATUS = 0xff
+};
+
+
+/*
+ * CMD_READ_MEMORY
+ *
+ * The host issues this command to read the WiLink device memory/registers.
+ *
+ * Note: The Base Band address has special handling (16 bits registers and
+ * addresses). For more information, see the hardware specification.
+ */
+/*
+ * CMD_WRITE_MEMORY
+ *
+ * The host issues this command to write the WiLink device memory/registers.
+ *
+ * The Base Band address has special handling (16 bits registers and
+ * addresses). For more information, see the hardware specification.
+ */
+#define MAX_READ_SIZE 256
+
+struct cmd_read_write_memory {
+ /* The address of the memory to read from or write to.*/
+ u32 addr;
+
+ /* The amount of data in bytes to read from or write to the WiLink
+ * device.*/
+ u32 size;
+
+ /* The actual value read from or written to the Wilink. The source
+ of this field is the Host in WRITE command or the Wilink in READ
+ command. */
+ u8 value[MAX_READ_SIZE];
+};
+
+#define CMDMBOX_HEADER_LEN 4
+#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
+
+
+struct basic_scan_parameters {
+ u32 rx_config_options;
+ u32 rx_filter_options;
+
+ /*
+ * Scan options:
+ * bit 0: When this bit is set, passive scan.
+ * bit 1: Band, when this bit is set we scan
+ * in the 5Ghz band.
+ * bit 2: voice mode, 0 for normal scan.
+ * bit 3: scan priority, 1 for high priority.
+ */
+ u16 scan_options;
+
+ /* Number of channels to scan */
+ u8 num_channels;
+
+ /* Number opf probe requests to send, per channel */
+ u8 num_probe_requests;
+
+ /* Rate and modulation for probe requests */
+ u16 tx_rate;
+
+ u8 tid_trigger;
+ u8 ssid_len;
+ u32 ssid[8];
+
+} __attribute__ ((packed));
+
+struct basic_scan_channel_parameters {
+ u32 min_duration; /* in TU */
+ u32 max_duration; /* in TU */
+ u32 bssid_lsb;
+ u16 bssid_msb;
+
+ /*
+ * bits 0-3: Early termination count.
+ * bits 4-5: Early termination condition.
+ */
+ u8 early_termination;
+
+ u8 tx_power_att;
+ u8 channel;
+ u8 pad[3];
+} __attribute__ ((packed));
+
+/* SCAN parameters */
+#define SCAN_MAX_NUM_OF_CHANNELS 16
+
+struct cmd_scan {
+ struct basic_scan_parameters params;
+ struct basic_scan_channel_parameters channels[SCAN_MAX_NUM_OF_CHANNELS];
+} __attribute__ ((packed));
+
+enum {
+ BSS_TYPE_IBSS = 0,
+ BSS_TYPE_STA_BSS = 2,
+ BSS_TYPE_AP_BSS = 3,
+ MAX_BSS_TYPE = 0xFF
+};
+
+#define JOIN_CMD_CTRL_TX_FLUSH 0x80 /* Firmware flushes all Tx */
+#define JOIN_CMD_CTRL_EARLY_WAKEUP_ENABLE 0x01 /* Early wakeup time */
+
+
+struct cmd_join {
+ u32 bssid_lsb;
+ u16 bssid_msb;
+ u16 beacon_interval; /* in TBTTs */
+ u32 rx_config_options;
+ u32 rx_filter_options;
+
+ /*
+ * The target uses this field to determine the rate at
+ * which to transmit control frame responses (such as
+ * ACK or CTS frames).
+ */
+ u16 basic_rate_set;
+ u8 dtim_interval;
+ u8 tx_ctrl_frame_rate; /* OBSOLETE */
+ u8 tx_ctrl_frame_mod; /* OBSOLETE */
+ /*
+ * bits 0-2: This bitwise field specifies the type
+ * of BSS to start or join (BSS_TYPE_*).
+ * bit 4: Band - The radio band in which to join
+ * or start.
+ * 0 - 2.4GHz band
+ * 1 - 5GHz band
+ * bits 3, 5-7: Reserved
+ */
+ u8 bss_type;
+ u8 channel;
+ u8 ssid_len;
+ u8 ssid[IW_ESSID_MAX_SIZE];
+ u8 ctrl; /* JOIN_CMD_CTRL_* */
+ u8 tx_mgt_frame_rate; /* OBSOLETE */
+ u8 tx_mgt_frame_mod; /* OBSOLETE */
+ u8 reserved;
+} __attribute__ ((packed));
+
+
+#endif /* __WL12XX_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
new file mode 100644
index 00000000000..cdb368ce4da
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -0,0 +1,508 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "debugfs.h"
+
+#include <linux/skbuff.h>
+
+#include "wl12xx.h"
+#include "acx.h"
+
+/* ms */
+#define WL12XX_DEBUGFS_STATS_LIFETIME 1000
+
+/* debugfs macros idea from mac80211 */
+
+#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \
+static ssize_t name## _read(struct file *file, char __user *userbuf, \
+ size_t count, loff_t *ppos) \
+{ \
+ struct wl12xx *wl = file->private_data; \
+ char buf[buflen]; \
+ int res; \
+ \
+ res = scnprintf(buf, buflen, fmt "\n", ##value); \
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+} \
+ \
+static const struct file_operations name## _ops = { \
+ .read = name## _read, \
+ .open = wl12xx_open_file_generic, \
+};
+
+#define DEBUGFS_ADD(name, parent) \
+ wl->debugfs.name = debugfs_create_file(#name, 0400, parent, \
+ wl, &name## _ops); \
+ if (IS_ERR(wl->debugfs.name)) { \
+ ret = PTR_ERR(wl->debugfs.name); \
+ wl->debugfs.name = NULL; \
+ goto out; \
+ }
+
+#define DEBUGFS_DEL(name) \
+ do { \
+ debugfs_remove(wl->debugfs.name); \
+ wl->debugfs.name = NULL; \
+ } while (0)
+
+#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt) \
+static ssize_t sub## _ ##name## _read(struct file *file, \
+ char __user *userbuf, \
+ size_t count, loff_t *ppos) \
+{ \
+ struct wl12xx *wl = file->private_data; \
+ char buf[buflen]; \
+ int res; \
+ \
+ wl12xx_debugfs_update_stats(wl); \
+ \
+ res = scnprintf(buf, buflen, fmt "\n", \
+ wl->stats.fw_stats->sub.name); \
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+} \
+ \
+static const struct file_operations sub## _ ##name## _ops = { \
+ .read = sub## _ ##name## _read, \
+ .open = wl12xx_open_file_generic, \
+};
+
+#define DEBUGFS_FWSTATS_ADD(sub, name) \
+ DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
+
+#define DEBUGFS_FWSTATS_DEL(sub, name) \
+ DEBUGFS_DEL(sub## _ ##name)
+
+static void wl12xx_debugfs_update_stats(struct wl12xx *wl)
+{
+ mutex_lock(&wl->mutex);
+
+ if (wl->state == WL12XX_STATE_ON &&
+ time_after(jiffies, wl->stats.fw_stats_update +
+ msecs_to_jiffies(WL12XX_DEBUGFS_STATS_LIFETIME))) {
+ wl12xx_acx_statistics(wl, wl->stats.fw_stats);
+ wl->stats.fw_stats_update = jiffies;
+ }
+
+ mutex_unlock(&wl->mutex);
+}
+
+static int wl12xx_open_file_generic(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
+/* skipping wep.reserved */
+DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
+/* skipping cont_miss_bcns_spread for now */
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
+ 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
+
+DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
+DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
+ wl->stats.excessive_retries);
+
+static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct wl12xx *wl = file->private_data;
+ u32 queue_len;
+ char buf[20];
+ int res;
+
+ queue_len = skb_queue_len(&wl->tx_queue);
+
+ res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+}
+
+static const struct file_operations tx_queue_len_ops = {
+ .read = tx_queue_len_read,
+ .open = wl12xx_open_file_generic,
+};
+
+static void wl12xx_debugfs_delete_files(struct wl12xx *wl)
+{
+ DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
+
+ DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
+ DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
+ DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
+ DEBUGFS_FWSTATS_DEL(rx, dropped);
+ DEBUGFS_FWSTATS_DEL(rx, fcs_err);
+ DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
+ DEBUGFS_FWSTATS_DEL(rx, path_reset);
+ DEBUGFS_FWSTATS_DEL(rx, reset_counter);
+
+ DEBUGFS_FWSTATS_DEL(dma, rx_requested);
+ DEBUGFS_FWSTATS_DEL(dma, rx_errors);
+ DEBUGFS_FWSTATS_DEL(dma, tx_requested);
+ DEBUGFS_FWSTATS_DEL(dma, tx_errors);
+
+ DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
+ DEBUGFS_FWSTATS_DEL(isr, fiqs);
+ DEBUGFS_FWSTATS_DEL(isr, rx_headers);
+ DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
+ DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
+ DEBUGFS_FWSTATS_DEL(isr, irqs);
+ DEBUGFS_FWSTATS_DEL(isr, tx_procs);
+ DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
+ DEBUGFS_FWSTATS_DEL(isr, dma0_done);
+ DEBUGFS_FWSTATS_DEL(isr, dma1_done);
+ DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
+ DEBUGFS_FWSTATS_DEL(isr, commands);
+ DEBUGFS_FWSTATS_DEL(isr, rx_procs);
+ DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
+ DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
+ DEBUGFS_FWSTATS_DEL(isr, pci_pm);
+ DEBUGFS_FWSTATS_DEL(isr, wakeups);
+ DEBUGFS_FWSTATS_DEL(isr, low_rssi);
+
+ DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
+ DEBUGFS_FWSTATS_DEL(wep, default_key_count);
+ /* skipping wep.reserved */
+ DEBUGFS_FWSTATS_DEL(wep, key_not_found);
+ DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
+ DEBUGFS_FWSTATS_DEL(wep, packets);
+ DEBUGFS_FWSTATS_DEL(wep, interrupt);
+
+ DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
+ DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
+ DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
+ DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
+ DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
+ DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
+ DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
+ DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
+ DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
+ DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
+ DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
+ DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
+ /* skipping cont_miss_bcns_spread for now */
+ DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
+
+ DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
+ DEBUGFS_FWSTATS_DEL(mic, calc_failure);
+
+ DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
+ DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
+ DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
+ DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
+ DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
+ DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
+
+ DEBUGFS_FWSTATS_DEL(event, heart_beat);
+ DEBUGFS_FWSTATS_DEL(event, calibration);
+ DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
+ DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
+ DEBUGFS_FWSTATS_DEL(event, rx_pool);
+ DEBUGFS_FWSTATS_DEL(event, oom_late);
+ DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
+ DEBUGFS_FWSTATS_DEL(event, tx_stuck);
+
+ DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
+ DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
+ DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
+ DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
+ DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
+ DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
+ DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
+
+ DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
+ DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
+
+ DEBUGFS_DEL(tx_queue_len);
+ DEBUGFS_DEL(retry_count);
+ DEBUGFS_DEL(excessive_retries);
+}
+
+static int wl12xx_debugfs_add_files(struct wl12xx *wl)
+{
+ int ret = 0;
+
+ DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
+
+ DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
+ DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
+ DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
+ DEBUGFS_FWSTATS_ADD(rx, dropped);
+ DEBUGFS_FWSTATS_ADD(rx, fcs_err);
+ DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
+ DEBUGFS_FWSTATS_ADD(rx, path_reset);
+ DEBUGFS_FWSTATS_ADD(rx, reset_counter);
+
+ DEBUGFS_FWSTATS_ADD(dma, rx_requested);
+ DEBUGFS_FWSTATS_ADD(dma, rx_errors);
+ DEBUGFS_FWSTATS_ADD(dma, tx_requested);
+ DEBUGFS_FWSTATS_ADD(dma, tx_errors);
+
+ DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
+ DEBUGFS_FWSTATS_ADD(isr, fiqs);
+ DEBUGFS_FWSTATS_ADD(isr, rx_headers);
+ DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
+ DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
+ DEBUGFS_FWSTATS_ADD(isr, irqs);
+ DEBUGFS_FWSTATS_ADD(isr, tx_procs);
+ DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
+ DEBUGFS_FWSTATS_ADD(isr, dma0_done);
+ DEBUGFS_FWSTATS_ADD(isr, dma1_done);
+ DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
+ DEBUGFS_FWSTATS_ADD(isr, commands);
+ DEBUGFS_FWSTATS_ADD(isr, rx_procs);
+ DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
+ DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
+ DEBUGFS_FWSTATS_ADD(isr, pci_pm);
+ DEBUGFS_FWSTATS_ADD(isr, wakeups);
+ DEBUGFS_FWSTATS_ADD(isr, low_rssi);
+
+ DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
+ DEBUGFS_FWSTATS_ADD(wep, default_key_count);
+ /* skipping wep.reserved */
+ DEBUGFS_FWSTATS_ADD(wep, key_not_found);
+ DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
+ DEBUGFS_FWSTATS_ADD(wep, packets);
+ DEBUGFS_FWSTATS_ADD(wep, interrupt);
+
+ DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
+ DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
+ DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
+ DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
+ DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
+ DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
+ DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
+ DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
+ DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
+ DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
+ DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
+ DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
+ /* skipping cont_miss_bcns_spread for now */
+ DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
+
+ DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
+ DEBUGFS_FWSTATS_ADD(mic, calc_failure);
+
+ DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
+ DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
+ DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
+ DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
+ DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
+ DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
+
+ DEBUGFS_FWSTATS_ADD(event, heart_beat);
+ DEBUGFS_FWSTATS_ADD(event, calibration);
+ DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
+ DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
+ DEBUGFS_FWSTATS_ADD(event, rx_pool);
+ DEBUGFS_FWSTATS_ADD(event, oom_late);
+ DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
+ DEBUGFS_FWSTATS_ADD(event, tx_stuck);
+
+ DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
+ DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
+ DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
+ DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
+ DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
+ DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
+ DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
+
+ DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
+ DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
+ DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
+
+ DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
+ DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
+ DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
+
+out:
+ if (ret < 0)
+ wl12xx_debugfs_delete_files(wl);
+
+ return ret;
+}
+
+void wl12xx_debugfs_reset(struct wl12xx *wl)
+{
+ memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
+ wl->stats.retry_count = 0;
+ wl->stats.excessive_retries = 0;
+}
+
+int wl12xx_debugfs_init(struct wl12xx *wl)
+{
+ int ret;
+
+ wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+
+ if (IS_ERR(wl->debugfs.rootdir)) {
+ ret = PTR_ERR(wl->debugfs.rootdir);
+ wl->debugfs.rootdir = NULL;
+ goto err;
+ }
+
+ wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
+ wl->debugfs.rootdir);
+
+ if (IS_ERR(wl->debugfs.fw_statistics)) {
+ ret = PTR_ERR(wl->debugfs.fw_statistics);
+ wl->debugfs.fw_statistics = NULL;
+ goto err_root;
+ }
+
+ wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
+ GFP_KERNEL);
+
+ if (!wl->stats.fw_stats) {
+ ret = -ENOMEM;
+ goto err_fw;
+ }
+
+ wl->stats.fw_stats_update = jiffies;
+
+ ret = wl12xx_debugfs_add_files(wl);
+
+ if (ret < 0)
+ goto err_file;
+
+ return 0;
+
+err_file:
+ kfree(wl->stats.fw_stats);
+ wl->stats.fw_stats = NULL;
+
+err_fw:
+ debugfs_remove(wl->debugfs.fw_statistics);
+ wl->debugfs.fw_statistics = NULL;
+
+err_root:
+ debugfs_remove(wl->debugfs.rootdir);
+ wl->debugfs.rootdir = NULL;
+
+err:
+ return ret;
+}
+
+void wl12xx_debugfs_exit(struct wl12xx *wl)
+{
+ wl12xx_debugfs_delete_files(wl);
+
+ kfree(wl->stats.fw_stats);
+ wl->stats.fw_stats = NULL;
+
+ debugfs_remove(wl->debugfs.fw_statistics);
+ wl->debugfs.fw_statistics = NULL;
+
+ debugfs_remove(wl->debugfs.rootdir);
+ wl->debugfs.rootdir = NULL;
+
+}
diff --git a/drivers/net/wireless/wl12xx/debugfs.h b/drivers/net/wireless/wl12xx/debugfs.h
new file mode 100644
index 00000000000..562cdcbcc87
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/debugfs.h
@@ -0,0 +1,33 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef WL12XX_DEBUGFS_H
+#define WL12XX_DEBUGFS_H
+
+#include "wl12xx.h"
+
+int wl12xx_debugfs_init(struct wl12xx *wl);
+void wl12xx_debugfs_exit(struct wl12xx *wl);
+void wl12xx_debugfs_reset(struct wl12xx *wl);
+
+#endif /* WL12XX_DEBUGFS_H */
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c
new file mode 100644
index 00000000000..99529ca89a7
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/event.c
@@ -0,0 +1,127 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "wl12xx.h"
+#include "reg.h"
+#include "spi.h"
+#include "event.h"
+#include "ps.h"
+
+static int wl12xx_event_scan_complete(struct wl12xx *wl,
+ struct event_mailbox *mbox)
+{
+ wl12xx_debug(DEBUG_EVENT, "status: 0x%x, channels: %d",
+ mbox->scheduled_scan_status,
+ mbox->scheduled_scan_channels);
+
+ if (wl->scanning) {
+ mutex_unlock(&wl->mutex);
+ ieee80211_scan_completed(wl->hw, false);
+ mutex_lock(&wl->mutex);
+ wl->scanning = false;
+ }
+
+ return 0;
+}
+
+static void wl12xx_event_mbox_dump(struct event_mailbox *mbox)
+{
+ wl12xx_debug(DEBUG_EVENT, "MBOX DUMP:");
+ wl12xx_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector);
+ wl12xx_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
+}
+
+static int wl12xx_event_process(struct wl12xx *wl, struct event_mailbox *mbox)
+{
+ int ret;
+ u32 vector;
+
+ wl12xx_event_mbox_dump(mbox);
+
+ vector = mbox->events_vector & ~(mbox->events_mask);
+ wl12xx_debug(DEBUG_EVENT, "vector: 0x%x", vector);
+
+ if (vector & SCAN_COMPLETE_EVENT_ID) {
+ ret = wl12xx_event_scan_complete(wl, mbox);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (vector & BSS_LOSE_EVENT_ID) {
+ wl12xx_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
+
+ if (wl->psm_requested && wl->psm) {
+ ret = wl12xx_ps_set_mode(wl, STATION_ACTIVE_MODE);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+int wl12xx_event_unmask(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl12xx_acx_event_mbox_mask(wl, ~(wl->event_mask));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+void wl12xx_event_mbox_config(struct wl12xx *wl)
+{
+ wl->mbox_ptr[0] = wl12xx_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
+ wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
+
+ wl12xx_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
+ wl->mbox_ptr[0], wl->mbox_ptr[1]);
+}
+
+int wl12xx_event_handle(struct wl12xx *wl, u8 mbox_num)
+{
+ struct event_mailbox mbox;
+ int ret;
+
+ wl12xx_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
+
+ if (mbox_num > 1)
+ return -EINVAL;
+
+ /* first we read the mbox descriptor */
+ wl12xx_spi_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
+ sizeof(struct event_mailbox));
+
+ /* process the descriptor */
+ ret = wl12xx_event_process(wl, &mbox);
+ if (ret < 0)
+ return ret;
+
+ /* then we let the firmware know it can go on...*/
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
+
+ return 0;
+}
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h
new file mode 100644
index 00000000000..1f4c2f7438a
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/event.h
@@ -0,0 +1,121 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_EVENT_H__
+#define __WL12XX_EVENT_H__
+
+/*
+ * Mbox events
+ *
+ * The event mechanism is based on a pair of event buffers (buffers A and
+ * B) at fixed locations in the target's memory. The host processes one
+ * buffer while the other buffer continues to collect events. If the host
+ * is not processing events, an interrupt is issued to signal that a buffer
+ * is ready. Once the host is done with processing events from one buffer,
+ * it signals the target (with an ACK interrupt) that the event buffer is
+ * free.
+ */
+
+enum {
+ RESERVED1_EVENT_ID = BIT(0),
+ RESERVED2_EVENT_ID = BIT(1),
+ MEASUREMENT_START_EVENT_ID = BIT(2),
+ SCAN_COMPLETE_EVENT_ID = BIT(3),
+ CALIBRATION_COMPLETE_EVENT_ID = BIT(4),
+ ROAMING_TRIGGER_LOW_RSSI_EVENT_ID = BIT(5),
+ PS_REPORT_EVENT_ID = BIT(6),
+ SYNCHRONIZATION_TIMEOUT_EVENT_ID = BIT(7),
+ HEALTH_REPORT_EVENT_ID = BIT(8),
+ ACI_DETECTION_EVENT_ID = BIT(9),
+ DEBUG_REPORT_EVENT_ID = BIT(10),
+ MAC_STATUS_EVENT_ID = BIT(11),
+ DISCONNECT_EVENT_COMPLETE_ID = BIT(12),
+ JOIN_EVENT_COMPLETE_ID = BIT(13),
+ CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(14),
+ BSS_LOSE_EVENT_ID = BIT(15),
+ ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(16),
+ MEASUREMENT_COMPLETE_EVENT_ID = BIT(17),
+ AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(18),
+ SCHEDULED_SCAN_COMPLETE_EVENT_ID = BIT(19),
+ PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(20),
+ RESET_BSS_EVENT_ID = BIT(21),
+ REGAINED_BSS_EVENT_ID = BIT(22),
+ ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID = BIT(23),
+ ROAMING_TRIGGER_LOW_SNR_EVENT_ID = BIT(24),
+ ROAMING_TRIGGER_REGAINED_SNR_EVENT_ID = BIT(25),
+
+ DBG_EVENT_ID = BIT(26),
+ BT_PTA_SENSE_EVENT_ID = BIT(27),
+ BT_PTA_PREDICTION_EVENT_ID = BIT(28),
+ BT_PTA_AVALANCHE_EVENT_ID = BIT(29),
+
+ PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(30),
+
+ EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff,
+};
+
+struct event_debug_report {
+ u8 debug_event_id;
+ u8 num_params;
+ u16 pad;
+ u32 report_1;
+ u32 report_2;
+ u32 report_3;
+} __attribute__ ((packed));
+
+struct event_mailbox {
+ u32 events_vector;
+ u32 events_mask;
+ u32 reserved_1;
+ u32 reserved_2;
+
+ char average_rssi_level;
+ u8 ps_status;
+ u8 channel_switch_status;
+ u8 scheduled_scan_status;
+
+ /* Channels scanned by the scheduled scan */
+ u16 scheduled_scan_channels;
+
+ /* If bit 0 is set -> target's fatal error */
+ u16 health_report;
+ u16 bad_fft_counter;
+ u8 bt_pta_sense_info;
+ u8 bt_pta_protective_info;
+ u32 reserved;
+ u32 debug_report[2];
+
+ /* Number of FCS errors since last event */
+ u32 fcs_err_counter;
+
+ struct event_debug_report report;
+ u8 average_snr_level;
+ u8 padding[19];
+} __attribute__ ((packed));
+
+int wl12xx_event_unmask(struct wl12xx *wl);
+void wl12xx_event_mbox_config(struct wl12xx *wl);
+int wl12xx_event_handle(struct wl12xx *wl, u8 mbox);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
new file mode 100644
index 00000000000..2a573a6010b
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -0,0 +1,200 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "init.h"
+#include "wl12xx_80211.h"
+#include "acx.h"
+#include "cmd.h"
+
+int wl12xx_hw_init_hwenc_config(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl12xx_acx_feature_cfg(wl);
+ if (ret < 0) {
+ wl12xx_warning("couldn't set feature config");
+ return ret;
+ }
+
+ ret = wl12xx_acx_default_key(wl, wl->default_key);
+ if (ret < 0) {
+ wl12xx_warning("couldn't set default key");
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_hw_init_templates_config(struct wl12xx *wl)
+{
+ int ret;
+ u8 partial_vbm[PARTIAL_VBM_MAX];
+
+ /* send empty templates for fw memory reservation */
+ ret = wl12xx_cmd_template_set(wl, CMD_PROBE_REQ, NULL,
+ sizeof(struct wl12xx_probe_req_template));
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_template_set(wl, CMD_NULL_DATA, NULL,
+ sizeof(struct wl12xx_null_data_template));
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_template_set(wl, CMD_PS_POLL, NULL,
+ sizeof(struct wl12xx_ps_poll_template));
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_template_set(wl, CMD_QOS_NULL_DATA, NULL,
+ sizeof
+ (struct wl12xx_qos_null_data_template));
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_template_set(wl, CMD_PROBE_RESP, NULL,
+ sizeof
+ (struct wl12xx_probe_resp_template));
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_template_set(wl, CMD_BEACON, NULL,
+ sizeof
+ (struct wl12xx_beacon_template));
+ if (ret < 0)
+ return ret;
+
+ /* tim templates, first reserve space then allocate an empty one */
+ memset(partial_vbm, 0, PARTIAL_VBM_MAX);
+ ret = wl12xx_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, PARTIAL_VBM_MAX, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, 1, 0);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_hw_init_rx_config(struct wl12xx *wl, u32 config, u32 filter)
+{
+ int ret;
+
+ ret = wl12xx_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_acx_rx_config(wl, config, filter);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_hw_init_phy_config(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl12xx_acx_pd_threshold(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_acx_slot(wl, DEFAULT_SLOT_TIME);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_acx_group_address_tbl(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_acx_service_period_timeout(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_hw_init_beacon_filter(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl12xx_acx_beacon_filter_opt(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_acx_beacon_filter_table(wl);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_hw_init_pta(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl12xx_acx_sg_enable(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_acx_sg_cfg(wl);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_hw_init_energy_detection(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl12xx_acx_cca_threshold(wl);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_hw_init_beacon_broadcast(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl12xx_acx_bcn_dtim_options(wl);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_hw_init_power_auth(struct wl12xx *wl)
+{
+ return wl12xx_acx_sleep_auth(wl, WL12XX_PSM_CAM);
+}
diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/wl12xx/init.h
new file mode 100644
index 00000000000..c8b6cd0b7c3
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/init.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_INIT_H__
+#define __WL12XX_INIT_H__
+
+#include "wl12xx.h"
+
+int wl12xx_hw_init_hwenc_config(struct wl12xx *wl);
+int wl12xx_hw_init_templates_config(struct wl12xx *wl);
+int wl12xx_hw_init_mem_config(struct wl12xx *wl);
+int wl12xx_hw_init_rx_config(struct wl12xx *wl, u32 config, u32 filter);
+int wl12xx_hw_init_phy_config(struct wl12xx *wl);
+int wl12xx_hw_init_beacon_filter(struct wl12xx *wl);
+int wl12xx_hw_init_pta(struct wl12xx *wl);
+int wl12xx_hw_init_energy_detection(struct wl12xx *wl);
+int wl12xx_hw_init_beacon_broadcast(struct wl12xx *wl);
+int wl12xx_hw_init_power_auth(struct wl12xx *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
new file mode 100644
index 00000000000..603d6114882
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -0,0 +1,1358 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/spi/spi.h>
+#include <linux/crc32.h>
+#include <linux/etherdevice.h>
+#include <linux/spi/wl12xx.h>
+
+#include "wl12xx.h"
+#include "wl12xx_80211.h"
+#include "reg.h"
+#include "wl1251.h"
+#include "spi.h"
+#include "event.h"
+#include "tx.h"
+#include "rx.h"
+#include "ps.h"
+#include "init.h"
+#include "debugfs.h"
+
+static void wl12xx_disable_interrupts(struct wl12xx *wl)
+{
+ disable_irq(wl->irq);
+}
+
+static void wl12xx_power_off(struct wl12xx *wl)
+{
+ wl->set_power(false);
+}
+
+static void wl12xx_power_on(struct wl12xx *wl)
+{
+ wl->set_power(true);
+}
+
+static irqreturn_t wl12xx_irq(int irq, void *cookie)
+{
+ struct wl12xx *wl;
+
+ wl12xx_debug(DEBUG_IRQ, "IRQ");
+
+ wl = cookie;
+
+ schedule_work(&wl->irq_work);
+
+ return IRQ_HANDLED;
+}
+
+static int wl12xx_fetch_firmware(struct wl12xx *wl)
+{
+ const struct firmware *fw;
+ int ret;
+
+ ret = request_firmware(&fw, wl->chip.fw_filename, &wl->spi->dev);
+
+ if (ret < 0) {
+ wl12xx_error("could not get firmware: %d", ret);
+ return ret;
+ }
+
+ if (fw->size % 4) {
+ wl12xx_error("firmware size is not multiple of 32 bits: %zu",
+ fw->size);
+ ret = -EILSEQ;
+ goto out;
+ }
+
+ wl->fw_len = fw->size;
+ wl->fw = kmalloc(wl->fw_len, GFP_KERNEL);
+
+ if (!wl->fw) {
+ wl12xx_error("could not allocate memory for the firmware");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(wl->fw, fw->data, wl->fw_len);
+
+ ret = 0;
+
+out:
+ release_firmware(fw);
+
+ return ret;
+}
+
+static int wl12xx_fetch_nvs(struct wl12xx *wl)
+{
+ const struct firmware *fw;
+ int ret;
+
+ ret = request_firmware(&fw, wl->chip.nvs_filename, &wl->spi->dev);
+
+ if (ret < 0) {
+ wl12xx_error("could not get nvs file: %d", ret);
+ return ret;
+ }
+
+ if (fw->size % 4) {
+ wl12xx_error("nvs size is not multiple of 32 bits: %zu",
+ fw->size);
+ ret = -EILSEQ;
+ goto out;
+ }
+
+ wl->nvs_len = fw->size;
+ wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL);
+
+ if (!wl->nvs) {
+ wl12xx_error("could not allocate memory for the nvs file");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(wl->nvs, fw->data, wl->nvs_len);
+
+ ret = 0;
+
+out:
+ release_firmware(fw);
+
+ return ret;
+}
+
+static void wl12xx_fw_wakeup(struct wl12xx *wl)
+{
+ u32 elp_reg;
+
+ elp_reg = ELPCTRL_WAKE_UP;
+ wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
+ elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+
+ if (!(elp_reg & ELPCTRL_WLAN_READY)) {
+ wl12xx_warning("WLAN not ready");
+ elp_reg = ELPCTRL_WAKE_UP_WLAN_READY;
+ wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
+ }
+}
+
+static int wl12xx_chip_wakeup(struct wl12xx *wl)
+{
+ int ret = 0;
+
+ wl12xx_power_on(wl);
+ msleep(wl->chip.power_on_sleep);
+ wl12xx_spi_reset(wl);
+ wl12xx_spi_init(wl);
+
+ /* We don't need a real memory partition here, because we only want
+ * to use the registers at this point. */
+ wl12xx_set_partition(wl,
+ 0x00000000,
+ 0x00000000,
+ REGISTERS_BASE,
+ REGISTERS_DOWN_SIZE);
+
+ /* ELP module wake up */
+ wl12xx_fw_wakeup(wl);
+
+ /* whal_FwCtrl_BootSm() */
+
+ /* 0. read chip id from CHIP_ID */
+ wl->chip.id = wl12xx_reg_read32(wl, CHIP_ID_B);
+
+ /* 1. check if chip id is valid */
+
+ switch (wl->chip.id) {
+ case CHIP_ID_1251_PG12:
+ wl12xx_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)",
+ wl->chip.id);
+
+ wl1251_setup(wl);
+
+ break;
+ case CHIP_ID_1271_PG10:
+ case CHIP_ID_1251_PG10:
+ case CHIP_ID_1251_PG11:
+ default:
+ wl12xx_error("unsupported chip id: 0x%x", wl->chip.id);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (wl->fw == NULL) {
+ ret = wl12xx_fetch_firmware(wl);
+ if (ret < 0)
+ goto out;
+ }
+
+ /* No NVS from netlink, try to get it from the filesystem */
+ if (wl->nvs == NULL) {
+ ret = wl12xx_fetch_nvs(wl);
+ if (ret < 0)
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void wl12xx_filter_work(struct work_struct *work)
+{
+ struct wl12xx *wl =
+ container_of(work, struct wl12xx, filter_work);
+ int ret;
+
+ mutex_lock(&wl->mutex);
+
+ if (wl->state == WL12XX_STATE_OFF)
+ goto out;
+
+ ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
+ if (ret < 0)
+ goto out;
+
+out:
+ mutex_unlock(&wl->mutex);
+}
+
+int wl12xx_plt_start(struct wl12xx *wl)
+{
+ int ret;
+
+ wl12xx_notice("power up");
+
+ if (wl->state != WL12XX_STATE_OFF) {
+ wl12xx_error("cannot go into PLT state because not "
+ "in off state: %d", wl->state);
+ return -EBUSY;
+ }
+
+ wl->state = WL12XX_STATE_PLT;
+
+ ret = wl12xx_chip_wakeup(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl->chip.op_boot(wl);
+ if (ret < 0)
+ return ret;
+
+ wl12xx_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver);
+
+ ret = wl->chip.op_plt_init(wl);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int wl12xx_plt_stop(struct wl12xx *wl)
+{
+ wl12xx_notice("power down");
+
+ if (wl->state != WL12XX_STATE_PLT) {
+ wl12xx_error("cannot power down because not in PLT "
+ "state: %d", wl->state);
+ return -EBUSY;
+ }
+
+ wl12xx_disable_interrupts(wl);
+ wl12xx_power_off(wl);
+
+ wl->state = WL12XX_STATE_OFF;
+
+ return 0;
+}
+
+
+static int wl12xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct wl12xx *wl = hw->priv;
+
+ skb_queue_tail(&wl->tx_queue, skb);
+
+ schedule_work(&wl->tx_work);
+
+ /*
+ * The workqueue is slow to process the tx_queue and we need stop
+ * the queue here, otherwise the queue will get too long.
+ */
+ if (skb_queue_len(&wl->tx_queue) >= WL12XX_TX_QUEUE_MAX_LENGTH) {
+ ieee80211_stop_queues(wl->hw);
+
+ /*
+ * FIXME: this is racy, the variable is not properly
+ * protected. Maybe fix this by removing the stupid
+ * variable altogether and checking the real queue state?
+ */
+ wl->tx_queue_stopped = true;
+ }
+
+ return NETDEV_TX_OK;
+}
+
+static int wl12xx_op_start(struct ieee80211_hw *hw)
+{
+ struct wl12xx *wl = hw->priv;
+ int ret = 0;
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 start");
+
+ mutex_lock(&wl->mutex);
+
+ if (wl->state != WL12XX_STATE_OFF) {
+ wl12xx_error("cannot start because not in off state: %d",
+ wl->state);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ ret = wl12xx_chip_wakeup(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl->chip.op_boot(wl);
+ if (ret < 0)
+ goto out;
+
+ ret = wl->chip.op_hw_init(wl);
+ if (ret < 0)
+ goto out;
+
+ ret = wl12xx_acx_station_id(wl);
+ if (ret < 0)
+ goto out;
+
+ wl->state = WL12XX_STATE_ON;
+
+ wl12xx_info("firmware booted (%s)", wl->chip.fw_ver);
+
+out:
+ if (ret < 0)
+ wl12xx_power_off(wl);
+
+ mutex_unlock(&wl->mutex);
+
+ return ret;
+}
+
+static void wl12xx_op_stop(struct ieee80211_hw *hw)
+{
+ struct wl12xx *wl = hw->priv;
+
+ wl12xx_info("down");
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 stop");
+
+ mutex_lock(&wl->mutex);
+
+ WARN_ON(wl->state != WL12XX_STATE_ON);
+
+ if (wl->scanning) {
+ mutex_unlock(&wl->mutex);
+ ieee80211_scan_completed(wl->hw, true);
+ mutex_lock(&wl->mutex);
+ wl->scanning = false;
+ }
+
+ wl->state = WL12XX_STATE_OFF;
+
+ wl12xx_disable_interrupts(wl);
+
+ mutex_unlock(&wl->mutex);
+
+ cancel_work_sync(&wl->irq_work);
+ cancel_work_sync(&wl->tx_work);
+ cancel_work_sync(&wl->filter_work);
+
+ mutex_lock(&wl->mutex);
+
+ /* let's notify MAC80211 about the remaining pending TX frames */
+ wl12xx_tx_flush(wl);
+
+ wl12xx_power_off(wl);
+
+ memset(wl->bssid, 0, ETH_ALEN);
+ wl->listen_int = 1;
+ wl->bss_type = MAX_BSS_TYPE;
+
+ wl->data_in_count = 0;
+ wl->rx_counter = 0;
+ wl->rx_handled = 0;
+ wl->rx_current_buffer = 0;
+ wl->rx_last_id = 0;
+ wl->next_tx_complete = 0;
+ wl->elp = false;
+ wl->psm = 0;
+ wl->tx_queue_stopped = false;
+ wl->power_level = WL12XX_DEFAULT_POWER_LEVEL;
+
+ wl12xx_debugfs_reset(wl);
+
+ mutex_unlock(&wl->mutex);
+}
+
+static int wl12xx_op_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct wl12xx *wl = hw->priv;
+ DECLARE_MAC_BUF(mac);
+ int ret = 0;
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %s",
+ conf->type, print_mac(mac, conf->mac_addr));
+
+ mutex_lock(&wl->mutex);
+
+ switch (conf->type) {
+ case NL80211_IFTYPE_STATION:
+ wl->bss_type = BSS_TYPE_STA_BSS;
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ wl->bss_type = BSS_TYPE_IBSS;
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (memcmp(wl->mac_addr, conf->mac_addr, ETH_ALEN)) {
+ memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
+ SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
+ ret = wl12xx_acx_station_id(wl);
+ if (ret < 0)
+ goto out;
+ }
+
+out:
+ mutex_unlock(&wl->mutex);
+ return ret;
+}
+
+static void wl12xx_op_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 remove interface");
+}
+
+static int wl12xx_build_null_data(struct wl12xx *wl)
+{
+ struct wl12xx_null_data_template template;
+
+ if (!is_zero_ether_addr(wl->bssid)) {
+ memcpy(template.header.da, wl->bssid, ETH_ALEN);
+ memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
+ } else {
+ memset(template.header.da, 0xff, ETH_ALEN);
+ memset(template.header.bssid, 0xff, ETH_ALEN);
+ }
+
+ memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
+ template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
+ IEEE80211_STYPE_NULLFUNC);
+
+ return wl12xx_cmd_template_set(wl, CMD_NULL_DATA, &template,
+ sizeof(template));
+
+}
+
+static int wl12xx_build_ps_poll(struct wl12xx *wl, u16 aid)
+{
+ struct wl12xx_ps_poll_template template;
+
+ memcpy(template.bssid, wl->bssid, ETH_ALEN);
+ memcpy(template.ta, wl->mac_addr, ETH_ALEN);
+ template.aid = aid;
+ template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
+
+ return wl12xx_cmd_template_set(wl, CMD_PS_POLL, &template,
+ sizeof(template));
+
+}
+
+static int wl12xx_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct wl12xx *wl = hw->priv;
+ struct ieee80211_conf *conf = &hw->conf;
+ int channel, ret = 0;
+
+ channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
+ channel,
+ conf->flags & IEEE80211_CONF_PS ? "on" : "off",
+ conf->power_level);
+
+ mutex_lock(&wl->mutex);
+
+ if (channel != wl->channel) {
+ /* FIXME: use beacon interval provided by mac80211 */
+ ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
+ if (ret < 0)
+ goto out;
+
+ wl->channel = channel;
+ }
+
+ ret = wl12xx_build_null_data(wl);
+ if (ret < 0)
+ goto out;
+
+ if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
+ wl12xx_info("psm enabled");
+
+ wl->psm_requested = true;
+
+ /*
+ * We enter PSM only if we're already associated.
+ * If we're not, we'll enter it when joining an SSID,
+ * through the bss_info_changed() hook.
+ */
+ ret = wl12xx_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+ } else if (!(conf->flags & IEEE80211_CONF_PS) &&
+ wl->psm_requested) {
+ wl12xx_info("psm disabled");
+
+ wl->psm_requested = false;
+
+ if (wl->psm)
+ ret = wl12xx_ps_set_mode(wl, STATION_ACTIVE_MODE);
+ }
+
+ if (conf->power_level != wl->power_level) {
+ ret = wl12xx_acx_tx_power(wl, conf->power_level);
+ if (ret < 0)
+ goto out;
+
+ wl->power_level = conf->power_level;
+ }
+
+out:
+ mutex_unlock(&wl->mutex);
+ return ret;
+}
+
+#define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
+ FIF_ALLMULTI | \
+ FIF_FCSFAIL | \
+ FIF_BCN_PRBRESP_PROMISC | \
+ FIF_CONTROL | \
+ FIF_OTHER_BSS)
+
+static void wl12xx_op_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed,
+ unsigned int *total,
+ int mc_count,
+ struct dev_addr_list *mc_list)
+{
+ struct wl12xx *wl = hw->priv;
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 configure filter");
+
+ *total &= WL12XX_SUPPORTED_FILTERS;
+ changed &= WL12XX_SUPPORTED_FILTERS;
+
+ if (changed == 0)
+ /* no filters which we support changed */
+ return;
+
+ /* FIXME: wl->rx_config and wl->rx_filter are not protected */
+
+ wl->rx_config = WL12XX_DEFAULT_RX_CONFIG;
+ wl->rx_filter = WL12XX_DEFAULT_RX_FILTER;
+
+ if (*total & FIF_PROMISC_IN_BSS) {
+ wl->rx_config |= CFG_BSSID_FILTER_EN;
+ wl->rx_config |= CFG_RX_ALL_GOOD;
+ }
+ if (*total & FIF_ALLMULTI)
+ /*
+ * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive
+ * all multicast frames
+ */
+ wl->rx_config &= ~CFG_MC_FILTER_EN;
+ if (*total & FIF_FCSFAIL)
+ wl->rx_filter |= CFG_RX_FCS_ERROR;
+ if (*total & FIF_BCN_PRBRESP_PROMISC) {
+ wl->rx_config &= ~CFG_BSSID_FILTER_EN;
+ wl->rx_config &= ~CFG_SSID_FILTER_EN;
+ }
+ if (*total & FIF_CONTROL)
+ wl->rx_filter |= CFG_RX_CTL_EN;
+ if (*total & FIF_OTHER_BSS)
+ wl->rx_filter &= ~CFG_BSSID_FILTER_EN;
+
+ /*
+ * FIXME: workqueues need to be properly cancelled on stop(), for
+ * now let's just disable changing the filter settings. They will
+ * be updated any on config().
+ */
+ /* schedule_work(&wl->filter_work); */
+}
+
+/* HW encryption */
+static int wl12xx_set_key_type(struct wl12xx *wl, struct acx_set_key *key,
+ enum set_key_cmd cmd,
+ struct ieee80211_key_conf *mac80211_key,
+ const u8 *addr)
+{
+ switch (mac80211_key->alg) {
+ case ALG_WEP:
+ if (is_broadcast_ether_addr(addr))
+ key->key_type = KEY_WEP_DEFAULT;
+ else
+ key->key_type = KEY_WEP_ADDR;
+
+ mac80211_key->hw_key_idx = mac80211_key->keyidx;
+ break;
+ case ALG_TKIP:
+ if (is_broadcast_ether_addr(addr))
+ key->key_type = KEY_TKIP_MIC_GROUP;
+ else
+ key->key_type = KEY_TKIP_MIC_PAIRWISE;
+
+ mac80211_key->hw_key_idx = mac80211_key->keyidx;
+ break;
+ case ALG_CCMP:
+ if (is_broadcast_ether_addr(addr))
+ key->key_type = KEY_AES_GROUP;
+ else
+ key->key_type = KEY_AES_PAIRWISE;
+ mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ break;
+ default:
+ wl12xx_error("Unknown key algo 0x%x", mac80211_key->alg);
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int wl12xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
+{
+ struct wl12xx *wl = hw->priv;
+ struct acx_set_key wl_key;
+ const u8 *addr;
+ int ret;
+
+ static const u8 bcast_addr[ETH_ALEN] =
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 set key");
+
+ memset(&wl_key, 0, sizeof(wl_key));
+
+ addr = sta ? sta->addr : bcast_addr;
+
+ wl12xx_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
+ wl12xx_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
+ wl12xx_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
+ key->alg, key->keyidx, key->keylen, key->flags);
+ wl12xx_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
+
+ mutex_lock(&wl->mutex);
+
+ switch (cmd) {
+ case SET_KEY:
+ wl_key.key_action = KEY_ADD_OR_REPLACE;
+ break;
+ case DISABLE_KEY:
+ wl_key.key_action = KEY_REMOVE;
+ break;
+ default:
+ wl12xx_error("Unsupported key cmd 0x%x", cmd);
+ break;
+ }
+
+ ret = wl12xx_set_key_type(wl, &wl_key, cmd, key, addr);
+ if (ret < 0) {
+ wl12xx_error("Set KEY type failed");
+ goto out;
+ }
+
+ if (wl_key.key_type != KEY_WEP_DEFAULT)
+ memcpy(wl_key.addr, addr, ETH_ALEN);
+
+ if ((wl_key.key_type == KEY_TKIP_MIC_GROUP) ||
+ (wl_key.key_type == KEY_TKIP_MIC_PAIRWISE)) {
+ /*
+ * We get the key in the following form:
+ * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
+ * but the target is expecting:
+ * TKIP - RX MIC - TX MIC
+ */
+ memcpy(wl_key.key, key->key, 16);
+ memcpy(wl_key.key + 16, key->key + 24, 8);
+ memcpy(wl_key.key + 24, key->key + 16, 8);
+
+ } else {
+ memcpy(wl_key.key, key->key, key->keylen);
+ }
+ wl_key.key_size = key->keylen;
+
+ wl_key.id = key->keyidx;
+ wl_key.ssid_profile = 0;
+
+ wl12xx_dump(DEBUG_CRYPT, "TARGET KEY: ", &wl_key, sizeof(wl_key));
+
+ if (wl12xx_cmd_send(wl, CMD_SET_KEYS, &wl_key, sizeof(wl_key)) < 0) {
+ wl12xx_error("Set KEY failed");
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+
+out:
+ mutex_unlock(&wl->mutex);
+ return ret;
+}
+
+static int wl12xx_build_basic_rates(char *rates)
+{
+ u8 index = 0;
+
+ rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
+ rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
+ rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
+ rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
+
+ return index;
+}
+
+static int wl12xx_build_extended_rates(char *rates)
+{
+ u8 index = 0;
+
+ rates[index++] = IEEE80211_OFDM_RATE_6MB;
+ rates[index++] = IEEE80211_OFDM_RATE_9MB;
+ rates[index++] = IEEE80211_OFDM_RATE_12MB;
+ rates[index++] = IEEE80211_OFDM_RATE_18MB;
+ rates[index++] = IEEE80211_OFDM_RATE_24MB;
+ rates[index++] = IEEE80211_OFDM_RATE_36MB;
+ rates[index++] = IEEE80211_OFDM_RATE_48MB;
+ rates[index++] = IEEE80211_OFDM_RATE_54MB;
+
+ return index;
+}
+
+
+static int wl12xx_build_probe_req(struct wl12xx *wl, u8 *ssid, size_t ssid_len)
+{
+ struct wl12xx_probe_req_template template;
+ struct wl12xx_ie_rates *rates;
+ char *ptr;
+ u16 size;
+
+ ptr = (char *)&template;
+ size = sizeof(struct ieee80211_header);
+
+ memset(template.header.da, 0xff, ETH_ALEN);
+ memset(template.header.bssid, 0xff, ETH_ALEN);
+ memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
+ template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
+
+ /* IEs */
+ /* SSID */
+ template.ssid.header.id = WLAN_EID_SSID;
+ template.ssid.header.len = ssid_len;
+ if (ssid_len && ssid)
+ memcpy(template.ssid.ssid, ssid, ssid_len);
+ size += sizeof(struct wl12xx_ie_header) + ssid_len;
+ ptr += size;
+
+ /* Basic Rates */
+ rates = (struct wl12xx_ie_rates *)ptr;
+ rates->header.id = WLAN_EID_SUPP_RATES;
+ rates->header.len = wl12xx_build_basic_rates(rates->rates);
+ size += sizeof(struct wl12xx_ie_header) + rates->header.len;
+ ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
+
+ /* Extended rates */
+ rates = (struct wl12xx_ie_rates *)ptr;
+ rates->header.id = WLAN_EID_EXT_SUPP_RATES;
+ rates->header.len = wl12xx_build_extended_rates(rates->rates);
+ size += sizeof(struct wl12xx_ie_header) + rates->header.len;
+
+ wl12xx_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
+
+ return wl12xx_cmd_template_set(wl, CMD_PROBE_REQ, &template,
+ size);
+}
+
+static int wl12xx_hw_scan(struct wl12xx *wl, u8 *ssid, size_t len,
+ u8 active_scan, u8 high_prio, u8 num_channels,
+ u8 probe_requests)
+{
+ int i, ret;
+ u32 split_scan = 0;
+ u16 scan_options = 0;
+ struct cmd_scan *params;
+ struct wl12xx_command *cmd_answer;
+
+ if (wl->scanning)
+ return -EINVAL;
+
+ params = kzalloc(sizeof(*params), GFP_KERNEL);
+ if (!params)
+ return -ENOMEM;
+
+ params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
+ params->params.rx_filter_options =
+ cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
+
+ /* High priority scan */
+ if (!active_scan)
+ scan_options |= SCAN_PASSIVE;
+ if (high_prio)
+ scan_options |= SCAN_PRIORITY_HIGH;
+ params->params.scan_options = scan_options;
+
+ params->params.num_channels = num_channels;
+ params->params.num_probe_requests = probe_requests;
+ params->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
+ params->params.tid_trigger = 0;
+
+ for (i = 0; i < num_channels; i++) {
+ params->channels[i].min_duration = cpu_to_le32(30000);
+ params->channels[i].max_duration = cpu_to_le32(60000);
+ memset(&params->channels[i].bssid_lsb, 0xff, 4);
+ memset(&params->channels[i].bssid_msb, 0xff, 2);
+ params->channels[i].early_termination = 0;
+ params->channels[i].tx_power_att = 0;
+ params->channels[i].channel = i + 1;
+ memset(params->channels[i].pad, 0, 3);
+ }
+
+ for (i = num_channels; i < SCAN_MAX_NUM_OF_CHANNELS; i++)
+ memset(&params->channels[i], 0,
+ sizeof(struct basic_scan_channel_parameters));
+
+ if (len && ssid) {
+ params->params.ssid_len = len;
+ memcpy(params->params.ssid, ssid, len);
+ } else {
+ params->params.ssid_len = 0;
+ memset(params->params.ssid, 0, 32);
+ }
+
+ ret = wl12xx_build_probe_req(wl, ssid, len);
+ if (ret < 0) {
+ wl12xx_error("PROBE request template failed");
+ goto out;
+ }
+
+ ret = wl12xx_cmd_send(wl, CMD_TRIGGER_SCAN_TO, &split_scan,
+ sizeof(u32));
+ if (ret < 0) {
+ wl12xx_error("Split SCAN failed");
+ goto out;
+ }
+
+ wl12xx_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
+
+ wl->scanning = true;
+
+ ret = wl12xx_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
+ if (ret < 0)
+ wl12xx_error("SCAN failed");
+
+ wl12xx_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
+
+ cmd_answer = (struct wl12xx_command *) params;
+ if (cmd_answer->status != CMD_STATUS_SUCCESS) {
+ wl12xx_error("TEST command answer error: %d",
+ cmd_answer->status);
+ wl->scanning = false;
+ ret = -EIO;
+ goto out;
+ }
+
+out:
+ kfree(params);
+ return ret;
+
+}
+
+static int wl12xx_op_hw_scan(struct ieee80211_hw *hw,
+ struct cfg80211_scan_request *req)
+{
+ struct wl12xx *wl = hw->priv;
+ int ret;
+ u8 *ssid = NULL;
+ size_t ssid_len = 0;
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 hw scan");
+
+ if (req->n_ssids) {
+ ssid = req->ssids[0].ssid;
+ ssid_len = req->ssids[0].ssid_len;
+ }
+
+ mutex_lock(&wl->mutex);
+ ret = wl12xx_hw_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3);
+ mutex_unlock(&wl->mutex);
+
+ return ret;
+}
+
+static int wl12xx_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+ struct wl12xx *wl = hw->priv;
+ int ret;
+
+ ret = wl12xx_acx_rts_threshold(wl, (u16) value);
+
+ if (ret < 0)
+ wl12xx_warning("wl12xx_op_set_rts_threshold failed: %d", ret);
+
+ return ret;
+}
+
+static void wl12xx_op_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changed)
+{
+ enum acx_ps_mode mode;
+ struct wl12xx *wl = hw->priv;
+ struct sk_buff *beacon;
+ int ret;
+
+ wl12xx_debug(DEBUG_MAC80211, "mac80211 bss info changed");
+
+ mutex_lock(&wl->mutex);
+
+ if (changed & BSS_CHANGED_ASSOC) {
+ if (bss_conf->assoc) {
+ wl->aid = bss_conf->aid;
+
+ ret = wl12xx_build_ps_poll(wl, wl->aid);
+ if (ret < 0)
+ goto out;
+
+ ret = wl12xx_acx_aid(wl, wl->aid);
+ if (ret < 0)
+ goto out;
+
+ /* If we want to go in PSM but we're not there yet */
+ if (wl->psm_requested && !wl->psm) {
+ mode = STATION_POWER_SAVE_MODE;
+ ret = wl12xx_ps_set_mode(wl, mode);
+ if (ret < 0)
+ goto out;
+ }
+ }
+ }
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ if (bss_conf->use_short_slot)
+ ret = wl12xx_acx_slot(wl, SLOT_TIME_SHORT);
+ else
+ ret = wl12xx_acx_slot(wl, SLOT_TIME_LONG);
+ if (ret < 0) {
+ wl12xx_warning("Set slot time failed %d", ret);
+ goto out;
+ }
+ }
+
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ if (bss_conf->use_short_preamble)
+ wl12xx_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
+ else
+ wl12xx_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
+ }
+
+ if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+ if (bss_conf->use_cts_prot)
+ ret = wl12xx_acx_cts_protect(wl, CTSPROTECT_ENABLE);
+ else
+ ret = wl12xx_acx_cts_protect(wl, CTSPROTECT_DISABLE);
+ if (ret < 0) {
+ wl12xx_warning("Set ctsprotect failed %d", ret);
+ goto out;
+ }
+ }
+
+ if (changed & BSS_CHANGED_BSSID) {
+ memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
+
+ ret = wl12xx_build_null_data(wl);
+ if (ret < 0)
+ goto out;
+
+ if (wl->bss_type != BSS_TYPE_IBSS) {
+ ret = wl12xx_cmd_join(wl, wl->bss_type, 5, 100, 1);
+ if (ret < 0)
+ goto out;
+ }
+ }
+
+ if (changed & BSS_CHANGED_BEACON) {
+ beacon = ieee80211_beacon_get(hw, vif);
+ ret = wl12xx_cmd_template_set(wl, CMD_BEACON, beacon->data,
+ beacon->len);
+
+ if (ret < 0) {
+ dev_kfree_skb(beacon);
+ goto out;
+ }
+
+ ret = wl12xx_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
+ beacon->len);
+
+ dev_kfree_skb(beacon);
+
+ if (ret < 0)
+ goto out;
+
+ ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
+
+ if (ret < 0)
+ goto out;
+ }
+
+out:
+ mutex_unlock(&wl->mutex);
+}
+
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_rate wl12xx_rates[] = {
+ { .bitrate = 10,
+ .hw_value = 0x1,
+ .hw_value_short = 0x1, },
+ { .bitrate = 20,
+ .hw_value = 0x2,
+ .hw_value_short = 0x2,
+ .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 55,
+ .hw_value = 0x4,
+ .hw_value_short = 0x4,
+ .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 110,
+ .hw_value = 0x20,
+ .hw_value_short = 0x20,
+ .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 60,
+ .hw_value = 0x8,
+ .hw_value_short = 0x8, },
+ { .bitrate = 90,
+ .hw_value = 0x10,
+ .hw_value_short = 0x10, },
+ { .bitrate = 120,
+ .hw_value = 0x40,
+ .hw_value_short = 0x40, },
+ { .bitrate = 180,
+ .hw_value = 0x80,
+ .hw_value_short = 0x80, },
+ { .bitrate = 240,
+ .hw_value = 0x200,
+ .hw_value_short = 0x200, },
+ { .bitrate = 360,
+ .hw_value = 0x400,
+ .hw_value_short = 0x400, },
+ { .bitrate = 480,
+ .hw_value = 0x800,
+ .hw_value_short = 0x800, },
+ { .bitrate = 540,
+ .hw_value = 0x1000,
+ .hw_value_short = 0x1000, },
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_channel wl12xx_channels[] = {
+ { .hw_value = 1, .center_freq = 2412},
+ { .hw_value = 2, .center_freq = 2417},
+ { .hw_value = 3, .center_freq = 2422},
+ { .hw_value = 4, .center_freq = 2427},
+ { .hw_value = 5, .center_freq = 2432},
+ { .hw_value = 6, .center_freq = 2437},
+ { .hw_value = 7, .center_freq = 2442},
+ { .hw_value = 8, .center_freq = 2447},
+ { .hw_value = 9, .center_freq = 2452},
+ { .hw_value = 10, .center_freq = 2457},
+ { .hw_value = 11, .center_freq = 2462},
+ { .hw_value = 12, .center_freq = 2467},
+ { .hw_value = 13, .center_freq = 2472},
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_supported_band wl12xx_band_2ghz = {
+ .channels = wl12xx_channels,
+ .n_channels = ARRAY_SIZE(wl12xx_channels),
+ .bitrates = wl12xx_rates,
+ .n_bitrates = ARRAY_SIZE(wl12xx_rates),
+};
+
+static const struct ieee80211_ops wl12xx_ops = {
+ .start = wl12xx_op_start,
+ .stop = wl12xx_op_stop,
+ .add_interface = wl12xx_op_add_interface,
+ .remove_interface = wl12xx_op_remove_interface,
+ .config = wl12xx_op_config,
+ .configure_filter = wl12xx_op_configure_filter,
+ .tx = wl12xx_op_tx,
+ .set_key = wl12xx_op_set_key,
+ .hw_scan = wl12xx_op_hw_scan,
+ .bss_info_changed = wl12xx_op_bss_info_changed,
+ .set_rts_threshold = wl12xx_op_set_rts_threshold,
+};
+
+static int wl12xx_register_hw(struct wl12xx *wl)
+{
+ int ret;
+
+ if (wl->mac80211_registered)
+ return 0;
+
+ SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
+
+ ret = ieee80211_register_hw(wl->hw);
+ if (ret < 0) {
+ wl12xx_error("unable to register mac80211 hw: %d", ret);
+ return ret;
+ }
+
+ wl->mac80211_registered = true;
+
+ wl12xx_notice("loaded");
+
+ return 0;
+}
+
+static int wl12xx_init_ieee80211(struct wl12xx *wl)
+{
+ /* The tx descriptor buffer and the TKIP space */
+ wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
+ + WL12XX_TKIP_IV_SPACE;
+
+ /* unit us */
+ /* FIXME: find a proper value */
+ wl->hw->channel_change_time = 10000;
+
+ wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_NOISE_DBM;
+
+ wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+ wl->hw->wiphy->max_scan_ssids = 1;
+ wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl12xx_band_2ghz;
+
+ SET_IEEE80211_DEV(wl->hw, &wl->spi->dev);
+
+ return 0;
+}
+
+#define WL12XX_DEFAULT_CHANNEL 1
+static int __devinit wl12xx_probe(struct spi_device *spi)
+{
+ struct wl12xx_platform_data *pdata;
+ struct ieee80211_hw *hw;
+ struct wl12xx *wl;
+ int ret, i;
+ static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
+
+ pdata = spi->dev.platform_data;
+ if (!pdata) {
+ wl12xx_error("no platform data");
+ return -ENODEV;
+ }
+
+ hw = ieee80211_alloc_hw(sizeof(*wl), &wl12xx_ops);
+ if (!hw) {
+ wl12xx_error("could not alloc ieee80211_hw");
+ return -ENOMEM;
+ }
+
+ wl = hw->priv;
+ memset(wl, 0, sizeof(*wl));
+
+ wl->hw = hw;
+ dev_set_drvdata(&spi->dev, wl);
+ wl->spi = spi;
+
+ wl->data_in_count = 0;
+
+ skb_queue_head_init(&wl->tx_queue);
+
+ INIT_WORK(&wl->tx_work, wl12xx_tx_work);
+ INIT_WORK(&wl->filter_work, wl12xx_filter_work);
+ wl->channel = WL12XX_DEFAULT_CHANNEL;
+ wl->scanning = false;
+ wl->default_key = 0;
+ wl->listen_int = 1;
+ wl->rx_counter = 0;
+ wl->rx_handled = 0;
+ wl->rx_current_buffer = 0;
+ wl->rx_last_id = 0;
+ wl->rx_config = WL12XX_DEFAULT_RX_CONFIG;
+ wl->rx_filter = WL12XX_DEFAULT_RX_FILTER;
+ wl->elp = false;
+ wl->psm = 0;
+ wl->psm_requested = false;
+ wl->tx_queue_stopped = false;
+ wl->power_level = WL12XX_DEFAULT_POWER_LEVEL;
+
+ /* We use the default power on sleep time until we know which chip
+ * we're using */
+ wl->chip.power_on_sleep = WL12XX_DEFAULT_POWER_ON_SLEEP;
+
+ for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+ wl->tx_frames[i] = NULL;
+
+ wl->next_tx_complete = 0;
+
+ /*
+ * In case our MAC address is not correctly set,
+ * we use a random but Nokia MAC.
+ */
+ memcpy(wl->mac_addr, nokia_oui, 3);
+ get_random_bytes(wl->mac_addr + 3, 3);
+
+ wl->state = WL12XX_STATE_OFF;
+ mutex_init(&wl->mutex);
+
+ wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
+ wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;
+
+ /* This is the only SPI value that we need to set here, the rest
+ * comes from the board-peripherals file */
+ spi->bits_per_word = 32;
+
+ ret = spi_setup(spi);
+ if (ret < 0) {
+ wl12xx_error("spi_setup failed");
+ goto out_free;
+ }
+
+ wl->set_power = pdata->set_power;
+ if (!wl->set_power) {
+ wl12xx_error("set power function missing in platform data");
+ return -ENODEV;
+ }
+
+ wl->irq = spi->irq;
+ if (wl->irq < 0) {
+ wl12xx_error("irq missing in platform data");
+ return -ENODEV;
+ }
+
+ ret = request_irq(wl->irq, wl12xx_irq, 0, DRIVER_NAME, wl);
+ if (ret < 0) {
+ wl12xx_error("request_irq() failed: %d", ret);
+ goto out_free;
+ }
+
+ set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
+
+ disable_irq(wl->irq);
+
+ ret = wl12xx_init_ieee80211(wl);
+ if (ret)
+ goto out_irq;
+
+ ret = wl12xx_register_hw(wl);
+ if (ret)
+ goto out_irq;
+
+ wl12xx_debugfs_init(wl);
+
+ wl12xx_notice("initialized");
+
+ return 0;
+
+ out_irq:
+ free_irq(wl->irq, wl);
+
+ out_free:
+ ieee80211_free_hw(hw);
+
+ return ret;
+}
+
+static int __devexit wl12xx_remove(struct spi_device *spi)
+{
+ struct wl12xx *wl = dev_get_drvdata(&spi->dev);
+
+ ieee80211_unregister_hw(wl->hw);
+
+ wl12xx_debugfs_exit(wl);
+
+ free_irq(wl->irq, wl);
+ kfree(wl->target_mem_map);
+ kfree(wl->data_path);
+ kfree(wl->fw);
+ wl->fw = NULL;
+ kfree(wl->nvs);
+ wl->nvs = NULL;
+ ieee80211_free_hw(wl->hw);
+
+ return 0;
+}
+
+
+static struct spi_driver wl12xx_spi_driver = {
+ .driver = {
+ .name = "wl12xx",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+
+ .probe = wl12xx_probe,
+ .remove = __devexit_p(wl12xx_remove),
+};
+
+static int __init wl12xx_init(void)
+{
+ int ret;
+
+ ret = spi_register_driver(&wl12xx_spi_driver);
+ if (ret < 0) {
+ wl12xx_error("failed to register spi driver: %d", ret);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void __exit wl12xx_exit(void)
+{
+ spi_unregister_driver(&wl12xx_spi_driver);
+
+ wl12xx_notice("unloaded");
+}
+
+module_init(wl12xx_init);
+module_exit(wl12xx_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <Kalle.Valo@nokia.com>, "
+ "Luciano Coelho <luciano.coelho@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
new file mode 100644
index 00000000000..83a10117330
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -0,0 +1,151 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "reg.h"
+#include "ps.h"
+#include "spi.h"
+
+#define WL12XX_WAKEUP_TIMEOUT 2000
+
+/* Routines to toggle sleep mode while in ELP */
+void wl12xx_ps_elp_sleep(struct wl12xx *wl)
+{
+ if (wl->elp || !wl->psm)
+ return;
+
+ wl12xx_debug(DEBUG_PSM, "chip to elp");
+
+ wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
+
+ wl->elp = true;
+}
+
+int wl12xx_ps_elp_wakeup(struct wl12xx *wl)
+{
+ unsigned long timeout;
+ u32 elp_reg;
+
+ if (!wl->elp)
+ return 0;
+
+ wl12xx_debug(DEBUG_PSM, "waking up chip from elp");
+
+ timeout = jiffies + msecs_to_jiffies(WL12XX_WAKEUP_TIMEOUT);
+
+ wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
+
+ elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+
+ /*
+ * FIXME: we should wait for irq from chip but, as a temporary
+ * solution to simplify locking, let's poll instead
+ */
+ while (!(elp_reg & ELPCTRL_WLAN_READY)) {
+ if (time_after(jiffies, timeout)) {
+ wl12xx_error("elp wakeup timeout");
+ return -ETIMEDOUT;
+ }
+ msleep(1);
+ elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+ }
+
+ wl12xx_debug(DEBUG_PSM, "wakeup time: %u ms",
+ jiffies_to_msecs(jiffies) -
+ (jiffies_to_msecs(timeout) - WL12XX_WAKEUP_TIMEOUT));
+
+ wl->elp = false;
+
+ return 0;
+}
+
+static int wl12xx_ps_set_elp(struct wl12xx *wl, bool enable)
+{
+ int ret;
+
+ if (enable) {
+ wl12xx_debug(DEBUG_PSM, "sleep auth psm/elp");
+
+ /*
+ * FIXME: we should PSM_ELP, but because of firmware wakeup
+ * problems let's use only PSM_PS
+ */
+ ret = wl12xx_acx_sleep_auth(wl, WL12XX_PSM_PS);
+ if (ret < 0)
+ return ret;
+
+ wl12xx_ps_elp_sleep(wl);
+ } else {
+ wl12xx_debug(DEBUG_PSM, "sleep auth cam");
+
+ /*
+ * When the target is in ELP, we can only
+ * access the ELP control register. Thus,
+ * we have to wake the target up before
+ * changing the power authorization.
+ */
+
+ wl12xx_ps_elp_wakeup(wl);
+
+ ret = wl12xx_acx_sleep_auth(wl, WL12XX_PSM_CAM);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+int wl12xx_ps_set_mode(struct wl12xx *wl, enum acx_ps_mode mode)
+{
+ int ret;
+
+ switch (mode) {
+ case STATION_POWER_SAVE_MODE:
+ wl12xx_debug(DEBUG_PSM, "entering psm");
+ ret = wl12xx_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_ps_set_elp(wl, true);
+ if (ret < 0)
+ return ret;
+
+ wl->psm = 1;
+ break;
+ case STATION_ACTIVE_MODE:
+ default:
+ wl12xx_debug(DEBUG_PSM, "leaving psm");
+ ret = wl12xx_ps_set_elp(wl, false);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
+ if (ret < 0)
+ return ret;
+
+ wl->psm = 0;
+ break;
+ }
+
+ return ret;
+}
+
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h
new file mode 100644
index 00000000000..5d7c5255383
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/ps.h
@@ -0,0 +1,36 @@
+#ifndef __WL12XX_PS_H__
+#define __WL12XX_PS_H__
+
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "wl12xx.h"
+#include "acx.h"
+
+int wl12xx_ps_set_mode(struct wl12xx *wl, enum acx_ps_mode mode);
+void wl12xx_ps_elp_sleep(struct wl12xx *wl);
+int wl12xx_ps_elp_wakeup(struct wl12xx *wl);
+
+
+#endif /* __WL12XX_PS_H__ */
diff --git a/drivers/net/wireless/wl12xx/reg.h b/drivers/net/wireless/wl12xx/reg.h
new file mode 100644
index 00000000000..e421643215c
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/reg.h
@@ -0,0 +1,745 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __REG_H__
+#define __REG_H__
+
+#include <linux/bitops.h>
+#include "wl12xx.h"
+
+#define REGISTERS_BASE 0x00300000
+#define DRPW_BASE 0x00310000
+
+#define REGISTERS_DOWN_SIZE 0x00008800
+#define REGISTERS_WORK_SIZE 0x0000b000
+
+#define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC
+
+/* ELP register commands */
+#define ELPCTRL_WAKE_UP 0x1
+#define ELPCTRL_WAKE_UP_WLAN_READY 0x5
+#define ELPCTRL_SLEEP 0x0
+/* ELP WLAN_READY bit */
+#define ELPCTRL_WLAN_READY 0x2
+
+/*
+ * Interrupt registers.
+ * 64 bit interrupt sources registers ws ced.
+ * sme interupts were removed and new ones were added.
+ * Order was changed.
+ */
+#define FIQ_MASK (REGISTERS_BASE + 0x0400)
+#define FIQ_MASK_L (REGISTERS_BASE + 0x0400)
+#define FIQ_MASK_H (REGISTERS_BASE + 0x0404)
+#define FIQ_MASK_SET (REGISTERS_BASE + 0x0408)
+#define FIQ_MASK_SET_L (REGISTERS_BASE + 0x0408)
+#define FIQ_MASK_SET_H (REGISTERS_BASE + 0x040C)
+#define FIQ_MASK_CLR (REGISTERS_BASE + 0x0410)
+#define FIQ_MASK_CLR_L (REGISTERS_BASE + 0x0410)
+#define FIQ_MASK_CLR_H (REGISTERS_BASE + 0x0414)
+#define IRQ_MASK (REGISTERS_BASE + 0x0418)
+#define IRQ_MASK_L (REGISTERS_BASE + 0x0418)
+#define IRQ_MASK_H (REGISTERS_BASE + 0x041C)
+#define IRQ_MASK_SET (REGISTERS_BASE + 0x0420)
+#define IRQ_MASK_SET_L (REGISTERS_BASE + 0x0420)
+#define IRQ_MASK_SET_H (REGISTERS_BASE + 0x0424)
+#define IRQ_MASK_CLR (REGISTERS_BASE + 0x0428)
+#define IRQ_MASK_CLR_L (REGISTERS_BASE + 0x0428)
+#define IRQ_MASK_CLR_H (REGISTERS_BASE + 0x042C)
+#define ECPU_MASK (REGISTERS_BASE + 0x0448)
+#define FIQ_STS_L (REGISTERS_BASE + 0x044C)
+#define FIQ_STS_H (REGISTERS_BASE + 0x0450)
+#define IRQ_STS_L (REGISTERS_BASE + 0x0454)
+#define IRQ_STS_H (REGISTERS_BASE + 0x0458)
+#define INT_STS_ND (REGISTERS_BASE + 0x0464)
+#define INT_STS_RAW_L (REGISTERS_BASE + 0x0464)
+#define INT_STS_RAW_H (REGISTERS_BASE + 0x0468)
+#define INT_STS_CLR (REGISTERS_BASE + 0x04B4)
+#define INT_STS_CLR_L (REGISTERS_BASE + 0x04B4)
+#define INT_STS_CLR_H (REGISTERS_BASE + 0x04B8)
+#define INT_ACK (REGISTERS_BASE + 0x046C)
+#define INT_ACK_L (REGISTERS_BASE + 0x046C)
+#define INT_ACK_H (REGISTERS_BASE + 0x0470)
+#define INT_TRIG (REGISTERS_BASE + 0x0474)
+#define INT_TRIG_L (REGISTERS_BASE + 0x0474)
+#define INT_TRIG_H (REGISTERS_BASE + 0x0478)
+#define HOST_STS_L (REGISTERS_BASE + 0x045C)
+#define HOST_STS_H (REGISTERS_BASE + 0x0460)
+#define HOST_MASK (REGISTERS_BASE + 0x0430)
+#define HOST_MASK_L (REGISTERS_BASE + 0x0430)
+#define HOST_MASK_H (REGISTERS_BASE + 0x0434)
+#define HOST_MASK_SET (REGISTERS_BASE + 0x0438)
+#define HOST_MASK_SET_L (REGISTERS_BASE + 0x0438)
+#define HOST_MASK_SET_H (REGISTERS_BASE + 0x043C)
+#define HOST_MASK_CLR (REGISTERS_BASE + 0x0440)
+#define HOST_MASK_CLR_L (REGISTERS_BASE + 0x0440)
+#define HOST_MASK_CLR_H (REGISTERS_BASE + 0x0444)
+
+/* Host Interrupts*/
+#define HINT_MASK (REGISTERS_BASE + 0x0494)
+#define HINT_MASK_SET (REGISTERS_BASE + 0x0498)
+#define HINT_MASK_CLR (REGISTERS_BASE + 0x049C)
+#define HINT_STS_ND_MASKED (REGISTERS_BASE + 0x04A0)
+/*1150 spec calls this HINT_STS_RAW*/
+#define HINT_STS_ND (REGISTERS_BASE + 0x04B0)
+#define HINT_STS_CLR (REGISTERS_BASE + 0x04A4)
+#define HINT_ACK (REGISTERS_BASE + 0x04A8)
+#define HINT_TRIG (REGISTERS_BASE + 0x04AC)
+
+/* Device Configuration registers*/
+#define SOR_CFG (REGISTERS_BASE + 0x0800)
+#define ECPU_CTRL (REGISTERS_BASE + 0x0804)
+#define HI_CFG (REGISTERS_BASE + 0x0808)
+#define EE_START (REGISTERS_BASE + 0x080C)
+
+#define CHIP_ID_B (REGISTERS_BASE + 0x5674)
+
+#define CHIP_ID_1251_PG10 (0x7010101)
+#define CHIP_ID_1251_PG11 (0x7020101)
+#define CHIP_ID_1251_PG12 (0x7030101)
+
+#define ENABLE (REGISTERS_BASE + 0x5450)
+
+/* Power Management registers */
+#define ELP_CFG_MODE (REGISTERS_BASE + 0x5804)
+#define ELP_CMD (REGISTERS_BASE + 0x5808)
+#define PLL_CAL_TIME (REGISTERS_BASE + 0x5810)
+#define CLK_REQ_TIME (REGISTERS_BASE + 0x5814)
+#define CLK_BUF_TIME (REGISTERS_BASE + 0x5818)
+
+#define CFG_PLL_SYNC_CNT (REGISTERS_BASE + 0x5820)
+
+/* Scratch Pad registers*/
+#define SCR_PAD0 (REGISTERS_BASE + 0x5608)
+#define SCR_PAD1 (REGISTERS_BASE + 0x560C)
+#define SCR_PAD2 (REGISTERS_BASE + 0x5610)
+#define SCR_PAD3 (REGISTERS_BASE + 0x5614)
+#define SCR_PAD4 (REGISTERS_BASE + 0x5618)
+#define SCR_PAD4_SET (REGISTERS_BASE + 0x561C)
+#define SCR_PAD4_CLR (REGISTERS_BASE + 0x5620)
+#define SCR_PAD5 (REGISTERS_BASE + 0x5624)
+#define SCR_PAD5_SET (REGISTERS_BASE + 0x5628)
+#define SCR_PAD5_CLR (REGISTERS_BASE + 0x562C)
+#define SCR_PAD6 (REGISTERS_BASE + 0x5630)
+#define SCR_PAD7 (REGISTERS_BASE + 0x5634)
+#define SCR_PAD8 (REGISTERS_BASE + 0x5638)
+#define SCR_PAD9 (REGISTERS_BASE + 0x563C)
+
+/* Spare registers*/
+#define SPARE_A1 (REGISTERS_BASE + 0x0994)
+#define SPARE_A2 (REGISTERS_BASE + 0x0998)
+#define SPARE_A3 (REGISTERS_BASE + 0x099C)
+#define SPARE_A4 (REGISTERS_BASE + 0x09A0)
+#define SPARE_A5 (REGISTERS_BASE + 0x09A4)
+#define SPARE_A6 (REGISTERS_BASE + 0x09A8)
+#define SPARE_A7 (REGISTERS_BASE + 0x09AC)
+#define SPARE_A8 (REGISTERS_BASE + 0x09B0)
+#define SPARE_B1 (REGISTERS_BASE + 0x5420)
+#define SPARE_B2 (REGISTERS_BASE + 0x5424)
+#define SPARE_B3 (REGISTERS_BASE + 0x5428)
+#define SPARE_B4 (REGISTERS_BASE + 0x542C)
+#define SPARE_B5 (REGISTERS_BASE + 0x5430)
+#define SPARE_B6 (REGISTERS_BASE + 0x5434)
+#define SPARE_B7 (REGISTERS_BASE + 0x5438)
+#define SPARE_B8 (REGISTERS_BASE + 0x543C)
+
+enum wl12xx_acx_int_reg {
+ ACX_REG_INTERRUPT_TRIG,
+ ACX_REG_INTERRUPT_TRIG_H,
+
+/*=============================================
+ Host Interrupt Mask Register - 32bit (RW)
+ ------------------------------------------
+ Setting a bit in this register masks the
+ corresponding interrupt to the host.
+ 0 - RX0 - Rx first dubble buffer Data Interrupt
+ 1 - TXD - Tx Data Interrupt
+ 2 - TXXFR - Tx Transfer Interrupt
+ 3 - RX1 - Rx second dubble buffer Data Interrupt
+ 4 - RXXFR - Rx Transfer Interrupt
+ 5 - EVENT_A - Event Mailbox interrupt
+ 6 - EVENT_B - Event Mailbox interrupt
+ 7 - WNONHST - Wake On Host Interrupt
+ 8 - TRACE_A - Debug Trace interrupt
+ 9 - TRACE_B - Debug Trace interrupt
+ 10 - CDCMP - Command Complete Interrupt
+ 11 -
+ 12 -
+ 13 -
+ 14 - ICOMP - Initialization Complete Interrupt
+ 16 - SG SE - Soft Gemini - Sense enable interrupt
+ 17 - SG SD - Soft Gemini - Sense disable interrupt
+ 18 - -
+ 19 - -
+ 20 - -
+ 21- -
+ Default: 0x0001
+*==============================================*/
+ ACX_REG_INTERRUPT_MASK,
+
+/*=============================================
+ Host Interrupt Mask Set 16bit, (Write only)
+ ------------------------------------------
+ Setting a bit in this register sets
+ the corresponding bin in ACX_HINT_MASK register
+ without effecting the mask
+ state of other bits (0 = no effect).
+==============================================*/
+ ACX_REG_HINT_MASK_SET,
+
+/*=============================================
+ Host Interrupt Mask Clear 16bit,(Write only)
+ ------------------------------------------
+ Setting a bit in this register clears
+ the corresponding bin in ACX_HINT_MASK register
+ without effecting the mask
+ state of other bits (0 = no effect).
+=============================================*/
+ ACX_REG_HINT_MASK_CLR,
+
+/*=============================================
+ Host Interrupt Status Nondestructive Read
+ 16bit,(Read only)
+ ------------------------------------------
+ The host can read this register to determine
+ which interrupts are active.
+ Reading this register doesn't
+ effect its content.
+=============================================*/
+ ACX_REG_INTERRUPT_NO_CLEAR,
+
+/*=============================================
+ Host Interrupt Status Clear on Read Register
+ 16bit,(Read only)
+ ------------------------------------------
+ The host can read this register to determine
+ which interrupts are active.
+ Reading this register clears it,
+ thus making all interrupts inactive.
+==============================================*/
+ ACX_REG_INTERRUPT_CLEAR,
+
+/*=============================================
+ Host Interrupt Acknowledge Register
+ 16bit,(Write only)
+ ------------------------------------------
+ The host can set individual bits in this
+ register to clear (acknowledge) the corresp.
+ interrupt status bits in the HINT_STS_CLR and
+ HINT_STS_ND registers, thus making the
+ assotiated interrupt inactive. (0-no effect)
+==============================================*/
+ ACX_REG_INTERRUPT_ACK,
+
+/*===============================================
+ Host Software Reset - 32bit RW
+ ------------------------------------------
+ [31:1] Reserved
+ 0 SOFT_RESET Soft Reset - When this bit is set,
+ it holds the Wlan hardware in a soft reset state.
+ This reset disables all MAC and baseband processor
+ clocks except the CardBus/PCI interface clock.
+ It also initializes all MAC state machines except
+ the host interface. It does not reload the
+ contents of the EEPROM. When this bit is cleared
+ (not self-clearing), the Wlan hardware
+ exits the software reset state.
+===============================================*/
+ ACX_REG_SLV_SOFT_RESET,
+
+/*===============================================
+ EEPROM Burst Read Start - 32bit RW
+ ------------------------------------------
+ [31:1] Reserved
+ 0 ACX_EE_START - EEPROM Burst Read Start 0
+ Setting this bit starts a burst read from
+ the external EEPROM.
+ If this bit is set (after reset) before an EEPROM read/write,
+ the burst read starts at EEPROM address 0.
+ Otherwise, it starts at the address
+ following the address of the previous access.
+ TheWlan hardware hardware clears this bit automatically.
+
+ Default: 0x00000000
+*================================================*/
+ ACX_REG_EE_START,
+
+/* Embedded ARM CPU Control */
+
+/*===============================================
+ Halt eCPU - 32bit RW
+ ------------------------------------------
+ 0 HALT_ECPU Halt Embedded CPU - This bit is the
+ compliment of bit 1 (MDATA2) in the SOR_CFG register.
+ During a hardware reset, this bit holds
+ the inverse of MDATA2.
+ When downloading firmware from the host,
+ set this bit (pull down MDATA2).
+ The host clears this bit after downloading the firmware into
+ zero-wait-state SSRAM.
+ When loading firmware from Flash, clear this bit (pull up MDATA2)
+ so that the eCPU can run the bootloader code in Flash
+ HALT_ECPU eCPU State
+ --------------------
+ 1 halt eCPU
+ 0 enable eCPU
+ ===============================================*/
+ ACX_REG_ECPU_CONTROL,
+
+ ACX_REG_TABLE_LEN
+};
+
+#define ACX_SLV_SOFT_RESET_BIT BIT(1)
+#define ACX_REG_EEPROM_START_BIT BIT(1)
+
+/* Command/Information Mailbox Pointers */
+
+/*===============================================
+ Command Mailbox Pointer - 32bit RW
+ ------------------------------------------
+ This register holds the start address of
+ the command mailbox located in the Wlan hardware memory.
+ The host must read this pointer after a reset to
+ find the location of the command mailbox.
+ The Wlan hardware initializes the command mailbox
+ pointer with the default address of the command mailbox.
+ The command mailbox pointer is not valid until after
+ the host receives the Init Complete interrupt from
+ the Wlan hardware.
+ ===============================================*/
+#define REG_COMMAND_MAILBOX_PTR (SCR_PAD0)
+
+/*===============================================
+ Information Mailbox Pointer - 32bit RW
+ ------------------------------------------
+ This register holds the start address of
+ the information mailbox located in the Wlan hardware memory.
+ The host must read this pointer after a reset to find
+ the location of the information mailbox.
+ The Wlan hardware initializes the information mailbox pointer
+ with the default address of the information mailbox.
+ The information mailbox pointer is not valid
+ until after the host receives the Init Complete interrupt from
+ the Wlan hardware.
+ ===============================================*/
+#define REG_EVENT_MAILBOX_PTR (SCR_PAD1)
+
+
+/* Misc */
+
+#define REG_ENABLE_TX_RX (ENABLE)
+/*
+ * Rx configuration (filter) information element
+ * ---------------------------------------------
+ */
+#define REG_RX_CONFIG (RX_CFG)
+#define REG_RX_FILTER (RX_FILTER_CFG)
+
+
+#define RX_CFG_ENABLE_PHY_HEADER_PLCP 0x0002
+
+/* promiscuous - receives all valid frames */
+#define RX_CFG_PROMISCUOUS 0x0008
+
+/* receives frames from any BSSID */
+#define RX_CFG_BSSID 0x0020
+
+/* receives frames destined to any MAC address */
+#define RX_CFG_MAC 0x0010
+
+#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC 0x0010
+#define RX_CFG_ENABLE_ANY_DEST_MAC 0x0000
+#define RX_CFG_ENABLE_ONLY_MY_BSSID 0x0020
+#define RX_CFG_ENABLE_ANY_BSSID 0x0000
+
+/* discards all broadcast frames */
+#define RX_CFG_DISABLE_BCAST 0x0200
+
+#define RX_CFG_ENABLE_ONLY_MY_SSID 0x0400
+#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800
+#define RX_CFG_COPY_RX_STATUS 0x2000
+#define RX_CFG_TSF 0x10000
+
+#define RX_CONFIG_OPTION_ANY_DST_MY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
+ RX_CFG_ENABLE_ONLY_MY_BSSID)
+
+#define RX_CONFIG_OPTION_MY_DST_ANY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
+ | RX_CFG_ENABLE_ANY_BSSID)
+
+#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
+ RX_CFG_ENABLE_ANY_BSSID)
+
+#define RX_CONFIG_OPTION_MY_DST_MY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
+ | RX_CFG_ENABLE_ONLY_MY_BSSID)
+
+#define RX_CONFIG_OPTION_FOR_SCAN (RX_CFG_ENABLE_PHY_HEADER_PLCP \
+ | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \
+ | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF)
+
+#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC)
+
+#define RX_CONFIG_OPTION_FOR_JOIN (RX_CFG_ENABLE_ONLY_MY_BSSID | \
+ RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
+
+#define RX_CONFIG_OPTION_FOR_IBSS_JOIN (RX_CFG_ENABLE_ONLY_MY_SSID | \
+ RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
+
+#define RX_FILTER_OPTION_DEF (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
+ | CFG_RX_CTL_EN | CFG_RX_BCN_EN\
+ | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
+
+#define RX_FILTER_OPTION_FILTER_ALL 0
+
+#define RX_FILTER_OPTION_DEF_PRSP_BCN (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\
+ | CFG_RX_RCTS_ACK | CFG_RX_BCN_EN)
+
+#define RX_FILTER_OPTION_JOIN (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
+ | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\
+ | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\
+ | CFG_RX_PRSP_EN)
+
+
+/*===============================================
+ Phy regs
+ ===============================================*/
+#define ACX_PHY_ADDR_REG SBB_ADDR
+#define ACX_PHY_DATA_REG SBB_DATA
+#define ACX_PHY_CTRL_REG SBB_CTL
+#define ACX_PHY_REG_WR_MASK 0x00000001ul
+#define ACX_PHY_REG_RD_MASK 0x00000002ul
+
+
+/*===============================================
+ EEPROM Read/Write Request 32bit RW
+ ------------------------------------------
+ 1 EE_READ - EEPROM Read Request 1 - Setting this bit
+ loads a single byte of data into the EE_DATA
+ register from the EEPROM location specified in
+ the EE_ADDR register.
+ The Wlan hardware hardware clears this bit automatically.
+ EE_DATA is valid when this bit is cleared.
+
+ 0 EE_WRITE - EEPROM Write Request - Setting this bit
+ writes a single byte of data from the EE_DATA register into the
+ EEPROM location specified in the EE_ADDR register.
+ The Wlan hardware hardware clears this bit automatically.
+*===============================================*/
+#define ACX_EE_CTL_REG EE_CTL
+#define EE_WRITE 0x00000001ul
+#define EE_READ 0x00000002ul
+
+/*===============================================
+ EEPROM Address - 32bit RW
+ ------------------------------------------
+ This register specifies the address
+ within the EEPROM from/to which to read/write data.
+ ===============================================*/
+#define ACX_EE_ADDR_REG EE_ADDR
+
+/*===============================================
+ EEPROM Data - 32bit RW
+ ------------------------------------------
+ This register either holds the read 8 bits of
+ data from the EEPROM or the write data
+ to be written to the EEPROM.
+ ===============================================*/
+#define ACX_EE_DATA_REG EE_DATA
+
+/*===============================================
+ EEPROM Base Address - 32bit RW
+ ------------------------------------------
+ This register holds the upper nine bits
+ [23:15] of the 24-bit Wlan hardware memory
+ address for burst reads from EEPROM accesses.
+ The EEPROM provides the lower 15 bits of this address.
+ The MSB of the address from the EEPROM is ignored.
+ ===============================================*/
+#define ACX_EE_CFG EE_CFG
+
+/*===============================================
+ GPIO Output Values -32bit, RW
+ ------------------------------------------
+ [31:16] Reserved
+ [15: 0] Specify the output values (at the output driver inputs) for
+ GPIO[15:0], respectively.
+ ===============================================*/
+#define ACX_GPIO_OUT_REG GPIO_OUT
+#define ACX_MAX_GPIO_LINES 15
+
+/*===============================================
+ Contention window -32bit, RW
+ ------------------------------------------
+ [31:26] Reserved
+ [25:16] Max (0x3ff)
+ [15:07] Reserved
+ [06:00] Current contention window value - default is 0x1F
+ ===============================================*/
+#define ACX_CONT_WIND_CFG_REG CONT_WIND_CFG
+#define ACX_CONT_WIND_MIN_MASK 0x0000007f
+#define ACX_CONT_WIND_MAX 0x03ff0000
+
+/*
+ * Indirect slave register/memory registers
+ * ----------------------------------------
+ */
+#define HW_SLAVE_REG_ADDR_REG 0x00000004
+#define HW_SLAVE_REG_DATA_REG 0x00000008
+#define HW_SLAVE_REG_CTRL_REG 0x0000000c
+
+#define SLAVE_AUTO_INC 0x00010000
+#define SLAVE_NO_AUTO_INC 0x00000000
+#define SLAVE_HOST_LITTLE_ENDIAN 0x00000000
+
+#define HW_SLAVE_MEM_ADDR_REG SLV_MEM_ADDR
+#define HW_SLAVE_MEM_DATA_REG SLV_MEM_DATA
+#define HW_SLAVE_MEM_CTRL_REG SLV_MEM_CTL
+#define HW_SLAVE_MEM_ENDIAN_REG SLV_END_CTL
+
+#define HW_FUNC_EVENT_INT_EN 0x8000
+#define HW_FUNC_EVENT_MASK_REG 0x00000034
+
+#define ACX_MAC_TIMESTAMP_REG (MAC_TIMESTAMP)
+
+/*===============================================
+ HI_CFG Interface Configuration Register Values
+ ------------------------------------------
+ ===============================================*/
+#define HI_CFG_UART_ENABLE 0x00000004
+#define HI_CFG_RST232_ENABLE 0x00000008
+#define HI_CFG_CLOCK_REQ_SELECT 0x00000010
+#define HI_CFG_HOST_INT_ENABLE 0x00000020
+#define HI_CFG_VLYNQ_OUTPUT_ENABLE 0x00000040
+#define HI_CFG_HOST_INT_ACTIVE_LOW 0x00000080
+#define HI_CFG_UART_TX_OUT_GPIO_15 0x00000100
+#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200
+#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400
+
+/*
+ * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile
+ * for platforms using active high interrupt level
+ */
+#ifdef USE_ACTIVE_HIGH
+#define HI_CFG_DEF_VAL \
+ (HI_CFG_UART_ENABLE | \
+ HI_CFG_RST232_ENABLE | \
+ HI_CFG_CLOCK_REQ_SELECT | \
+ HI_CFG_HOST_INT_ENABLE)
+#else
+#define HI_CFG_DEF_VAL \
+ (HI_CFG_UART_ENABLE | \
+ HI_CFG_RST232_ENABLE | \
+ HI_CFG_CLOCK_REQ_SELECT | \
+ HI_CFG_HOST_INT_ENABLE)
+
+#endif
+
+#define REF_FREQ_19_2 0
+#define REF_FREQ_26_0 1
+#define REF_FREQ_38_4 2
+#define REF_FREQ_40_0 3
+#define REF_FREQ_33_6 4
+#define REF_FREQ_NUM 5
+
+#define LUT_PARAM_INTEGER_DIVIDER 0
+#define LUT_PARAM_FRACTIONAL_DIVIDER 1
+#define LUT_PARAM_ATTN_BB 2
+#define LUT_PARAM_ALPHA_BB 3
+#define LUT_PARAM_STOP_TIME_BB 4
+#define LUT_PARAM_BB_PLL_LOOP_FILTER 5
+#define LUT_PARAM_NUM 6
+
+#define ACX_EEPROMLESS_IND_REG (SCR_PAD4)
+#define USE_EEPROM 0
+#define SOFT_RESET_MAX_TIME 1000000
+#define SOFT_RESET_STALL_TIME 1000
+#define NVS_DATA_BUNDARY_ALIGNMENT 4
+
+
+/* Firmware image load chunk size */
+#define CHUNK_SIZE 512
+
+/* Firmware image header size */
+#define FW_HDR_SIZE 8
+
+#define ECPU_CONTROL_HALT 0x00000101
+
+
+/******************************************************************************
+
+ CHANNELS, BAND & REG DOMAINS definitions
+
+******************************************************************************/
+
+
+enum {
+ RADIO_BAND_2_4GHZ = 0, /* 2.4 Ghz band */
+ RADIO_BAND_5GHZ = 1, /* 5 Ghz band */
+ RADIO_BAND_JAPAN_4_9_GHZ = 2,
+ DEFAULT_BAND = RADIO_BAND_2_4GHZ,
+ INVALID_BAND = 0xFE,
+ MAX_RADIO_BANDS = 0xFF
+};
+
+enum {
+ NO_RATE = 0,
+ RATE_1MBPS = 0x0A,
+ RATE_2MBPS = 0x14,
+ RATE_5_5MBPS = 0x37,
+ RATE_6MBPS = 0x0B,
+ RATE_9MBPS = 0x0F,
+ RATE_11MBPS = 0x6E,
+ RATE_12MBPS = 0x0A,
+ RATE_18MBPS = 0x0E,
+ RATE_22MBPS = 0xDC,
+ RATE_24MBPS = 0x09,
+ RATE_36MBPS = 0x0D,
+ RATE_48MBPS = 0x08,
+ RATE_54MBPS = 0x0C
+};
+
+enum {
+ RATE_INDEX_1MBPS = 0,
+ RATE_INDEX_2MBPS = 1,
+ RATE_INDEX_5_5MBPS = 2,
+ RATE_INDEX_6MBPS = 3,
+ RATE_INDEX_9MBPS = 4,
+ RATE_INDEX_11MBPS = 5,
+ RATE_INDEX_12MBPS = 6,
+ RATE_INDEX_18MBPS = 7,
+ RATE_INDEX_22MBPS = 8,
+ RATE_INDEX_24MBPS = 9,
+ RATE_INDEX_36MBPS = 10,
+ RATE_INDEX_48MBPS = 11,
+ RATE_INDEX_54MBPS = 12,
+ RATE_INDEX_MAX = RATE_INDEX_54MBPS,
+ MAX_RATE_INDEX,
+ INVALID_RATE_INDEX = MAX_RATE_INDEX,
+ RATE_INDEX_ENUM_MAX_SIZE = 0x7FFFFFFF
+};
+
+enum {
+ RATE_MASK_1MBPS = 0x1,
+ RATE_MASK_2MBPS = 0x2,
+ RATE_MASK_5_5MBPS = 0x4,
+ RATE_MASK_11MBPS = 0x20,
+};
+
+#define SHORT_PREAMBLE_BIT BIT(0) /* CCK or Barker depending on the rate */
+#define OFDM_RATE_BIT BIT(6)
+#define PBCC_RATE_BIT BIT(7)
+
+enum {
+ CCK_LONG = 0,
+ CCK_SHORT = SHORT_PREAMBLE_BIT,
+ PBCC_LONG = PBCC_RATE_BIT,
+ PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT,
+ OFDM = OFDM_RATE_BIT
+};
+
+/******************************************************************************
+
+Transmit-Descriptor RATE-SET field definitions...
+
+Define a new "Rate-Set" for TX path that incorporates the
+Rate & Modulation info into a single 16-bit field.
+
+TxdRateSet_t:
+b15 - Indicates Preamble type (1=SHORT, 0=LONG).
+ Notes:
+ Must be LONG (0) for 1Mbps rate.
+ Does not apply (set to 0) for RevG-OFDM rates.
+b14 - Indicates PBCC encoding (1=PBCC, 0=not).
+ Notes:
+ Does not apply (set to 0) for rates 1 and 2 Mbps.
+ Does not apply (set to 0) for RevG-OFDM rates.
+b13 - Unused (set to 0).
+b12-b0 - Supported Rate indicator bits as defined below.
+
+******************************************************************************/
+
+
+#define TNETW1251_CHIP_ID_PG1_0 0x07010101
+#define TNETW1251_CHIP_ID_PG1_1 0x07020101
+#define TNETW1251_CHIP_ID_PG1_2 0x07030101
+
+/*************************************************************************
+
+ Interrupt Trigger Register (Host -> WiLink)
+
+**************************************************************************/
+
+/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
+
+/*
+ * Host Command Interrupt. Setting this bit masks
+ * the interrupt that the host issues to inform
+ * the FW that it has sent a command
+ * to the Wlan hardware Command Mailbox.
+ */
+#define INTR_TRIG_CMD BIT(0)
+
+/*
+ * Host Event Acknowlegde Interrupt. The host
+ * sets this bit to acknowledge that it received
+ * the unsolicited information from the event
+ * mailbox.
+ */
+#define INTR_TRIG_EVENT_ACK BIT(1)
+
+/*
+ * The host sets this bit to inform the Wlan
+ * FW that a TX packet is in the XFER
+ * Buffer #0.
+ */
+#define INTR_TRIG_TX_PROC0 BIT(2)
+
+/*
+ * The host sets this bit to inform the FW
+ * that it read a packet from RX XFER
+ * Buffer #0.
+ */
+#define INTR_TRIG_RX_PROC0 BIT(3)
+
+#define INTR_TRIG_DEBUG_ACK BIT(4)
+
+#define INTR_TRIG_STATE_CHANGED BIT(5)
+
+
+/* Hardware to Embedded CPU Interrupts - second 32-bit register set */
+
+/*
+ * The host sets this bit to inform the FW
+ * that it read a packet from RX XFER
+ * Buffer #1.
+ */
+#define INTR_TRIG_RX_PROC1 BIT(17)
+
+/*
+ * The host sets this bit to inform the Wlan
+ * hardware that a TX packet is in the XFER
+ * Buffer #1.
+ */
+#define INTR_TRIG_TX_PROC1 BIT(18)
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
new file mode 100644
index 00000000000..981ea259eb8
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -0,0 +1,208 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/skbuff.h>
+#include <net/mac80211.h>
+
+#include "wl12xx.h"
+#include "reg.h"
+#include "spi.h"
+#include "rx.h"
+
+static void wl12xx_rx_header(struct wl12xx *wl,
+ struct wl12xx_rx_descriptor *desc)
+{
+ u32 rx_packet_ring_addr;
+
+ rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr;
+ if (wl->rx_current_buffer)
+ rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
+
+ wl12xx_spi_mem_read(wl, rx_packet_ring_addr, desc,
+ sizeof(struct wl12xx_rx_descriptor));
+}
+
+static void wl12xx_rx_status(struct wl12xx *wl,
+ struct wl12xx_rx_descriptor *desc,
+ struct ieee80211_rx_status *status,
+ u8 beacon)
+{
+ memset(status, 0, sizeof(struct ieee80211_rx_status));
+
+ status->band = IEEE80211_BAND_2GHZ;
+ status->mactime = desc->timestamp;
+
+ /*
+ * The rx status timestamp is a 32 bits value while the TSF is a
+ * 64 bits one.
+ * For IBSS merging, TSF is mandatory, so we have to get it
+ * somehow, so we ask for ACX_TSF_INFO.
+ * That could be moved to the get_tsf() hook, but unfortunately,
+ * this one must be atomic, while our SPI routines can sleep.
+ */
+ if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) {
+ u64 mactime;
+ int ret;
+ struct wl12xx_command cmd;
+ struct acx_tsf_info *tsf_info;
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ ret = wl12xx_cmd_interrogate(wl, ACX_TSF_INFO,
+ sizeof(struct acx_tsf_info),
+ &cmd);
+ if (ret < 0) {
+ wl12xx_warning("ACX_FW_REV interrogate failed");
+ return;
+ }
+
+ tsf_info = (struct acx_tsf_info *)&(cmd.parameters);
+
+ mactime = tsf_info->current_tsf_lsb |
+ (tsf_info->current_tsf_msb << 31);
+
+ status->mactime = mactime;
+ }
+
+ status->signal = desc->rssi;
+ status->qual = (desc->rssi - WL12XX_RX_MIN_RSSI) * 100 /
+ (WL12XX_RX_MAX_RSSI - WL12XX_RX_MIN_RSSI);
+ status->qual = min(status->qual, 100);
+ status->qual = max(status->qual, 0);
+
+ /*
+ * FIXME: guessing that snr needs to be divided by two, otherwise
+ * the values don't make any sense
+ */
+ status->noise = desc->rssi - desc->snr / 2;
+
+ status->freq = ieee80211_channel_to_frequency(desc->channel);
+
+ status->flag |= RX_FLAG_TSFT;
+
+ if (desc->flags & RX_DESC_ENCRYPTION_MASK) {
+ status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
+
+ if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL)))
+ status->flag |= RX_FLAG_DECRYPTED;
+
+ if (unlikely(desc->flags & RX_DESC_MIC_FAIL))
+ status->flag |= RX_FLAG_MMIC_ERROR;
+ }
+
+ if (unlikely(!(desc->flags & RX_DESC_VALID_FCS)))
+ status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
+
+ /* FIXME: set status->rate_idx */
+}
+
+static void wl12xx_rx_body(struct wl12xx *wl,
+ struct wl12xx_rx_descriptor *desc)
+{
+ struct sk_buff *skb;
+ struct ieee80211_rx_status status;
+ u8 *rx_buffer, beacon = 0;
+ u16 length, *fc;
+ u32 curr_id, last_id_inc, rx_packet_ring_addr;
+
+ length = WL12XX_RX_ALIGN(desc->length - PLCP_HEADER_LENGTH);
+ curr_id = (desc->flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT;
+ last_id_inc = (wl->rx_last_id + 1) % (RX_MAX_PACKET_ID + 1);
+
+ if (last_id_inc != curr_id) {
+ wl12xx_warning("curr ID:%d, last ID inc:%d",
+ curr_id, last_id_inc);
+ wl->rx_last_id = curr_id;
+ } else {
+ wl->rx_last_id = last_id_inc;
+ }
+
+ rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr +
+ sizeof(struct wl12xx_rx_descriptor) + 20;
+ if (wl->rx_current_buffer)
+ rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
+
+ skb = dev_alloc_skb(length);
+ if (!skb) {
+ wl12xx_error("Couldn't allocate RX frame");
+ return;
+ }
+
+ rx_buffer = skb_put(skb, length);
+ wl12xx_spi_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
+
+ /* The actual lenght doesn't include the target's alignment */
+ skb->len = desc->length - PLCP_HEADER_LENGTH;
+
+ fc = (u16 *)skb->data;
+
+ if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
+ beacon = 1;
+
+ wl12xx_rx_status(wl, desc, &status, beacon);
+
+ wl12xx_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
+ beacon ? "beacon" : "");
+
+ ieee80211_rx(wl->hw, skb, &status);
+}
+
+static void wl12xx_rx_ack(struct wl12xx *wl)
+{
+ u32 data, addr;
+
+ if (wl->rx_current_buffer) {
+ addr = ACX_REG_INTERRUPT_TRIG_H;
+ data = INTR_TRIG_RX_PROC1;
+ } else {
+ addr = ACX_REG_INTERRUPT_TRIG;
+ data = INTR_TRIG_RX_PROC0;
+ }
+
+ wl12xx_reg_write32(wl, addr, data);
+
+ /* Toggle buffer ring */
+ wl->rx_current_buffer = !wl->rx_current_buffer;
+}
+
+
+void wl12xx_rx(struct wl12xx *wl)
+{
+ struct wl12xx_rx_descriptor rx_desc;
+
+ if (wl->state != WL12XX_STATE_ON)
+ return;
+
+ /* We first read the frame's header */
+ wl12xx_rx_header(wl, &rx_desc);
+
+ /* Now we can read the body */
+ wl12xx_rx_body(wl, &rx_desc);
+
+ /* Finally, we need to ACK the RX */
+ wl12xx_rx_ack(wl);
+
+ return;
+}
diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h
new file mode 100644
index 00000000000..8a23fdea501
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/rx.h
@@ -0,0 +1,122 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_RX_H__
+#define __WL12XX_RX_H__
+
+#include <linux/bitops.h>
+
+/*
+ * RX PATH
+ *
+ * The Rx path uses a double buffer and an rx_contro structure, each located
+ * at a fixed address in the device memory. The host keeps track of which
+ * buffer is available and alternates between them on a per packet basis.
+ * The size of each of the two buffers is large enough to hold the longest
+ * 802.3 packet.
+ * The RX path goes like that:
+ * 1) The target generates an interrupt each time a new packet is received.
+ * There are 2 RX interrupts, one for each buffer.
+ * 2) The host reads the received packet from one of the double buffers.
+ * 3) The host triggers a target interrupt.
+ * 4) The target prepares the next RX packet.
+ */
+
+#define WL12XX_RX_MAX_RSSI -30
+#define WL12XX_RX_MIN_RSSI -95
+
+#define WL12XX_RX_ALIGN_TO 4
+#define WL12XX_RX_ALIGN(len) (((len) + WL12XX_RX_ALIGN_TO - 1) & \
+ ~(WL12XX_RX_ALIGN_TO - 1))
+
+#define SHORT_PREAMBLE_BIT BIT(0)
+#define OFDM_RATE_BIT BIT(6)
+#define PBCC_RATE_BIT BIT(7)
+
+#define PLCP_HEADER_LENGTH 8
+#define RX_DESC_PACKETID_SHIFT 11
+#define RX_MAX_PACKET_ID 3
+
+#define RX_DESC_VALID_FCS 0x0001
+#define RX_DESC_MATCH_RXADDR1 0x0002
+#define RX_DESC_MCAST 0x0004
+#define RX_DESC_STAINTIM 0x0008
+#define RX_DESC_VIRTUAL_BM 0x0010
+#define RX_DESC_BCAST 0x0020
+#define RX_DESC_MATCH_SSID 0x0040
+#define RX_DESC_MATCH_BSSID 0x0080
+#define RX_DESC_ENCRYPTION_MASK 0x0300
+#define RX_DESC_MEASURMENT 0x0400
+#define RX_DESC_SEQNUM_MASK 0x1800
+#define RX_DESC_MIC_FAIL 0x2000
+#define RX_DESC_DECRYPT_FAIL 0x4000
+
+struct wl12xx_rx_descriptor {
+ u32 timestamp; /* In microseconds */
+ u16 length; /* Paylod length, including headers */
+ u16 flags;
+
+ /*
+ * 0 - 802.11
+ * 1 - 802.3
+ * 2 - IP
+ * 3 - Raw Codec
+ */
+ u8 type;
+
+ /*
+ * Recevied Rate:
+ * 0x0A - 1MBPS
+ * 0x14 - 2MBPS
+ * 0x37 - 5_5MBPS
+ * 0x0B - 6MBPS
+ * 0x0F - 9MBPS
+ * 0x6E - 11MBPS
+ * 0x0A - 12MBPS
+ * 0x0E - 18MBPS
+ * 0xDC - 22MBPS
+ * 0x09 - 24MBPS
+ * 0x0D - 36MBPS
+ * 0x08 - 48MBPS
+ * 0x0C - 54MBPS
+ */
+ u8 rate;
+
+ u8 mod_pre; /* Modulation and preamble */
+ u8 channel;
+
+ /*
+ * 0 - 2.4 Ghz
+ * 1 - 5 Ghz
+ */
+ u8 band;
+
+ s8 rssi; /* in dB */
+ u8 rcpi; /* in dB */
+ u8 snr; /* in dB */
+} __attribute__ ((packed));
+
+void wl12xx_rx(struct wl12xx *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c
new file mode 100644
index 00000000000..abdf171a47e
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/spi.c
@@ -0,0 +1,358 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+
+#include "wl12xx.h"
+#include "wl12xx_80211.h"
+#include "reg.h"
+#include "spi.h"
+#include "ps.h"
+
+static int wl12xx_translate_reg_addr(struct wl12xx *wl, int addr)
+{
+ /* If the address is lower than REGISTERS_BASE, it means that this is
+ * a chip-specific register address, so look it up in the registers
+ * table */
+ if (addr < REGISTERS_BASE) {
+ /* Make sure we don't go over the table */
+ if (addr >= ACX_REG_TABLE_LEN) {
+ wl12xx_error("address out of range (%d)", addr);
+ return -EINVAL;
+ }
+ addr = wl->chip.acx_reg_table[addr];
+ }
+
+ return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
+}
+
+static int wl12xx_translate_mem_addr(struct wl12xx *wl, int addr)
+{
+ return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
+}
+
+
+void wl12xx_spi_reset(struct wl12xx *wl)
+{
+ u8 *cmd;
+ struct spi_transfer t;
+ struct spi_message m;
+
+ cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
+ if (!cmd) {
+ wl12xx_error("could not allocate cmd for spi reset");
+ return;
+ }
+
+ memset(&t, 0, sizeof(t));
+ spi_message_init(&m);
+
+ memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
+
+ t.tx_buf = cmd;
+ t.len = WSPI_INIT_CMD_LEN;
+ spi_message_add_tail(&t, &m);
+
+ spi_sync(wl->spi, &m);
+
+ wl12xx_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
+}
+
+void wl12xx_spi_init(struct wl12xx *wl)
+{
+ u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
+ struct spi_transfer t;
+ struct spi_message m;
+
+ cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
+ if (!cmd) {
+ wl12xx_error("could not allocate cmd for spi init");
+ return;
+ }
+
+ memset(crc, 0, sizeof(crc));
+ memset(&t, 0, sizeof(t));
+ spi_message_init(&m);
+
+ /*
+ * Set WSPI_INIT_COMMAND
+ * the data is being send from the MSB to LSB
+ */
+ cmd[2] = 0xff;
+ cmd[3] = 0xff;
+ cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
+ cmd[0] = 0;
+ cmd[7] = 0;
+ cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
+ cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
+
+ if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
+ cmd[5] |= WSPI_INIT_CMD_DIS_FIXEDBUSY;
+ else
+ cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
+
+ cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
+ | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
+
+ crc[0] = cmd[1];
+ crc[1] = cmd[0];
+ crc[2] = cmd[7];
+ crc[3] = cmd[6];
+ crc[4] = cmd[5];
+
+ cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
+ cmd[4] |= WSPI_INIT_CMD_END;
+
+ t.tx_buf = cmd;
+ t.len = WSPI_INIT_CMD_LEN;
+ spi_message_add_tail(&t, &m);
+
+ spi_sync(wl->spi, &m);
+
+ wl12xx_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
+}
+
+/* Set the SPI partitions to access the chip addresses
+ *
+ * There are two VIRTUAL (SPI) partitions (the memory partition and the
+ * registers partition), which are mapped to two different areas of the
+ * PHYSICAL (hardware) memory. This function also makes other checks to
+ * ensure that the partitions are not overlapping. In the diagram below, the
+ * memory partition comes before the register partition, but the opposite is
+ * also supported.
+ *
+ * PHYSICAL address
+ * space
+ *
+ * | |
+ * ...+----+--> mem_start
+ * VIRTUAL address ... | |
+ * space ... | | [PART_0]
+ * ... | |
+ * 0x00000000 <--+----+... ...+----+--> mem_start + mem_size
+ * | | ... | |
+ * |MEM | ... | |
+ * | | ... | |
+ * part_size <--+----+... | | {unused area)
+ * | | ... | |
+ * |REG | ... | |
+ * part_size | | ... | |
+ * + <--+----+... ...+----+--> reg_start
+ * reg_size ... | |
+ * ... | | [PART_1]
+ * ... | |
+ * ...+----+--> reg_start + reg_size
+ * | |
+ *
+ */
+void wl12xx_set_partition(struct wl12xx *wl,
+ u32 mem_start, u32 mem_size,
+ u32 reg_start, u32 reg_size)
+{
+ u8 tx_buf[sizeof(u32) + 2 * sizeof(struct wl12xx_partition)];
+ struct wl12xx_partition *partition;
+ struct spi_transfer t;
+ struct spi_message m;
+ u32 *cmd;
+ size_t len;
+ int addr;
+
+ spi_message_init(&m);
+ memset(&t, 0, sizeof(t));
+ memset(tx_buf, 0, sizeof(tx_buf));
+
+ cmd = (u32 *) tx_buf;
+ partition = (struct wl12xx_partition *) (tx_buf + sizeof(u32));
+ addr = HW_ACCESS_PART0_SIZE_ADDR;
+ len = 2 * sizeof(struct wl12xx_partition);
+
+ *cmd |= WSPI_CMD_WRITE;
+ *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+ *cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+ wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+ mem_start, mem_size);
+ wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+ reg_start, reg_size);
+
+ /* Make sure that the two partitions together don't exceed the
+ * address range */
+ if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
+ wl12xx_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
+ " address range. Truncating partition[0].");
+ mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
+ wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+ mem_start, mem_size);
+ wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+ reg_start, reg_size);
+ }
+
+ if ((mem_start < reg_start) &&
+ ((mem_start + mem_size) > reg_start)) {
+ /* Guarantee that the memory partition doesn't overlap the
+ * registers partition */
+ wl12xx_debug(DEBUG_SPI, "End of partition[0] is "
+ "overlapping partition[1]. Adjusted.");
+ mem_size = reg_start - mem_start;
+ wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+ mem_start, mem_size);
+ wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+ reg_start, reg_size);
+ } else if ((reg_start < mem_start) &&
+ ((reg_start + reg_size) > mem_start)) {
+ /* Guarantee that the register partition doesn't overlap the
+ * memory partition */
+ wl12xx_debug(DEBUG_SPI, "End of partition[1] is"
+ " overlapping partition[0]. Adjusted.");
+ reg_size = mem_start - reg_start;
+ wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+ mem_start, mem_size);
+ wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+ reg_start, reg_size);
+ }
+
+ partition[0].start = mem_start;
+ partition[0].size = mem_size;
+ partition[1].start = reg_start;
+ partition[1].size = reg_size;
+
+ wl->physical_mem_addr = mem_start;
+ wl->physical_reg_addr = reg_start;
+
+ wl->virtual_mem_addr = 0;
+ wl->virtual_reg_addr = mem_size;
+
+ t.tx_buf = tx_buf;
+ t.len = sizeof(tx_buf);
+ spi_message_add_tail(&t, &m);
+
+ spi_sync(wl->spi, &m);
+}
+
+void wl12xx_spi_read(struct wl12xx *wl, int addr, void *buf,
+ size_t len)
+{
+ struct spi_transfer t[3];
+ struct spi_message m;
+ char busy_buf[TNETWIF_READ_OFFSET_BYTES];
+ u32 cmd;
+
+ cmd = 0;
+ cmd |= WSPI_CMD_READ;
+ cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+ cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
+
+ t[0].tx_buf = &cmd;
+ t[0].len = 4;
+ spi_message_add_tail(&t[0], &m);
+
+ /* Busy and non busy words read */
+ t[1].rx_buf = busy_buf;
+ t[1].len = TNETWIF_READ_OFFSET_BYTES;
+ spi_message_add_tail(&t[1], &m);
+
+ t[2].rx_buf = buf;
+ t[2].len = len;
+ spi_message_add_tail(&t[2], &m);
+
+ spi_sync(wl->spi, &m);
+
+ /* FIXME: check busy words */
+
+ wl12xx_dump(DEBUG_SPI, "spi_read cmd -> ", &cmd, sizeof(cmd));
+ wl12xx_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
+}
+
+void wl12xx_spi_write(struct wl12xx *wl, int addr, void *buf,
+ size_t len)
+{
+ struct spi_transfer t[2];
+ struct spi_message m;
+ u32 cmd;
+
+ cmd = 0;
+ cmd |= WSPI_CMD_WRITE;
+ cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+ cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
+
+ t[0].tx_buf = &cmd;
+ t[0].len = sizeof(cmd);
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].tx_buf = buf;
+ t[1].len = len;
+ spi_message_add_tail(&t[1], &m);
+
+ spi_sync(wl->spi, &m);
+
+ wl12xx_dump(DEBUG_SPI, "spi_write cmd -> ", &cmd, sizeof(cmd));
+ wl12xx_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
+}
+
+void wl12xx_spi_mem_read(struct wl12xx *wl, int addr, void *buf,
+ size_t len)
+{
+ int physical;
+
+ physical = wl12xx_translate_mem_addr(wl, addr);
+
+ wl12xx_spi_read(wl, physical, buf, len);
+}
+
+void wl12xx_spi_mem_write(struct wl12xx *wl, int addr, void *buf,
+ size_t len)
+{
+ int physical;
+
+ physical = wl12xx_translate_mem_addr(wl, addr);
+
+ wl12xx_spi_write(wl, physical, buf, len);
+}
+
+u32 wl12xx_mem_read32(struct wl12xx *wl, int addr)
+{
+ return wl12xx_read32(wl, wl12xx_translate_mem_addr(wl, addr));
+}
+
+void wl12xx_mem_write32(struct wl12xx *wl, int addr, u32 val)
+{
+ wl12xx_write32(wl, wl12xx_translate_mem_addr(wl, addr), val);
+}
+
+u32 wl12xx_reg_read32(struct wl12xx *wl, int addr)
+{
+ return wl12xx_read32(wl, wl12xx_translate_reg_addr(wl, addr));
+}
+
+void wl12xx_reg_write32(struct wl12xx *wl, int addr, u32 val)
+{
+ wl12xx_write32(wl, wl12xx_translate_reg_addr(wl, addr), val);
+}
diff --git a/drivers/net/wireless/wl12xx/spi.h b/drivers/net/wireless/wl12xx/spi.h
new file mode 100644
index 00000000000..fd3227e904a
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/spi.h
@@ -0,0 +1,109 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_SPI_H__
+#define __WL12XX_SPI_H__
+
+#include "cmd.h"
+#include "acx.h"
+#include "reg.h"
+
+#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
+
+#define HW_ACCESS_PART0_SIZE_ADDR 0x1FFC0
+#define HW_ACCESS_PART0_START_ADDR 0x1FFC4
+#define HW_ACCESS_PART1_SIZE_ADDR 0x1FFC8
+#define HW_ACCESS_PART1_START_ADDR 0x1FFCC
+
+#define HW_ACCESS_REGISTER_SIZE 4
+
+#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
+
+#define WSPI_CMD_READ 0x40000000
+#define WSPI_CMD_WRITE 0x00000000
+#define WSPI_CMD_FIXED 0x20000000
+#define WSPI_CMD_BYTE_LENGTH 0x1FFE0000
+#define WSPI_CMD_BYTE_LENGTH_OFFSET 17
+#define WSPI_CMD_BYTE_ADDR 0x0001FFFF
+
+#define WSPI_INIT_CMD_CRC_LEN 5
+
+#define WSPI_INIT_CMD_START 0x00
+#define WSPI_INIT_CMD_TX 0x40
+/* the extra bypass bit is sampled by the TNET as '1' */
+#define WSPI_INIT_CMD_BYPASS_BIT 0x80
+#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
+#define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80
+#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
+#define WSPI_INIT_CMD_IOD 0x40
+#define WSPI_INIT_CMD_IP 0x20
+#define WSPI_INIT_CMD_CS 0x10
+#define WSPI_INIT_CMD_WS 0x08
+#define WSPI_INIT_CMD_WSPI 0x01
+#define WSPI_INIT_CMD_END 0x01
+
+#define WSPI_INIT_CMD_LEN 8
+
+#define TNETWIF_READ_OFFSET_BYTES 8
+#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
+ ((TNETWIF_READ_OFFSET_BYTES - 4) / sizeof(u32))
+#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
+
+
+/* Raw target IO, address is not translated */
+void wl12xx_spi_read(struct wl12xx *wl, int addr, void *buf, size_t len);
+void wl12xx_spi_write(struct wl12xx *wl, int addr, void *buf, size_t len);
+
+/* Memory target IO, address is tranlated to partition 0 */
+void wl12xx_spi_mem_read(struct wl12xx *wl, int addr, void *buf, size_t len);
+void wl12xx_spi_mem_write(struct wl12xx *wl, int addr, void *buf, size_t len);
+u32 wl12xx_mem_read32(struct wl12xx *wl, int addr);
+void wl12xx_mem_write32(struct wl12xx *wl, int addr, u32 val);
+
+/* Registers IO */
+u32 wl12xx_reg_read32(struct wl12xx *wl, int addr);
+void wl12xx_reg_write32(struct wl12xx *wl, int addr, u32 val);
+
+/* INIT and RESET words */
+void wl12xx_spi_reset(struct wl12xx *wl);
+void wl12xx_spi_init(struct wl12xx *wl);
+void wl12xx_set_partition(struct wl12xx *wl,
+ u32 part_start, u32 part_size,
+ u32 reg_start, u32 reg_size);
+
+static inline u32 wl12xx_read32(struct wl12xx *wl, int addr)
+{
+ u32 response;
+
+ wl12xx_spi_read(wl, addr, &response, sizeof(u32));
+
+ return response;
+}
+
+static inline void wl12xx_write32(struct wl12xx *wl, int addr, u32 val)
+{
+ wl12xx_spi_write(wl, addr, &val, sizeof(u32));
+}
+
+#endif /* __WL12XX_SPI_H__ */
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
new file mode 100644
index 00000000000..62145e205a8
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -0,0 +1,557 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "wl12xx.h"
+#include "reg.h"
+#include "spi.h"
+#include "tx.h"
+#include "ps.h"
+
+static bool wl12xx_tx_double_buffer_busy(struct wl12xx *wl, u32 data_out_count)
+{
+ int used, data_in_count;
+
+ data_in_count = wl->data_in_count;
+
+ if (data_in_count < data_out_count)
+ /* data_in_count has wrapped */
+ data_in_count += TX_STATUS_DATA_OUT_COUNT_MASK + 1;
+
+ used = data_in_count - data_out_count;
+
+ WARN_ON(used < 0);
+ WARN_ON(used > DP_TX_PACKET_RING_CHUNK_NUM);
+
+ if (used >= DP_TX_PACKET_RING_CHUNK_NUM)
+ return true;
+ else
+ return false;
+}
+
+static int wl12xx_tx_path_status(struct wl12xx *wl)
+{
+ u32 status, addr, data_out_count;
+ bool busy;
+
+ addr = wl->data_path->tx_control_addr;
+ status = wl12xx_mem_read32(wl, addr);
+ data_out_count = status & TX_STATUS_DATA_OUT_COUNT_MASK;
+ busy = wl12xx_tx_double_buffer_busy(wl, data_out_count);
+
+ if (busy)
+ return -EBUSY;
+
+ return 0;
+}
+
+static int wl12xx_tx_id(struct wl12xx *wl, struct sk_buff *skb)
+{
+ int i;
+
+ for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+ if (wl->tx_frames[i] == NULL) {
+ wl->tx_frames[i] = skb;
+ return i;
+ }
+
+ return -EBUSY;
+}
+
+static void wl12xx_tx_control(struct tx_double_buffer_desc *tx_hdr,
+ struct ieee80211_tx_info *control, u16 fc)
+{
+ *(u16 *)&tx_hdr->control = 0;
+
+ tx_hdr->control.rate_policy = 0;
+
+ /* 802.11 packets */
+ tx_hdr->control.packet_type = 0;
+
+ if (control->flags & IEEE80211_TX_CTL_NO_ACK)
+ tx_hdr->control.ack_policy = 1;
+
+ tx_hdr->control.tx_complete = 1;
+
+ if ((fc & IEEE80211_FTYPE_DATA) &&
+ ((fc & IEEE80211_STYPE_QOS_DATA) ||
+ (fc & IEEE80211_STYPE_QOS_NULLFUNC)))
+ tx_hdr->control.qos = 1;
+}
+
+/* RSN + MIC = 8 + 8 = 16 bytes (worst case - AES). */
+#define MAX_MSDU_SECURITY_LENGTH 16
+#define MAX_MPDU_SECURITY_LENGTH 16
+#define WLAN_QOS_HDR_LEN 26
+#define MAX_MPDU_HEADER_AND_SECURITY (MAX_MPDU_SECURITY_LENGTH + \
+ WLAN_QOS_HDR_LEN)
+#define HW_BLOCK_SIZE 252
+static void wl12xx_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr)
+{
+ u16 payload_len, frag_threshold, mem_blocks;
+ u16 num_mpdus, mem_blocks_per_frag;
+
+ frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
+ tx_hdr->frag_threshold = cpu_to_le16(frag_threshold);
+
+ payload_len = tx_hdr->length + MAX_MSDU_SECURITY_LENGTH;
+
+ if (payload_len > frag_threshold) {
+ mem_blocks_per_frag =
+ ((frag_threshold + MAX_MPDU_HEADER_AND_SECURITY) /
+ HW_BLOCK_SIZE) + 1;
+ num_mpdus = payload_len / frag_threshold;
+ mem_blocks = num_mpdus * mem_blocks_per_frag;
+ payload_len -= num_mpdus * frag_threshold;
+ num_mpdus++;
+
+ } else {
+ mem_blocks_per_frag = 0;
+ mem_blocks = 0;
+ num_mpdus = 1;
+ }
+
+ mem_blocks += (payload_len / HW_BLOCK_SIZE) + 1;
+
+ if (num_mpdus > 1)
+ mem_blocks += min(num_mpdus, mem_blocks_per_frag);
+
+ tx_hdr->num_mem_blocks = mem_blocks;
+}
+
+static int wl12xx_tx_fill_hdr(struct wl12xx *wl, struct sk_buff *skb,
+ struct ieee80211_tx_info *control)
+{
+ struct tx_double_buffer_desc *tx_hdr;
+ struct ieee80211_rate *rate;
+ int id;
+ u16 fc;
+
+ if (!skb)
+ return -EINVAL;
+
+ id = wl12xx_tx_id(wl, skb);
+ if (id < 0)
+ return id;
+
+ fc = *(u16 *)skb->data;
+ tx_hdr = (struct tx_double_buffer_desc *) skb_push(skb,
+ sizeof(*tx_hdr));
+
+ tx_hdr->length = cpu_to_le16(skb->len - sizeof(*tx_hdr));
+ rate = ieee80211_get_tx_rate(wl->hw, control);
+ tx_hdr->rate = cpu_to_le16(rate->hw_value);
+ tx_hdr->expiry_time = cpu_to_le32(1 << 16);
+ tx_hdr->id = id;
+
+ /* FIXME: how to get the correct queue id? */
+ tx_hdr->xmit_queue = 0;
+
+ wl12xx_tx_control(tx_hdr, control, fc);
+ wl12xx_tx_frag_block_num(tx_hdr);
+
+ return 0;
+}
+
+/* We copy the packet to the target */
+static int wl12xx_tx_send_packet(struct wl12xx *wl, struct sk_buff *skb,
+ struct ieee80211_tx_info *control)
+{
+ struct tx_double_buffer_desc *tx_hdr;
+ int len;
+ u32 addr;
+
+ if (!skb)
+ return -EINVAL;
+
+ tx_hdr = (struct tx_double_buffer_desc *) skb->data;
+
+ if (control->control.hw_key &&
+ control->control.hw_key->alg == ALG_TKIP) {
+ int hdrlen;
+ u16 fc;
+ u8 *pos;
+
+ fc = *(u16 *)(skb->data + sizeof(*tx_hdr));
+ tx_hdr->length += WL12XX_TKIP_IV_SPACE;
+
+ hdrlen = ieee80211_hdrlen(fc);
+
+ pos = skb_push(skb, WL12XX_TKIP_IV_SPACE);
+ memmove(pos, pos + WL12XX_TKIP_IV_SPACE,
+ sizeof(*tx_hdr) + hdrlen);
+ }
+
+ /* Revisit. This is a workaround for getting non-aligned packets.
+ This happens at least with EAPOL packets from the user space.
+ Our DMA requires packets to be aligned on a 4-byte boundary.
+ */
+ if (unlikely((long)skb->data & 0x03)) {
+ int offset = (4 - (long)skb->data) & 0x03;
+ wl12xx_debug(DEBUG_TX, "skb offset %d", offset);
+
+ /* check whether the current skb can be used */
+ if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
+ unsigned char *src = skb->data;
+
+ /* align the buffer on a 4-byte boundary */
+ skb_reserve(skb, offset);
+ memmove(skb->data, src, skb->len);
+ } else {
+ wl12xx_info("No handler, fixme!");
+ return -EINVAL;
+ }
+ }
+
+ /* Our skb->data at this point includes the HW header */
+ len = WL12XX_TX_ALIGN(skb->len);
+
+ if (wl->data_in_count & 0x1)
+ addr = wl->data_path->tx_packet_ring_addr +
+ wl->data_path->tx_packet_ring_chunk_size;
+ else
+ addr = wl->data_path->tx_packet_ring_addr;
+
+ wl12xx_spi_mem_write(wl, addr, skb->data, len);
+
+ wl12xx_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x",
+ tx_hdr->id, skb, tx_hdr->length, tx_hdr->rate);
+
+ return 0;
+}
+
+static void wl12xx_tx_trigger(struct wl12xx *wl)
+{
+ u32 data, addr;
+
+ if (wl->data_in_count & 0x1) {
+ addr = ACX_REG_INTERRUPT_TRIG_H;
+ data = INTR_TRIG_TX_PROC1;
+ } else {
+ addr = ACX_REG_INTERRUPT_TRIG;
+ data = INTR_TRIG_TX_PROC0;
+ }
+
+ wl12xx_reg_write32(wl, addr, data);
+
+ /* Bumping data in */
+ wl->data_in_count = (wl->data_in_count + 1) &
+ TX_STATUS_DATA_OUT_COUNT_MASK;
+}
+
+/* caller must hold wl->mutex */
+static int wl12xx_tx_frame(struct wl12xx *wl, struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info;
+ int ret = 0;
+ u8 idx;
+
+ info = IEEE80211_SKB_CB(skb);
+
+ if (info->control.hw_key) {
+ idx = info->control.hw_key->hw_key_idx;
+ if (unlikely(wl->default_key != idx)) {
+ ret = wl12xx_acx_default_key(wl, idx);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ ret = wl12xx_tx_path_status(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_tx_fill_hdr(wl, skb, info);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_tx_send_packet(wl, skb, info);
+ if (ret < 0)
+ return ret;
+
+ wl12xx_tx_trigger(wl);
+
+ return ret;
+}
+
+void wl12xx_tx_work(struct work_struct *work)
+{
+ struct wl12xx *wl = container_of(work, struct wl12xx, tx_work);
+ struct sk_buff *skb;
+ bool woken_up = false;
+ int ret;
+
+ mutex_lock(&wl->mutex);
+
+ if (unlikely(wl->state == WL12XX_STATE_OFF))
+ goto out;
+
+ while ((skb = skb_dequeue(&wl->tx_queue))) {
+ if (!woken_up) {
+ wl12xx_ps_elp_wakeup(wl);
+ woken_up = true;
+ }
+
+ ret = wl12xx_tx_frame(wl, skb);
+ if (ret == -EBUSY) {
+ /* firmware buffer is full, stop queues */
+ wl12xx_debug(DEBUG_TX, "tx_work: fw buffer full, "
+ "stop queues");
+ ieee80211_stop_queues(wl->hw);
+ wl->tx_queue_stopped = true;
+ skb_queue_head(&wl->tx_queue, skb);
+ goto out;
+ } else if (ret < 0) {
+ dev_kfree_skb(skb);
+ goto out;
+ }
+ }
+
+out:
+ if (woken_up)
+ wl12xx_ps_elp_sleep(wl);
+
+ mutex_unlock(&wl->mutex);
+}
+
+static const char *wl12xx_tx_parse_status(u8 status)
+{
+ /* 8 bit status field, one character per bit plus null */
+ static char buf[9];
+ int i = 0;
+
+ memset(buf, 0, sizeof(buf));
+
+ if (status & TX_DMA_ERROR)
+ buf[i++] = 'm';
+ if (status & TX_DISABLED)
+ buf[i++] = 'd';
+ if (status & TX_RETRY_EXCEEDED)
+ buf[i++] = 'r';
+ if (status & TX_TIMEOUT)
+ buf[i++] = 't';
+ if (status & TX_KEY_NOT_FOUND)
+ buf[i++] = 'k';
+ if (status & TX_ENCRYPT_FAIL)
+ buf[i++] = 'e';
+ if (status & TX_UNAVAILABLE_PRIORITY)
+ buf[i++] = 'p';
+
+ /* bit 0 is unused apparently */
+
+ return buf;
+}
+
+static void wl12xx_tx_packet_cb(struct wl12xx *wl,
+ struct tx_result *result)
+{
+ struct ieee80211_tx_info *info;
+ struct sk_buff *skb;
+ int hdrlen, ret;
+ u8 *frame;
+
+ skb = wl->tx_frames[result->id];
+ if (skb == NULL) {
+ wl12xx_error("SKB for packet %d is NULL", result->id);
+ return;
+ }
+
+ info = IEEE80211_SKB_CB(skb);
+
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+ (result->status == TX_SUCCESS))
+ info->flags |= IEEE80211_TX_STAT_ACK;
+
+ info->status.rates[0].count = result->ack_failures + 1;
+ wl->stats.retry_count += result->ack_failures;
+
+ /*
+ * We have to remove our private TX header before pushing
+ * the skb back to mac80211.
+ */
+ frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc));
+ if (info->control.hw_key &&
+ info->control.hw_key->alg == ALG_TKIP) {
+ hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+ memmove(frame + WL12XX_TKIP_IV_SPACE, frame, hdrlen);
+ skb_pull(skb, WL12XX_TKIP_IV_SPACE);
+ }
+
+ wl12xx_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
+ " status 0x%x (%s)",
+ result->id, skb, result->ack_failures, result->rate,
+ result->status, wl12xx_tx_parse_status(result->status));
+
+
+ ieee80211_tx_status(wl->hw, skb);
+
+ wl->tx_frames[result->id] = NULL;
+
+ if (wl->tx_queue_stopped) {
+ wl12xx_debug(DEBUG_TX, "cb: queue was stopped");
+
+ skb = skb_dequeue(&wl->tx_queue);
+
+ /* The skb can be NULL because tx_work might have been
+ scheduled before the queue was stopped making the
+ queue empty */
+
+ if (skb) {
+ ret = wl12xx_tx_frame(wl, skb);
+ if (ret == -EBUSY) {
+ /* firmware buffer is still full */
+ wl12xx_debug(DEBUG_TX, "cb: fw buffer "
+ "still full");
+ skb_queue_head(&wl->tx_queue, skb);
+ return;
+ } else if (ret < 0) {
+ dev_kfree_skb(skb);
+ return;
+ }
+ }
+
+ wl12xx_debug(DEBUG_TX, "cb: waking queues");
+ ieee80211_wake_queues(wl->hw);
+ wl->tx_queue_stopped = false;
+ }
+}
+
+/* Called upon reception of a TX complete interrupt */
+void wl12xx_tx_complete(struct wl12xx *wl)
+{
+ int i, result_index, num_complete = 0;
+ struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr;
+
+ if (unlikely(wl->state != WL12XX_STATE_ON))
+ return;
+
+ /* First we read the result */
+ wl12xx_spi_mem_read(wl, wl->data_path->tx_complete_addr,
+ result, sizeof(result));
+
+ result_index = wl->next_tx_complete;
+
+ for (i = 0; i < ARRAY_SIZE(result); i++) {
+ result_ptr = &result[result_index];
+
+ if (result_ptr->done_1 == 1 &&
+ result_ptr->done_2 == 1) {
+ wl12xx_tx_packet_cb(wl, result_ptr);
+
+ result_ptr->done_1 = 0;
+ result_ptr->done_2 = 0;
+
+ result_index = (result_index + 1) &
+ (FW_TX_CMPLT_BLOCK_SIZE - 1);
+ num_complete++;
+ } else {
+ break;
+ }
+ }
+
+ /* Every completed frame needs to be acknowledged */
+ if (num_complete) {
+ /*
+ * If we've wrapped, we have to clear
+ * the results in 2 steps.
+ */
+ if (result_index > wl->next_tx_complete) {
+ /* Only 1 write is needed */
+ wl12xx_spi_mem_write(wl,
+ wl->data_path->tx_complete_addr +
+ (wl->next_tx_complete *
+ sizeof(struct tx_result)),
+ &result[wl->next_tx_complete],
+ num_complete *
+ sizeof(struct tx_result));
+
+
+ } else if (result_index < wl->next_tx_complete) {
+ /* 2 writes are needed */
+ wl12xx_spi_mem_write(wl,
+ wl->data_path->tx_complete_addr +
+ (wl->next_tx_complete *
+ sizeof(struct tx_result)),
+ &result[wl->next_tx_complete],
+ (FW_TX_CMPLT_BLOCK_SIZE -
+ wl->next_tx_complete) *
+ sizeof(struct tx_result));
+
+ wl12xx_spi_mem_write(wl,
+ wl->data_path->tx_complete_addr,
+ result,
+ (num_complete -
+ FW_TX_CMPLT_BLOCK_SIZE +
+ wl->next_tx_complete) *
+ sizeof(struct tx_result));
+
+ } else {
+ /* We have to write the whole array */
+ wl12xx_spi_mem_write(wl,
+ wl->data_path->tx_complete_addr,
+ result,
+ FW_TX_CMPLT_BLOCK_SIZE *
+ sizeof(struct tx_result));
+ }
+
+ }
+
+ wl->next_tx_complete = result_index;
+}
+
+/* caller must hold wl->mutex */
+void wl12xx_tx_flush(struct wl12xx *wl)
+{
+ int i;
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+
+ /* TX failure */
+/* control->flags = 0; FIXME */
+
+ while ((skb = skb_dequeue(&wl->tx_queue))) {
+ info = IEEE80211_SKB_CB(skb);
+
+ wl12xx_debug(DEBUG_TX, "flushing skb 0x%p", skb);
+
+ if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
+ continue;
+
+ ieee80211_tx_status(wl->hw, skb);
+ }
+
+ for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+ if (wl->tx_frames[i] != NULL) {
+ skb = wl->tx_frames[i];
+ info = IEEE80211_SKB_CB(skb);
+
+ if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
+ continue;
+
+ ieee80211_tx_status(wl->hw, skb);
+ wl->tx_frames[i] = NULL;
+ }
+}
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h
new file mode 100644
index 00000000000..dc82691f4c1
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/tx.h
@@ -0,0 +1,215 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_TX_H__
+#define __WL12XX_TX_H__
+
+#include <linux/bitops.h>
+
+/*
+ *
+ * TX PATH
+ *
+ * The Tx path uses a double buffer and a tx_control structure, each located
+ * at a fixed address in the device's memory. On startup, the host retrieves
+ * the pointers to these addresses. A double buffer allows for continuous data
+ * flow towards the device. The host keeps track of which buffer is available
+ * and alternates between these two buffers on a per packet basis.
+ *
+ * The size of each of the two buffers is large enough to hold the longest
+ * 802.3 packet - maximum size Ethernet packet + header + descriptor.
+ * TX complete indication will be received a-synchronously in a TX done cyclic
+ * buffer which is composed of 16 tx_result descriptors structures and is used
+ * in a cyclic manner.
+ *
+ * The TX (HOST) procedure is as follows:
+ * 1. Read the Tx path status, that will give the data_out_count.
+ * 2. goto 1, if not possible.
+ * i.e. if data_in_count - data_out_count >= HwBuffer size (2 for double
+ * buffer).
+ * 3. Copy the packet (preceded by double_buffer_desc), if possible.
+ * i.e. if data_in_count - data_out_count < HwBuffer size (2 for double
+ * buffer).
+ * 4. increment data_in_count.
+ * 5. Inform the firmware by generating a firmware internal interrupt.
+ * 6. FW will increment data_out_count after it reads the buffer.
+ *
+ * The TX Complete procedure:
+ * 1. To get a TX complete indication the host enables the tx_complete flag in
+ * the TX descriptor Structure.
+ * 2. For each packet with a Tx Complete field set, the firmware adds the
+ * transmit results to the cyclic buffer (txDoneRing) and sets both done_1
+ * and done_2 to 1 to indicate driver ownership.
+ * 3. The firmware sends a Tx Complete interrupt to the host to trigger the
+ * host to process the new data. Note: interrupt will be send per packet if
+ * TX complete indication was requested in tx_control or per crossing
+ * aggregation threshold.
+ * 4. After receiving the Tx Complete interrupt, the host reads the
+ * TxDescriptorDone information in a cyclic manner and clears both done_1
+ * and done_2 fields.
+ *
+ */
+
+#define TX_COMPLETE_REQUIRED_BIT 0x80
+#define TX_STATUS_DATA_OUT_COUNT_MASK 0xf
+#define WL12XX_TX_ALIGN_TO 4
+#define WL12XX_TX_ALIGN(len) (((len) + WL12XX_TX_ALIGN_TO - 1) & \
+ ~(WL12XX_TX_ALIGN_TO - 1))
+#define WL12XX_TKIP_IV_SPACE 4
+
+struct tx_control {
+ /* Rate Policy (class) index */
+ unsigned rate_policy:3;
+
+ /* When set, no ack policy is expected */
+ unsigned ack_policy:1;
+
+ /*
+ * Packet type:
+ * 0 -> 802.11
+ * 1 -> 802.3
+ * 2 -> IP
+ * 3 -> raw codec
+ */
+ unsigned packet_type:2;
+
+ /* If set, this is a QoS-Null or QoS-Data frame */
+ unsigned qos:1;
+
+ /*
+ * If set, the target triggers the tx complete INT
+ * upon frame sending completion.
+ */
+ unsigned tx_complete:1;
+
+ /* 2 bytes padding before packet header */
+ unsigned xfer_pad:1;
+
+ unsigned reserved:7;
+} __attribute__ ((packed));
+
+
+struct tx_double_buffer_desc {
+ /* Length of payload, including headers. */
+ u16 length;
+
+ /*
+ * A bit mask that specifies the initial rate to be used
+ * Possible values are:
+ * 0x0001 - 1Mbits
+ * 0x0002 - 2Mbits
+ * 0x0004 - 5.5Mbits
+ * 0x0008 - 6Mbits
+ * 0x0010 - 9Mbits
+ * 0x0020 - 11Mbits
+ * 0x0040 - 12Mbits
+ * 0x0080 - 18Mbits
+ * 0x0100 - 22Mbits
+ * 0x0200 - 24Mbits
+ * 0x0400 - 36Mbits
+ * 0x0800 - 48Mbits
+ * 0x1000 - 54Mbits
+ */
+ u16 rate;
+
+ /* Time in us that a packet can spend in the target */
+ u32 expiry_time;
+
+ /* index of the TX queue used for this packet */
+ u8 xmit_queue;
+
+ /* Used to identify a packet */
+ u8 id;
+
+ struct tx_control control;
+
+ /*
+ * The FW should cut the packet into fragments
+ * of this size.
+ */
+ u16 frag_threshold;
+
+ /* Numbers of HW queue blocks to be allocated */
+ u8 num_mem_blocks;
+
+ u8 reserved;
+} __attribute__ ((packed));
+
+enum {
+ TX_SUCCESS = 0,
+ TX_DMA_ERROR = BIT(7),
+ TX_DISABLED = BIT(6),
+ TX_RETRY_EXCEEDED = BIT(5),
+ TX_TIMEOUT = BIT(4),
+ TX_KEY_NOT_FOUND = BIT(3),
+ TX_ENCRYPT_FAIL = BIT(2),
+ TX_UNAVAILABLE_PRIORITY = BIT(1),
+};
+
+struct tx_result {
+ /*
+ * Ownership synchronization between the host and
+ * the firmware. If done_1 and done_2 are cleared,
+ * owned by the FW (no info ready).
+ */
+ u8 done_1;
+
+ /* same as double_buffer_desc->id */
+ u8 id;
+
+ /*
+ * Total air access duration consumed by this
+ * packet, including all retries and overheads.
+ */
+ u16 medium_usage;
+
+ /* Total media delay (from 1st EDCA AIFS counter until TX Complete). */
+ u32 medium_delay;
+
+ /* Time between host xfer and tx complete */
+ u32 fw_hnadling_time;
+
+ /* The LS-byte of the last TKIP sequence number. */
+ u8 lsb_seq_num;
+
+ /* Retry count */
+ u8 ack_failures;
+
+ /* At which rate we got a ACK */
+ u16 rate;
+
+ u16 reserved;
+
+ /* TX_* */
+ u8 status;
+
+ /* See done_1 */
+ u8 done_2;
+} __attribute__ ((packed));
+
+void wl12xx_tx_work(struct work_struct *work);
+void wl12xx_tx_complete(struct wl12xx *wl);
+void wl12xx_tx_flush(struct wl12xx *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251.c b/drivers/net/wireless/wl12xx/wl1251.c
new file mode 100644
index 00000000000..ce1561a41fa
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251.c
@@ -0,0 +1,709 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "wl1251.h"
+#include "reg.h"
+#include "spi.h"
+#include "boot.h"
+#include "event.h"
+#include "acx.h"
+#include "tx.h"
+#include "rx.h"
+#include "ps.h"
+#include "init.h"
+
+static struct wl12xx_partition_set wl1251_part_table[PART_TABLE_LEN] = {
+ [PART_DOWN] = {
+ .mem = {
+ .start = 0x00000000,
+ .size = 0x00016800
+ },
+ .reg = {
+ .start = REGISTERS_BASE,
+ .size = REGISTERS_DOWN_SIZE
+ },
+ },
+
+ [PART_WORK] = {
+ .mem = {
+ .start = 0x00028000,
+ .size = 0x00014000
+ },
+ .reg = {
+ .start = REGISTERS_BASE,
+ .size = REGISTERS_WORK_SIZE
+ },
+ },
+
+ /* WL1251 doesn't use the DRPW partition, so we don't set it here */
+};
+
+static enum wl12xx_acx_int_reg wl1251_acx_reg_table[ACX_REG_TABLE_LEN] = {
+ [ACX_REG_INTERRUPT_TRIG] = (REGISTERS_BASE + 0x0474),
+ [ACX_REG_INTERRUPT_TRIG_H] = (REGISTERS_BASE + 0x0478),
+ [ACX_REG_INTERRUPT_MASK] = (REGISTERS_BASE + 0x0494),
+ [ACX_REG_HINT_MASK_SET] = (REGISTERS_BASE + 0x0498),
+ [ACX_REG_HINT_MASK_CLR] = (REGISTERS_BASE + 0x049C),
+ [ACX_REG_INTERRUPT_NO_CLEAR] = (REGISTERS_BASE + 0x04B0),
+ [ACX_REG_INTERRUPT_CLEAR] = (REGISTERS_BASE + 0x04A4),
+ [ACX_REG_INTERRUPT_ACK] = (REGISTERS_BASE + 0x04A8),
+ [ACX_REG_SLV_SOFT_RESET] = (REGISTERS_BASE + 0x0000),
+ [ACX_REG_EE_START] = (REGISTERS_BASE + 0x080C),
+ [ACX_REG_ECPU_CONTROL] = (REGISTERS_BASE + 0x0804)
+};
+
+static int wl1251_upload_firmware(struct wl12xx *wl)
+{
+ struct wl12xx_partition_set *p_table = wl->chip.p_table;
+ int addr, chunk_num, partition_limit;
+ size_t fw_data_len;
+ u8 *p;
+
+ /* whal_FwCtrl_LoadFwImageSm() */
+
+ wl12xx_debug(DEBUG_BOOT, "chip id before fw upload: 0x%x",
+ wl12xx_reg_read32(wl, CHIP_ID_B));
+
+ /* 10.0 check firmware length and set partition */
+ fw_data_len = (wl->fw[4] << 24) | (wl->fw[5] << 16) |
+ (wl->fw[6] << 8) | (wl->fw[7]);
+
+ wl12xx_debug(DEBUG_BOOT, "fw_data_len %zu chunk_size %d", fw_data_len,
+ CHUNK_SIZE);
+
+ if ((fw_data_len % 4) != 0) {
+ wl12xx_error("firmware length not multiple of four");
+ return -EIO;
+ }
+
+ wl12xx_set_partition(wl,
+ p_table[PART_DOWN].mem.start,
+ p_table[PART_DOWN].mem.size,
+ p_table[PART_DOWN].reg.start,
+ p_table[PART_DOWN].reg.size);
+
+ /* 10.1 set partition limit and chunk num */
+ chunk_num = 0;
+ partition_limit = p_table[PART_DOWN].mem.size;
+
+ while (chunk_num < fw_data_len / CHUNK_SIZE) {
+ /* 10.2 update partition, if needed */
+ addr = p_table[PART_DOWN].mem.start +
+ (chunk_num + 2) * CHUNK_SIZE;
+ if (addr > partition_limit) {
+ addr = p_table[PART_DOWN].mem.start +
+ chunk_num * CHUNK_SIZE;
+ partition_limit = chunk_num * CHUNK_SIZE +
+ p_table[PART_DOWN].mem.size;
+ wl12xx_set_partition(wl,
+ addr,
+ p_table[PART_DOWN].mem.size,
+ p_table[PART_DOWN].reg.start,
+ p_table[PART_DOWN].reg.size);
+ }
+
+ /* 10.3 upload the chunk */
+ addr = p_table[PART_DOWN].mem.start + chunk_num * CHUNK_SIZE;
+ p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
+ wl12xx_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
+ p, addr);
+ wl12xx_spi_mem_write(wl, addr, p, CHUNK_SIZE);
+
+ chunk_num++;
+ }
+
+ /* 10.4 upload the last chunk */
+ addr = p_table[PART_DOWN].mem.start + chunk_num * CHUNK_SIZE;
+ p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
+ wl12xx_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
+ fw_data_len % CHUNK_SIZE, p, addr);
+ wl12xx_spi_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE);
+
+ return 0;
+}
+
+static int wl1251_upload_nvs(struct wl12xx *wl)
+{
+ size_t nvs_len, nvs_bytes_written, burst_len;
+ int nvs_start, i;
+ u32 dest_addr, val;
+ u8 *nvs_ptr, *nvs;
+
+ nvs = wl->nvs;
+ if (nvs == NULL)
+ return -ENODEV;
+
+ nvs_ptr = nvs;
+
+ nvs_len = wl->nvs_len;
+ nvs_start = wl->fw_len;
+
+ /*
+ * Layout before the actual NVS tables:
+ * 1 byte : burst length.
+ * 2 bytes: destination address.
+ * n bytes: data to burst copy.
+ *
+ * This is ended by a 0 length, then the NVS tables.
+ */
+
+ while (nvs_ptr[0]) {
+ burst_len = nvs_ptr[0];
+ dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
+
+ /* We move our pointer to the data */
+ nvs_ptr += 3;
+
+ for (i = 0; i < burst_len; i++) {
+ val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
+ | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
+
+ wl12xx_debug(DEBUG_BOOT,
+ "nvs burst write 0x%x: 0x%x",
+ dest_addr, val);
+ wl12xx_mem_write32(wl, dest_addr, val);
+
+ nvs_ptr += 4;
+ dest_addr += 4;
+ }
+ }
+
+ /*
+ * We've reached the first zero length, the first NVS table
+ * is 7 bytes further.
+ */
+ nvs_ptr += 7;
+ nvs_len -= nvs_ptr - nvs;
+ nvs_len = ALIGN(nvs_len, 4);
+
+ /* Now we must set the partition correctly */
+ wl12xx_set_partition(wl, nvs_start,
+ wl->chip.p_table[PART_DOWN].mem.size,
+ wl->chip.p_table[PART_DOWN].reg.start,
+ wl->chip.p_table[PART_DOWN].reg.size);
+
+ /* And finally we upload the NVS tables */
+ nvs_bytes_written = 0;
+ while (nvs_bytes_written < nvs_len) {
+ val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
+ | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
+
+ val = cpu_to_le32(val);
+
+ wl12xx_debug(DEBUG_BOOT,
+ "nvs write table 0x%x: 0x%x",
+ nvs_start, val);
+ wl12xx_mem_write32(wl, nvs_start, val);
+
+ nvs_ptr += 4;
+ nvs_bytes_written += 4;
+ nvs_start += 4;
+ }
+
+ return 0;
+}
+
+static int wl1251_boot(struct wl12xx *wl)
+{
+ int ret = 0, minor_minor_e2_ver;
+ u32 tmp, boot_data;
+
+ ret = wl12xx_boot_soft_reset(wl);
+ if (ret < 0)
+ goto out;
+
+ /* 2. start processing NVS file */
+ ret = wl->chip.op_upload_nvs(wl);
+ if (ret < 0)
+ goto out;
+
+ /* write firmware's last address (ie. it's length) to
+ * ACX_EEPROMLESS_IND_REG */
+ wl12xx_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
+
+ /* 6. read the EEPROM parameters */
+ tmp = wl12xx_reg_read32(wl, SCR_PAD2);
+
+ /* 7. read bootdata */
+ wl->boot_attr.radio_type = (tmp & 0x0000FF00) >> 8;
+ wl->boot_attr.major = (tmp & 0x00FF0000) >> 16;
+ tmp = wl12xx_reg_read32(wl, SCR_PAD3);
+
+ /* 8. check bootdata and call restart sequence */
+ wl->boot_attr.minor = (tmp & 0x00FF0000) >> 16;
+ minor_minor_e2_ver = (tmp & 0xFF000000) >> 24;
+
+ wl12xx_debug(DEBUG_BOOT, "radioType 0x%x majorE2Ver 0x%x "
+ "minorE2Ver 0x%x minor_minor_e2_ver 0x%x",
+ wl->boot_attr.radio_type, wl->boot_attr.major,
+ wl->boot_attr.minor, minor_minor_e2_ver);
+
+ ret = wl12xx_boot_init_seq(wl);
+ if (ret < 0)
+ goto out;
+
+ /* 9. NVS processing done */
+ boot_data = wl12xx_reg_read32(wl, ACX_REG_ECPU_CONTROL);
+
+ wl12xx_debug(DEBUG_BOOT, "halt boot_data 0x%x", boot_data);
+
+ /* 10. check that ECPU_CONTROL_HALT bits are set in
+ * pWhalBus->uBootData and start uploading firmware
+ */
+ if ((boot_data & ECPU_CONTROL_HALT) == 0) {
+ wl12xx_error("boot failed, ECPU_CONTROL_HALT not set");
+ ret = -EIO;
+ goto out;
+ }
+
+ ret = wl->chip.op_upload_fw(wl);
+ if (ret < 0)
+ goto out;
+
+ /* 10.5 start firmware */
+ ret = wl12xx_boot_run_firmware(wl);
+ if (ret < 0)
+ goto out;
+
+ /* Get and save the firmware version */
+ wl12xx_acx_fw_version(wl, wl->chip.fw_ver, sizeof(wl->chip.fw_ver));
+
+out:
+ return ret;
+}
+
+static int wl1251_mem_cfg(struct wl12xx *wl)
+{
+ struct wl1251_acx_config_memory mem_conf;
+ int ret, i;
+
+ wl12xx_debug(DEBUG_ACX, "wl1251 mem cfg");
+
+ /* memory config */
+ mem_conf.mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
+ mem_conf.mem_config.rx_mem_block_num = 35;
+ mem_conf.mem_config.tx_min_mem_block_num = 64;
+ mem_conf.mem_config.num_tx_queues = MAX_TX_QUEUES;
+ mem_conf.mem_config.host_if_options = HOSTIF_PKT_RING;
+ mem_conf.mem_config.num_ssid_profiles = 1;
+ mem_conf.mem_config.debug_buffer_size =
+ cpu_to_le16(TRACE_BUFFER_MAX_SIZE);
+
+ /* RX queue config */
+ mem_conf.rx_queue_config.dma_address = 0;
+ mem_conf.rx_queue_config.num_descs = ACX_RX_DESC_DEF;
+ mem_conf.rx_queue_config.priority = DEFAULT_RXQ_PRIORITY;
+ mem_conf.rx_queue_config.type = DEFAULT_RXQ_TYPE;
+
+ /* TX queue config */
+ for (i = 0; i < MAX_TX_QUEUES; i++) {
+ mem_conf.tx_queue_config[i].num_descs = ACX_TX_DESC_DEF;
+ mem_conf.tx_queue_config[i].attributes = i;
+ }
+
+ mem_conf.header.id = ACX_MEM_CFG;
+ mem_conf.header.len = sizeof(struct wl1251_acx_config_memory) -
+ sizeof(struct acx_header);
+ mem_conf.header.len -=
+ (MAX_TX_QUEUE_CONFIGS - mem_conf.mem_config.num_tx_queues) *
+ sizeof(struct wl1251_acx_tx_queue_config);
+
+ ret = wl12xx_cmd_configure(wl, &mem_conf,
+ sizeof(struct wl1251_acx_config_memory));
+ if (ret < 0)
+ wl12xx_warning("wl1251 mem config failed: %d", ret);
+
+ return ret;
+}
+
+static int wl1251_hw_init_mem_config(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl1251_mem_cfg(wl);
+ if (ret < 0)
+ return ret;
+
+ wl->target_mem_map = kzalloc(sizeof(struct wl1251_acx_mem_map),
+ GFP_KERNEL);
+ if (!wl->target_mem_map) {
+ wl12xx_error("couldn't allocate target memory map");
+ return -ENOMEM;
+ }
+
+ /* we now ask for the firmware built memory map */
+ ret = wl12xx_acx_mem_map(wl, wl->target_mem_map,
+ sizeof(struct wl1251_acx_mem_map));
+ if (ret < 0) {
+ wl12xx_error("couldn't retrieve firmware memory map");
+ kfree(wl->target_mem_map);
+ wl->target_mem_map = NULL;
+ return ret;
+ }
+
+ return 0;
+}
+
+static void wl1251_set_ecpu_ctrl(struct wl12xx *wl, u32 flag)
+{
+ u32 cpu_ctrl;
+
+ /* 10.5.0 run the firmware (I) */
+ cpu_ctrl = wl12xx_reg_read32(wl, ACX_REG_ECPU_CONTROL);
+
+ /* 10.5.1 run the firmware (II) */
+ cpu_ctrl &= ~flag;
+ wl12xx_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
+}
+
+static void wl1251_target_enable_interrupts(struct wl12xx *wl)
+{
+ /* Enable target's interrupts */
+ wl->intr_mask = WL1251_ACX_INTR_RX0_DATA |
+ WL1251_ACX_INTR_RX1_DATA |
+ WL1251_ACX_INTR_TX_RESULT |
+ WL1251_ACX_INTR_EVENT_A |
+ WL1251_ACX_INTR_EVENT_B |
+ WL1251_ACX_INTR_INIT_COMPLETE;
+ wl12xx_boot_target_enable_interrupts(wl);
+}
+
+static void wl1251_irq_work(struct work_struct *work)
+{
+ u32 intr;
+ struct wl12xx *wl =
+ container_of(work, struct wl12xx, irq_work);
+
+ mutex_lock(&wl->mutex);
+
+ wl12xx_debug(DEBUG_IRQ, "IRQ work");
+
+ if (wl->state == WL12XX_STATE_OFF)
+ goto out;
+
+ wl12xx_ps_elp_wakeup(wl);
+
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1251_ACX_INTR_ALL);
+
+ intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
+ wl12xx_debug(DEBUG_IRQ, "intr: 0x%x", intr);
+
+ if (wl->data_path) {
+ wl12xx_spi_mem_read(wl, wl->data_path->rx_control_addr,
+ &wl->rx_counter, sizeof(u32));
+
+ /* We handle a frmware bug here */
+ switch ((wl->rx_counter - wl->rx_handled) & 0xf) {
+ case 0:
+ wl12xx_debug(DEBUG_IRQ, "RX: FW and host in sync");
+ intr &= ~WL1251_ACX_INTR_RX0_DATA;
+ intr &= ~WL1251_ACX_INTR_RX1_DATA;
+ break;
+ case 1:
+ wl12xx_debug(DEBUG_IRQ, "RX: FW +1");
+ intr |= WL1251_ACX_INTR_RX0_DATA;
+ intr &= ~WL1251_ACX_INTR_RX1_DATA;
+ break;
+ case 2:
+ wl12xx_debug(DEBUG_IRQ, "RX: FW +2");
+ intr |= WL1251_ACX_INTR_RX0_DATA;
+ intr |= WL1251_ACX_INTR_RX1_DATA;
+ break;
+ default:
+ wl12xx_warning("RX: FW and host out of sync: %d",
+ wl->rx_counter - wl->rx_handled);
+ break;
+ }
+
+ wl->rx_handled = wl->rx_counter;
+
+
+ wl12xx_debug(DEBUG_IRQ, "RX counter: %d", wl->rx_counter);
+ }
+
+ intr &= wl->intr_mask;
+
+ if (intr == 0) {
+ wl12xx_debug(DEBUG_IRQ, "INTR is 0");
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
+ ~(wl->intr_mask));
+
+ goto out_sleep;
+ }
+
+ if (intr & WL1251_ACX_INTR_RX0_DATA) {
+ wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
+ wl12xx_rx(wl);
+ }
+
+ if (intr & WL1251_ACX_INTR_RX1_DATA) {
+ wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA");
+ wl12xx_rx(wl);
+ }
+
+ if (intr & WL1251_ACX_INTR_TX_RESULT) {
+ wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
+ wl12xx_tx_complete(wl);
+ }
+
+ if (intr & (WL1251_ACX_INTR_EVENT_A | WL1251_ACX_INTR_EVENT_B)) {
+ wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", intr);
+ if (intr & WL1251_ACX_INTR_EVENT_A)
+ wl12xx_event_handle(wl, 0);
+ else
+ wl12xx_event_handle(wl, 1);
+ }
+
+ if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
+ wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_INIT_COMPLETE");
+
+ wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
+
+out_sleep:
+ wl12xx_ps_elp_sleep(wl);
+out:
+ mutex_unlock(&wl->mutex);
+}
+
+static int wl1251_hw_init_txq_fill(u8 qid,
+ struct acx_tx_queue_qos_config *config,
+ u32 num_blocks)
+{
+ config->qid = qid;
+
+ switch (qid) {
+ case QOS_AC_BE:
+ config->high_threshold =
+ (QOS_TX_HIGH_BE_DEF * num_blocks) / 100;
+ config->low_threshold =
+ (QOS_TX_LOW_BE_DEF * num_blocks) / 100;
+ break;
+ case QOS_AC_BK:
+ config->high_threshold =
+ (QOS_TX_HIGH_BK_DEF * num_blocks) / 100;
+ config->low_threshold =
+ (QOS_TX_LOW_BK_DEF * num_blocks) / 100;
+ break;
+ case QOS_AC_VI:
+ config->high_threshold =
+ (QOS_TX_HIGH_VI_DEF * num_blocks) / 100;
+ config->low_threshold =
+ (QOS_TX_LOW_VI_DEF * num_blocks) / 100;
+ break;
+ case QOS_AC_VO:
+ config->high_threshold =
+ (QOS_TX_HIGH_VO_DEF * num_blocks) / 100;
+ config->low_threshold =
+ (QOS_TX_LOW_VO_DEF * num_blocks) / 100;
+ break;
+ default:
+ wl12xx_error("Invalid TX queue id: %d", qid);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int wl1251_hw_init_tx_queue_config(struct wl12xx *wl)
+{
+ struct acx_tx_queue_qos_config config;
+ struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map;
+ int ret, i;
+
+ wl12xx_debug(DEBUG_ACX, "acx tx queue config");
+
+ config.header.id = ACX_TX_QUEUE_CFG;
+ config.header.len = sizeof(struct acx_tx_queue_qos_config) -
+ sizeof(struct acx_header);
+
+ for (i = 0; i < MAX_NUM_OF_AC; i++) {
+ ret = wl1251_hw_init_txq_fill(i, &config,
+ wl_mem_map->num_tx_mem_blocks);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_configure(wl, &config, sizeof(config));
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int wl1251_hw_init_data_path_config(struct wl12xx *wl)
+{
+ int ret;
+
+ /* asking for the data path parameters */
+ wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp),
+ GFP_KERNEL);
+ if (!wl->data_path) {
+ wl12xx_error("Couldnt allocate data path parameters");
+ return -ENOMEM;
+ }
+
+ ret = wl12xx_acx_data_path_params(wl, wl->data_path);
+ if (ret < 0) {
+ kfree(wl->data_path);
+ wl->data_path = NULL;
+ return ret;
+ }
+
+ return 0;
+}
+
+static int wl1251_hw_init(struct wl12xx *wl)
+{
+ struct wl1251_acx_mem_map *wl_mem_map;
+ int ret;
+
+ ret = wl12xx_hw_init_hwenc_config(wl);
+ if (ret < 0)
+ return ret;
+
+ /* Template settings */
+ ret = wl12xx_hw_init_templates_config(wl);
+ if (ret < 0)
+ return ret;
+
+ /* Default memory configuration */
+ ret = wl1251_hw_init_mem_config(wl);
+ if (ret < 0)
+ return ret;
+
+ /* Default data path configuration */
+ ret = wl1251_hw_init_data_path_config(wl);
+ if (ret < 0)
+ goto out_free_memmap;
+
+ /* RX config */
+ ret = wl12xx_hw_init_rx_config(wl,
+ RX_CFG_PROMISCUOUS | RX_CFG_TSF,
+ RX_FILTER_OPTION_DEF);
+ /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
+ RX_FILTER_OPTION_FILTER_ALL); */
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* TX queues config */
+ ret = wl1251_hw_init_tx_queue_config(wl);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* PHY layer config */
+ ret = wl12xx_hw_init_phy_config(wl);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* Beacon filtering */
+ ret = wl12xx_hw_init_beacon_filter(wl);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* Bluetooth WLAN coexistence */
+ ret = wl12xx_hw_init_pta(wl);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* Energy detection */
+ ret = wl12xx_hw_init_energy_detection(wl);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* Beacons and boradcast settings */
+ ret = wl12xx_hw_init_beacon_broadcast(wl);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* Enable data path */
+ ret = wl12xx_cmd_data_path(wl, wl->channel, 1);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ /* Default power state */
+ ret = wl12xx_hw_init_power_auth(wl);
+ if (ret < 0)
+ goto out_free_data_path;
+
+ wl_mem_map = wl->target_mem_map;
+ wl12xx_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x",
+ wl_mem_map->num_tx_mem_blocks,
+ wl->data_path->tx_control_addr,
+ wl_mem_map->num_rx_mem_blocks,
+ wl->data_path->rx_control_addr);
+
+ return 0;
+
+ out_free_data_path:
+ kfree(wl->data_path);
+
+ out_free_memmap:
+ kfree(wl->target_mem_map);
+
+ return ret;
+}
+
+static int wl1251_plt_init(struct wl12xx *wl)
+{
+ int ret;
+
+ ret = wl1251_hw_init_mem_config(wl);
+ if (ret < 0)
+ return ret;
+
+ ret = wl12xx_cmd_data_path(wl, wl->channel, 1);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+void wl1251_setup(struct wl12xx *wl)
+{
+ /* FIXME: Is it better to use strncpy here or is this ok? */
+ wl->chip.fw_filename = WL1251_FW_NAME;
+ wl->chip.nvs_filename = WL1251_NVS_NAME;
+
+ /* Now we know what chip we're using, so adjust the power on sleep
+ * time accordingly */
+ wl->chip.power_on_sleep = WL1251_POWER_ON_SLEEP;
+
+ wl->chip.intr_cmd_complete = WL1251_ACX_INTR_CMD_COMPLETE;
+ wl->chip.intr_init_complete = WL1251_ACX_INTR_INIT_COMPLETE;
+
+ wl->chip.op_upload_nvs = wl1251_upload_nvs;
+ wl->chip.op_upload_fw = wl1251_upload_firmware;
+ wl->chip.op_boot = wl1251_boot;
+ wl->chip.op_set_ecpu_ctrl = wl1251_set_ecpu_ctrl;
+ wl->chip.op_target_enable_interrupts = wl1251_target_enable_interrupts;
+ wl->chip.op_hw_init = wl1251_hw_init;
+ wl->chip.op_plt_init = wl1251_plt_init;
+
+ wl->chip.p_table = wl1251_part_table;
+ wl->chip.acx_reg_table = wl1251_acx_reg_table;
+
+ INIT_WORK(&wl->irq_work, wl1251_irq_work);
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
new file mode 100644
index 00000000000..1f4a4433039
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -0,0 +1,165 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL1251_H__
+#define __WL1251_H__
+
+#include <linux/bitops.h>
+
+#include "wl12xx.h"
+#include "acx.h"
+
+#define WL1251_FW_NAME "wl1251-fw.bin"
+#define WL1251_NVS_NAME "wl1251-nvs.bin"
+
+#define WL1251_POWER_ON_SLEEP 10 /* in miliseconds */
+
+void wl1251_setup(struct wl12xx *wl);
+
+
+struct wl1251_acx_memory {
+ __le16 num_stations; /* number of STAs to be supported. */
+ u16 reserved_1;
+
+ /*
+ * Nmber of memory buffers for the RX mem pool.
+ * The actual number may be less if there are
+ * not enough blocks left for the minimum num
+ * of TX ones.
+ */
+ u8 rx_mem_block_num;
+ u8 reserved_2;
+ u8 num_tx_queues; /* From 1 to 16 */
+ u8 host_if_options; /* HOST_IF* */
+ u8 tx_min_mem_block_num;
+ u8 num_ssid_profiles;
+ __le16 debug_buffer_size;
+} __attribute__ ((packed));
+
+
+#define ACX_RX_DESC_MIN 1
+#define ACX_RX_DESC_MAX 127
+#define ACX_RX_DESC_DEF 32
+struct wl1251_acx_rx_queue_config {
+ u8 num_descs;
+ u8 pad;
+ u8 type;
+ u8 priority;
+ __le32 dma_address;
+} __attribute__ ((packed));
+
+#define ACX_TX_DESC_MIN 1
+#define ACX_TX_DESC_MAX 127
+#define ACX_TX_DESC_DEF 16
+struct wl1251_acx_tx_queue_config {
+ u8 num_descs;
+ u8 pad[2];
+ u8 attributes;
+} __attribute__ ((packed));
+
+#define MAX_TX_QUEUE_CONFIGS 5
+#define MAX_TX_QUEUES 4
+struct wl1251_acx_config_memory {
+ struct acx_header header;
+
+ struct wl1251_acx_memory mem_config;
+ struct wl1251_acx_rx_queue_config rx_queue_config;
+ struct wl1251_acx_tx_queue_config tx_queue_config[MAX_TX_QUEUE_CONFIGS];
+} __attribute__ ((packed));
+
+struct wl1251_acx_mem_map {
+ struct acx_header header;
+
+ void *code_start;
+ void *code_end;
+
+ void *wep_defkey_start;
+ void *wep_defkey_end;
+
+ void *sta_table_start;
+ void *sta_table_end;
+
+ void *packet_template_start;
+ void *packet_template_end;
+
+ void *queue_memory_start;
+ void *queue_memory_end;
+
+ void *packet_memory_pool_start;
+ void *packet_memory_pool_end;
+
+ void *debug_buffer1_start;
+ void *debug_buffer1_end;
+
+ void *debug_buffer2_start;
+ void *debug_buffer2_end;
+
+ /* Number of blocks FW allocated for TX packets */
+ u32 num_tx_mem_blocks;
+
+ /* Number of blocks FW allocated for RX packets */
+ u32 num_rx_mem_blocks;
+} __attribute__ ((packed));
+
+/*************************************************************************
+
+ Host Interrupt Register (WiLink -> Host)
+
+**************************************************************************/
+
+/* RX packet is ready in Xfer buffer #0 */
+#define WL1251_ACX_INTR_RX0_DATA BIT(0)
+
+/* TX result(s) are in the TX complete buffer */
+#define WL1251_ACX_INTR_TX_RESULT BIT(1)
+
+/* OBSOLETE */
+#define WL1251_ACX_INTR_TX_XFR BIT(2)
+
+/* RX packet is ready in Xfer buffer #1 */
+#define WL1251_ACX_INTR_RX1_DATA BIT(3)
+
+/* Event was entered to Event MBOX #A */
+#define WL1251_ACX_INTR_EVENT_A BIT(4)
+
+/* Event was entered to Event MBOX #B */
+#define WL1251_ACX_INTR_EVENT_B BIT(5)
+
+/* OBSOLETE */
+#define WL1251_ACX_INTR_WAKE_ON_HOST BIT(6)
+
+/* Trace meassge on MBOX #A */
+#define WL1251_ACX_INTR_TRACE_A BIT(7)
+
+/* Trace meassge on MBOX #B */
+#define WL1251_ACX_INTR_TRACE_B BIT(8)
+
+/* Command processing completion */
+#define WL1251_ACX_INTR_CMD_COMPLETE BIT(9)
+
+/* Init sequence is done */
+#define WL1251_ACX_INTR_INIT_COMPLETE BIT(14)
+
+#define WL1251_ACX_INTR_ALL 0xFFFFFFFF
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
new file mode 100644
index 00000000000..48641437414
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -0,0 +1,409 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_H__
+#define __WL12XX_H__
+
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/bitops.h>
+#include <net/mac80211.h>
+
+#define DRIVER_NAME "wl12xx"
+#define DRIVER_PREFIX DRIVER_NAME ": "
+
+enum {
+ DEBUG_NONE = 0,
+ DEBUG_IRQ = BIT(0),
+ DEBUG_SPI = BIT(1),
+ DEBUG_BOOT = BIT(2),
+ DEBUG_MAILBOX = BIT(3),
+ DEBUG_NETLINK = BIT(4),
+ DEBUG_EVENT = BIT(5),
+ DEBUG_TX = BIT(6),
+ DEBUG_RX = BIT(7),
+ DEBUG_SCAN = BIT(8),
+ DEBUG_CRYPT = BIT(9),
+ DEBUG_PSM = BIT(10),
+ DEBUG_MAC80211 = BIT(11),
+ DEBUG_CMD = BIT(12),
+ DEBUG_ACX = BIT(13),
+ DEBUG_ALL = ~0,
+};
+
+#define DEBUG_LEVEL (DEBUG_NONE)
+
+#define DEBUG_DUMP_LIMIT 1024
+
+#define wl12xx_error(fmt, arg...) \
+ printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
+
+#define wl12xx_warning(fmt, arg...) \
+ printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
+
+#define wl12xx_notice(fmt, arg...) \
+ printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
+
+#define wl12xx_info(fmt, arg...) \
+ printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg)
+
+#define wl12xx_debug(level, fmt, arg...) \
+ do { \
+ if (level & DEBUG_LEVEL) \
+ printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
+ } while (0)
+
+#define wl12xx_dump(level, prefix, buf, len) \
+ do { \
+ if (level & DEBUG_LEVEL) \
+ print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
+ DUMP_PREFIX_OFFSET, 16, 1, \
+ buf, \
+ min_t(size_t, len, DEBUG_DUMP_LIMIT), \
+ 0); \
+ } while (0)
+
+#define wl12xx_dump_ascii(level, prefix, buf, len) \
+ do { \
+ if (level & DEBUG_LEVEL) \
+ print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
+ DUMP_PREFIX_OFFSET, 16, 1, \
+ buf, \
+ min_t(size_t, len, DEBUG_DUMP_LIMIT), \
+ true); \
+ } while (0)
+
+#define WL12XX_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \
+ CFG_BSSID_FILTER_EN)
+
+#define WL12XX_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN | \
+ CFG_RX_MGMT_EN | \
+ CFG_RX_DATA_EN | \
+ CFG_RX_CTL_EN | \
+ CFG_RX_BCN_EN | \
+ CFG_RX_AUTH_EN | \
+ CFG_RX_ASSOC_EN)
+
+
+struct boot_attr {
+ u32 radio_type;
+ u8 mac_clock;
+ u8 arm_clock;
+ int firmware_debug;
+ u32 minor;
+ u32 major;
+ u32 bugfix;
+};
+
+enum wl12xx_state {
+ WL12XX_STATE_OFF,
+ WL12XX_STATE_ON,
+ WL12XX_STATE_PLT,
+};
+
+enum wl12xx_partition_type {
+ PART_DOWN,
+ PART_WORK,
+ PART_DRPW,
+
+ PART_TABLE_LEN
+};
+
+struct wl12xx_partition {
+ u32 size;
+ u32 start;
+};
+
+struct wl12xx_partition_set {
+ struct wl12xx_partition mem;
+ struct wl12xx_partition reg;
+};
+
+struct wl12xx;
+
+/* FIXME: I'm not sure about this structure name */
+struct wl12xx_chip {
+ u32 id;
+
+ const char *fw_filename;
+ const char *nvs_filename;
+
+ char fw_ver[21];
+
+ unsigned int power_on_sleep;
+ int intr_cmd_complete;
+ int intr_init_complete;
+
+ int (*op_upload_fw)(struct wl12xx *wl);
+ int (*op_upload_nvs)(struct wl12xx *wl);
+ int (*op_boot)(struct wl12xx *wl);
+ void (*op_set_ecpu_ctrl)(struct wl12xx *wl, u32 flag);
+ void (*op_target_enable_interrupts)(struct wl12xx *wl);
+ int (*op_hw_init)(struct wl12xx *wl);
+ int (*op_plt_init)(struct wl12xx *wl);
+
+ struct wl12xx_partition_set *p_table;
+ enum wl12xx_acx_int_reg *acx_reg_table;
+};
+
+struct wl12xx_stats {
+ struct acx_statistics *fw_stats;
+ unsigned long fw_stats_update;
+
+ unsigned int retry_count;
+ unsigned int excessive_retries;
+};
+
+struct wl12xx_debugfs {
+ struct dentry *rootdir;
+ struct dentry *fw_statistics;
+
+ struct dentry *tx_internal_desc_overflow;
+
+ struct dentry *rx_out_of_mem;
+ struct dentry *rx_hdr_overflow;
+ struct dentry *rx_hw_stuck;
+ struct dentry *rx_dropped;
+ struct dentry *rx_fcs_err;
+ struct dentry *rx_xfr_hint_trig;
+ struct dentry *rx_path_reset;
+ struct dentry *rx_reset_counter;
+
+ struct dentry *dma_rx_requested;
+ struct dentry *dma_rx_errors;
+ struct dentry *dma_tx_requested;
+ struct dentry *dma_tx_errors;
+
+ struct dentry *isr_cmd_cmplt;
+ struct dentry *isr_fiqs;
+ struct dentry *isr_rx_headers;
+ struct dentry *isr_rx_mem_overflow;
+ struct dentry *isr_rx_rdys;
+ struct dentry *isr_irqs;
+ struct dentry *isr_tx_procs;
+ struct dentry *isr_decrypt_done;
+ struct dentry *isr_dma0_done;
+ struct dentry *isr_dma1_done;
+ struct dentry *isr_tx_exch_complete;
+ struct dentry *isr_commands;
+ struct dentry *isr_rx_procs;
+ struct dentry *isr_hw_pm_mode_changes;
+ struct dentry *isr_host_acknowledges;
+ struct dentry *isr_pci_pm;
+ struct dentry *isr_wakeups;
+ struct dentry *isr_low_rssi;
+
+ struct dentry *wep_addr_key_count;
+ struct dentry *wep_default_key_count;
+ /* skipping wep.reserved */
+ struct dentry *wep_key_not_found;
+ struct dentry *wep_decrypt_fail;
+ struct dentry *wep_packets;
+ struct dentry *wep_interrupt;
+
+ struct dentry *pwr_ps_enter;
+ struct dentry *pwr_elp_enter;
+ struct dentry *pwr_missing_bcns;
+ struct dentry *pwr_wake_on_host;
+ struct dentry *pwr_wake_on_timer_exp;
+ struct dentry *pwr_tx_with_ps;
+ struct dentry *pwr_tx_without_ps;
+ struct dentry *pwr_rcvd_beacons;
+ struct dentry *pwr_power_save_off;
+ struct dentry *pwr_enable_ps;
+ struct dentry *pwr_disable_ps;
+ struct dentry *pwr_fix_tsf_ps;
+ /* skipping cont_miss_bcns_spread for now */
+ struct dentry *pwr_rcvd_awake_beacons;
+
+ struct dentry *mic_rx_pkts;
+ struct dentry *mic_calc_failure;
+
+ struct dentry *aes_encrypt_fail;
+ struct dentry *aes_decrypt_fail;
+ struct dentry *aes_encrypt_packets;
+ struct dentry *aes_decrypt_packets;
+ struct dentry *aes_encrypt_interrupt;
+ struct dentry *aes_decrypt_interrupt;
+
+ struct dentry *event_heart_beat;
+ struct dentry *event_calibration;
+ struct dentry *event_rx_mismatch;
+ struct dentry *event_rx_mem_empty;
+ struct dentry *event_rx_pool;
+ struct dentry *event_oom_late;
+ struct dentry *event_phy_transmit_error;
+ struct dentry *event_tx_stuck;
+
+ struct dentry *ps_pspoll_timeouts;
+ struct dentry *ps_upsd_timeouts;
+ struct dentry *ps_upsd_max_sptime;
+ struct dentry *ps_upsd_max_apturn;
+ struct dentry *ps_pspoll_max_apturn;
+ struct dentry *ps_pspoll_utilization;
+ struct dentry *ps_upsd_utilization;
+
+ struct dentry *rxpipe_rx_prep_beacon_drop;
+ struct dentry *rxpipe_descr_host_int_trig_rx_data;
+ struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data;
+ struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data;
+ struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
+
+ struct dentry *tx_queue_len;
+
+ struct dentry *retry_count;
+ struct dentry *excessive_retries;
+};
+
+struct wl12xx {
+ struct ieee80211_hw *hw;
+ bool mac80211_registered;
+
+ struct spi_device *spi;
+
+ void (*set_power)(bool enable);
+ int irq;
+
+ enum wl12xx_state state;
+ struct mutex mutex;
+
+ int physical_mem_addr;
+ int physical_reg_addr;
+ int virtual_mem_addr;
+ int virtual_reg_addr;
+
+ struct wl12xx_chip chip;
+
+ int cmd_box_addr;
+ int event_box_addr;
+ struct boot_attr boot_attr;
+
+ u8 *fw;
+ size_t fw_len;
+ u8 *nvs;
+ size_t nvs_len;
+
+ u8 bssid[ETH_ALEN];
+ u8 mac_addr[ETH_ALEN];
+ u8 bss_type;
+ u8 listen_int;
+ int channel;
+
+ void *target_mem_map;
+ struct acx_data_path_params_resp *data_path;
+
+ /* Number of TX packets transferred to the FW, modulo 16 */
+ u32 data_in_count;
+
+ /* Frames scheduled for transmission, not handled yet */
+ struct sk_buff_head tx_queue;
+ bool tx_queue_stopped;
+
+ struct work_struct tx_work;
+ struct work_struct filter_work;
+
+ /* Pending TX frames */
+ struct sk_buff *tx_frames[16];
+
+ /*
+ * Index pointing to the next TX complete entry
+ * in the cyclic XT complete array we get from
+ * the FW.
+ */
+ u32 next_tx_complete;
+
+ /* FW Rx counter */
+ u32 rx_counter;
+
+ /* Rx frames handled */
+ u32 rx_handled;
+
+ /* Current double buffer */
+ u32 rx_current_buffer;
+ u32 rx_last_id;
+
+ /* The target interrupt mask */
+ u32 intr_mask;
+ struct work_struct irq_work;
+
+ /* The mbox event mask */
+ u32 event_mask;
+
+ /* Mailbox pointers */
+ u32 mbox_ptr[2];
+
+ /* Are we currently scanning */
+ bool scanning;
+
+ /* Our association ID */
+ u16 aid;
+
+ /* Default key (for WEP) */
+ u32 default_key;
+
+ unsigned int tx_mgmt_frm_rate;
+ unsigned int tx_mgmt_frm_mod;
+
+ unsigned int rx_config;
+ unsigned int rx_filter;
+
+ /* is firmware in elp mode */
+ bool elp;
+
+ /* we can be in psm, but not in elp, we have to differentiate */
+ bool psm;
+
+ /* PSM mode requested */
+ bool psm_requested;
+
+ /* in dBm */
+ int power_level;
+
+ struct wl12xx_stats stats;
+ struct wl12xx_debugfs debugfs;
+};
+
+int wl12xx_plt_start(struct wl12xx *wl);
+int wl12xx_plt_stop(struct wl12xx *wl);
+
+#define DEFAULT_HW_GEN_MODULATION_TYPE CCK_LONG /* Long Preamble */
+#define DEFAULT_HW_GEN_TX_RATE RATE_2MBPS
+#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
+
+#define WL12XX_DEFAULT_POWER_LEVEL 20
+
+#define WL12XX_TX_QUEUE_MAX_LENGTH 20
+
+/* Different chips need different sleep times after power on. WL1271 needs
+ * 200ms, WL1251 needs only 10ms. By default we use 200ms, but as soon as we
+ * know the chip ID, we change the sleep value in the wl12xx chip structure,
+ * so in subsequent power ons, we don't waste more time then needed. */
+#define WL12XX_DEFAULT_POWER_ON_SLEEP 200
+
+#define CHIP_ID_1251_PG10 (0x7010101)
+#define CHIP_ID_1251_PG11 (0x7020101)
+#define CHIP_ID_1251_PG12 (0x7030101)
+#define CHIP_ID_1271_PG10 (0x4030101)
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h
new file mode 100644
index 00000000000..657c2dbcb7d
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/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];
+} __attribute__ ((packed));
+
+struct wl12xx_ie_header {
+ u8 id;
+ u8 len;
+} __attribute__ ((packed));
+
+/* IEs */
+
+struct wl12xx_ie_ssid {
+ struct wl12xx_ie_header header;
+ char ssid[IW_ESSID_MAX_SIZE];
+} __attribute__ ((packed));
+
+struct wl12xx_ie_rates {
+ struct wl12xx_ie_header header;
+ u8 rates[MAX_SUPPORTED_RATES];
+} __attribute__ ((packed));
+
+struct wl12xx_ie_ds_params {
+ struct wl12xx_ie_header header;
+ u8 channel;
+} __attribute__ ((packed));
+
+struct country_triplet {
+ u8 channel;
+ u8 num_channels;
+ u8 max_tx_power;
+} __attribute__ ((packed));
+
+struct wl12xx_ie_country {
+ struct wl12xx_ie_header header;
+ u8 country_string[COUNTRY_STRING_LEN];
+ struct country_triplet triplets[MAX_COUNTRY_TRIPLETS];
+} __attribute__ ((packed));
+
+
+/* Templates */
+
+struct wl12xx_beacon_template {
+ struct ieee80211_header header;
+ __le32 time_stamp[2];
+ __le16 beacon_interval;
+ __le16 capability;
+ struct wl12xx_ie_ssid ssid;
+ struct wl12xx_ie_rates rates;
+ struct wl12xx_ie_rates ext_rates;
+ struct wl12xx_ie_ds_params ds_params;
+ struct wl12xx_ie_country country;
+} __attribute__ ((packed));
+
+struct wl12xx_null_data_template {
+ struct ieee80211_header header;
+} __attribute__ ((packed));
+
+struct wl12xx_ps_poll_template {
+ u16 fc;
+ u16 aid;
+ u8 bssid[ETH_ALEN];
+ u8 ta[ETH_ALEN];
+} __attribute__ ((packed));
+
+struct wl12xx_qos_null_data_template {
+ struct ieee80211_header header;
+ __le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct wl12xx_probe_req_template {
+ struct ieee80211_header header;
+ struct wl12xx_ie_ssid ssid;
+ struct wl12xx_ie_rates rates;
+ struct wl12xx_ie_rates ext_rates;
+} __attribute__ ((packed));
+
+
+struct wl12xx_probe_resp_template {
+ struct ieee80211_header header;
+ __le32 time_stamp[2];
+ __le16 beacon_interval;
+ __le16 capability;
+ struct wl12xx_ie_ssid ssid;
+ struct wl12xx_ie_rates rates;
+ struct wl12xx_ie_rates ext_rates;
+ struct wl12xx_ie_ds_params ds_params;
+ struct wl12xx_ie_country country;
+} __attribute__ ((packed));
+
+#endif
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 1f64d6033ab..e3e96bb2c24 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1348,6 +1348,7 @@ static int wl3501_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (rc) {
++dev->stats.tx_dropped;
netif_stop_queue(dev);
+ rc = NETDEV_TX_OK;
} else {
++dev->stats.tx_packets;
dev->stats.tx_bytes += skb->len;
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 5fabd9c0f07..4430b8d92e2 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -819,11 +819,11 @@ static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (err) {
dev->stats.tx_errors++;
netif_start_queue(dev);
- return err;
+ } else {
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
+ dev->trans_start = jiffies;
}
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += skb->len;
- dev->trans_start = jiffies;
kfree_skb(skb);
return 0;
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index c3a51266de2..40b07b98822 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -420,9 +420,9 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
cs->control |= ZD_CS_NEED_RANDOM_BACKOFF;
- /* Multicast */
- if (is_multicast_ether_addr(header->addr1))
- cs->control |= ZD_CS_MULTICAST;
+ /* No ACK expected (multicast, etc.) */
+ if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+ cs->control |= ZD_CS_NO_ACK;
/* PS-POLL */
if (ieee80211_is_pspoll(header->frame_control))
@@ -755,52 +755,6 @@ static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
}
-static int zd_op_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct zd_mac *mac = zd_hw_mac(hw);
- int associated;
- int r;
-
- if (mac->type == NL80211_IFTYPE_MESH_POINT ||
- mac->type == NL80211_IFTYPE_ADHOC) {
- associated = true;
- if (conf->changed & IEEE80211_IFCC_BEACON) {
- struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
-
- if (!beacon)
- return -ENOMEM;
- r = zd_mac_config_beacon(hw, beacon);
- kfree_skb(beacon);
-
- if (r < 0)
- return r;
- }
-
- if (conf->changed & IEEE80211_IFCC_BEACON_ENABLED) {
- u32 interval;
-
- if (conf->enable_beacon)
- interval = BCN_MODE_IBSS | hw->conf.beacon_int;
- else
- interval = 0;
-
- r = zd_set_beacon_interval(&mac->chip, interval);
- if (r < 0)
- return r;
- }
- } else
- associated = is_valid_ether_addr(conf->bssid);
-
- spin_lock_irq(&mac->lock);
- mac->associated = associated;
- spin_unlock_irq(&mac->lock);
-
- /* TODO: do hardware bssid filtering */
- return 0;
-}
-
static void zd_process_intr(struct work_struct *work)
{
u16 int_status;
@@ -923,9 +877,42 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
{
struct zd_mac *mac = zd_hw_mac(hw);
unsigned long flags;
+ int associated;
dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);
+ if (mac->type == NL80211_IFTYPE_MESH_POINT ||
+ mac->type == NL80211_IFTYPE_ADHOC) {
+ associated = true;
+ if (changes & BSS_CHANGED_BEACON) {
+ struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
+
+ if (beacon) {
+ zd_mac_config_beacon(hw, beacon);
+ kfree_skb(beacon);
+ }
+ }
+
+ if (changes & BSS_CHANGED_BEACON_ENABLED) {
+ u32 interval;
+
+ if (bss_conf->enable_beacon)
+ interval = BCN_MODE_IBSS |
+ bss_conf->beacon_int;
+ else
+ interval = 0;
+
+ zd_set_beacon_interval(&mac->chip, interval);
+ }
+ } else
+ associated = is_valid_ether_addr(bss_conf->bssid);
+
+ spin_lock_irq(&mac->lock);
+ mac->associated = associated;
+ spin_unlock_irq(&mac->lock);
+
+ /* TODO: do hardware bssid filtering */
+
if (changes & BSS_CHANGED_ERP_PREAMBLE) {
spin_lock_irqsave(&mac->lock, flags);
mac->short_preamble = bss_conf->use_short_preamble;
@@ -952,7 +939,6 @@ static const struct ieee80211_ops zd_ops = {
.add_interface = zd_op_add_interface,
.remove_interface = zd_op_remove_interface,
.config = zd_op_config,
- .config_interface = zd_op_config_interface,
.configure_filter = zd_op_configure_filter,
.bss_info_changed = zd_op_bss_info_changed,
.get_tsf = zd_op_get_tsf,
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index 4c05d3ee4c3..7c2759118d1 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -87,7 +87,7 @@ struct zd_ctrlset {
/* zd_ctrlset control field */
#define ZD_CS_NEED_RANDOM_BACKOFF 0x01
-#define ZD_CS_MULTICAST 0x02
+#define ZD_CS_NO_ACK 0x02
#define ZD_CS_FRAME_TYPE_MASK 0x0c
#define ZD_CS_DATA_FRAME 0x00
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index 7477ffdcddb..3c7a5053f1d 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -717,7 +717,7 @@ static void yellowfin_tx_timeout(struct net_device *dev)
if (yp->cur_tx - yp->dirty_tx < TX_QUEUE_SIZE)
netif_wake_queue (dev); /* Typical path */
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
dev->stats.tx_errors++;
}
@@ -876,7 +876,6 @@ static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_start_queue (dev); /* Typical path */
else
yp->tx_full = 1;
- dev->trans_start = jiffies;
if (yellowfin_debug > 4) {
printk(KERN_DEBUG "%s: Yellowfin transmit frame #%d queued in slot %d.\n",